1 /*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "avrecorder_callback.h"
17 #include <uv.h>
18 #include "media_errors.h"
19 #include "scope_guard.h"
20 #include "media_log.h"
21 #ifdef SUPPORT_RECORDER_CREATE_FILE
22 #include "media_library_comm_napi.h"
23 #endif
24
25 namespace {
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_RECORDER, "AVRecorderCallback"};
27 }
28
29 namespace OHOS {
30 namespace Media {
31 #ifdef SUPPORT_RECORDER_CREATE_FILE
32 const int32_t CAMERA_SHOT_TYPE = 1; // CameraShotType VIDEO
33 #endif
AVRecorderCallback(napi_env env)34 AVRecorderCallback::AVRecorderCallback(napi_env env) : env_(env)
35 {
36 MEDIA_LOGI("0x%{public}06" PRIXPTR "Instances create", FAKE_POINTER(this));
37 }
38
~AVRecorderCallback()39 AVRecorderCallback::~AVRecorderCallback()
40 {
41 MEDIA_LOGI("0x%{public}06" PRIXPTR "Instances destroy", FAKE_POINTER(this));
42 }
43
SaveCallbackReference(const std::string & name,std::weak_ptr<AutoRef> ref)44 void AVRecorderCallback::SaveCallbackReference(const std::string &name, std::weak_ptr<AutoRef> ref)
45 {
46 std::lock_guard<std::mutex> lock(mutex_);
47 refMap_[name] = ref;
48 MEDIA_LOGI("Set callback type: %{public}s", name.c_str());
49 }
50
CancelCallbackReference(const std::string & name)51 void AVRecorderCallback::CancelCallbackReference(const std::string &name)
52 {
53 std::lock_guard<std::mutex> lock(mutex_);
54 auto iter = refMap_.find(name);
55 if (iter != refMap_.end()) {
56 refMap_.erase(iter);
57 }
58 MEDIA_LOGI("Cancel callback type: %{public}s", name.c_str());
59 }
60
ClearCallbackReference()61 void AVRecorderCallback::ClearCallbackReference()
62 {
63 std::lock_guard<std::mutex> lock(mutex_);
64 refMap_.clear();
65 MEDIA_LOGI("ClearCallback!");
66 }
67
SendErrorCallback(int32_t errCode,const std::string & msg)68 void AVRecorderCallback::SendErrorCallback(int32_t errCode, const std::string &msg)
69 {
70 std::lock_guard<std::mutex> lock(mutex_);
71 if (refMap_.find(AVRecorderEvent::EVENT_ERROR) == refMap_.end()) {
72 MEDIA_LOGW("can not find error callback!");
73 return;
74 }
75
76 AVRecordJsCallback *cb = new(std::nothrow) AVRecordJsCallback();
77 CHECK_AND_RETURN_LOG(cb != nullptr, "cb is nullptr");
78 cb->autoRef = refMap_.at(AVRecorderEvent::EVENT_ERROR);
79 cb->callbackName = AVRecorderEvent::EVENT_ERROR;
80 cb->errorCode = errCode;
81 cb->errorMsg = msg;
82 return OnJsErrorCallBack(cb);
83 }
84
SendStateCallback(const std::string & state,const StateChangeReason & reason)85 void AVRecorderCallback::SendStateCallback(const std::string &state, const StateChangeReason &reason)
86 {
87 std::lock_guard<std::mutex> lock(mutex_);
88 currentState_ = state;
89 if (refMap_.find(AVRecorderEvent::EVENT_STATE_CHANGE) == refMap_.end()) {
90 MEDIA_LOGW("can not find statechange callback!");
91 return;
92 }
93
94 AVRecordJsCallback *cb = new(std::nothrow) AVRecordJsCallback();
95 CHECK_AND_RETURN_LOG(cb != nullptr, "cb is nullptr");
96 cb->autoRef = refMap_.at(AVRecorderEvent::EVENT_STATE_CHANGE);
97 cb->callbackName = AVRecorderEvent::EVENT_STATE_CHANGE;
98 cb->reason = reason;
99 cb->state = state;
100 return OnJsStateCallBack(cb);
101 }
102
SendAudioCaptureChangeCallback(const AudioRecorderChangeInfo & audioRecorderChangeInfo)103 void AVRecorderCallback::SendAudioCaptureChangeCallback(const AudioRecorderChangeInfo &audioRecorderChangeInfo)
104 {
105 std::lock_guard<std::mutex> lock(mutex_);
106 if (refMap_.find(AVRecorderEvent::EVENT_AUDIO_CAPTURE_CHANGE) == refMap_.end()) {
107 MEDIA_LOGW("can not find audioCaptureChange callback");
108 return;
109 }
110
111 AVRecordJsCallback *cb = new(std::nothrow) AVRecordJsCallback();
112 CHECK_AND_RETURN_LOG(cb != nullptr, "cb is nullptr");
113 cb->autoRef = refMap_.at(AVRecorderEvent::EVENT_AUDIO_CAPTURE_CHANGE);
114 cb->callbackName = AVRecorderEvent::EVENT_AUDIO_CAPTURE_CHANGE;
115 cb->audioRecorderChangeInfo = audioRecorderChangeInfo;
116 return OnJsAudioCaptureChangeCallback(cb);
117 }
118
SendPhotoAssertAvailableCallback(const std::string & uri)119 void AVRecorderCallback::SendPhotoAssertAvailableCallback(const std::string &uri)
120 {
121 std::lock_guard<std::mutex> lock(mutex_);
122 if (refMap_.find(AVRecorderEvent::EVENT_PHOTO_ASSET_AVAILABLE) == refMap_.end()) {
123 MEDIA_LOGW("can not find PhotoAssertAvailable callback");
124 return;
125 }
126
127 AVRecordJsCallback *cb = new(std::nothrow) AVRecordJsCallback();
128 CHECK_AND_RETURN_LOG(cb != nullptr, "cb is nullptr");
129 cb->autoRef = refMap_.at(AVRecorderEvent::EVENT_PHOTO_ASSET_AVAILABLE);
130 cb->callbackName = AVRecorderEvent::EVENT_PHOTO_ASSET_AVAILABLE;
131 cb->uri = uri;
132 #ifdef SUPPORT_RECORDER_CREATE_FILE
133 return OnJsPhotoAssertAvailableCallback(cb);
134 #endif
135 }
136
GetState()137 std::string AVRecorderCallback::GetState()
138 {
139 std::lock_guard<std::mutex> lock(mutex_);
140 return currentState_;
141 }
142
OnError(RecorderErrorType errorType,int32_t errCode)143 void AVRecorderCallback::OnError(RecorderErrorType errorType, int32_t errCode)
144 {
145 MEDIA_LOGI("OnError is called, name: %{public}d, error message: %{public}d", errorType, errCode);
146 if (errCode == MSERR_DATA_SOURCE_IO_ERROR) {
147 SendErrorCallback(MSERR_EXT_API9_TIMEOUT,
148 "The video input stream timed out. Please confirm that the input stream is normal.");
149 } else if (errCode == MSERR_DATA_SOURCE_OBTAIN_MEM_ERROR) {
150 SendErrorCallback(MSERR_EXT_API9_TIMEOUT,
151 "Read data from audio timeout, please confirm whether the audio module is normal.");
152 } else if (errCode == MSERR_DATA_SOURCE_ERROR_UNKNOWN) {
153 SendErrorCallback(MSERR_EXT_API9_IO, "Video input data is abnormal."
154 " Please confirm that the pts, width, height, size and other data are normal.");
155 } else if (errCode == MSERR_AUD_INTERRUPT) {
156 SendErrorCallback(MSERR_EXT_API9_AUDIO_INTERRUPTED,
157 "Record failed by audio interrupt.");
158 } else {
159 SendErrorCallback(MSERR_EXT_API9_IO, "IO error happened.");
160 }
161 SendStateCallback(AVRecorderState::STATE_ERROR, StateChangeReason::BACKGROUND);
162 }
163
OnInfo(int32_t type,int32_t extra)164 void AVRecorderCallback::OnInfo(int32_t type, int32_t extra)
165 {
166 MEDIA_LOGI("OnInfo() is called, type: %{public}d, extra: %{public}d", type, extra);
167 }
168
OnAudioCaptureChange(const AudioRecorderChangeInfo & audioRecorderChangeInfo)169 void AVRecorderCallback::OnAudioCaptureChange(const AudioRecorderChangeInfo &audioRecorderChangeInfo)
170 {
171 MEDIA_LOGI("OnAudioCaptureChange() is called");
172 SendAudioCaptureChangeCallback(audioRecorderChangeInfo);
173 }
174
OnPhotoAssertAvailable(const std::string & uri)175 void AVRecorderCallback::OnPhotoAssertAvailable(const std::string &uri)
176 {
177 MEDIA_LOGI("OnPhotoAssertAvailable() is called");
178 SendPhotoAssertAvailableCallback(uri);
179 }
180
OnJsStateCallBack(AVRecordJsCallback * jsCb) const181 void AVRecorderCallback::OnJsStateCallBack(AVRecordJsCallback *jsCb) const
182 {
183 ON_SCOPE_EXIT(0) {
184 delete jsCb;
185 };
186
187 uv_loop_s *loop = nullptr;
188 napi_get_uv_event_loop(env_, &loop);
189 CHECK_AND_RETURN_LOG(loop != nullptr, "Fail to get uv event loop");
190
191 uv_work_t *work = new(std::nothrow) uv_work_t;
192 CHECK_AND_RETURN_LOG(work != nullptr, "fail to new uv_work_t");
193 ON_SCOPE_EXIT(1) {
194 delete work;
195 };
196
197 work->data = reinterpret_cast<void *>(jsCb);
198 int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {}, [] (uv_work_t *work, int status) {
199 // Js Thread
200 CHECK_AND_RETURN_LOG(work != nullptr, "work is nullptr");
201 AVRecordJsCallback *event = reinterpret_cast<AVRecordJsCallback *>(work->data);
202 std::string request = event->callbackName;
203 MEDIA_LOGI("uv_queue_work_with_qos start, state changes to %{public}s", event->state.c_str());
204 do {
205 CHECK_AND_BREAK_LOG(status != UV_ECANCELED, "%{public}s canceled", request.c_str());
206 std::shared_ptr<AutoRef> ref = event->autoRef.lock();
207 CHECK_AND_BREAK_LOG(ref != nullptr, "%{public}s AutoRef is nullptr", request.c_str());
208
209 napi_handle_scope scope = nullptr;
210 napi_open_handle_scope(ref->env_, &scope);
211 CHECK_AND_BREAK_LOG(scope != nullptr, "%{public}s scope is nullptr", request.c_str());
212 ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
213
214 napi_value jsCallback = nullptr;
215 napi_status nstatus = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
216 CHECK_AND_BREAK_LOG(nstatus == napi_ok && jsCallback != nullptr, "%{public}s get reference value fail",
217 request.c_str());
218
219 napi_value args[2] = { nullptr };
220 nstatus = napi_create_string_utf8(ref->env_, event->state.c_str(), NAPI_AUTO_LENGTH, &args[0]);
221 CHECK_AND_BREAK_LOG(nstatus == napi_ok && args[0] != nullptr,
222 "%{public}s fail to create callback", request.c_str());
223
224 nstatus = napi_create_int32(ref->env_, event->reason, &args[1]);
225 CHECK_AND_BREAK_LOG(nstatus == napi_ok && args[1] != nullptr,
226 "%{public}s fail to create callback", request.c_str());
227
228 const size_t argCount = 2;
229 napi_value result = nullptr;
230 nstatus = napi_call_function(ref->env_, nullptr, jsCallback, argCount, args, &result);
231 CHECK_AND_BREAK_LOG(nstatus == napi_ok, "%{public}s fail to napi call function", request.c_str());
232 } while (0);
233 delete event;
234 delete work;
235 }, uv_qos_user_initiated);
236 CHECK_AND_RETURN_LOG(ret == 0, "fail to uv_queue_work_with_qos task");
237
238 CANCEL_SCOPE_EXIT_GUARD(0);
239 CANCEL_SCOPE_EXIT_GUARD(1);
240 }
241
242 #ifdef SUPPORT_RECORDER_CREATE_FILE
OnJsPhotoAssertAvailableCallback(AVRecordJsCallback * jsCb) const243 void AVRecorderCallback::OnJsPhotoAssertAvailableCallback(AVRecordJsCallback *jsCb) const
244 {
245 ON_SCOPE_EXIT(0) {
246 delete jsCb;
247 };
248
249 uv_loop_s *loop = nullptr;
250 napi_get_uv_event_loop(env_, &loop);
251 CHECK_AND_RETURN_LOG(loop != nullptr, "Fail to get uv event loop");
252
253 uv_work_t *work = new(std::nothrow) uv_work_t;
254 CHECK_AND_RETURN_LOG(work != nullptr, "fail to new uv_work_t");
255 ON_SCOPE_EXIT(1) {
256 delete work;
257 };
258
259 work->data = reinterpret_cast<void *>(jsCb);
260 int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {}, [] (uv_work_t *work, int status) {
261 CHECK_AND_RETURN_LOG(work != nullptr, "work is nullptr");
262 if (work->data == nullptr) {
263 delete work;
264 MEDIA_LOGE("workdata is nullptr");
265 return;
266 }
267 AVRecordJsCallback *event = reinterpret_cast<AVRecordJsCallback *>(work->data);
268 std::string request = event->callbackName;
269 do {
270 CHECK_AND_BREAK_LOG(status != UV_ECANCELED, "%{public}s canceled", request.c_str());
271 std::shared_ptr<AutoRef> ref = event->autoRef.lock();
272 CHECK_AND_BREAK_LOG(ref != nullptr, "%{public}s AutoRef is nullptr", request.c_str());
273
274 napi_handle_scope scope = nullptr;
275 napi_open_handle_scope(ref->env_, &scope);
276 CHECK_AND_BREAK_LOG(scope != nullptr, "%{public}s scope is nullptr", request.c_str());
277 ON_SCOPE_EXIT(0) {
278 napi_close_handle_scope(ref->env_, scope);
279 };
280
281 napi_value jsCallback = nullptr;
282 napi_status nstatus = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
283 CHECK_AND_BREAK_LOG(nstatus == napi_ok && jsCallback != nullptr, "%{public}s get reference value fail",
284 request.c_str());
285
286 const size_t argCount = 1;
287 napi_value args[argCount] = { nullptr };
288
289 args[0] = Media::MediaLibraryCommNapi::CreatePhotoAssetNapi(ref->env_, event->uri, CAMERA_SHOT_TYPE);
290 napi_value result = nullptr;
291 nstatus = napi_call_function(ref->env_, nullptr, jsCallback, argCount, args, &result);
292 CHECK_AND_BREAK_LOG(nstatus == napi_ok, "%{public}s fail to napi call function", request.c_str());
293 } while (0);
294 delete event;
295 delete work;
296 }, uv_qos_user_initiated);
297 CHECK_AND_RETURN_LOG(ret == 0, "fail to uv_queue_work_with_qos task");
298
299 CANCEL_SCOPE_EXIT_GUARD(0);
300 CANCEL_SCOPE_EXIT_GUARD(1);
301 }
302 #endif
303
OnJsAudioCaptureChangeCallback(AVRecordJsCallback * jsCb) const304 void AVRecorderCallback::OnJsAudioCaptureChangeCallback(AVRecordJsCallback *jsCb) const
305 {
306 ON_SCOPE_EXIT(0) {
307 delete jsCb;
308 };
309
310 uv_loop_s *loop = nullptr;
311 napi_get_uv_event_loop(env_, &loop);
312 CHECK_AND_RETURN_LOG(loop != nullptr, "Fail to get uv event loop");
313
314 uv_work_t *work = new(std::nothrow) uv_work_t;
315 CHECK_AND_RETURN_LOG(work != nullptr, "fail to new uv_work_t");
316 ON_SCOPE_EXIT(1) {
317 delete work;
318 };
319
320 work->data = reinterpret_cast<void *>(jsCb);
321 int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {}, [] (uv_work_t *work, int status) {
322 // Js Thread
323 CHECK_AND_RETURN_LOG(work != nullptr, "work is nullptr");
324 if (work->data == nullptr) {
325 delete work;
326 MEDIA_LOGE("workdata is nullptr");
327 return;
328 }
329 AVRecordJsCallback *event = reinterpret_cast<AVRecordJsCallback *>(work->data);
330 std::string request = event->callbackName;
331 do {
332 CHECK_AND_BREAK_LOG(status != UV_ECANCELED, "%{public}s canceled", request.c_str());
333 std::shared_ptr<AutoRef> ref = event->autoRef.lock();
334 CHECK_AND_BREAK_LOG(ref != nullptr, "%{public}s AutoRef is nullptr", request.c_str());
335
336 napi_handle_scope scope = nullptr;
337 napi_open_handle_scope(ref->env_, &scope);
338 CHECK_AND_BREAK_LOG(scope != nullptr, "%{public}s scope is nullptr", request.c_str());
339 ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
340
341 napi_value jsCallback = nullptr;
342 napi_status nstatus = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
343 CHECK_AND_BREAK_LOG(nstatus == napi_ok && jsCallback != nullptr, "%{public}s get reference value fail",
344 request.c_str());
345
346 const size_t argCount = 1;
347 napi_value args[argCount] = { nullptr };
348 std::shared_ptr<AudioCaptureChangeInfoJsCallback> ChangeInfoJsCallback =
349 std::make_shared<AudioCaptureChangeInfoJsCallback>(event->audioRecorderChangeInfo);
350 nstatus = ChangeInfoJsCallback->GetJsResult(ref->env_, args[0]);
351 napi_value result = nullptr;
352 nstatus = napi_call_function(ref->env_, nullptr, jsCallback, argCount, args, &result);
353 CHECK_AND_BREAK_LOG(nstatus == napi_ok, "%{public}s fail to napi call function", request.c_str());
354 } while (0);
355 delete event;
356 delete work;
357 }, uv_qos_user_initiated);
358 CHECK_AND_RETURN_LOG(ret == 0, "fail to uv_queue_work_with_qos task");
359
360 CANCEL_SCOPE_EXIT_GUARD(0);
361 CANCEL_SCOPE_EXIT_GUARD(1);
362 }
363
OnJsErrorCallBack(AVRecordJsCallback * jsCb) const364 void AVRecorderCallback::OnJsErrorCallBack(AVRecordJsCallback *jsCb) const
365 {
366 ON_SCOPE_EXIT(0) {
367 delete jsCb;
368 };
369
370 uv_loop_s *loop = nullptr;
371 napi_get_uv_event_loop(env_, &loop);
372 CHECK_AND_RETURN_LOG(loop != nullptr, "Fail to get uv event loop");
373
374 uv_work_t *work = new(std::nothrow) uv_work_t;
375 CHECK_AND_RETURN_LOG(work != nullptr, "fail to new uv_work_t");
376 ON_SCOPE_EXIT(1) {
377 delete work;
378 };
379
380 work->data = reinterpret_cast<void *>(jsCb);
381 // async callback, jsWork and jsWork->data should be heap object.
382 int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {}, [] (uv_work_t *work, int status) {
383 // Js Thread
384 CHECK_AND_RETURN_LOG(work != nullptr, "work is nullptr");
385 if (work->data == nullptr) {
386 delete work;
387 MEDIA_LOGE("workdata is nullptr");
388 return;
389 }
390 AVRecordJsCallback *event = reinterpret_cast<AVRecordJsCallback *>(work->data);
391 std::string request = event->callbackName;
392 MEDIA_LOGI("uv_queue_work_with_qos start, errorcode:%{public}d , errormessage:%{public}s:",
393 event->errorCode, event->errorMsg.c_str());
394 do {
395 CHECK_AND_BREAK_LOG(status != UV_ECANCELED, "%{public}s canceled", request.c_str());
396 std::shared_ptr<AutoRef> ref = event->autoRef.lock();
397 CHECK_AND_BREAK_LOG(ref != nullptr, "%{public}s AutoRef is nullptr", request.c_str());
398
399 napi_handle_scope scope = nullptr;
400 napi_open_handle_scope(ref->env_, &scope);
401 CHECK_AND_BREAK_LOG(scope != nullptr, "%{public}s scope is nullptr", request.c_str());
402 ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
403
404 napi_value jsCallback = nullptr;
405 napi_status nstatus = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
406 CHECK_AND_BREAK_LOG(nstatus == napi_ok && jsCallback != nullptr, "%{public}s get reference value fail",
407 request.c_str());
408
409 napi_value msgValStr = nullptr;
410 nstatus = napi_create_string_utf8(ref->env_, event->errorMsg.c_str(), NAPI_AUTO_LENGTH, &msgValStr);
411 CHECK_AND_BREAK_LOG(nstatus == napi_ok && msgValStr != nullptr, "create error message str fail");
412
413 napi_value args[1] = { nullptr };
414 nstatus = napi_create_error(ref->env_, nullptr, msgValStr, &args[0]);
415 CHECK_AND_BREAK_LOG(nstatus == napi_ok && args[0] != nullptr, "create error callback fail");
416
417 nstatus = CommonNapi::FillErrorArgs(ref->env_, event->errorCode, args[0]);
418 CHECK_AND_BREAK_LOG(nstatus == napi_ok, "create error callback fail");
419
420 // Call back function
421 napi_value result = nullptr;
422 nstatus = napi_call_function(ref->env_, nullptr, jsCallback, 1, args, &result);
423 CHECK_AND_BREAK_LOG(nstatus == napi_ok, "%{public}s fail to napi call function", request.c_str());
424 } while (0);
425 delete event;
426 delete work;
427 }, uv_qos_user_initiated);
428 CHECK_AND_RETURN_LOG(ret == 0, "fail to uv_queue_work_with_qos task");
429
430 CANCEL_SCOPE_EXIT_GUARD(0);
431 CANCEL_SCOPE_EXIT_GUARD(1);
432 }
433
GetJsResult(napi_env env,napi_value & result)434 napi_status AudioCaptureChangeInfoJsCallback::GetJsResult(napi_env env, napi_value &result)
435 {
436 napi_status ret = napi_ok;
437 bool setRet = true;
438 CHECK_AND_RETURN_RET((ret = napi_create_object(env, &result)) == napi_ok, ret);
439
440 setRet = CommonNapi::SetPropertyInt32(env, result, "streamId", value_.sessionId);
441 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
442 setRet = CommonNapi::SetPropertyInt32(env, result, "clientUid", value_.clientUID);
443 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
444 setRet = CommonNapi::SetPropertyInt32(env, result, "capturerState", value_.capturerState);
445 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
446 setRet = CommonNapi::SetPropertyBool(env, result, "muted", value_.muted);
447 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
448
449 napi_value captureInfo;
450 napi_value deviceDescriptors;
451 CHECK_AND_RETURN_RET((ret = napi_create_object(env, &captureInfo)) == napi_ok, ret);
452 CHECK_AND_RETURN_RET((ret = napi_create_array_with_length(env, 1, &deviceDescriptors)) == napi_ok, ret);
453 CHECK_AND_RETURN_RET((ret = SetAudioCapturerInfo(env, captureInfo, result)) == napi_ok, ret);
454 CHECK_AND_RETURN_RET((ret = SetDeviceInfo(env, deviceDescriptors, result)) == napi_ok, ret);
455 return ret;
456 }
457
SetAudioCapturerInfo(napi_env env,napi_value & captureInfo,napi_value & result)458 napi_status AudioCaptureChangeInfoJsCallback::SetAudioCapturerInfo(napi_env env,
459 napi_value &captureInfo, napi_value &result)
460 {
461 bool setRet = true;
462 setRet = CommonNapi::SetPropertyInt32(env, captureInfo, "source",
463 static_cast<int32_t>(value_.capturerInfo.sourceType));
464 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
465 setRet = CommonNapi::SetPropertyInt32(env, captureInfo, "capturerFlags", value_.capturerInfo.capturerFlags);
466 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
467 napi_set_named_property(env, result, "capturerInfo", captureInfo);
468 return napi_ok;
469 }
470
SetDeviceProperty(napi_env env,napi_value & element)471 napi_status AudioCaptureChangeInfoJsCallback::SetDeviceProperty(napi_env env, napi_value &element)
472 {
473 bool setRet = true;
474 setRet = CommonNapi::SetPropertyInt32(env, element, "deviceRole",
475 static_cast<int32_t>(value_.inputDeviceInfo.deviceRole));
476 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
477 setRet = CommonNapi::SetPropertyInt32(env, element, "deviceType",
478 static_cast<int32_t>(value_.inputDeviceInfo.deviceType));
479 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
480 setRet = CommonNapi::SetPropertyInt32(env, element, "id", value_.inputDeviceInfo.deviceId);
481 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
482 setRet = CommonNapi::SetPropertyString(env, element, "name", value_.inputDeviceInfo.deviceName);
483 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
484 setRet = CommonNapi::SetPropertyString(env, element, "address", value_.inputDeviceInfo.macAddress);
485 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
486 setRet = CommonNapi::SetPropertyString(env, element, "networkId", value_.inputDeviceInfo.networkId);
487 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
488 setRet = CommonNapi::SetPropertyString(env, element, "displayName", value_.inputDeviceInfo.displayName);
489 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
490 setRet = CommonNapi::SetPropertyInt32(env, element, "interruptGroupId",
491 value_.inputDeviceInfo.interruptGroupId);
492 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
493 setRet = CommonNapi::SetPropertyInt32(env, element, "volumeGroupId",
494 value_.inputDeviceInfo.volumeGroupId);
495 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
496 return napi_ok;
497 }
498
SetDeviceInfo(napi_env env,napi_value & deviceDescriptors,napi_value & result)499 napi_status AudioCaptureChangeInfoJsCallback::SetDeviceInfo(napi_env env,
500 napi_value &deviceDescriptors, napi_value &result)
501 {
502 napi_value element;
503 napi_create_object(env, &element);
504 CHECK_AND_RETURN_RET(SetDeviceProperty(env, element) == napi_ok, napi_generic_failure);
505
506 bool setRet = true;
507 napi_value sampleRates;
508 setRet = CommonNapi::AddArrayInt(env, sampleRates,
509 std::vector<int32_t>(value_.inputDeviceInfo.audioStreamInfo.samplingRate.begin(),
510 value_.inputDeviceInfo.audioStreamInfo.samplingRate.end()));
511 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
512 napi_set_named_property(env, element, "sampleRates", sampleRates);
513
514 napi_value channelCounts;
515 setRet = CommonNapi::AddArrayInt(env, channelCounts,
516 std::vector<int32_t>(value_.inputDeviceInfo.audioStreamInfo.channels.begin(),
517 value_.inputDeviceInfo.audioStreamInfo.channels.end()));
518 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
519 napi_set_named_property(env, element, "channelCounts", channelCounts);
520
521 napi_value channelMasks;
522 setRet = CommonNapi::AddArrayInt(env, channelMasks, std::vector<int32_t>({value_.inputDeviceInfo.channelMasks}));
523 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
524 napi_set_named_property(env, element, "channelMasks", channelMasks);
525
526 napi_value channelIndexMasks;
527 setRet = CommonNapi::AddArrayInt(env, channelIndexMasks,
528 std::vector<int32_t>({value_.inputDeviceInfo.channelIndexMasks}));
529 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
530 napi_set_named_property(env, element, "channelIndexMasks", channelIndexMasks);
531
532 napi_value encodingTypes;
533 setRet = CommonNapi::AddArrayInt(env, encodingTypes,
534 std::vector<int32_t>({value_.inputDeviceInfo.audioStreamInfo.encoding}));
535 CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
536 napi_set_named_property(env, element, "encodingTypes", encodingTypes);
537
538 napi_set_element(env, deviceDescriptors, 0, element);
539 napi_set_named_property(env, result, "deviceDescriptors", deviceDescriptors);
540 return napi_ok;
541 }
542 } // namespace Media
543 } // namespace OHOS