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], ¶mArg1);
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