• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     MEDIA_LOGI("AVRecorderCallback SendAudioCaptureChangeCallback is start");
106     std::lock_guard<std::mutex> lock(mutex_);
107     if (refMap_.find(AVRecorderEvent::EVENT_AUDIO_CAPTURE_CHANGE) == refMap_.end()) {
108         MEDIA_LOGW("can not find audioCaptureChange callback");
109         return;
110     }
111 
112     AVRecordJsCallback *cb = new(std::nothrow) AVRecordJsCallback();
113     CHECK_AND_RETURN_LOG(cb != nullptr, "cb is nullptr");
114     cb->autoRef = refMap_.at(AVRecorderEvent::EVENT_AUDIO_CAPTURE_CHANGE);
115     cb->callbackName = AVRecorderEvent::EVENT_AUDIO_CAPTURE_CHANGE;
116     cb->audioRecorderChangeInfo = audioRecorderChangeInfo;
117     return OnJsAudioCaptureChangeCallback(cb);
118 }
119 
SendPhotoAssertAvailableCallback(const std::string & uri)120 void AVRecorderCallback::SendPhotoAssertAvailableCallback(const std::string &uri)
121 {
122     std::lock_guard<std::mutex> lock(mutex_);
123     if (refMap_.find(AVRecorderEvent::EVENT_PHOTO_ASSET_AVAILABLE) == refMap_.end()) {
124         MEDIA_LOGW("can not find PhotoAssertAvailable callback");
125         return;
126     }
127 
128     AVRecordJsCallback *cb = new(std::nothrow) AVRecordJsCallback();
129     CHECK_AND_RETURN_LOG(cb != nullptr, "cb is nullptr");
130     cb->autoRef = refMap_.at(AVRecorderEvent::EVENT_PHOTO_ASSET_AVAILABLE);
131     cb->callbackName = AVRecorderEvent::EVENT_PHOTO_ASSET_AVAILABLE;
132     cb->uri = uri;
133 #ifdef SUPPORT_RECORDER_CREATE_FILE
134     return OnJsPhotoAssertAvailableCallback(cb);
135 #endif
136 }
137 
GetState()138 std::string AVRecorderCallback::GetState()
139 {
140     std::lock_guard<std::mutex> lock(mutex_);
141     return currentState_;
142 }
143 
OnError(RecorderErrorType errorType,int32_t errCode)144 void AVRecorderCallback::OnError(RecorderErrorType errorType, int32_t errCode)
145 {
146     MEDIA_LOGI("OnError is called, name: %{public}d, error message: %{public}d", errorType, errCode);
147     SendStateCallback(AVRecorderState::STATE_ERROR, StateChangeReason::BACKGROUND);
148     if (errCode == MSERR_DATA_SOURCE_IO_ERROR) {
149         SendErrorCallback(MSERR_EXT_API9_TIMEOUT,
150             "The video input stream timed out. Please confirm that the input stream is normal.");
151     } else if (errCode == MSERR_DATA_SOURCE_OBTAIN_MEM_ERROR) {
152         SendErrorCallback(MSERR_EXT_API9_TIMEOUT,
153             "Read data from audio timeout, please confirm whether the audio module is normal.");
154     } else if (errCode == MSERR_DATA_SOURCE_ERROR_UNKNOWN) {
155         SendErrorCallback(MSERR_EXT_API9_IO, "Video input data is abnormal."
156             " Please confirm that the pts, width, height, size and other data are normal.");
157     } else if (errCode == MSERR_AUD_INTERRUPT) {
158         SendErrorCallback(MSERR_EXT_API9_AUDIO_INTERRUPTED,
159             "Record failed by audio interrupt.");
160     } else {
161         SendErrorCallback(MSERR_EXT_API9_IO, "IO error happened.");
162     }
163 }
164 
OnInfo(int32_t type,int32_t extra)165 void AVRecorderCallback::OnInfo(int32_t type, int32_t extra)
166 {
167     MEDIA_LOGI("OnInfo() is called, type: %{public}d, extra: %{public}d", type, extra);
168     if (type == RecorderInfoType::RECORDER_INFO_MAX_DURATION_REACHED) {
169         MEDIA_LOGI("OnInfo() type = MAX_DURATION_REACHED, type: %{public}d, extra: %{public}d", type, extra);
170         SendStateCallback(AVRecorderState::STATE_STOPPED, StateChangeReason::BACKGROUND);
171     }
172 }
173 
OnAudioCaptureChange(const AudioRecorderChangeInfo & audioRecorderChangeInfo)174 void AVRecorderCallback::OnAudioCaptureChange(const AudioRecorderChangeInfo &audioRecorderChangeInfo)
175 {
176     MEDIA_LOGI("OnAudioCaptureChange() is called");
177     MEDIA_LOGI("AVRecorderCallback OnAudioCaptureChange is start");
178     SendAudioCaptureChangeCallback(audioRecorderChangeInfo);
179 }
180 
OnPhotoAssertAvailable(const std::string & uri)181 void AVRecorderCallback::OnPhotoAssertAvailable(const std::string &uri)
182 {
183     MEDIA_LOGI("OnPhotoAssertAvailable() is called");
184     SendPhotoAssertAvailableCallback(uri);
185 }
186 
OnJsStateCallBack(AVRecordJsCallback * jsCb) const187 void AVRecorderCallback::OnJsStateCallBack(AVRecordJsCallback *jsCb) const
188 {
189     ON_SCOPE_EXIT(0) {
190         delete jsCb;
191     };
192 
193     auto task = [event = jsCb]() {
194         std::string request = event->callbackName;
195         do {
196             std::shared_ptr<AutoRef> ref = event->autoRef.lock();
197             CHECK_AND_BREAK_LOG(ref != nullptr, "%{public}s AutoRef is nullptr", request.c_str());
198 
199             napi_handle_scope scope = nullptr;
200             napi_open_handle_scope(ref->env_, &scope);
201             CHECK_AND_BREAK_LOG(scope != nullptr, "%{public}s scope is nullptr", request.c_str());
202             ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
203 
204             napi_value jsCallback = nullptr;
205             napi_status nstatus = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
206             CHECK_AND_BREAK_LOG(nstatus == napi_ok && jsCallback != nullptr, "%{public}s get reference value failed",
207                 request.c_str());
208 
209             napi_value args[2] = { nullptr };
210             nstatus = napi_create_string_utf8(ref->env_, event->state.c_str(), NAPI_AUTO_LENGTH, &args[0]);
211             CHECK_AND_BREAK_LOG(nstatus == napi_ok && args[0] != nullptr,
212                 "%{public}s failed to create callback", request.c_str());
213 
214             nstatus = napi_create_int32(ref->env_, event->reason, &args[1]);
215             CHECK_AND_BREAK_LOG(nstatus == napi_ok && args[1] != nullptr,
216                 "%{public}s failed to create callback", request.c_str());
217 
218             const size_t argCount = 2;
219             napi_value result = nullptr;
220             nstatus = napi_call_function(ref->env_, nullptr, jsCallback, argCount, args, &result);
221             CHECK_AND_BREAK_LOG(nstatus == napi_ok, "%{public}s failed to napi call function", request.c_str());
222         } while (0);
223         delete event;
224     };
225     auto ret = napi_send_event(env_, task, napi_eprio_immediate);
226     CHECK_AND_RETURN_LOG(ret == napi_status::napi_ok, "failed to napi_send_event task");
227 
228     CANCEL_SCOPE_EXIT_GUARD(0);
229 }
230 
231 #ifdef SUPPORT_RECORDER_CREATE_FILE
OnJsPhotoAssertAvailableCallback(AVRecordJsCallback * jsCb) const232 void AVRecorderCallback::OnJsPhotoAssertAvailableCallback(AVRecordJsCallback *jsCb) const
233 {
234     ON_SCOPE_EXIT(0) {
235         delete jsCb;
236     };
237 
238     auto task = [event = jsCb]() {
239         std::string request = event->callbackName;
240         do {
241             std::shared_ptr<AutoRef> ref = event->autoRef.lock();
242             CHECK_AND_BREAK_LOG(ref != nullptr, "%{public}s AutoRef is nullptr", request.c_str());
243 
244             napi_handle_scope scope = nullptr;
245             napi_open_handle_scope(ref->env_, &scope);
246             CHECK_AND_BREAK_LOG(scope != nullptr, "%{public}s scope is nullptr", request.c_str());
247             ON_SCOPE_EXIT(0) {
248                 napi_close_handle_scope(ref->env_, scope);
249             };
250 
251             napi_value jsCallback = nullptr;
252             napi_status nstatus = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
253             CHECK_AND_BREAK_LOG(nstatus == napi_ok && jsCallback != nullptr, "%{public}s get reference value failed",
254                 request.c_str());
255 
256             const size_t argCount = 1;
257             napi_value args[argCount] = { nullptr };
258 
259             args[0] = Media::MediaLibraryCommNapi::CreatePhotoAssetNapi(ref->env_, event->uri, CAMERA_SHOT_TYPE);
260             napi_value result = nullptr;
261             nstatus = napi_call_function(ref->env_, nullptr, jsCallback, argCount, args, &result);
262             CHECK_AND_BREAK_LOG(nstatus == napi_ok, "%{public}s failed to napi call function", request.c_str());
263         } while (0);
264         delete event;
265     };
266     auto ret = napi_send_event(env_, task, napi_eprio_immediate);
267     CHECK_AND_RETURN_LOG(ret == napi_status::napi_ok, "failed to napi_send_event task");
268 
269     CANCEL_SCOPE_EXIT_GUARD(0);
270 }
271 #endif
272 
OnJsAudioCaptureChangeCallback(AVRecordJsCallback * jsCb) const273 void AVRecorderCallback::OnJsAudioCaptureChangeCallback(AVRecordJsCallback *jsCb) const
274 {
275     MEDIA_LOGI("AVRecorderCallback OnJsAudioCaptureChangeCallback is start");
276     ON_SCOPE_EXIT(0) {
277         delete jsCb;
278     };
279 
280     auto task = [event = jsCb]() {
281         std::string request = event->callbackName;
282         do {
283             std::shared_ptr<AutoRef> ref = event->autoRef.lock();
284             CHECK_AND_BREAK_LOG(ref != nullptr, "%{public}s AutoRef is nullptr", request.c_str());
285 
286             napi_handle_scope scope = nullptr;
287             napi_open_handle_scope(ref->env_, &scope);
288             CHECK_AND_BREAK_LOG(scope != nullptr, "%{public}s scope is nullptr", request.c_str());
289             ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
290 
291             napi_value jsCallback = nullptr;
292             napi_status nstatus = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
293             CHECK_AND_BREAK_LOG(nstatus == napi_ok && jsCallback != nullptr, "%{public}s get reference value failed",
294                 request.c_str());
295 
296             const size_t argCount = 1;
297             napi_value args[argCount] = { nullptr };
298             std::shared_ptr<AudioCaptureChangeInfoJsCallback> ChangeInfoJsCallback =
299                 std::make_shared<AudioCaptureChangeInfoJsCallback>(event->audioRecorderChangeInfo);
300             nstatus = ChangeInfoJsCallback->GetJsResult(ref->env_, args[0]);
301             napi_value result = nullptr;
302             nstatus = napi_call_function(ref->env_, nullptr, jsCallback, argCount, args, &result);
303             CHECK_AND_BREAK_LOG(nstatus == napi_ok, "%{public}s failed to napi call function", request.c_str());
304         } while (0);
305         delete event;
306     };
307     auto ret = napi_send_event(env_, task, napi_eprio_immediate);
308     CHECK_AND_RETURN_LOG(ret == napi_status::napi_ok, "failed to napi_send_event task");
309 
310     CANCEL_SCOPE_EXIT_GUARD(0);
311 }
312 
OnJsErrorCallBack(AVRecordJsCallback * jsCb) const313 void AVRecorderCallback::OnJsErrorCallBack(AVRecordJsCallback *jsCb) const
314 {
315     ON_SCOPE_EXIT(0) {
316         delete jsCb;
317     };
318 
319     auto task = [event = jsCb]() {
320         std::string request = event->callbackName;
321         do {
322             std::shared_ptr<AutoRef> ref = event->autoRef.lock();
323             CHECK_AND_BREAK_LOG(ref != nullptr, "%{public}s AutoRef is nullptr", request.c_str());
324 
325             napi_handle_scope scope = nullptr;
326             napi_open_handle_scope(ref->env_, &scope);
327             CHECK_AND_BREAK_LOG(scope != nullptr, "%{public}s scope is nullptr", request.c_str());
328             ON_SCOPE_EXIT(0) { napi_close_handle_scope(ref->env_, scope); };
329 
330             napi_value jsCallback = nullptr;
331             napi_status nstatus = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
332             CHECK_AND_BREAK_LOG(nstatus == napi_ok && jsCallback != nullptr, "%{public}s get reference value failed",
333                 request.c_str());
334 
335             napi_value msgValStr = nullptr;
336             nstatus = napi_create_string_utf8(ref->env_, event->errorMsg.c_str(), NAPI_AUTO_LENGTH, &msgValStr);
337             CHECK_AND_BREAK_LOG(nstatus == napi_ok && msgValStr != nullptr, "create error message str failed");
338 
339             napi_value args[1] = { nullptr };
340             nstatus = napi_create_error(ref->env_, nullptr, msgValStr, &args[0]);
341             CHECK_AND_BREAK_LOG(nstatus == napi_ok && args[0] != nullptr, "create error callback failed");
342 
343             nstatus = CommonNapi::FillErrorArgs(ref->env_, event->errorCode, args[0]);
344             CHECK_AND_BREAK_LOG(nstatus == napi_ok, "create error callback failed");
345 
346             // Call back function
347             napi_value result = nullptr;
348             nstatus = napi_call_function(ref->env_, nullptr, jsCallback, 1, args, &result);
349             CHECK_AND_BREAK_LOG(nstatus == napi_ok, "%{public}s failed to napi call function", request.c_str());
350         } while (0);
351         delete event;
352     };
353     auto ret = napi_send_event(env_, task, napi_eprio_immediate);
354     CHECK_AND_RETURN_LOG(ret == napi_status::napi_ok, "failed to napi_send_event task");
355 
356     CANCEL_SCOPE_EXIT_GUARD(0);
357 }
358 
GetJsResult(napi_env env,napi_value & result)359 napi_status AudioCaptureChangeInfoJsCallback::GetJsResult(napi_env env, napi_value &result)
360 {
361     napi_status ret = napi_ok;
362     bool setRet = true;
363     CHECK_AND_RETURN_RET((ret = napi_create_object(env, &result)) == napi_ok, ret);
364 
365     setRet = CommonNapi::SetPropertyInt32(env, result, "streamId", value_.sessionId);
366     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
367     setRet = CommonNapi::SetPropertyInt32(env, result, "clientUid", value_.clientUID);
368     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
369     setRet = CommonNapi::SetPropertyInt32(env, result, "capturerState", value_.capturerState);
370     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
371     setRet = CommonNapi::SetPropertyBool(env, result, "muted", value_.muted);
372     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
373 
374     napi_value captureInfo;
375     napi_value deviceDescriptors;
376     CHECK_AND_RETURN_RET((ret = napi_create_object(env, &captureInfo)) == napi_ok, ret);
377     CHECK_AND_RETURN_RET((ret = napi_create_array_with_length(env, 1, &deviceDescriptors)) == napi_ok, ret);
378     CHECK_AND_RETURN_RET((ret = SetAudioCapturerInfo(env, captureInfo, result)) == napi_ok, ret);
379     CHECK_AND_RETURN_RET((ret = SetDeviceInfo(env, deviceDescriptors, result)) == napi_ok, ret);
380     return ret;
381 }
382 
SetAudioCapturerInfo(napi_env env,napi_value & captureInfo,napi_value & result)383 napi_status AudioCaptureChangeInfoJsCallback::SetAudioCapturerInfo(napi_env env,
384     napi_value &captureInfo, napi_value &result)
385 {
386     bool setRet = true;
387     setRet = CommonNapi::SetPropertyInt32(env, captureInfo, "source",
388         static_cast<int32_t>(value_.capturerInfo.sourceType));
389     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
390     setRet = CommonNapi::SetPropertyInt32(env, captureInfo, "capturerFlags", value_.capturerInfo.capturerFlags);
391     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
392     napi_set_named_property(env, result, "capturerInfo", captureInfo);
393     return napi_ok;
394 }
395 
SetDeviceProperty(napi_env env,napi_value & element)396 napi_status AudioCaptureChangeInfoJsCallback::SetDeviceProperty(napi_env env, napi_value &element)
397 {
398     bool setRet = true;
399     setRet = CommonNapi::SetPropertyInt32(env, element, "deviceRole",
400         static_cast<int32_t>(value_.inputDeviceInfo.deviceRole));
401     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
402     setRet = CommonNapi::SetPropertyInt32(env, element, "deviceType",
403         static_cast<int32_t>(value_.inputDeviceInfo.deviceType));
404     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
405     setRet = CommonNapi::SetPropertyInt32(env, element, "id", value_.inputDeviceInfo.deviceId);
406     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
407     setRet = CommonNapi::SetPropertyString(env, element, "name", value_.inputDeviceInfo.deviceName);
408     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
409     setRet = CommonNapi::SetPropertyString(env, element, "address", value_.inputDeviceInfo.macAddress);
410     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
411     setRet = CommonNapi::SetPropertyString(env, element, "networkId", value_.inputDeviceInfo.networkId);
412     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
413     setRet = CommonNapi::SetPropertyString(env, element, "displayName", value_.inputDeviceInfo.displayName);
414     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
415     setRet = CommonNapi::SetPropertyInt32(env, element, "interruptGroupId",
416         value_.inputDeviceInfo.interruptGroupId);
417     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
418     setRet = CommonNapi::SetPropertyInt32(env, element, "volumeGroupId",
419         value_.inputDeviceInfo.volumeGroupId);
420     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
421     return napi_ok;
422 }
423 
SetDeviceInfo(napi_env env,napi_value & deviceDescriptors,napi_value & result)424 napi_status AudioCaptureChangeInfoJsCallback::SetDeviceInfo(napi_env env,
425     napi_value &deviceDescriptors, napi_value &result)
426 {
427     napi_value element;
428     napi_status ret = napi_ok;
429     CHECK_AND_RETURN_RET((ret = napi_create_object(env, &element)) == napi_ok, ret);
430     CHECK_AND_RETURN_RET(SetDeviceProperty(env, element) == napi_ok, napi_generic_failure);
431 
432     bool setRet = true;
433     napi_value sampleRates;
434     setRet = CommonNapi::AddArrayInt(env, sampleRates,
435         std::vector<int32_t>(value_.inputDeviceInfo.audioStreamInfo.samplingRate.begin(),
436         value_.inputDeviceInfo.audioStreamInfo.samplingRate.end()));
437     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
438     napi_set_named_property(env, element, "sampleRates", sampleRates);
439 
440     napi_value channelCounts;
441     setRet = CommonNapi::AddArrayInt(env, channelCounts,
442         std::vector<int32_t>(value_.inputDeviceInfo.audioStreamInfo.channels.begin(),
443         value_.inputDeviceInfo.audioStreamInfo.channels.end()));
444     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
445     napi_set_named_property(env, element, "channelCounts", channelCounts);
446 
447     napi_value channelMasks;
448     setRet = CommonNapi::AddArrayInt(env, channelMasks, std::vector<int32_t>({value_.inputDeviceInfo.channelMasks}));
449     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
450     napi_set_named_property(env, element, "channelMasks", channelMasks);
451 
452     napi_value channelIndexMasks;
453     setRet = CommonNapi::AddArrayInt(env, channelIndexMasks,
454         std::vector<int32_t>({value_.inputDeviceInfo.channelIndexMasks}));
455     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
456     napi_set_named_property(env, element, "channelIndexMasks", channelIndexMasks);
457 
458     napi_value encodingTypes;
459     setRet = CommonNapi::AddArrayInt(env, encodingTypes,
460         std::vector<int32_t>({value_.inputDeviceInfo.audioStreamInfo.encoding}));
461     CHECK_AND_RETURN_RET(setRet == true, napi_generic_failure);
462     napi_set_named_property(env, element, "encodingTypes", encodingTypes);
463 
464     napi_set_element(env, deviceDescriptors, 0, element);
465     napi_set_named_property(env, result, "deviceDescriptors", deviceDescriptors);
466     return napi_ok;
467 }
468 } // namespace Media
469 } // namespace OHOS