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