• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "audio_capturer_napi.h"
17 
18 #include "ability.h"
19 #include "hilog/log.h"
20 #include "napi_base_context.h"
21 #include "securec.h"
22 #include "xpower_event_js.h"
23 
24 #include "audio_errors.h"
25 #include "audio_log.h"
26 #include "audio_common_napi.h"
27 #include "audio_parameters_napi.h"
28 #include "audio_capturer_callback_napi.h"
29 #include "capturer_period_position_callback_napi.h"
30 #include "capturer_position_callback_napi.h"
31 #include "audio_manager_napi.h"
32 
33 using namespace std;
34 using OHOS::HiviewDFX::HiLog;
35 using OHOS::HiviewDFX::HiLogLabel;
36 
37 namespace OHOS {
38 namespace AudioStandard {
39 static __thread napi_ref g_capturerConstructor = nullptr;
40 std::unique_ptr<AudioParameters> AudioCapturerNapi::sAudioParameters_ = nullptr;
41 std::unique_ptr<AudioCapturerOptions> AudioCapturerNapi::sCapturerOptions_ = nullptr;
42 mutex AudioCapturerNapi::createMutex_;
43 int32_t AudioCapturerNapi::isConstructSuccess_ = SUCCESS;
44 
45 namespace {
46     constexpr int ARGS_ONE = 1;
47     constexpr int ARGS_TWO = 2;
48     constexpr int ARGS_THREE = 3;
49 
50     constexpr int PARAM0 = 0;
51     constexpr int PARAM1 = 1;
52     constexpr int PARAM2 = 2;
53 
54     constexpr int TYPE_COMMUNICATION = 7;
55     constexpr int TYPE_PLAYBACK_CAPTURE = 2;
56     constexpr int TYPE_WAKEUP = 3;
57     constexpr int TYPE_VOICE_RECOGNITION = 1;
58     constexpr int TYPE_MIC = 0;
59     constexpr int TYPE_INVALID = -1;
60 
61     constexpr HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AudioCapturerNapi"};
62 
63     const std::string MARK_REACH_CALLBACK_NAME = "markReach";
64     const std::string PERIOD_REACH_CALLBACK_NAME = "periodReach";
65 #define GET_PARAMS(env, info, num) \
66     size_t argc = num;             \
67     napi_value argv[num] = {0};    \
68     napi_value thisVar = nullptr;  \
69     void *data;                    \
70     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)
71 }
72 
AudioCapturerNapi()73 AudioCapturerNapi::AudioCapturerNapi()
74     : audioCapturer_(nullptr), contentType_(CONTENT_TYPE_MUSIC), streamUsage_(STREAM_USAGE_MEDIA),
75       deviceRole_(INPUT_DEVICE), deviceType_(DEVICE_TYPE_MIC), sourceType_(SOURCE_TYPE_MIC),
76       capturerFlags_(0), env_(nullptr) {}
77 
78 AudioCapturerNapi::~AudioCapturerNapi() = default;
79 
SetValid(bool valid)80 void AudioCapturerNapi::SetValid(bool valid)
81 {
82     if (audioCapturer_ != nullptr) {
83         audioCapturer_->SetValid(valid);
84     }
85 }
86 
Destructor(napi_env env,void * nativeObject,void * finalize_hint)87 void AudioCapturerNapi::Destructor(napi_env env, void *nativeObject, void *finalize_hint)
88 {
89     if (nativeObject != nullptr) {
90         auto obj = static_cast<AudioCapturerNapi *>(nativeObject);
91         obj->SetValid(false);
92         delete obj;
93     }
94 }
95 
Init(napi_env env,napi_value exports)96 napi_value AudioCapturerNapi::Init(napi_env env, napi_value exports)
97 {
98     napi_value constructor;
99     napi_value result = nullptr;
100     const int32_t refCount = 1;
101     napi_get_undefined(env, &result);
102 
103     napi_property_descriptor audio_capturer_properties[] = {
104         DECLARE_NAPI_FUNCTION("getCapturerInfo", GetCapturerInfo),
105         DECLARE_NAPI_FUNCTION("getCapturerInfoSync", GetCapturerInfoSync),
106         DECLARE_NAPI_FUNCTION("getStreamInfo", GetStreamInfo),
107         DECLARE_NAPI_FUNCTION("getStreamInfoSync", GetStreamInfoSync),
108         DECLARE_NAPI_FUNCTION("start", Start),
109         DECLARE_NAPI_FUNCTION("read", Read),
110         DECLARE_NAPI_FUNCTION("getAudioTime", GetAudioTime),
111         DECLARE_NAPI_FUNCTION("getAudioTimeSync", GetAudioTimeSync),
112         DECLARE_NAPI_FUNCTION("stop", Stop),
113         DECLARE_NAPI_FUNCTION("release", Release),
114         DECLARE_NAPI_FUNCTION("getBufferSize", GetBufferSize),
115         DECLARE_NAPI_FUNCTION("getBufferSizeSync", GetBufferSizeSync),
116         DECLARE_NAPI_FUNCTION("getAudioStreamId", GetAudioStreamId),
117         DECLARE_NAPI_FUNCTION("getAudioStreamIdSync", GetAudioStreamIdSync),
118         DECLARE_NAPI_FUNCTION("on", On),
119         DECLARE_NAPI_FUNCTION("off", Off),
120         DECLARE_NAPI_GETTER("state", GetState)
121     };
122 
123     napi_property_descriptor static_prop[] = {
124         DECLARE_NAPI_STATIC_FUNCTION("createAudioCapturer", CreateAudioCapturer),
125         DECLARE_NAPI_STATIC_FUNCTION("createAudioCapturerSync", CreateAudioCapturerSync)
126     };
127 
128     napi_status status = napi_define_class(env, AUDIO_CAPTURER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct,
129         nullptr, sizeof(audio_capturer_properties) / sizeof(audio_capturer_properties[PARAM0]),
130         audio_capturer_properties, &constructor);
131     if (status != napi_ok) {
132         return result;
133     }
134 
135     status = napi_create_reference(env, constructor, refCount, &g_capturerConstructor);
136     if (status == napi_ok) {
137         status = napi_set_named_property(env, exports, AUDIO_CAPTURER_NAPI_CLASS_NAME.c_str(), constructor);
138         if (status == napi_ok) {
139             status = napi_define_properties(env, exports,
140                                             sizeof(static_prop) / sizeof(static_prop[PARAM0]), static_prop);
141             if (status == napi_ok) {
142                 return exports;
143             }
144         }
145     }
146 
147     HiLog::Error(LABEL, "Failure in AudioCapturerNapi::Init()");
148 
149     return result;
150 }
151 
AddNamedProperty(napi_env env,napi_value object,const std::string name,int32_t enumValue)152 napi_status AudioCapturerNapi::AddNamedProperty(napi_env env, napi_value object,
153                                                 const std::string name, int32_t enumValue)
154 {
155     napi_status status;
156     napi_value enumNapiValue;
157 
158     status = napi_create_int32(env, enumValue, &enumNapiValue);
159     if (status == napi_ok) {
160         status = napi_set_named_property(env, object, name.c_str(), enumNapiValue);
161     }
162 
163     return status;
164 }
165 
SetValueInt32(const napi_env & env,const std::string & fieldStr,const int intValue,napi_value & result)166 static void SetValueInt32(const napi_env& env, const std::string& fieldStr, const int intValue, napi_value& result)
167 {
168     napi_value value = nullptr;
169     napi_create_int32(env, intValue, &value);
170     napi_set_named_property(env, result, fieldStr.c_str(), value);
171 }
172 
GetAbilityContext(napi_env env)173 static shared_ptr<AbilityRuntime::Context> GetAbilityContext(napi_env env)
174 {
175     HiLog::Info(LABEL, "Getting context with FA model");
176     auto ability = OHOS::AbilityRuntime::GetCurrentAbility(env);
177     if (ability == nullptr) {
178         HiLog::Error(LABEL, "Failed to obtain ability in FA mode");
179         return nullptr;
180     }
181 
182     auto faContext = ability->GetAbilityContext();
183     if (faContext == nullptr) {
184         HiLog::Error(LABEL, "GetAbilityContext returned null in FA model");
185         return nullptr;
186     }
187 
188     return faContext;
189 }
190 
Construct(napi_env env,napi_callback_info info)191 napi_value AudioCapturerNapi::Construct(napi_env env, napi_callback_info info)
192 {
193     napi_status status;
194     napi_value result = nullptr;
195     napi_get_undefined(env, &result);
196 
197     GET_PARAMS(env, info, ARGS_TWO);
198 
199     unique_ptr<AudioCapturerNapi> capturerNapi = make_unique<AudioCapturerNapi>();
200     CHECK_AND_RETURN_RET_LOG(capturerNapi != nullptr, result, "No memory");
201     capturerNapi->env_ = env;
202     capturerNapi->sourceType_ = sCapturerOptions_->capturerInfo.sourceType;
203 
204     AudioCapturerOptions capturerOptions = {};
205     capturerOptions.streamInfo.samplingRate = sCapturerOptions_->streamInfo.samplingRate;
206     capturerOptions.streamInfo.encoding = sCapturerOptions_->streamInfo.encoding;
207     capturerOptions.streamInfo.format = sCapturerOptions_->streamInfo.format;
208     capturerOptions.streamInfo.channels = sCapturerOptions_->streamInfo.channels;
209 
210     capturerOptions.capturerInfo.sourceType = sCapturerOptions_->capturerInfo.sourceType;
211 
212     capturerOptions.playbackCaptureConfig.filterOptions =
213         sCapturerOptions_->playbackCaptureConfig.filterOptions;
214 
215     std::shared_ptr<AbilityRuntime::Context> abilityContext = GetAbilityContext(env);
216     std::string cacheDir = "";
217     if (abilityContext != nullptr) {
218         cacheDir = abilityContext->GetCacheDir();
219     } else {
220         cacheDir = "/data/storage/el2/base/temp";
221     }
222     capturerNapi->audioCapturer_ = AudioCapturer::Create(capturerOptions, cacheDir);
223 
224     if (capturerNapi->audioCapturer_ == nullptr) {
225         HiLog::Error(LABEL, "Capturer Create failed");
226         AudioCapturerNapi::isConstructSuccess_ = NAPI_ERR_SYSTEM;
227     }
228 
229     if (capturerNapi->audioCapturer_ != nullptr && capturerNapi->callbackNapi_ == nullptr) {
230         capturerNapi->callbackNapi_ = std::make_shared<AudioCapturerCallbackNapi>(env);
231         CHECK_AND_RETURN_RET_LOG(capturerNapi->callbackNapi_ != nullptr, result, "No memory");
232         int32_t ret = capturerNapi->audioCapturer_->SetCapturerCallback(capturerNapi->callbackNapi_);
233         if (ret) {
234             AUDIO_DEBUG_LOG("AudioCapturerNapi::Construct SetCapturerCallback failed");
235         }
236     }
237 
238     status = napi_wrap(env, thisVar, static_cast<void*>(capturerNapi.get()),
239                        AudioCapturerNapi::Destructor, nullptr, nullptr);
240     if (status == napi_ok) {
241         capturerNapi.release();
242         return thisVar;
243     }
244 
245     HiLog::Error(LABEL, "Failed in AudioCapturerNapi::Construct()!");
246     return result;
247 }
248 
CreateAudioCapturer(napi_env env,napi_callback_info info)249 napi_value AudioCapturerNapi::CreateAudioCapturer(napi_env env, napi_callback_info info)
250 {
251     HiLog::Info(LABEL, "%{public}s IN", __func__);
252     napi_status status;
253     napi_value result = nullptr;
254     bool inputRight = true;
255 
256     GET_PARAMS(env, info, ARGS_TWO);
257     unique_ptr<AudioCapturerAsyncContext> asyncContext = make_unique<AudioCapturerAsyncContext>();
258 
259     if (asyncContext == nullptr) {
260         return result;
261     }
262 
263     if (argc < ARGS_ONE) {
264         asyncContext->status = NAPI_ERR_INVALID_PARAM;
265     }
266 
267     for (size_t i = PARAM0; i < argc; i++) {
268         napi_valuetype valueType = napi_undefined;
269         napi_typeof(env, argv[i], &valueType);
270         if (i == PARAM0 && valueType == napi_object) {
271             if (ParseCapturerOptions(env, argv[i], &(asyncContext->capturerOptions)) == false) {
272                 HiLog::Error(LABEL, "Parsing of capturer options failed");
273                 inputRight = false;
274             }
275         } else if (i == PARAM1) {
276             if (valueType == napi_function) {
277                 napi_create_reference(env, argv[i], REFERENCE_CREATION_COUNT, &asyncContext->callbackRef);
278             }
279             break;
280         } else {
281             asyncContext->status = NAPI_ERR_INVALID_PARAM;
282         }
283     }
284 
285     if (asyncContext->callbackRef == nullptr) {
286         napi_create_promise(env, &asyncContext->deferred, &result);
287     } else {
288         napi_get_undefined(env, &result);
289     }
290 
291     napi_value resource = nullptr;
292     napi_create_string_utf8(env, "CreateAudioCapturer", NAPI_AUTO_LENGTH, &resource);
293 
294     if (inputRight == false){
295         status = napi_create_async_work(
296             env, nullptr, resource,
297             [](napi_env env, void *data) {
298                 auto context = static_cast<AudioCapturerAsyncContext *>(data);
299                 context->status = NAPI_ERR_INVALID_PARAM;
300                 HiLog::Error(LABEL, "ParseCapturerOptions fail, invalid param!");
301             },
302             CheckCapturerAsyncCallbackComplete, static_cast<void *>(asyncContext.get()), &asyncContext->work);
303     } else {
304         status = napi_create_async_work(
305             env, nullptr, resource,
306             [](napi_env env, void *data) {
307                 auto context = static_cast<AudioCapturerAsyncContext *>(data);
308                 context->status = SUCCESS;
309             },
310             GetCapturerAsyncCallbackComplete, static_cast<void *>(asyncContext.get()), &asyncContext->work);
311     }
312 
313     if (status != napi_ok) {
314         result = nullptr;
315     } else {
316         status = napi_queue_async_work(env, asyncContext->work);
317         if (status == napi_ok) {
318             asyncContext.release();
319         } else {
320             result = nullptr;
321         }
322     }
323 
324     return result;
325 }
326 
CreateAudioCapturerSync(napi_env env,napi_callback_info info)327 napi_value AudioCapturerNapi::CreateAudioCapturerSync(napi_env env, napi_callback_info info)
328 {
329     HiLog::Info(LABEL, "%{public}s IN", __func__);
330     napi_value result = nullptr;
331 
332     GET_PARAMS(env, info, ARGS_ONE);
333     if (argc < ARGS_ONE) {
334         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
335         return result;
336     }
337 
338     napi_valuetype valueType = napi_undefined;
339     napi_typeof(env, argv[PARAM0], &valueType);
340     if (valueType != napi_object) {
341         AudioCommonNapi::throwError(env, NAPI_ERR_INPUT_INVALID);
342         return result;
343     }
344 
345     AudioCapturerOptions capturerOptions;
346     if (!ParseCapturerOptions(env, argv[PARAM0], &capturerOptions)) {
347         AudioCommonNapi::throwError(env, NAPI_ERR_INVALID_PARAM);
348         return result;
349     }
350 
351     unique_ptr<AudioCapturerOptions> audioCapturerOptions = make_unique<AudioCapturerOptions>();
352     audioCapturerOptions->streamInfo.samplingRate = capturerOptions.streamInfo.samplingRate;
353     audioCapturerOptions->streamInfo.encoding = capturerOptions.streamInfo.encoding;
354     audioCapturerOptions->streamInfo.format = capturerOptions.streamInfo.format;
355     audioCapturerOptions->streamInfo.channels = capturerOptions.streamInfo.channels;
356     audioCapturerOptions->capturerInfo.sourceType = capturerOptions.capturerInfo.sourceType;
357     audioCapturerOptions->capturerInfo.capturerFlags = capturerOptions.capturerInfo.capturerFlags;
358     audioCapturerOptions->playbackCaptureConfig.filterOptions = capturerOptions.playbackCaptureConfig.filterOptions;
359 
360     return AudioCapturerNapi::CreateAudioCapturerWrapper(env, audioCapturerOptions);
361 }
362 
CommonCallbackRoutine(napi_env env,AudioCapturerAsyncContext * & asyncContext,const napi_value & valueParam)363 void AudioCapturerNapi::CommonCallbackRoutine(napi_env env, AudioCapturerAsyncContext* &asyncContext,
364                                               const napi_value &valueParam)
365 {
366     napi_value result[ARGS_TWO] = {0};
367     napi_value retVal;
368 
369     if (!asyncContext->status) {
370         napi_get_undefined(env, &result[PARAM0]);
371         result[PARAM1] = valueParam;
372     } else {
373         napi_value message = nullptr;
374         std::string messageValue = AudioCommonNapi::getMessageByCode(asyncContext->status);
375         napi_create_string_utf8(env, messageValue.c_str(), NAPI_AUTO_LENGTH, &message);
376 
377         napi_value code = nullptr;
378         napi_create_string_utf8(env, (std::to_string(asyncContext->status)).c_str(), NAPI_AUTO_LENGTH, &code);
379 
380         napi_create_error(env, code, message, &result[PARAM0]);
381         napi_get_undefined(env, &result[PARAM1]);
382     }
383 
384     if (asyncContext->deferred) {
385         if (!asyncContext->status) {
386             napi_resolve_deferred(env, asyncContext->deferred, result[PARAM1]);
387         } else {
388             napi_reject_deferred(env, asyncContext->deferred, result[PARAM0]);
389         }
390     } else {
391         napi_value callback = nullptr;
392         napi_get_reference_value(env, asyncContext->callbackRef, &callback);
393         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
394         napi_delete_reference(env, asyncContext->callbackRef);
395     }
396     napi_delete_async_work(env, asyncContext->work);
397 
398     delete asyncContext;
399     asyncContext = nullptr;
400 }
401 
GetCapturerAsyncCallbackComplete(napi_env env,napi_status status,void * data)402 void AudioCapturerNapi::GetCapturerAsyncCallbackComplete(napi_env env, napi_status status, void *data)
403 {
404     napi_value valueParam = nullptr;
405     auto asyncContext = static_cast<AudioCapturerAsyncContext *>(data);
406 
407     if (asyncContext != nullptr) {
408         if (!asyncContext->status) {
409             unique_ptr<AudioCapturerOptions> capturerOptions = make_unique<AudioCapturerOptions>();
410             capturerOptions->streamInfo.samplingRate = asyncContext->capturerOptions.streamInfo.samplingRate;
411             capturerOptions->streamInfo.encoding = asyncContext->capturerOptions.streamInfo.encoding;
412             capturerOptions->streamInfo.format = asyncContext->capturerOptions.streamInfo.format;
413             capturerOptions->streamInfo.channels = asyncContext->capturerOptions.streamInfo.channels;
414             capturerOptions->capturerInfo.sourceType = asyncContext->capturerOptions.capturerInfo.sourceType;
415             capturerOptions->capturerInfo.capturerFlags = asyncContext->capturerOptions.capturerInfo.capturerFlags;
416             capturerOptions->playbackCaptureConfig.filterOptions =
417                 asyncContext->capturerOptions.playbackCaptureConfig.filterOptions;
418 
419             valueParam = CreateAudioCapturerWrapper(env, capturerOptions);
420             asyncContext->status = AudioCapturerNapi::isConstructSuccess_;
421             AudioCapturerNapi::isConstructSuccess_ = SUCCESS;
422         }
423         CommonCallbackRoutine(env, asyncContext, valueParam);
424     } else {
425         HiLog::Error(LABEL, "ERROR: GetCapturerAsyncCallbackComplete is Null!");
426     }
427 }
428 
CheckCapturerAsyncCallbackComplete(napi_env env,napi_status status,void * data)429 void AudioCapturerNapi::CheckCapturerAsyncCallbackComplete(napi_env env, napi_status status, void *data)
430 {
431     napi_value valueParam = nullptr;
432     auto asyncContext = static_cast<AudioCapturerAsyncContext *>(data);
433     if (asyncContext != nullptr) {
434         CommonCallbackRoutine(env, asyncContext, valueParam);
435     } else {
436         HiLog::Error(LABEL, "ERROR: CheckCapturerAsyncCallbackComplete is Null!");
437     }
438 }
439 
SetFunctionAsyncCallbackComplete(napi_env env,napi_status status,void * data)440 void AudioCapturerNapi::SetFunctionAsyncCallbackComplete(napi_env env, napi_status status, void *data)
441 {
442     auto asyncContext = static_cast<AudioCapturerAsyncContext*>(data);
443     napi_value valueParam = nullptr;
444 
445     if (asyncContext != nullptr) {
446         if (!asyncContext->status) {
447             napi_get_undefined(env, &valueParam);
448         }
449         CommonCallbackRoutine(env, asyncContext, valueParam);
450     } else {
451         HiLog::Error(LABEL, "ERROR: AudioCapturerAsyncContext* is Null!");
452     }
453 }
454 
AudioCapturerInfoAsyncCallbackComplete(napi_env env,napi_status status,void * data)455 void AudioCapturerNapi::AudioCapturerInfoAsyncCallbackComplete(napi_env env, napi_status status, void *data)
456 {
457     auto asyncContext = static_cast<AudioCapturerAsyncContext *>(data);
458     napi_value valueParam = nullptr;
459 
460     if (asyncContext != nullptr) {
461         if (!asyncContext->status) {
462             (void)napi_create_object(env, &valueParam);
463             SetValueInt32(env, "source", static_cast<int32_t>(asyncContext->sourceType), valueParam);
464             SetValueInt32(env, "capturerFlags", static_cast<int32_t>(asyncContext->capturerFlags), valueParam);
465         }
466         CommonCallbackRoutine(env, asyncContext, valueParam);
467     } else {
468         HiLog::Error(LABEL, "ERROR: AudioCapturerInfoAsyncCallbackComplete* is Null!");
469     }
470 }
471 
AudioStreamInfoAsyncCallbackComplete(napi_env env,napi_status status,void * data)472 void AudioCapturerNapi::AudioStreamInfoAsyncCallbackComplete(napi_env env, napi_status status, void *data)
473 {
474     auto asyncContext = static_cast<AudioCapturerAsyncContext *>(data);
475     napi_value valueParam = nullptr;
476 
477     if (asyncContext != nullptr) {
478         if (!asyncContext->status) {
479             (void)napi_create_object(env, &valueParam);
480             SetValueInt32(env, "samplingRate", static_cast<int32_t>(asyncContext->samplingRate), valueParam);
481             SetValueInt32(env, "channels", static_cast<int32_t>(asyncContext->audioChannel), valueParam);
482             SetValueInt32(env, "sampleFormat", static_cast<int32_t>(asyncContext->audioSampleFormat), valueParam);
483             SetValueInt32(env, "encodingType", static_cast<int32_t>(asyncContext->audioEncoding), valueParam);
484         }
485         CommonCallbackRoutine(env, asyncContext, valueParam);
486     } else {
487         HiLog::Error(LABEL, "ERROR: AudioCapturerAsyncContext* is Null!");
488     }
489 }
490 
ReadAsyncCallbackComplete(napi_env env,napi_status status,void * data)491 void AudioCapturerNapi::ReadAsyncCallbackComplete(napi_env env, napi_status status, void *data)
492 {
493     auto asyncContext = static_cast<AudioCapturerAsyncContext *>(data);
494     napi_value valueParam = nullptr;
495 
496     if (asyncContext != nullptr) {
497         if (!asyncContext->status) {
498             uint8_t *native = nullptr;
499             napi_create_arraybuffer(env, asyncContext->bytesRead, reinterpret_cast<void **>(&native), &valueParam);
500             if (memcpy_s(native, asyncContext->bytesRead, asyncContext->buffer, asyncContext->bytesRead)) {
501                 valueParam = nullptr;
502             }
503 
504             free(asyncContext->buffer);
505         }
506         CommonCallbackRoutine(env, asyncContext, valueParam);
507     } else {
508         HiLog::Error(LABEL, "ERROR: AudioCapturerAsyncContext* is Null!");
509     }
510 }
511 
VoidAsyncCallbackComplete(napi_env env,napi_status status,void * data)512 void AudioCapturerNapi::VoidAsyncCallbackComplete(napi_env env, napi_status status, void *data)
513 {
514     auto asyncContext = static_cast<AudioCapturerAsyncContext*>(data);
515     napi_value valueParam = nullptr;
516 
517     if (asyncContext != nullptr) {
518         if (!asyncContext->status) {
519             napi_get_undefined(env, &valueParam);
520         }
521         CommonCallbackRoutine(env, asyncContext, valueParam);
522     } else {
523         HiLog::Error(LABEL, "ERROR: AudioCapturerAsyncContext* is Null!");
524     }
525 }
526 
IsTrueAsyncCallbackComplete(napi_env env,napi_status status,void * data)527 void AudioCapturerNapi::IsTrueAsyncCallbackComplete(napi_env env, napi_status status, void *data)
528 {
529     auto asyncContext = static_cast<AudioCapturerAsyncContext*>(data);
530     napi_value valueParam = nullptr;
531 
532     if (asyncContext != nullptr) {
533         if (!asyncContext->status) {
534             napi_get_boolean(env, asyncContext->isTrue, &valueParam);
535         }
536         CommonCallbackRoutine(env, asyncContext, valueParam);
537     } else {
538         HiLog::Error(LABEL, "ERROR: AudioCapturerAsyncContext* is Null!");
539     }
540 }
541 
GetBufferSizeAsyncCallbackComplete(napi_env env,napi_status status,void * data)542 void AudioCapturerNapi::GetBufferSizeAsyncCallbackComplete(napi_env env, napi_status status, void *data)
543 {
544     auto asyncContext = static_cast<AudioCapturerAsyncContext*>(data);
545     napi_value valueParam = nullptr;
546 
547     if (asyncContext != nullptr) {
548         if (!asyncContext->status) {
549             napi_create_uint32(env, asyncContext->bufferSize, &valueParam);
550         }
551         CommonCallbackRoutine(env, asyncContext, valueParam);
552     } else {
553         HiLog::Error(LABEL, "ERROR: AudioCapturerAsyncContext* is Null!");
554     }
555 }
556 
GetAudioStreamIdCallbackComplete(napi_env env,napi_status status,void * data)557 void AudioCapturerNapi::GetAudioStreamIdCallbackComplete(napi_env env, napi_status status, void *data)
558 {
559     auto asyncContext = static_cast<AudioCapturerAsyncContext *>(data);
560     napi_value valueParam = nullptr;
561 
562     if (asyncContext != nullptr) {
563         if (!asyncContext->status) {
564             napi_create_uint32(env, asyncContext->audioStreamId, &valueParam);
565         }
566         CommonCallbackRoutine(env, asyncContext, valueParam);
567     } else {
568         HiLog::Error(LABEL, "ERROR::GetAudioStreamIdCallbackComplete* is Null!");
569     }
570 }
571 
GetIntValueAsyncCallbackComplete(napi_env env,napi_status status,void * data)572 void AudioCapturerNapi::GetIntValueAsyncCallbackComplete(napi_env env, napi_status status, void *data)
573 {
574     auto asyncContext = static_cast<AudioCapturerAsyncContext*>(data);
575     napi_value valueParam = nullptr;
576 
577     if (asyncContext != nullptr) {
578         if (!asyncContext->status) {
579             napi_create_int32(env, asyncContext->intValue, &valueParam);
580         }
581         CommonCallbackRoutine(env, asyncContext, valueParam);
582     } else {
583         HiLog::Error(LABEL, "ERROR: AudioCapturerAsyncContext* is Null!");
584     }
585 }
586 
GetInt64ValueAsyncCallbackComplete(napi_env env,napi_status status,void * data)587 void AudioCapturerNapi::GetInt64ValueAsyncCallbackComplete(napi_env env, napi_status status, void *data)
588 {
589     auto asyncContext = static_cast<AudioCapturerAsyncContext*>(data);
590     napi_value valueParam = nullptr;
591 
592     if (asyncContext != nullptr) {
593         if (!asyncContext->status) {
594             napi_create_int64(env, asyncContext->time, &valueParam);
595         }
596         CommonCallbackRoutine(env, asyncContext, valueParam);
597     } else {
598         HiLog::Error(LABEL, "ERROR: AudioCapturerAsyncContext* is Null!");
599     }
600 }
601 
GetCapturerInfo(napi_env env,napi_callback_info info)602 napi_value AudioCapturerNapi::GetCapturerInfo(napi_env env, napi_callback_info info)
603 {
604     HiLog::Info(LABEL, "%{public}s IN", __func__);
605     napi_status status;
606     const int32_t refCount = 1;
607     napi_value result = nullptr;
608 
609     GET_PARAMS(env, info, ARGS_ONE);
610 
611     unique_ptr<AudioCapturerAsyncContext> asyncContext = make_unique<AudioCapturerAsyncContext>();
612     THROW_ERROR_ASSERT(env, asyncContext != nullptr, NAPI_ERR_NO_MEMORY);
613     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
614     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
615         if (argc > PARAM0) {
616             napi_valuetype valueType = napi_undefined;
617             napi_typeof(env, argv[PARAM0], &valueType);
618             if (valueType == napi_function) {
619                 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
620             }
621         }
622 
623         if (asyncContext->callbackRef == nullptr) {
624             napi_create_promise(env, &asyncContext->deferred, &result);
625         } else {
626             napi_get_undefined(env, &result);
627         }
628 
629         napi_value resource = nullptr;
630         napi_create_string_utf8(env, "GetCapturerInfo", NAPI_AUTO_LENGTH, &resource);
631 
632         status = napi_create_async_work(
633             env, nullptr, resource,
634             [](napi_env env, void *data) {
635                 auto context = static_cast<AudioCapturerAsyncContext *>(data);
636                 AudioCapturerInfo capturerInfo = {};
637                 context->status = context->objectInfo->audioCapturer_->GetCapturerInfo(capturerInfo);
638                 if (context->status == SUCCESS) {
639                     context->sourceType = capturerInfo.sourceType;
640                     context->capturerFlags = capturerInfo.capturerFlags;
641                 }
642             },
643             AudioCapturerInfoAsyncCallbackComplete, static_cast<void *>(asyncContext.get()), &asyncContext->work);
644         if (status != napi_ok) {
645             result = nullptr;
646         } else {
647             status = napi_queue_async_work(env, asyncContext->work);
648             if (status == napi_ok) {
649                 asyncContext.release();
650             } else {
651                 result = nullptr;
652             }
653         }
654     }
655 
656     return result;
657 }
658 
GetCapturerInfoSync(napi_env env,napi_callback_info info)659 napi_value AudioCapturerNapi::GetCapturerInfoSync(napi_env env, napi_callback_info info)
660 {
661     HiLog::Info(LABEL, "%{public}s IN", __func__);
662     napi_status status;
663     napi_value thisVar = nullptr;
664     napi_value result = nullptr;
665     size_t argCount = 0;
666     void *native = nullptr;
667 
668     status = napi_get_cb_info(env, info, &argCount, nullptr, &thisVar, nullptr);
669     if (status != napi_ok) {
670         AUDIO_ERR_LOG("Invalid parameters!");
671         return result;
672     }
673 
674     status = napi_unwrap(env, thisVar, &native);
675     auto *audioCapturerNapi = reinterpret_cast<AudioCapturerNapi *>(native);
676     if (status != napi_ok || audioCapturerNapi == nullptr) {
677         AUDIO_ERR_LOG("GetCapturerInfoSync unwrap failure!");
678         return result;
679     }
680 
681     AudioCapturerInfo capturerInfo;
682     int32_t ret = audioCapturerNapi->audioCapturer_->GetCapturerInfo(capturerInfo);
683     if (ret != SUCCESS) {
684         AUDIO_ERR_LOG("GetCapturerInfo failure!");
685         return result;
686     }
687 
688     (void)napi_create_object(env, &result);
689     SetValueInt32(env, "source", static_cast<int32_t>(capturerInfo.sourceType), result);
690     SetValueInt32(env, "capturerFlags", static_cast<int32_t>(capturerInfo.capturerFlags), result);
691 
692     return result;
693 }
694 
GetStreamInfo(napi_env env,napi_callback_info info)695 napi_value AudioCapturerNapi::GetStreamInfo(napi_env env, napi_callback_info info)
696 {
697     napi_status status;
698     const int32_t refCount = 1;
699     napi_value result = nullptr;
700 
701     GET_PARAMS(env, info, ARGS_ONE);
702 
703     unique_ptr<AudioCapturerAsyncContext> asyncContext = make_unique<AudioCapturerAsyncContext>();
704     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
705     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
706         if (argc > PARAM0) {
707             napi_valuetype valueType = napi_undefined;
708             napi_typeof(env, argv[PARAM0], &valueType);
709             if (valueType == napi_function) {
710                 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
711             }
712         }
713 
714         if (asyncContext->callbackRef == nullptr) {
715             napi_create_promise(env, &asyncContext->deferred, &result);
716         } else {
717             napi_get_undefined(env, &result);
718         }
719 
720         napi_value resource = nullptr;
721         napi_create_string_utf8(env, "GetStreamInfo", NAPI_AUTO_LENGTH, &resource);
722         status = napi_create_async_work(
723             env, nullptr, resource,
724             [](napi_env env, void *data) {
725                 auto context = static_cast<AudioCapturerAsyncContext *>(data);
726 
727                 AudioStreamInfo streamInfo;
728                 context->status = context->objectInfo->audioCapturer_->GetStreamInfo(streamInfo);
729                 if (context->status == SUCCESS) {
730                     context->audioSampleFormat = static_cast<AudioSampleFormat>(streamInfo.format);
731                     context->samplingRate = streamInfo.samplingRate;
732                     context->audioChannel = streamInfo.channels;
733                     context->audioEncoding = streamInfo.encoding;
734                 }
735             },
736             AudioStreamInfoAsyncCallbackComplete, static_cast<void *>(asyncContext.get()), &asyncContext->work);
737         if (status != napi_ok) {
738             result = nullptr;
739         } else {
740             status = napi_queue_async_work(env, asyncContext->work);
741             if (status == napi_ok) {
742                 asyncContext.release();
743             } else {
744                 result = nullptr;
745             }
746         }
747     }
748 
749     return result;
750 }
751 
GetStreamInfoSync(napi_env env,napi_callback_info info)752 napi_value AudioCapturerNapi::GetStreamInfoSync(napi_env env, napi_callback_info info)
753 {
754     napi_status status;
755     napi_value thisVar = nullptr;
756     napi_value result = nullptr;
757     size_t argCount = 0;
758     void *native = nullptr;
759 
760     status = napi_get_cb_info(env, info, &argCount, nullptr, &thisVar, nullptr);
761     if (status != napi_ok) {
762         AUDIO_ERR_LOG("Invalid parameters!");
763         return result;
764     }
765 
766     status = napi_unwrap(env, thisVar, &native);
767     auto *audioCapturerNapi = reinterpret_cast<AudioCapturerNapi *>(native);
768     if (status != napi_ok || audioCapturerNapi == nullptr) {
769         AUDIO_ERR_LOG("GetStreamInfoSync unwrap failure!");
770         return result;
771     }
772 
773     AudioStreamInfo streamInfo;
774     int32_t ret = audioCapturerNapi->audioCapturer_->GetStreamInfo(streamInfo);
775     if (ret != SUCCESS) {
776         AUDIO_ERR_LOG("GetStreamInfo failure!");
777         return result;
778     }
779 
780     (void)napi_create_object(env, &result);
781     SetValueInt32(env, "samplingRate", static_cast<int32_t>(streamInfo.samplingRate), result);
782     SetValueInt32(env, "channels", static_cast<int32_t>(streamInfo.channels), result);
783     SetValueInt32(env, "sampleFormat", static_cast<int32_t>(streamInfo.format), result);
784     SetValueInt32(env, "encodingType", static_cast<int32_t>(streamInfo.encoding), result);
785 
786     return result;
787 }
788 
GetAudioStreamId(napi_env env,napi_callback_info info)789 napi_value AudioCapturerNapi::GetAudioStreamId(napi_env env, napi_callback_info info)
790 {
791     napi_status status;
792     const int32_t refCount = 1;
793     napi_value result = nullptr;
794 
795     GET_PARAMS(env, info, ARGS_ONE);
796 
797     unique_ptr<AudioCapturerAsyncContext> asyncContext = make_unique<AudioCapturerAsyncContext>();
798     THROW_ERROR_ASSERT(env, asyncContext != nullptr, NAPI_ERR_NO_MEMORY);
799 
800     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
801     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
802         if (argc > PARAM0) {
803             napi_valuetype valueType = napi_undefined;
804             napi_typeof(env, argv[PARAM0], &valueType);
805             if (valueType == napi_function) {
806                 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
807             }
808         }
809 
810         if (asyncContext->callbackRef == nullptr) {
811             napi_create_promise(env, &asyncContext->deferred, &result);
812         } else {
813             napi_get_undefined(env, &result);
814         }
815 
816         napi_value resource = nullptr;
817         napi_create_string_utf8(env, "GetAudioStreamId", NAPI_AUTO_LENGTH, &resource);
818         status = napi_create_async_work(
819             env, nullptr, resource,
820             [](napi_env env, void *data) {
821                 auto context = static_cast<AudioCapturerAsyncContext *>(data);
822                 int32_t streamIdStatus;
823                 streamIdStatus = context->objectInfo->audioCapturer_->
824                     GetAudioStreamId(context->audioStreamId);
825                 if (streamIdStatus == ERR_ILLEGAL_STATE) {
826                     context->status = NAPI_ERR_ILLEGAL_STATE;
827                 } else if (streamIdStatus == ERR_INVALID_INDEX) {
828                     context->status = NAPI_ERR_SYSTEM;
829                 } else {
830                     context->status = SUCCESS;
831                 }
832             },
833             GetAudioStreamIdCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
834         if (status != napi_ok) {
835             result = nullptr;
836         } else {
837             status = napi_queue_async_work(env, asyncContext->work);
838             if (status == napi_ok) {
839                 asyncContext.release();
840             } else {
841                 result = nullptr;
842             }
843         }
844     }
845     return result;
846 }
847 
GetAudioStreamIdSync(napi_env env,napi_callback_info info)848 napi_value AudioCapturerNapi::GetAudioStreamIdSync(napi_env env, napi_callback_info info)
849 {
850     napi_status status;
851     napi_value thisVar = nullptr;
852     napi_value result = nullptr;
853     size_t argCount = 0;
854     void *native = nullptr;
855 
856     status = napi_get_cb_info(env, info, &argCount, nullptr, &thisVar, nullptr);
857     if (status != napi_ok) {
858         AUDIO_ERR_LOG("Invalid parameters!");
859         return result;
860     }
861 
862     status = napi_unwrap(env, thisVar, &native);
863     auto *audioCapturerNapi = reinterpret_cast<AudioCapturerNapi *>(native);
864     if (status != napi_ok || audioCapturerNapi == nullptr) {
865         AUDIO_ERR_LOG("GetAudioStreamIdSync unwrap failure!");
866         return result;
867     }
868 
869     uint32_t audioStreamId;
870     int32_t streamIdStatus = audioCapturerNapi->audioCapturer_->GetAudioStreamId(audioStreamId);
871     if (streamIdStatus != SUCCESS) {
872         AUDIO_ERR_LOG("GetAudioStreamId failure!");
873         return result;
874     }
875     napi_create_uint32(env, audioStreamId, &result);
876 
877     return result;
878 }
879 
Start(napi_env env,napi_callback_info info)880 napi_value AudioCapturerNapi::Start(napi_env env, napi_callback_info info)
881 {
882     napi_status status;
883     const int32_t refCount = 1;
884     napi_value result = nullptr;
885 
886     GET_PARAMS(env, info, ARGS_ONE);
887 
888     unique_ptr<AudioCapturerAsyncContext> asyncContext = make_unique<AudioCapturerAsyncContext>();
889     THROW_ERROR_ASSERT(env, asyncContext != nullptr, NAPI_ERR_NO_MEMORY);
890 
891     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
892     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
893         if (argc > PARAM0) {
894             napi_valuetype valueType = napi_undefined;
895             napi_typeof(env, argv[PARAM0], &valueType);
896             if (valueType == napi_function) {
897                 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
898             }
899         }
900 
901         if (asyncContext->callbackRef == nullptr) {
902             napi_create_promise(env, &asyncContext->deferred, &result);
903         } else {
904             napi_get_undefined(env, &result);
905         }
906 
907         HiviewDFX::ReportXPowerJsStackSysEvent(env, "STREAM_CHANGE", "SRC=Audio");
908         napi_value resource = nullptr;
909         napi_create_string_utf8(env, "Start", NAPI_AUTO_LENGTH, &resource);
910 
911         status = napi_create_async_work(
912             env, nullptr, resource,
913             [](napi_env env, void *data) {
914                 auto context = static_cast<AudioCapturerAsyncContext *>(data);
915                 context->isTrue = context->objectInfo->audioCapturer_->Start();
916                 if (context->isTrue) {
917                     context->status = SUCCESS;
918                 } else {
919                     context->status = NAPI_ERR_SYSTEM;
920                 }
921             },
922             VoidAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
923         if (status != napi_ok) {
924             result = nullptr;
925         } else {
926             status = napi_queue_async_work(env, asyncContext->work);
927             if (status == napi_ok) {
928                 asyncContext.release();
929             } else {
930                 result = nullptr;
931             }
932         }
933     }
934 
935     return result;
936 }
937 
Read(napi_env env,napi_callback_info info)938 napi_value AudioCapturerNapi::Read(napi_env env, napi_callback_info info)
939 {
940     napi_status status;
941     const int32_t refCount = 1;
942     napi_value result = nullptr;
943 
944     GET_PARAMS(env, info, ARGS_THREE);
945 
946     unique_ptr<AudioCapturerAsyncContext> asyncContext = make_unique<AudioCapturerAsyncContext>();
947     if (argc < ARGS_TWO) {
948         asyncContext->status = NAPI_ERR_INVALID_PARAM;
949     }
950 
951     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
952     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
953         for (size_t i = PARAM0; i < argc; i++) {
954             napi_valuetype valueType = napi_undefined;
955             napi_typeof(env, argv[i], &valueType);
956 
957             if ((i == PARAM0) && (valueType == napi_number)) {
958                 napi_get_value_uint32(env, argv[i], &asyncContext->userSize);
959             } else if ((i == PARAM1) && (valueType == napi_boolean)) {
960                 napi_get_value_bool(env, argv[i], &asyncContext->isBlocking);
961             } else if (i == PARAM2) {
962                 if (valueType == napi_function) {
963                     napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
964                 }
965                 break;
966             } else {
967                 asyncContext->status = NAPI_ERR_INVALID_PARAM;
968             }
969         }
970 
971         if (asyncContext->callbackRef == nullptr) {
972             napi_create_promise(env, &asyncContext->deferred, &result);
973         } else {
974             napi_get_undefined(env, &result);
975         }
976 
977         napi_value resource = nullptr;
978         napi_create_string_utf8(env, "Read", NAPI_AUTO_LENGTH, &resource);
979 
980         status = napi_create_async_work(
981             env, nullptr, resource,
982             [](napi_env env, void *data) {
983                 auto context = static_cast<AudioCapturerAsyncContext *>(data);
984                 if (context->status == SUCCESS) {
985                     context->status = NAPI_ERR_SYSTEM;
986                     uint32_t userSize = context->userSize;
987                     auto buffer = std::make_unique<uint8_t[]>(userSize);
988                     if (!buffer) {
989                         return;
990                     }
991 
992                     size_t bytesRead = 0;
993                     while (bytesRead < context->userSize) {
994                         int32_t len = context->objectInfo->audioCapturer_->Read(*(buffer.get() + bytesRead),
995                                                                                 userSize - bytesRead,
996                                                                                 context->isBlocking);
997                         if (len >= 0) {
998                             bytesRead += len;
999                         } else {
1000                             bytesRead = len;
1001                             break;
1002                         }
1003                     }
1004 
1005                     if (bytesRead > 0) {
1006                         context->bytesRead = bytesRead;
1007                         context->buffer = buffer.get();
1008                         buffer.release();
1009                         context->status = SUCCESS;
1010                     }
1011                 }
1012             },
1013             ReadAsyncCallbackComplete, static_cast<void *>(asyncContext.get()), &asyncContext->work);
1014         if (status != napi_ok) {
1015             result = nullptr;
1016         } else {
1017             status = napi_queue_async_work(env, asyncContext->work);
1018             if (status == napi_ok) {
1019                 asyncContext.release();
1020             } else {
1021                 result = nullptr;
1022             }
1023         }
1024     }
1025 
1026     return result;
1027 }
1028 
GetAudioTime(napi_env env,napi_callback_info info)1029 napi_value AudioCapturerNapi::GetAudioTime(napi_env env, napi_callback_info info)
1030 {
1031     napi_status status;
1032     const int32_t refCount = 1;
1033     napi_value result = nullptr;
1034 
1035     GET_PARAMS(env, info, ARGS_ONE);
1036 
1037     unique_ptr<AudioCapturerAsyncContext> asyncContext = make_unique<AudioCapturerAsyncContext>();
1038 
1039     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1040     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1041         if (argc > PARAM0) {
1042             napi_valuetype valueType = napi_undefined;
1043             napi_typeof(env, argv[PARAM0], &valueType);
1044             if (valueType == napi_function) {
1045                 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
1046             }
1047         }
1048 
1049         if (asyncContext->callbackRef == nullptr) {
1050             napi_create_promise(env, &asyncContext->deferred, &result);
1051         } else {
1052             napi_get_undefined(env, &result);
1053         }
1054 
1055         napi_value resource = nullptr;
1056         napi_create_string_utf8(env, "GetAudioTime", NAPI_AUTO_LENGTH, &resource);
1057 
1058         status = napi_create_async_work(
1059             env, nullptr, resource,
1060             [](napi_env env, void *data) {
1061                 auto context = static_cast<AudioCapturerAsyncContext *>(data);
1062                 context->status = NAPI_ERR_SYSTEM;
1063                 Timestamp timestamp;
1064                 if (context->objectInfo->audioCapturer_->GetAudioTime(timestamp, Timestamp::Timestampbase::MONOTONIC)) {
1065                     const uint64_t secToNanosecond = 1000000000;
1066                     context->time = timestamp.time.tv_nsec + timestamp.time.tv_sec * secToNanosecond;
1067                     context->status = SUCCESS;
1068                 }
1069             },
1070             GetInt64ValueAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1071         if (status != napi_ok) {
1072             result = nullptr;
1073         } else {
1074             status = napi_queue_async_work(env, asyncContext->work);
1075             if (status == napi_ok) {
1076                 asyncContext.release();
1077             } else {
1078                 result = nullptr;
1079             }
1080         }
1081     }
1082 
1083     return result;
1084 }
1085 
GetAudioTimeSync(napi_env env,napi_callback_info info)1086 napi_value AudioCapturerNapi::GetAudioTimeSync(napi_env env, napi_callback_info info)
1087 {
1088     napi_status status;
1089     napi_value thisVar = nullptr;
1090     napi_value result = nullptr;
1091     size_t argCount = 0;
1092     void *native = nullptr;
1093 
1094     status = napi_get_cb_info(env, info, &argCount, nullptr, &thisVar, nullptr);
1095     if (status != napi_ok) {
1096         AUDIO_ERR_LOG("Invalid parameters!");
1097         return result;
1098     }
1099 
1100     status = napi_unwrap(env, thisVar, &native);
1101     auto *audioCapturerNapi = reinterpret_cast<AudioCapturerNapi *>(native);
1102     if (status != napi_ok || audioCapturerNapi == nullptr) {
1103         AUDIO_ERR_LOG("GetAudioTimeSync unwrap failure!");
1104         return result;
1105     }
1106 
1107     Timestamp timestamp;
1108     bool ret = audioCapturerNapi->audioCapturer_->GetAudioTime(timestamp, Timestamp::Timestampbase::MONOTONIC);
1109     if (!ret) {
1110         AUDIO_ERR_LOG("GetAudioTime failure!");
1111         return result;
1112     }
1113     const uint64_t secToNanosecond = 1000000000;
1114     uint64_t time = timestamp.time.tv_nsec + timestamp.time.tv_sec * secToNanosecond;
1115 
1116     napi_create_int64(env, time, &result);
1117 
1118     return result;
1119 }
1120 
Stop(napi_env env,napi_callback_info info)1121 napi_value AudioCapturerNapi::Stop(napi_env env, napi_callback_info info)
1122 {
1123     napi_status status;
1124     const int32_t refCount = 1;
1125     napi_value result = nullptr;
1126 
1127     GET_PARAMS(env, info, ARGS_ONE);
1128 
1129     unique_ptr<AudioCapturerAsyncContext> asyncContext = make_unique<AudioCapturerAsyncContext>();
1130 
1131     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1132     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1133         if (argc > PARAM0) {
1134             napi_valuetype valueType = napi_undefined;
1135             napi_typeof(env, argv[PARAM0], &valueType);
1136             if (valueType == napi_function) {
1137                 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
1138             }
1139         }
1140 
1141         if (asyncContext->callbackRef == nullptr) {
1142             napi_create_promise(env, &asyncContext->deferred, &result);
1143         } else {
1144             napi_get_undefined(env, &result);
1145         }
1146 
1147         napi_value resource = nullptr;
1148         napi_create_string_utf8(env, "Stop", NAPI_AUTO_LENGTH, &resource);
1149 
1150         status = napi_create_async_work(
1151             env, nullptr, resource,
1152             [](napi_env env, void *data) {
1153                 auto context = static_cast<AudioCapturerAsyncContext *>(data);
1154                 context->isTrue = context->objectInfo->audioCapturer_->Stop();
1155                 if (context->isTrue) {
1156                     context->status = SUCCESS;
1157                 } else {
1158                     context->status = NAPI_ERR_SYSTEM;
1159                 }
1160             },
1161             VoidAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1162         if (status != napi_ok) {
1163             result = nullptr;
1164         } else {
1165             status = napi_queue_async_work(env, asyncContext->work);
1166             if (status == napi_ok) {
1167                 asyncContext.release();
1168             } else {
1169                 result = nullptr;
1170             }
1171         }
1172     }
1173 
1174     return result;
1175 }
1176 
Release(napi_env env,napi_callback_info info)1177 napi_value AudioCapturerNapi::Release(napi_env env, napi_callback_info info)
1178 {
1179     napi_status status;
1180     const int32_t refCount = 1;
1181     napi_value result = nullptr;
1182 
1183     GET_PARAMS(env, info, ARGS_ONE);
1184 
1185     unique_ptr<AudioCapturerAsyncContext> asyncContext = make_unique<AudioCapturerAsyncContext>();
1186 
1187     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1188     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1189         if (argc > PARAM0) {
1190             napi_valuetype valueType = napi_undefined;
1191             napi_typeof(env, argv[PARAM0], &valueType);
1192             if (valueType == napi_function) {
1193                 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
1194             }
1195         }
1196 
1197         if (asyncContext->callbackRef == nullptr) {
1198             napi_create_promise(env, &asyncContext->deferred, &result);
1199         } else {
1200             napi_get_undefined(env, &result);
1201         }
1202 
1203         napi_value resource = nullptr;
1204         napi_create_string_utf8(env, "Release", NAPI_AUTO_LENGTH, &resource);
1205 
1206         status = napi_create_async_work(
1207             env, nullptr, resource,
1208             [](napi_env env, void *data) {
1209                 auto context = static_cast<AudioCapturerAsyncContext *>(data);
1210                 context->isTrue = context->objectInfo->audioCapturer_->Release();
1211                 if (context->isTrue) {
1212                     context->status = SUCCESS;
1213                 } else {
1214                     context->status = NAPI_ERR_SYSTEM;
1215                 }
1216             },
1217             VoidAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1218         if (status != napi_ok) {
1219             result = nullptr;
1220         } else {
1221             status = napi_queue_async_work(env, asyncContext->work);
1222             if (status == napi_ok) {
1223                 asyncContext.release();
1224             } else {
1225                 result = nullptr;
1226             }
1227         }
1228     }
1229 
1230     return result;
1231 }
1232 
RegisterPeriodPositionCallback(napi_env env,napi_value * argv,const std::string & cbName,AudioCapturerNapi * capturerNapi)1233 napi_value AudioCapturerNapi::RegisterPeriodPositionCallback(napi_env env, napi_value* argv, const std::string& cbName,
1234                                                              AudioCapturerNapi *capturerNapi)
1235 {
1236     int64_t frameCount = 0;
1237     napi_get_value_int64(env, argv[PARAM1], &frameCount);
1238 
1239     if (frameCount > 0) {
1240         if (capturerNapi->periodPositionCBNapi_ == nullptr) {
1241             capturerNapi->periodPositionCBNapi_ = std::make_shared<CapturerPeriodPositionCallbackNapi>(env);
1242             THROW_ERROR_ASSERT(env, capturerNapi->periodPositionCBNapi_ != nullptr, NAPI_ERR_NO_MEMORY);
1243 
1244             int32_t ret = capturerNapi->audioCapturer_->SetCapturerPeriodPositionCallback(frameCount,
1245                 capturerNapi->periodPositionCBNapi_);
1246             THROW_ERROR_ASSERT(env, ret == SUCCESS, NAPI_ERR_SYSTEM);
1247 
1248             std::shared_ptr<CapturerPeriodPositionCallbackNapi> cb =
1249                 std::static_pointer_cast<CapturerPeriodPositionCallbackNapi>(capturerNapi->periodPositionCBNapi_);
1250             cb->SaveCallbackReference(cbName, argv[PARAM2]);
1251         } else {
1252             AUDIO_DEBUG_LOG("AudioCapturerNapi: periodReach already subscribed.");
1253             THROW_ERROR_ASSERT(env, false, NAPI_ERR_ILLEGAL_STATE);
1254         }
1255     } else {
1256         AUDIO_ERR_LOG("AudioCapturerNapi: frameCount value not supported!");
1257         THROW_ERROR_ASSERT(env, false, NAPI_ERR_INPUT_INVALID);
1258     }
1259 
1260     napi_value result = nullptr;
1261     napi_get_undefined(env, &result);
1262     return result;
1263 }
1264 
RegisterPositionCallback(napi_env env,napi_value * argv,const std::string & cbName,AudioCapturerNapi * capturerNapi)1265 napi_value AudioCapturerNapi::RegisterPositionCallback(napi_env env, napi_value* argv,
1266                                                        const std::string& cbName, AudioCapturerNapi *capturerNapi)
1267 {
1268     int64_t markPosition = 0;
1269     napi_get_value_int64(env, argv[PARAM1], &markPosition);
1270 
1271     if (markPosition > 0) {
1272         capturerNapi->positionCBNapi_ = std::make_shared<CapturerPositionCallbackNapi>(env);
1273         THROW_ERROR_ASSERT(env, capturerNapi->positionCBNapi_ != nullptr, NAPI_ERR_NO_MEMORY);
1274         int32_t ret = capturerNapi->audioCapturer_->SetCapturerPositionCallback(markPosition,
1275             capturerNapi->positionCBNapi_);
1276         THROW_ERROR_ASSERT(env, ret == SUCCESS, NAPI_ERR_SYSTEM);
1277 
1278         std::shared_ptr<CapturerPositionCallbackNapi> cb =
1279             std::static_pointer_cast<CapturerPositionCallbackNapi>(capturerNapi->positionCBNapi_);
1280         cb->SaveCallbackReference(cbName, argv[PARAM2]);
1281     } else {
1282         AUDIO_ERR_LOG("AudioCapturerNapi: Mark Position value not supported!!");
1283         THROW_ERROR_ASSERT(env, false, NAPI_ERR_INPUT_INVALID);
1284     }
1285 
1286     napi_value result = nullptr;
1287     napi_get_undefined(env, &result);
1288     return result;
1289 }
1290 
RegisterCapturerCallback(napi_env env,napi_value * argv,const std::string & cbName,AudioCapturerNapi * capturerNapi)1291 napi_value AudioCapturerNapi::RegisterCapturerCallback(napi_env env, napi_value* argv,
1292                                                        const std::string& cbName, AudioCapturerNapi *capturerNapi)
1293 {
1294     THROW_ERROR_ASSERT(env, capturerNapi->callbackNapi_ != nullptr, NAPI_ERR_NO_MEMORY);
1295 
1296     std::shared_ptr<AudioCapturerCallbackNapi> cb =
1297         std::static_pointer_cast<AudioCapturerCallbackNapi>(capturerNapi->callbackNapi_);
1298     cb->SaveCallbackReference(cbName, argv[PARAM1]);
1299 
1300     if (!cbName.compare(STATE_CHANGE_CALLBACK_NAME)) {
1301         CapturerState state = capturerNapi->audioCapturer_->GetStatus();
1302         if (state == CAPTURER_PREPARED) {
1303             capturerNapi->callbackNapi_->OnStateChange(state);
1304         }
1305     }
1306 
1307     napi_value result = nullptr;
1308     napi_get_undefined(env, &result);
1309     return result;
1310 }
1311 
RegisterCallback(napi_env env,napi_value jsThis,napi_value * argv,const std::string & cbName)1312 napi_value AudioCapturerNapi::RegisterCallback(napi_env env, napi_value jsThis,
1313                                                napi_value* argv, const std::string& cbName)
1314 {
1315     AudioCapturerNapi *capturerNapi = nullptr;
1316     napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&capturerNapi));
1317     THROW_ERROR_ASSERT(env, status == napi_ok, NAPI_ERR_SYSTEM);
1318     THROW_ERROR_ASSERT(env, capturerNapi != nullptr, NAPI_ERR_NO_MEMORY);
1319     THROW_ERROR_ASSERT(env, capturerNapi->audioCapturer_ != nullptr, NAPI_ERR_NO_MEMORY);
1320 
1321     napi_value result = nullptr;
1322     napi_get_undefined(env, &result);
1323 
1324     if (!cbName.compare(STATE_CHANGE_CALLBACK_NAME) ||
1325         !cbName.compare(AUDIO_INTERRUPT_CALLBACK_NAME)) {
1326         result = RegisterCapturerCallback(env, argv, cbName, capturerNapi);
1327     } else if (!cbName.compare(MARK_REACH_CALLBACK_NAME)) {
1328         result = RegisterPositionCallback(env, argv, cbName, capturerNapi);
1329     } else if (!cbName.compare(PERIOD_REACH_CALLBACK_NAME)) {
1330         result = RegisterPeriodPositionCallback(env, argv, cbName, capturerNapi);
1331     } else {
1332         bool unknownCallback = true;
1333         THROW_ERROR_ASSERT(env, !unknownCallback, NAPI_ERROR_INVALID_PARAM);
1334     }
1335 
1336     return result;
1337 }
1338 
On(napi_env env,napi_callback_info info)1339 napi_value AudioCapturerNapi::On(napi_env env, napi_callback_info info)
1340 {
1341     const size_t requireArgc = 2;
1342     size_t argc = 3;
1343 
1344     napi_value argv[requireArgc + 1] = {nullptr, nullptr, nullptr};
1345     napi_value jsThis = nullptr;
1346     napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr);
1347     THROW_ERROR_ASSERT(env, status == napi_ok, NAPI_ERR_SYSTEM);
1348     THROW_ERROR_ASSERT(env, argc >= requireArgc, NAPI_ERR_INPUT_INVALID);
1349 
1350     napi_valuetype eventType = napi_undefined;
1351     napi_typeof(env, argv[0], &eventType);
1352     THROW_ERROR_ASSERT(env, eventType == napi_string, NAPI_ERR_INPUT_INVALID);
1353 
1354     std::string callbackName = AudioCommonNapi::GetStringArgument(env, argv[0]);
1355     AUDIO_DEBUG_LOG("AudioCapturerNapi: On callbackName: %{public}s", callbackName.c_str());
1356 
1357     napi_valuetype handler = napi_undefined;
1358     if (argc == requireArgc) {
1359         napi_typeof(env, argv[1], &handler);
1360         THROW_ERROR_ASSERT(env, handler == napi_function, NAPI_ERR_INPUT_INVALID);
1361     } else {
1362         napi_valuetype paramArg1 = napi_undefined;
1363         napi_typeof(env, argv[1], &paramArg1);
1364         napi_valuetype expectedValType = napi_number;  // Default. Reset it with 'callbackName' if check, if required.
1365         THROW_ERROR_ASSERT(env, paramArg1 == expectedValType, NAPI_ERR_INPUT_INVALID);
1366 
1367         const int32_t arg2 = 2;
1368         napi_typeof(env, argv[arg2], &handler);
1369         THROW_ERROR_ASSERT(env, handler == napi_function, NAPI_ERR_INPUT_INVALID);
1370     }
1371 
1372     return RegisterCallback(env, jsThis, argv, callbackName);
1373 }
1374 
UnregisterCapturerCallback(napi_env env,const std::string & cbName,AudioCapturerNapi * capturerNapi)1375 void AudioCapturerNapi::UnregisterCapturerCallback(napi_env env, const std::string& cbName,
1376     AudioCapturerNapi *capturerNapi)
1377 {
1378     CHECK_AND_RETURN_LOG(capturerNapi->callbackNapi_ != nullptr, "capturerCallbackNapi is nullptr");
1379 
1380     std::shared_ptr<AudioCapturerCallbackNapi> cb =
1381         std::static_pointer_cast<AudioCapturerCallbackNapi>(capturerNapi->callbackNapi_);
1382     cb->RemoveCallbackReference(cbName);
1383 }
1384 
UnregisterCallback(napi_env env,napi_value jsThis,const std::string & cbName)1385 napi_value AudioCapturerNapi::UnregisterCallback(napi_env env, napi_value jsThis, const std::string& cbName)
1386 {
1387     AudioCapturerNapi *capturerNapi = nullptr;
1388     napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&capturerNapi));
1389     THROW_ERROR_ASSERT(env, status == napi_ok, NAPI_ERR_SYSTEM);
1390     THROW_ERROR_ASSERT(env, capturerNapi != nullptr, NAPI_ERR_NO_MEMORY);
1391     THROW_ERROR_ASSERT(env, capturerNapi->audioCapturer_ != nullptr, NAPI_ERR_NO_MEMORY);
1392 
1393     if (!cbName.compare(MARK_REACH_CALLBACK_NAME)) {
1394         capturerNapi->audioCapturer_->UnsetCapturerPositionCallback();
1395         capturerNapi->positionCBNapi_ = nullptr;
1396     } else if (!cbName.compare(PERIOD_REACH_CALLBACK_NAME)) {
1397         capturerNapi->audioCapturer_->UnsetCapturerPeriodPositionCallback();
1398         capturerNapi->periodPositionCBNapi_ = nullptr;
1399     } else if (!cbName.compare(AUDIO_INTERRUPT_CALLBACK_NAME)) {
1400         UnregisterCapturerCallback(env, cbName, capturerNapi);
1401     } else {
1402         bool unknownCallback = true;
1403         THROW_ERROR_ASSERT(env, !unknownCallback, NAPI_ERR_UNSUPPORTED);
1404     }
1405 
1406     napi_value result = nullptr;
1407     napi_get_undefined(env, &result);
1408     return result;
1409 }
1410 
Off(napi_env env,napi_callback_info info)1411 napi_value AudioCapturerNapi::Off(napi_env env, napi_callback_info info)
1412 {
1413     const size_t requireArgc = 1;
1414     size_t argc = 1;
1415 
1416     napi_value argv[requireArgc] = {nullptr};
1417     napi_value jsThis = nullptr;
1418     napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr);
1419     THROW_ERROR_ASSERT(env, status == napi_ok, NAPI_ERR_SYSTEM);
1420     THROW_ERROR_ASSERT(env, argc >= requireArgc, NAPI_ERR_INVALID_PARAM);
1421 
1422     napi_valuetype eventType = napi_undefined;
1423     napi_typeof(env, argv[0], &eventType);
1424     THROW_ERROR_ASSERT(env, eventType == napi_string, NAPI_ERR_INVALID_PARAM);
1425 
1426     std::string callbackName = AudioCommonNapi::GetStringArgument(env, argv[0]);
1427     AUDIO_DEBUG_LOG("AudioCapturerNapi: Off callbackName: %{public}s", callbackName.c_str());
1428 
1429     return UnregisterCallback(env, jsThis, callbackName);
1430 }
1431 
GetBufferSize(napi_env env,napi_callback_info info)1432 napi_value AudioCapturerNapi::GetBufferSize(napi_env env, napi_callback_info info)
1433 {
1434     napi_status status;
1435     const int32_t refCount = 1;
1436     napi_value result = nullptr;
1437 
1438     GET_PARAMS(env, info, ARGS_ONE);
1439 
1440     unique_ptr<AudioCapturerAsyncContext> asyncContext = make_unique<AudioCapturerAsyncContext>();
1441 
1442     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1443     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1444         if (argc > PARAM0) {
1445             napi_valuetype valueType = napi_undefined;
1446             napi_typeof(env, argv[PARAM0], &valueType);
1447             if (valueType == napi_function) {
1448                 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
1449             }
1450         }
1451 
1452         if (asyncContext->callbackRef == nullptr) {
1453             napi_create_promise(env, &asyncContext->deferred, &result);
1454         } else {
1455             napi_get_undefined(env, &result);
1456         }
1457 
1458         napi_value resource = nullptr;
1459         napi_create_string_utf8(env, "GetBufferSize", NAPI_AUTO_LENGTH, &resource);
1460 
1461         status = napi_create_async_work(
1462             env, nullptr, resource,
1463             [](napi_env env, void *data) {
1464                 auto context = static_cast<AudioCapturerAsyncContext *>(data);
1465                 size_t bufferSize;
1466                 context->status = context->objectInfo->audioCapturer_->GetBufferSize(bufferSize);
1467                 if (context->status == SUCCESS) {
1468                     context->bufferSize = bufferSize;
1469                 }
1470             },
1471             GetBufferSizeAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1472         if (status != napi_ok) {
1473             result = nullptr;
1474         } else {
1475             status = napi_queue_async_work(env, asyncContext->work);
1476             if (status == napi_ok) {
1477                 asyncContext.release();
1478             } else {
1479                 result = nullptr;
1480             }
1481         }
1482     }
1483 
1484     return result;
1485 }
1486 
GetBufferSizeSync(napi_env env,napi_callback_info info)1487 napi_value AudioCapturerNapi::GetBufferSizeSync(napi_env env, napi_callback_info info)
1488 {
1489     napi_status status;
1490     napi_value thisVar = nullptr;
1491     napi_value result = nullptr;
1492     size_t argCount = 0;
1493     void *native = nullptr;
1494 
1495     status = napi_get_cb_info(env, info, &argCount, nullptr, &thisVar, nullptr);
1496     if (status != napi_ok) {
1497         AUDIO_ERR_LOG("Invalid parameters!");
1498         return result;
1499     }
1500 
1501     status = napi_unwrap(env, thisVar, &native);
1502     auto *audioCapturerNapi = reinterpret_cast<AudioCapturerNapi *>(native);
1503     if (status != napi_ok || audioCapturerNapi == nullptr) {
1504         AUDIO_ERR_LOG("GetBufferSizeSync unwrap failure!");
1505         return result;
1506     }
1507 
1508     size_t bufferSize;
1509     int32_t ret = audioCapturerNapi->audioCapturer_->GetBufferSize(bufferSize);
1510     if (ret != SUCCESS) {
1511         AUDIO_ERR_LOG("GetBufferSize failure!");
1512         return result;
1513     }
1514     napi_create_uint32(env, bufferSize, &result);
1515 
1516     return result;
1517 }
1518 
GetState(napi_env env,napi_callback_info info)1519 napi_value AudioCapturerNapi::GetState(napi_env env, napi_callback_info info)
1520 {
1521     napi_value jsThis = nullptr;
1522     napi_value undefinedResult = nullptr;
1523     napi_get_undefined(env, &undefinedResult);
1524 
1525     size_t argCount = 0;
1526     napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
1527     if (status != napi_ok || jsThis == nullptr) {
1528         HiLog::Error(LABEL, "Failed to retrieve details about the callback");
1529         return undefinedResult;
1530     }
1531 
1532     AudioCapturerNapi *capturerNapi = nullptr;
1533     status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&capturerNapi));
1534     if (status != napi_ok || capturerNapi == nullptr) {
1535         HiLog::Error(LABEL, "Failed to get instance");
1536         return undefinedResult;
1537     }
1538 
1539     if (capturerNapi->audioCapturer_ == nullptr) {
1540         HiLog::Error(LABEL, "No memory");
1541         return undefinedResult;
1542     }
1543 
1544     int32_t capturerState = capturerNapi->audioCapturer_->GetStatus();
1545 
1546     napi_value jsResult = nullptr;
1547     status = napi_create_int32(env, capturerState, &jsResult);
1548     if (status != napi_ok) {
1549         HiLog::Error(LABEL, "napi_create_int32 error");
1550         return undefinedResult;
1551     }
1552 
1553     HiLog::Debug(LABEL, "AudioCapturerNapi: GetState Complete, Current state: %{public}d", capturerState);
1554     return jsResult;
1555 }
1556 
ParseCaptureFilterOptionsVector(napi_env env,napi_value root,CaptureFilterOptions * filterOptions)1557 bool AudioCapturerNapi::ParseCaptureFilterOptionsVector(napi_env env, napi_value root,
1558     CaptureFilterOptions *filterOptions)
1559 {
1560     napi_value usagesValue = nullptr;
1561 
1562     if (napi_get_named_property(env, root, "usages", &usagesValue) == napi_ok) {
1563         uint32_t arrayLen = 0;
1564         napi_get_array_length(env, usagesValue, &arrayLen);
1565 
1566         if (arrayLen == 0) {
1567             filterOptions->usages = {};
1568             HiLog::Info(LABEL, "ParseCaptureFilterOptions get empty usage");
1569             return true;
1570         }
1571 
1572         for (size_t i = 0; i < static_cast<size_t>(arrayLen); i++) {
1573             napi_value element;
1574             if (napi_get_element(env, usagesValue, i, &element) == napi_ok) {
1575                 int32_t val = {0};
1576                 napi_get_value_int32(env, element, &val);
1577                 filterOptions->usages.emplace_back(static_cast<StreamUsage>(val));
1578             }
1579         }
1580     }
1581     return true;
1582 }
1583 
ParsePlaybackCaptureConfig(napi_env env,napi_value root,AudioPlaybackCaptureConfig * captureConfig)1584 bool AudioCapturerNapi::ParsePlaybackCaptureConfig(napi_env env, napi_value root,
1585     AudioPlaybackCaptureConfig* captureConfig)
1586 {
1587     napi_value res = nullptr;
1588 
1589     if (napi_get_named_property(env, root, "filterOptions", &res) == napi_ok) {
1590         return ParseCaptureFilterOptionsVector(env, res, &(captureConfig->filterOptions));
1591     } else {
1592         return true;
1593     }
1594 }
1595 
ParseCapturerOptions(napi_env env,napi_value root,AudioCapturerOptions * opts)1596 bool AudioCapturerNapi::ParseCapturerOptions(napi_env env, napi_value root, AudioCapturerOptions *opts)
1597 {
1598     napi_value res = nullptr;
1599     bool result = false;
1600 
1601     if (napi_get_named_property(env, root, "streamInfo", &res) == napi_ok) {
1602         result = ParseStreamInfo(env, res, &(opts->streamInfo));
1603     }
1604 
1605     if (result == false) {
1606         return result;
1607     }
1608 
1609     if (napi_get_named_property(env, root, "capturerInfo", &res) == napi_ok) {
1610         result = ParseCapturerInfo(env, res, &(opts->capturerInfo));
1611     }
1612 
1613     if (result == false) {
1614         return result;
1615     }
1616 
1617     if (napi_get_named_property(env, root, "playbackCaptureConfig", &res) == napi_ok) {
1618         return ParsePlaybackCaptureConfig(env, res, &(opts->playbackCaptureConfig));
1619     }
1620 
1621     HiLog::Info(LABEL, "ParseCapturerOptions, without playbackCaptureConfig");
1622     return true;
1623 }
1624 
ParseCapturerInfo(napi_env env,napi_value root,AudioCapturerInfo * capturerInfo)1625 bool AudioCapturerNapi::ParseCapturerInfo(napi_env env, napi_value root, AudioCapturerInfo *capturerInfo)
1626 {
1627     napi_value tempValue = nullptr;
1628     int32_t intValue = {0};
1629 
1630     if (napi_get_named_property(env, root, "source", &tempValue) == napi_ok) {
1631         napi_get_value_int32(env, tempValue, &intValue);
1632         switch (intValue) {
1633             case TYPE_INVALID:
1634             case TYPE_MIC:
1635             case TYPE_VOICE_RECOGNITION:
1636             case TYPE_PLAYBACK_CAPTURE:
1637             case TYPE_WAKEUP:
1638             case TYPE_COMMUNICATION:
1639                 capturerInfo->sourceType = static_cast<SourceType>(intValue);
1640                 break;
1641             default:
1642                 HiLog::Error(LABEL, "Unknown SourceType: %{public}d", intValue);
1643                 return false;
1644         }
1645     }
1646 
1647     if (napi_get_named_property(env, root, "capturerFlags", &tempValue) == napi_ok) {
1648         napi_get_value_int32(env, tempValue, &(capturerInfo->capturerFlags));
1649     }
1650 
1651     return true;
1652 }
1653 
ParseStreamInfo(napi_env env,napi_value root,AudioStreamInfo * streamInfo)1654 bool AudioCapturerNapi::ParseStreamInfo(napi_env env, napi_value root, AudioStreamInfo* streamInfo)
1655 {
1656     napi_value tempValue = nullptr;
1657     int32_t intValue = {0};
1658 
1659     if (napi_get_named_property(env, root, "samplingRate", &tempValue) == napi_ok) {
1660         napi_get_value_int32(env, tempValue, &intValue);
1661         if (intValue >= SAMPLE_RATE_8000 && intValue <= SAMPLE_RATE_96000) {
1662             streamInfo->samplingRate = static_cast<AudioSamplingRate>(intValue);
1663         } else {
1664             HiLog::Error(LABEL, "Unknown AudioSamplingRate: %{public}d", intValue);
1665             return false;
1666         }
1667     }
1668 
1669     if (napi_get_named_property(env, root, "channels", &tempValue) == napi_ok) {
1670         napi_get_value_int32(env, tempValue, &intValue);
1671         streamInfo->channels = static_cast<AudioChannel>(intValue);
1672     }
1673 
1674     if (napi_get_named_property(env, root, "sampleFormat", &tempValue) == napi_ok) {
1675         napi_get_value_int32(env, tempValue, &intValue);
1676         streamInfo->format = static_cast<OHOS::AudioStandard::AudioSampleFormat>(intValue);
1677     }
1678 
1679     if (napi_get_named_property(env, root, "encodingType", &tempValue) == napi_ok) {
1680         napi_get_value_int32(env, tempValue, &intValue);
1681         streamInfo->encoding = static_cast<AudioEncodingType>(intValue);
1682     }
1683 
1684     return true;
1685 }
1686 
CreateAudioCapturerWrapper(napi_env env,unique_ptr<AudioCapturerOptions> & captureOptions)1687 napi_value AudioCapturerNapi::CreateAudioCapturerWrapper(napi_env env, unique_ptr<AudioCapturerOptions> &captureOptions)
1688 {
1689     lock_guard<mutex> lock(createMutex_);
1690     napi_status status;
1691     napi_value result = nullptr;
1692     napi_value constructor;
1693 
1694     if (captureOptions != nullptr) {
1695         status = napi_get_reference_value(env, g_capturerConstructor, &constructor);
1696         if (status == napi_ok) {
1697             sCapturerOptions_ = move(captureOptions);
1698             status = napi_new_instance(env, constructor, 0, nullptr, &result);
1699             sCapturerOptions_.release();
1700             if (status == napi_ok) {
1701                 return result;
1702             }
1703         }
1704         HiLog::Error(LABEL, "Failed in CreateAudioCapturerWrapper, %{public}d", status);
1705     }
1706 
1707     napi_get_undefined(env, &result);
1708 
1709     return result;
1710 }
1711 }  // namespace AudioStandard
1712 }  // namespace OHOS
1713