• 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 "napi_utils.h"
17 #include "securec.h"
18 #include "avsession_log.h"
19 #include "av_session.h"
20 #include "napi_meta_data.h"
21 #include "napi_playback_state.h"
22 #include "native_engine/native_value.h"
23 #include "native_engine/native_engine.h"
24 #include "extension_context.h"
25 #include "ability_context.h"
26 
27 namespace OHOS::AVSession {
28 static constexpr int32_t STR_MAX_LENGTH = 4096;
29 static constexpr size_t STR_TAIL_LENGTH = 1;
30 
ConvertSessionType(const std::string & typeString)31 int32_t NapiUtils::ConvertSessionType(const std::string& typeString)
32 {
33     if (typeString == "audio") {
34         return AVSession::SESSION_TYPE_AUDIO;
35     } else if (typeString == "video") {
36         return AVSession::SESSION_TYPE_VIDEO;
37     } else {
38         return AVSession::SESSION_TYPE_INVALID;
39     }
40 }
41 
ConvertSessionType(int32_t type)42 std::string NapiUtils::ConvertSessionType(int32_t type)
43 {
44     if (type == AVSession::SESSION_TYPE_AUDIO) {
45         return "audio";
46     } else if (type == AVSession::SESSION_TYPE_VIDEO) {
47         return "video";
48     } else {
49         return "";
50     }
51 }
52 
53 /* napi_value <-> bool */
GetValue(napi_env env,napi_value in,bool & out)54 napi_status NapiUtils::GetValue(napi_env env, napi_value in, bool& out)
55 {
56     return napi_get_value_bool(env, in, &out);
57 }
58 
SetValue(napi_env env,const bool & in,napi_value & out)59 napi_status NapiUtils::SetValue(napi_env env, const bool& in, napi_value& out)
60 {
61     return napi_get_boolean(env, in, &out);
62 }
63 
64 /* napi_value <-> int32_t */
GetValue(napi_env env,napi_value in,int32_t & out)65 napi_status NapiUtils::GetValue(napi_env env, napi_value in, int32_t& out)
66 {
67     return napi_get_value_int32(env, in, &out);
68 }
69 
SetValue(napi_env env,const int32_t & in,napi_value & out)70 napi_status NapiUtils::SetValue(napi_env env, const int32_t& in, napi_value& out)
71 {
72     return napi_create_int32(env, in, &out);
73 }
74 
75 /* napi_value <-> uint32_t */
GetValue(napi_env env,napi_value in,uint32_t & out)76 napi_status NapiUtils::GetValue(napi_env env, napi_value in, uint32_t& out)
77 {
78     return napi_get_value_uint32(env, in, &out);
79 }
80 
SetValue(napi_env env,const uint32_t & in,napi_value & out)81 napi_status NapiUtils::SetValue(napi_env env, const uint32_t& in, napi_value& out)
82 {
83     return napi_create_uint32(env, in, &out);
84 }
85 
86 /* napi_value <-> int64_t */
GetValue(napi_env env,napi_value in,int64_t & out)87 napi_status NapiUtils::GetValue(napi_env env, napi_value in, int64_t& out)
88 {
89     return napi_get_value_int64(env, in, &out);
90 }
91 
SetValue(napi_env env,const int64_t & in,napi_value & out)92 napi_status NapiUtils::SetValue(napi_env env, const int64_t& in, napi_value& out)
93 {
94     return napi_create_int64(env, in, &out);
95 }
96 
97 /* napi_value <-> double */
GetValue(napi_env env,napi_value in,double & out)98 napi_status NapiUtils::GetValue(napi_env env, napi_value in, double& out)
99 {
100     return napi_get_value_double(env, in, &out);
101 }
102 
SetValue(napi_env env,const double & in,napi_value & out)103 napi_status NapiUtils::SetValue(napi_env env, const double& in, napi_value& out)
104 {
105     return napi_create_double(env, in, &out);
106 }
107 
108 /* napi_value <-> std::string */
GetValue(napi_env env,napi_value in,std::string & out)109 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::string& out)
110 {
111     napi_valuetype type = napi_undefined;
112     napi_status status = napi_typeof(env, in, &type);
113     CHECK_RETURN((status == napi_ok) && (type == napi_string), "invalid type", napi_invalid_arg);
114 
115     size_t maxLen = STR_MAX_LENGTH;
116     status = napi_get_value_string_utf8(env, in, nullptr, 0, &maxLen);
117     if (maxLen <= 0 || maxLen >= STR_MAX_LENGTH) {
118         return napi_invalid_arg;
119     }
120 
121     char buf[STR_MAX_LENGTH + STR_TAIL_LENGTH] {};
122     size_t len = 0;
123     status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len);
124     if (status == napi_ok) {
125         out = std::string(buf);
126     }
127     return status;
128 }
129 
SetValue(napi_env env,const std::string & in,napi_value & out)130 napi_status NapiUtils::SetValue(napi_env env, const std::string& in, napi_value& out)
131 {
132     return napi_create_string_utf8(env, in.c_str(), in.size(), &out);
133 }
134 
135 /* napi_value <-> AppExecFwk::ElementName */
SetValue(napi_env env,const AppExecFwk::ElementName & in,napi_value & out)136 napi_status NapiUtils::SetValue(napi_env env, const AppExecFwk::ElementName& in, napi_value& out)
137 {
138     napi_status status = napi_create_object(env, &out);
139     CHECK_RETURN((status == napi_ok) && (out != nullptr), "create object failed", status);
140 
141     napi_value property = nullptr;
142     status = SetValue(env, in.GetDeviceID(), property);
143     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
144     status = napi_set_named_property(env, out, "deviceId", property);
145     CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
146 
147     status = SetValue(env, in.GetBundleName(), property);
148     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
149     status = napi_set_named_property(env, out, "bundleName", property);
150     CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
151 
152     status = SetValue(env, in.GetAbilityName(), property);
153     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
154     status = napi_set_named_property(env, out, "abilityName", property);
155     CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
156 
157     return napi_ok;
158 }
159 
SetOutPutDeviceIdValue(napi_env env,const std::vector<std::string> & in,napi_value & out)160 napi_status NapiUtils::SetOutPutDeviceIdValue(napi_env env, const std::vector<std::string>& in, napi_value& out)
161 {
162     napi_status status = napi_create_array_with_length(env, in.size(), &out);
163     CHECK_RETURN(status == napi_ok, "create array failed!", status);
164     int index = 0;
165     for (auto& item : in) {
166         napi_value element = nullptr;
167         SetValue(env, static_cast<int32_t>(std::stoi(item)), element);
168         status = napi_set_element(env, out, index++, element);
169         CHECK_RETURN((status == napi_ok), "napi_set_element failed!", status);
170     }
171     return status;
172 }
173 
174 /* napi_value <-> OutputDeviceInfo */
SetValue(napi_env env,const OutputDeviceInfo & in,napi_value & out)175 napi_status NapiUtils::SetValue(napi_env env, const OutputDeviceInfo& in, napi_value& out)
176 {
177     napi_status status = napi_create_object(env, &out);
178     CHECK_RETURN((status == napi_ok) && (out != nullptr), "create object failed", status);
179 
180     napi_value property = nullptr;
181     status = SetValue(env, in.isRemote_, property);
182     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
183     status = napi_set_named_property(env, out, "isRemote", property);
184     CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
185 
186     status = SetOutPutDeviceIdValue(env, in.deviceIds_, property);
187     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
188     status = napi_set_named_property(env, out, "deviceId", property);
189     CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
190 
191     status = SetValue(env, in.deviceNames_, property);
192     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
193     status = napi_set_named_property(env, out, "deviceName", property);
194     CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
195 
196     return napi_ok;
197 }
198 
199 /* napi_value <-> AVSessionDescriptor */
SetValue(napi_env env,const AVSessionDescriptor & in,napi_value & out)200 napi_status NapiUtils::SetValue(napi_env env, const AVSessionDescriptor& in, napi_value& out)
201 {
202     napi_status status = napi_create_object(env, &out);
203     CHECK_RETURN((status == napi_ok) && (out != nullptr), "create object failed", status);
204 
205     napi_value property = nullptr;
206     status = SetValue(env, in.sessionId_, property);
207     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
208     status = napi_set_named_property(env, out, "sessionId", property);
209     CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
210 
211     status = SetValue(env, ConvertSessionType(in.sessionType_), property);
212     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
213     status = napi_set_named_property(env, out, "type", property);
214     CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
215 
216     status = SetValue(env, in.sessionTag_, property);
217     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
218     status = napi_set_named_property(env, out, "sessionTag", property);
219     CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
220 
221     status = SetValue(env, in.elementName_, property);
222     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
223     status = napi_set_named_property(env, out, "elementName", property);
224     CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
225 
226     status = SetValue(env, in.isActive_, property);
227     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
228     status = napi_set_named_property(env, out, "isActive", property);
229     CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
230 
231     status = SetValue(env, in.isTopSession_, property);
232     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
233     status = napi_set_named_property(env, out, "isTopSession", property);
234     CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
235 
236     status = SetValue(env, in.outputDeviceInfo_, property);
237     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
238     status = napi_set_named_property(env, out, "isTopSession", property);
239     CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
240 
241     return napi_ok;
242 }
243 
244 /* napi_value <-> MMI::KeyEvent::KeyItem */
GetValue(napi_env env,napi_value in,MMI::KeyEvent::KeyItem & out)245 napi_status NapiUtils::GetValue(napi_env env, napi_value in, MMI::KeyEvent::KeyItem& out)
246 {
247     int32_t code {};
248     auto status = GetNamedProperty(env, in, "code", code);
249     CHECK_RETURN(status == napi_ok, "get code property failed", status);
250     SLOGI("code=%{public}d", code);
251     out.SetKeyCode(code);
252 
253     int64_t pressedTime {};
254     status = GetNamedProperty(env, in, "pressedTime", pressedTime);
255     CHECK_RETURN(status == napi_ok, "get pressedTime property failed", status);
256     SLOGI("pressedTime=%{public}" PRIu64, pressedTime);
257     out.SetDownTime(pressedTime);
258 
259     int32_t deviceId {};
260     status = GetNamedProperty(env, in, "deviceId", deviceId);
261     CHECK_RETURN(status == napi_ok, "get deviceId property failed", status);
262     SLOGI("deviceId=%{public}d", deviceId);
263     out.SetDeviceId(deviceId);
264     out.SetPressed(true);
265 
266     return status;
267 }
268 
SetValue(napi_env env,const MMI::KeyEvent::KeyItem & in,napi_value & out)269 napi_status NapiUtils::SetValue(napi_env env, const MMI::KeyEvent::KeyItem& in, napi_value& out)
270 {
271     auto status = napi_create_object(env, &out);
272     CHECK_RETURN(status == napi_ok, "create object failed", status);
273 
274     napi_value code {};
275     status = SetValue(env, in.GetKeyCode(), code);
276     CHECK_RETURN(status == napi_ok, "create property failed", status);
277     status = napi_set_named_property(env, out, "code", code);
278     CHECK_RETURN(status == napi_ok, "set property failed", status);
279 
280     napi_value pressedTime {};
281     status = SetValue(env, in.GetDownTime(), pressedTime);
282     CHECK_RETURN(status == napi_ok, "create property failed", status);
283     status = napi_set_named_property(env, out, "pressedTime", pressedTime);
284     CHECK_RETURN(status == napi_ok, "set property failed", status);
285 
286     napi_value deviceId {};
287     status = SetValue(env, in.GetDeviceId(), deviceId);
288     CHECK_RETURN(status == napi_ok, "create property failed", status);
289     status = napi_set_named_property(env, out, "deviceId", deviceId);
290     CHECK_RETURN(status == napi_ok, "set property failed", status);
291 
292     return status;
293 }
294 
295 /* napi_value <-> MMI::KeyEvent */
GetValue(napi_env env,napi_value in,std::shared_ptr<MMI::KeyEvent> & out)296 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::shared_ptr<MMI::KeyEvent>& out)
297 {
298     napi_valuetype valueType = napi_undefined;
299     auto status = napi_typeof(env, in, &valueType);
300     CHECK_RETURN((status == napi_ok) && (valueType == napi_object), "object type invalid", status);
301 
302     out = MMI::KeyEvent::Create();
303     CHECK_RETURN(out != nullptr, "create keyEvent failed", napi_generic_failure);
304 
305     int32_t action {};
306     status = GetNamedProperty(env, in, "action", action);
307     CHECK_RETURN(status == napi_ok, "get action property failed", napi_generic_failure);
308     SLOGI("action=%{public}d", action);
309     action += KEYEVENT_ACTION_JS_NATIVE_DELTA;
310     out->SetKeyAction(action);
311 
312     MMI::KeyEvent::KeyItem key;
313     status = GetNamedProperty(env, in, "key", key);
314     CHECK_RETURN(status == napi_ok, "get action property failed", napi_generic_failure);
315     out->SetKeyCode(key.GetKeyCode());
316 
317     napi_value keyItems {};
318     status = napi_get_named_property(env, in, "keys", &keyItems);
319     CHECK_RETURN((status == napi_ok) && (keyItems != nullptr), "get keys property failed", status);
320 
321     uint32_t length {};
322     status = napi_get_array_length(env, keyItems, &length);
323     CHECK_RETURN(status == napi_ok, "get array length failed", status);
324 
325     for (uint32_t i = 0; i < length; ++i) {
326         napi_value keyItem {};
327         status = napi_get_element(env, keyItems, i, &keyItem);
328         CHECK_RETURN((status == napi_ok) && (keyItem != nullptr), "get element failed", status);
329         MMI::KeyEvent::KeyItem item;
330         status = GetValue(env, keyItem, item);
331         CHECK_RETURN(status == napi_ok, "get KeyItem failed", status);
332         if ((key.GetKeyCode() == item.GetKeyCode()) && (action == MMI::KeyEvent::KEY_ACTION_UP)) {
333             item.SetPressed(false);
334         }
335         out->AddKeyItem(item);
336     }
337 
338     return napi_ok;
339 }
340 
SetValue(napi_env env,const std::shared_ptr<MMI::KeyEvent> & in,napi_value & out)341 napi_status NapiUtils::SetValue(napi_env env, const std::shared_ptr<MMI::KeyEvent>& in, napi_value& out)
342 {
343     CHECK_RETURN(in != nullptr, "key event is nullptr", napi_generic_failure);
344 
345     auto status = napi_create_object(env, &out);
346     CHECK_RETURN(status == napi_ok, "create object failed", status);
347 
348     napi_value action {};
349     status = SetValue(env, in->GetKeyAction() - KEYEVENT_ACTION_JS_NATIVE_DELTA, action);
350     CHECK_RETURN(status == napi_ok, "create action property failed", status);
351     status = napi_set_named_property(env, out, "action", action);
352     CHECK_RETURN(status == napi_ok, "set action property failed", status);
353 
354     napi_value key {};
355     CHECK_RETURN(in->GetKeyItem() != nullptr, "get key item failed", napi_generic_failure);
356     status = SetValue(env, *in->GetKeyItem(), key);
357     CHECK_RETURN(status == napi_ok, "create key property failed", status);
358     status = napi_set_named_property(env, out, "key", key);
359     CHECK_RETURN(status == napi_ok, "set key property failed", status);
360 
361     napi_value keys {};
362     status = napi_create_array(env, &keys);
363     CHECK_RETURN(status == napi_ok, "create array failed", status);
364 
365     uint32_t idx = 0;
366     std::vector<MMI::KeyEvent::KeyItem> keyItems = in->GetKeyItems();
367     for (const auto& keyItem : keyItems) {
368         napi_value item {};
369         status = SetValue(env, keyItem, item);
370         CHECK_RETURN(status == napi_ok, "create keyItem failed", status);
371 
372         status = napi_set_element(env, keys, idx, item);
373         CHECK_RETURN(status == napi_ok, "set element failed", status);
374         ++idx;
375     }
376 
377     status = napi_set_named_property(env, out, "keys", keys);
378     CHECK_RETURN(status == napi_ok, "set keys property failed", status);
379     return status;
380 }
381 
382 /* napi_value <-> AbilityRuntime::WantAgent::WantAgent */
GetValue(napi_env env,napi_value in,AbilityRuntime::WantAgent::WantAgent * & out)383 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AbilityRuntime::WantAgent::WantAgent*& out)
384 {
385     auto status = napi_unwrap(env, in, reinterpret_cast<void**>(&out));
386     CHECK_RETURN(status == napi_ok, "unwrap failed", napi_invalid_arg);
387     return status;
388 }
389 
SetValue(napi_env env,AbilityRuntime::WantAgent::WantAgent & in,napi_value & out)390 napi_status NapiUtils::SetValue(napi_env env, AbilityRuntime::WantAgent::WantAgent& in, napi_value& out)
391 {
392     auto status = napi_create_object(env, &out);
393     CHECK_RETURN(status == napi_ok, "create object failed", napi_generic_failure);
394     auto finalizecb = [](napi_env env, void* data, void* hint) {};
395     status = napi_wrap(env, out, static_cast<void*>(&in), finalizecb, nullptr, nullptr);
396     CHECK_RETURN(status == napi_ok, "wrap object failed", napi_generic_failure);
397     return status;
398 }
399 
400 /* napi_value <-> AVMetaData */
GetValue(napi_env env,napi_value in,AVMetaData & out)401 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AVMetaData& out)
402 {
403     return NapiMetaData::GetValue(env, in, out);
404 }
405 
SetValue(napi_env env,const AVMetaData & in,napi_value & out)406 napi_status NapiUtils::SetValue(napi_env env, const AVMetaData& in, napi_value& out)
407 {
408     return NapiMetaData::SetValue(env, in, out);
409 }
410 
411 /* napi_value <-> AVPlaybackState */
GetValue(napi_env env,napi_value in,AVPlaybackState & out)412 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AVPlaybackState& out)
413 {
414     return NapiPlaybackState::GetValue(env, in, out);
415 }
416 
SetValue(napi_env env,const AVPlaybackState & in,napi_value & out)417 napi_status NapiUtils::SetValue(napi_env env, const AVPlaybackState& in, napi_value& out)
418 {
419     return NapiPlaybackState::SetValue(env, in, out);
420 }
421 
422 /* napi_value <-> std::vector<std::string> */
GetValue(napi_env env,napi_value in,std::vector<std::string> & out)423 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<std::string>& out)
424 {
425     SLOGD("napi_value -> std::vector<std::string>");
426     out.clear();
427     bool isArray = false;
428     napi_is_array(env, in, &isArray);
429     CHECK_RETURN(isArray, "not an array", napi_invalid_arg);
430 
431     uint32_t length = 0;
432     napi_status status = napi_get_array_length(env, in, &length);
433     CHECK_RETURN((status == napi_ok) && (length > 0), "get_array failed!", napi_invalid_arg);
434     for (uint32_t i = 0; i < length; ++i) {
435         napi_value item = nullptr;
436         status = napi_get_element(env, in, i, &item);
437         CHECK_RETURN((item != nullptr) && (status == napi_ok), "no element", napi_invalid_arg);
438         std::string value;
439         status = GetValue(env, item, value);
440         CHECK_RETURN(status == napi_ok, "not a string", napi_invalid_arg);
441         out.push_back(value);
442     }
443     return status;
444 }
445 
SetValue(napi_env env,const std::vector<std::string> & in,napi_value & out)446 napi_status NapiUtils::SetValue(napi_env env, const std::vector<std::string>& in, napi_value& out)
447 {
448     SLOGD("napi_value <- std::vector<std::string>");
449     napi_status status = napi_create_array_with_length(env, in.size(), &out);
450     CHECK_RETURN(status == napi_ok, "create array failed!", status);
451     int index = 0;
452     for (auto& item : in) {
453         napi_value element = nullptr;
454         SetValue(env, item, element);
455         status = napi_set_element(env, out, index++, element);
456         CHECK_RETURN((status == napi_ok), "napi_set_element failed!", status);
457     }
458     return status;
459 }
460 
461 /* napi_value <-> std::vector<uint8_t> */
GetValue(napi_env env,napi_value in,std::vector<uint8_t> & out)462 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<uint8_t>& out)
463 {
464     out.clear();
465     SLOGD("napi_value -> std::vector<uint8_t> ");
466     napi_typedarray_type type = napi_biguint64_array;
467     size_t length = 0;
468     napi_value buffer = nullptr;
469     size_t offset = 0;
470     void* data = nullptr;
471     napi_status status = napi_get_typedarray_info(env, in, &type, &length, &data, &buffer, &offset);
472     SLOGD("array type=%{public}d length=%{public}d offset=%{public}d", static_cast<int>(type), static_cast<int>(length),
473           static_cast<int>(offset));
474     CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
475     CHECK_RETURN(type == napi_uint8_array, "is not Uint8Array!", napi_invalid_arg);
476     CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
477     out.assign(static_cast<uint8_t*>(data), static_cast<uint8_t*>(data) + length);
478     return status;
479 }
480 
SetValue(napi_env env,const std::vector<uint8_t> & in,napi_value & out)481 napi_status NapiUtils::SetValue(napi_env env, const std::vector<uint8_t>& in, napi_value& out)
482 {
483     SLOGD("napi_value <- std::vector<uint8_t> ");
484     CHECK_RETURN(!in.empty(), "invalid std::vector<uint8_t>", napi_invalid_arg);
485     void* data = nullptr;
486     napi_value buffer = nullptr;
487     napi_status status = napi_create_arraybuffer(env, in.size(), &data, &buffer);
488     CHECK_RETURN((status == napi_ok), "create array buffer failed!", status);
489 
490     if (memcpy_s(data, in.size(), in.data(), in.size()) != EOK) {
491         SLOGE("memcpy_s not EOK");
492         return napi_invalid_arg;
493     }
494     status = napi_create_typedarray(env, napi_uint8_array, in.size(), buffer, 0, &out);
495     CHECK_RETURN((status == napi_ok), "napi_value <- std::vector<uint8_t> invalid value", status);
496     return status;
497 }
498 
499 template <typename T>
TypedArray2Vector(uint8_t * data,size_t length,napi_typedarray_type type,std::vector<T> & out)500 void TypedArray2Vector(uint8_t* data, size_t length, napi_typedarray_type type, std::vector<T>& out)
501 {
502     auto convert = [&out](auto* data, size_t elements) {
503         for (size_t index = 0; index < elements; index++) {
504             out.push_back(static_cast<T>(data[index]));
505         }
506     };
507 
508     switch (type) {
509         case napi_int8_array:
510             convert(reinterpret_cast<int8_t*>(data), length);
511             break;
512         case napi_uint8_array:
513             convert(data, length);
514             break;
515         case napi_uint8_clamped_array:
516             convert(data, length);
517             break;
518         case napi_int16_array:
519             convert(reinterpret_cast<int16_t*>(data), length / sizeof(int16_t));
520             break;
521         case napi_uint16_array:
522             convert(reinterpret_cast<uint16_t*>(data), length / sizeof(uint16_t));
523             break;
524         case napi_int32_array:
525             convert(reinterpret_cast<int32_t*>(data), length / sizeof(int32_t));
526             break;
527         case napi_uint32_array:
528             convert(reinterpret_cast<uint32_t*>(data), length / sizeof(uint32_t));
529             break;
530         case napi_float32_array:
531             convert(reinterpret_cast<float*>(data), length / sizeof(float));
532             break;
533         case napi_float64_array:
534             convert(reinterpret_cast<double*>(data), length / sizeof(double));
535             break;
536         case napi_bigint64_array:
537             convert(reinterpret_cast<int64_t*>(data), length / sizeof(int64_t));
538             break;
539         case napi_biguint64_array:
540             convert(reinterpret_cast<uint64_t*>(data), length / sizeof(uint64_t));
541             break;
542         default:
543             CHECK_RETURN_VOID(false, "[FATAL] invalid napi_typedarray_type!");
544     }
545 }
546 
547 /* napi_value <-> std::vector<int32_t> */
GetValue(napi_env env,napi_value in,std::vector<int32_t> & out)548 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<int32_t>& out)
549 {
550     out.clear();
551     SLOGD("napi_value -> std::vector<int32_t> ");
552     napi_typedarray_type type = napi_biguint64_array;
553     size_t length = 0;
554     napi_value buffer = nullptr;
555     size_t offset = 0;
556     uint8_t* data = nullptr;
557     napi_status status = napi_get_typedarray_info(env, in, &type, &length,
558                                                   reinterpret_cast<void**>(&data), &buffer, &offset);
559     SLOGD("array type=%{public}d length=%{public}d offset=%{public}d", static_cast<int>(type), static_cast<int>(length),
560           static_cast<int>(offset));
561     CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
562     CHECK_RETURN(type <= napi_int32_array, "is not int32 supported typed array!", napi_invalid_arg);
563     CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
564     TypedArray2Vector<int32_t>(data, length, type, out);
565     return status;
566 }
567 
SetValue(napi_env env,const std::vector<int32_t> & in,napi_value & out)568 napi_status NapiUtils::SetValue(napi_env env, const std::vector<int32_t>& in, napi_value& out)
569 {
570     SLOGD("napi_value <- std::vector<int32_t> ");
571     size_t bytes = in.size() * sizeof(int32_t);
572     CHECK_RETURN(bytes > 0, "invalid std::vector<int32_t>", napi_invalid_arg);
573     void* data = nullptr;
574     napi_value buffer = nullptr;
575     napi_status status = napi_create_arraybuffer(env, bytes, &data, &buffer);
576     CHECK_RETURN((status == napi_ok), "invalid buffer", status);
577 
578     if (memcpy_s(data, bytes, in.data(), bytes) != EOK) {
579         SLOGE("memcpy_s not EOK");
580         return napi_invalid_arg;
581     }
582     status = napi_create_typedarray(env, napi_int32_array, in.size(), buffer, 0, &out);
583     CHECK_RETURN((status == napi_ok), "invalid buffer", status);
584     return status;
585 }
586 
587 /* napi_value <-> std::vector<uint32_t> */
GetValue(napi_env env,napi_value in,std::vector<uint32_t> & out)588 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<uint32_t>& out)
589 {
590     out.clear();
591     SLOGD("napi_value -> std::vector<uint32_t> ");
592     napi_typedarray_type type = napi_biguint64_array;
593     size_t length = 0;
594     napi_value buffer = nullptr;
595     size_t offset = 0;
596     uint8_t* data = nullptr;
597     napi_status status = napi_get_typedarray_info(env, in, &type, &length,
598                                                   reinterpret_cast<void**>(&data), &buffer, &offset);
599     SLOGD("napi_get_typedarray_info type=%{public}d", static_cast<int>(type));
600     CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
601     CHECK_RETURN((type <= napi_uint16_array) || (type == napi_uint32_array), "invalid type!", napi_invalid_arg);
602     CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
603     TypedArray2Vector<uint32_t>(data, length, type, out);
604     return status;
605 }
606 
SetValue(napi_env env,const std::vector<uint32_t> & in,napi_value & out)607 napi_status NapiUtils::SetValue(napi_env env, const std::vector<uint32_t>& in, napi_value& out)
608 {
609     SLOGD("napi_value <- std::vector<uint32_t> ");
610     size_t bytes = in.size() * sizeof(uint32_t);
611     CHECK_RETURN(bytes > 0, "invalid std::vector<uint32_t>", napi_invalid_arg);
612     void* data = nullptr;
613     napi_value buffer = nullptr;
614     napi_status status = napi_create_arraybuffer(env, bytes, &data, &buffer);
615     CHECK_RETURN((status == napi_ok), "invalid buffer", status);
616 
617     if (memcpy_s(data, bytes, in.data(), bytes) != EOK) {
618         SLOGE("memcpy_s not EOK");
619         return napi_invalid_arg;
620     }
621     status = napi_create_typedarray(env, napi_uint32_array, in.size(), buffer, 0, &out);
622     CHECK_RETURN((status == napi_ok), "invalid buffer", status);
623     return status;
624 }
625 
626 /* napi_value <-> std::vector<int64_t> */
GetValue(napi_env env,napi_value in,std::vector<int64_t> & out)627 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<int64_t>& out)
628 {
629     out.clear();
630     SLOGD("napi_value -> std::vector<int64_t> ");
631     napi_typedarray_type type = napi_biguint64_array;
632     size_t length = 0;
633     napi_value buffer = nullptr;
634     size_t offset = 0;
635     uint8_t* data = nullptr;
636     napi_status status = napi_get_typedarray_info(env, in, &type, &length,
637                                                   reinterpret_cast<void**>(&data), &buffer, &offset);
638     SLOGD("array type=%{public}d length=%{public}d offset=%{public}d", static_cast<int>(type), static_cast<int>(length),
639           static_cast<int>(offset));
640     CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
641     CHECK_RETURN((type <= napi_uint32_array) || (type == napi_bigint64_array), "invalid type!", napi_invalid_arg);
642     CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
643     TypedArray2Vector<int64_t>(data, length, type, out);
644     return status;
645 }
646 
SetValue(napi_env env,const std::vector<int64_t> & in,napi_value & out)647 napi_status NapiUtils::SetValue(napi_env env, const std::vector<int64_t>& in, napi_value& out)
648 {
649     SLOGD("napi_value <- std::vector<int64_t> ");
650     size_t bytes = in.size() * sizeof(int64_t);
651     CHECK_RETURN(bytes > 0, "invalid std::vector<uint32_t>", napi_invalid_arg);
652     void* data = nullptr;
653     napi_value buffer = nullptr;
654     napi_status status = napi_create_arraybuffer(env, bytes, &data, &buffer);
655     CHECK_RETURN((status == napi_ok), "invalid buffer", status);
656 
657     if (memcpy_s(data, bytes, in.data(), bytes) != EOK) {
658         SLOGE("memcpy_s not EOK");
659         return napi_invalid_arg;
660     }
661     status = napi_create_typedarray(env, napi_bigint64_array, in.size(), buffer, 0, &out);
662     CHECK_RETURN((status == napi_ok), "invalid buffer", status);
663     return status;
664 }
665 /* napi_value <-> std::vector<double> */
GetValue(napi_env env,napi_value in,std::vector<double> & out)666 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<double>& out)
667 {
668     out.clear();
669     bool isTypedArray = false;
670     napi_status status = napi_is_typedarray(env, in, &isTypedArray);
671     SLOGD("napi_value -> std::vector<double> input %{public}s a TypedArray", isTypedArray ? "is" : "is not");
672     CHECK_RETURN((status == napi_ok), "napi_is_typedarray failed!", status);
673     if (isTypedArray) {
674         SLOGD("napi_value -> std::vector<double> ");
675         napi_typedarray_type type = napi_biguint64_array;
676         size_t length = 0;
677         napi_value buffer = nullptr;
678         size_t offset = 0;
679         uint8_t* data = nullptr;
680         status = napi_get_typedarray_info(env, in, &type, &length, reinterpret_cast<void**>(&data), &buffer, &offset);
681         SLOGD("napi_get_typedarray_info status=%{public}d type=%{public}d", status, static_cast<int>(type));
682         CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
683         CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
684         TypedArray2Vector<double>(data, length, type, out);
685     } else {
686         bool isArray = false;
687         status = napi_is_array(env, in, &isArray);
688         SLOGD("napi_value -> std::vector<double> input %{public}s an Array", isArray ? "is" : "is not");
689         CHECK_RETURN((status == napi_ok) && isArray, "invalid data!", napi_invalid_arg);
690         uint32_t length = 0;
691         status = napi_get_array_length(env, in, &length);
692         CHECK_RETURN((status == napi_ok) && (length > 0), "invalid data!", napi_invalid_arg);
693         for (uint32_t i = 0; i < length; ++i) {
694             napi_value item = nullptr;
695             status = napi_get_element(env, in, i, &item);
696             CHECK_RETURN((item != nullptr) && (status == napi_ok), "no element", napi_invalid_arg);
697             double vi = 0.0f;
698             status = napi_get_value_double(env, item, &vi);
699             CHECK_RETURN(status == napi_ok, "element not a double", napi_invalid_arg);
700             out.push_back(vi);
701         }
702     }
703     return status;
704 }
705 
SetValue(napi_env env,const std::vector<double> & in,napi_value & out)706 napi_status NapiUtils::SetValue(napi_env env, const std::vector<double>& in, napi_value& out)
707 {
708     SLOGD("napi_value <- std::vector<double> ");
709     (void)(env);
710     (void)(in);
711     (void)(out);
712     CHECK_RETURN(false, "std::vector<double> to napi_value, unsupported!", napi_invalid_arg);
713     return napi_invalid_arg;
714 }
715 
716 /* std::vector<AVSessionDescriptor> <-> napi_value */
SetValue(napi_env env,const std::vector<AVSessionDescriptor> & in,napi_value & out)717 napi_status NapiUtils::SetValue(napi_env env, const std::vector<AVSessionDescriptor>& in, napi_value& out)
718 {
719     SLOGD("napi_value <- std::vector<AVSessionDescriptor>  %{public}d", static_cast<int>(in.size()));
720     napi_status status = napi_create_array_with_length(env, in.size(), &out);
721     CHECK_RETURN((status == napi_ok), "create_array failed!", status);
722     int index = 0;
723     for (const auto& item : in) {
724         napi_value entry = nullptr;
725         SetValue(env, item, entry);
726         napi_set_element(env, out, index++, entry);
727     }
728     return status;
729 }
730 
Unwrap(napi_env env,napi_value in,void ** out,napi_value constructor)731 napi_status NapiUtils::Unwrap(napi_env env, napi_value in, void** out, napi_value constructor)
732 {
733     if (constructor != nullptr) {
734         bool isInstance = false;
735         napi_instanceof(env, in, constructor, &isInstance);
736         if (!isInstance) {
737             SLOGE("not a instance of *");
738             return napi_invalid_arg;
739         }
740     }
741     return napi_unwrap(env, in, out);
742 }
743 
Equals(napi_env env,napi_value value,napi_ref copy)744 bool NapiUtils::Equals(napi_env env, napi_value value, napi_ref copy)
745 {
746     if (copy == nullptr) {
747         return (value == nullptr);
748     }
749 
750     napi_value copyValue = nullptr;
751     napi_get_reference_value(env, copy, &copyValue);
752     CHECK_RETURN((napi_get_reference_value(env, copy, &copyValue) == napi_ok),
753                  "get ref value failed", napi_generic_failure);
754     bool isEquals = false;
755     CHECK_RETURN(napi_strict_equals(env, value, copyValue, &isEquals) == napi_ok,
756                  "get equals result failed", napi_generic_failure);
757     return isEquals;
758 }
759 
GetUndefinedValue(napi_env env)760 napi_value NapiUtils::GetUndefinedValue(napi_env env)
761 {
762     napi_value result {};
763     napi_get_undefined(env, &result);
764     return result;
765 }
766 
GetPropertyNames(napi_env env,napi_value in,std::vector<std::string> & out)767 napi_status NapiUtils::GetPropertyNames(napi_env env, napi_value in, std::vector<std::string>& out)
768 {
769     napi_value names {};
770     NAPI_CALL_BASE(env, napi_get_property_names(env, in, &names), napi_generic_failure);
771     uint32_t length = 0;
772     NAPI_CALL_BASE(env, napi_get_array_length(env, names, &length), napi_generic_failure);
773 
774     for (uint32_t index = 0; index < length; ++index) {
775         napi_value name {};
776         std::string nameString;
777         if (napi_get_element(env, names, index, &name) != napi_ok) {
778             continue;
779         }
780         if (GetValue(env, name, nameString) != napi_ok) {
781             continue;
782         }
783         out.push_back(nameString);
784     }
785 
786     return napi_ok;
787 }
788 
GetDateValue(napi_env env,napi_value value,double & result)789 napi_status NapiUtils::GetDateValue(napi_env env, napi_value value, double& result)
790 {
791     CHECK_RETURN(env != nullptr, "env is nullptr", napi_invalid_arg);
792     CHECK_RETURN(value != nullptr, "value is nullptr", napi_invalid_arg);
793 
794     auto engine = reinterpret_cast<NativeEngine*>(env);
795     auto nativeValue = reinterpret_cast<NativeValue*>(value);
796     auto isDate = nativeValue->IsDate();
797     if (isDate) {
798         auto nativeDate = reinterpret_cast<NativeDate*>(nativeValue->GetInterface(NativeDate::INTERFACE_ID));
799         result = nativeDate->GetTime();
800         engine->ClearLastError();
801         return napi_ok;
802     } else {
803         SLOGE("value is not date type");
804         return napi_date_expected;
805     }
806 }
807 
SetDateValue(napi_env env,double time,napi_value & result)808 napi_status NapiUtils::SetDateValue(napi_env env, double time, napi_value& result)
809 {
810     CHECK_RETURN(env != nullptr, "env is nullptr", napi_invalid_arg);
811 
812     auto engine = reinterpret_cast<NativeEngine*>(env);
813     auto resultValue = engine->CreateDate(time);
814     result = reinterpret_cast<napi_value>(resultValue);
815     engine->ClearLastError();
816     return napi_ok;
817 }
818 
GetRefByCallback(napi_env env,std::list<napi_ref> callbackList,napi_value callback,napi_ref & callbackRef)819 napi_status NapiUtils::GetRefByCallback(napi_env env, std::list<napi_ref> callbackList, napi_value callback,
820                                         napi_ref& callbackRef)
821 {
822     for (auto ref = callbackList.begin(); ref != callbackList.end(); ++ref) {
823         if (Equals(env, callback, *ref)) {
824             callbackRef = *ref;
825             break;
826         }
827     }
828     return napi_ok;
829 }
830 
831 /* napi_value is napi stage context */
GetStageElementName(napi_env env,napi_value in,AppExecFwk::ElementName & out)832 napi_status NapiUtils::GetStageElementName(napi_env env, napi_value in, AppExecFwk::ElementName& out)
833 {
834     std::shared_ptr<AbilityRuntime::Context> stageContext = AbilityRuntime::GetStageModeContext(env, in);
835     CHECK_RETURN(stageContext != nullptr, "get StagContext failed", napi_generic_failure);
836     std::shared_ptr <AppExecFwk::AbilityInfo> abilityInfo;
837     auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(stageContext);
838     if (abilityContext != nullptr) {
839         abilityInfo = abilityContext->GetAbilityInfo();
840     } else {
841         auto extensionContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::ExtensionContext>(stageContext);
842         CHECK_RETURN(extensionContext != nullptr, "context ConvertTo AbilityContext and ExtensionContext fail",
843                      napi_generic_failure);
844         abilityInfo = extensionContext->GetAbilityInfo();
845     }
846     out.SetBundleName(abilityInfo->bundleName);
847     out.SetAbilityName(abilityInfo->name);
848     return napi_ok;
849 }
850 
GetFaElementName(napi_env env,AppExecFwk::ElementName & out)851 napi_status NapiUtils::GetFaElementName(napi_env env, AppExecFwk::ElementName& out)
852 {
853     auto* ability = AbilityRuntime::GetCurrentAbility(env);
854     CHECK_RETURN(ability != nullptr, "get feature ability failed", napi_generic_failure);
855     auto want = ability->GetWant();
856     CHECK_RETURN(want != nullptr, "get want failed", napi_generic_failure);
857     out = want->GetElement();
858     return napi_ok;
859 }
860 
GetValue(napi_env env,napi_value in,AppExecFwk::ElementName & out)861 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AppExecFwk::ElementName& out)
862 {
863     bool isStageMode = false;
864     CHECK_RETURN(AbilityRuntime::IsStageContext(env, in, isStageMode) == napi_ok, "get context type failed",
865                  napi_generic_failure);
866     if (isStageMode) {
867         CHECK_RETURN(GetStageElementName(env, in, out) == napi_ok, "get StagContext failed", napi_generic_failure);
868     } else {
869         CHECK_RETURN(GetFaElementName(env, out) == napi_ok, "get FaContext failed", napi_generic_failure);
870     }
871     return napi_ok;
872 }
873 
GetValue(napi_env env,napi_value in,SessionToken & out)874 napi_status NapiUtils::GetValue(napi_env env, napi_value in, SessionToken& out)
875 {
876     napi_value value {};
877     auto status = napi_get_named_property(env, in, "sessionId", &value);
878     CHECK_RETURN(status == napi_ok, "get SessionToken sessionId failed", status);
879     status = GetValue(env, value, out.sessionId);
880     CHECK_RETURN(status == napi_ok, "get SessionToken sessionId value failed", status);
881 
882     status = napi_get_named_property(env, in, "pid", &value);
883     CHECK_RETURN(status == napi_ok, "get SessionToken pid failed", status);
884     status = GetValue(env, value, out.pid);
885     CHECK_RETURN(status == napi_ok, "get SessionToken pid value failed", status);
886 
887     status = napi_get_named_property(env, in, "uid", &value);
888     CHECK_RETURN(status == napi_ok, "get SessionToken uid failed", status);
889     status = GetValue(env, value, out.uid);
890     CHECK_RETURN(status == napi_ok, "get SessionToken uid value failed", status);
891     return napi_ok;
892 }
893 
GetValue(napi_env env,napi_value in,AudioStandard::DeviceRole & out)894 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AudioStandard::DeviceRole& out)
895 {
896     int32_t deviceRole;
897     auto status = GetValue(env, in, deviceRole);
898     CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceRole failed", status);
899     out = static_cast<AudioStandard::DeviceRole>(deviceRole);
900     return napi_ok;
901 }
902 
GetValue(napi_env env,napi_value in,AudioStandard::DeviceType & out)903 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AudioStandard::DeviceType& out)
904 {
905     int32_t deviceType;
906     auto status = GetValue(env, in, deviceType);
907     CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceType failed", status);
908     out = static_cast<AudioStandard::DeviceType>(deviceType);
909     return napi_ok;
910 }
911 
GetSampleRate(napi_env env,napi_value in,AudioStandard::AudioSamplingRate & out)912 napi_status NapiUtils::GetSampleRate(napi_env env, napi_value in, AudioStandard::AudioSamplingRate& out)
913 {
914     napi_value value {};
915     auto status = napi_get_named_property(env, in, "sampleRates", &value);
916     uint32_t length {};
917     napi_get_array_length(env, value, &length);
918     CHECK_RETURN(status == napi_ok, "get array length failed", status);
919     if (length > 0) {
920         napi_value element {};
921         status = napi_get_element(env, value, 0, &element);
922         CHECK_RETURN((status == napi_ok) && (element != nullptr), "get element failed", status);
923         int32_t samplingRate;
924         status = GetValue(env, element, samplingRate);
925         CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor audioStreamInfo_ samplingRate value failed", status);
926         out = static_cast<AudioStandard::AudioSamplingRate>(samplingRate);
927     }
928     return status;
929 }
930 
GetChannels(napi_env env,napi_value in,AudioStandard::AudioChannel & out)931 napi_status NapiUtils::GetChannels(napi_env env, napi_value in, AudioStandard::AudioChannel& out)
932 {
933     napi_value value {};
934     auto status = napi_get_named_property(env, in, "channelCounts", &value);
935     uint32_t length {};
936     napi_get_array_length(env, value, &length);
937     CHECK_RETURN(status == napi_ok, "get array length failed", status);
938     if (length > 0) {
939         napi_value element {};
940         status = napi_get_element(env, value, 0, &element);
941         CHECK_RETURN((status == napi_ok) && (element != nullptr), "get element failed", status);
942         int32_t channel;
943         status = GetValue(env, element, channel);
944         CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor audioStreamInfo_ channels value failed", status);
945         out = static_cast<AudioStandard::AudioChannel>(channel);
946     }
947     return status;
948 }
949 
GetChannelMasks(napi_env env,napi_value in,int32_t & out)950 napi_status NapiUtils::GetChannelMasks(napi_env env, napi_value in, int32_t& out)
951 {
952     napi_value value {};
953     auto status = napi_get_named_property(env, in, "channelMasks", &value);
954     uint32_t length {};
955     napi_get_array_length(env, value, &length);
956     CHECK_RETURN(status == napi_ok, "get array length failed", status);
957     if (length > 0) {
958         napi_value element {};
959         status = napi_get_element(env, value, 0, &element);
960         CHECK_RETURN((status == napi_ok) && (element != nullptr), "get element failed", status);
961         status = GetValue(env, element, out);
962         CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor channelMasks_ value failed", status);
963     }
964     return status;
965 }
966 
GetValue(napi_env env,napi_value in,AudioStandard::AudioDeviceDescriptor & out)967 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AudioStandard::AudioDeviceDescriptor& out)
968 {
969     napi_value value {};
970     auto status = napi_get_named_property(env, in, "id", &value);
971     CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceId_ failed", status);
972     status = GetValue(env, value, out.deviceId_);
973     CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceId_ value failed", status);
974 
975     status = napi_get_named_property(env, in, "name", &value);
976     CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceName_ failed", status);
977     status = GetValue(env, value, out.deviceName_);
978     CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceName_ value failed", status);
979 
980     status = napi_get_named_property(env, in, "networkId", &value);
981     CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor networkId failed", status);
982     status = GetValue(env, value, out.networkId_);
983     CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor networkId value failed", status);
984 
985     status = napi_get_named_property(env, in, "deviceRole", &value);
986     CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceRole_ failed", status);
987     status = GetValue(env, value, out.deviceRole_);
988     CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceRole_ value failed", status);
989 
990     if (napi_get_named_property(env, in, "address", &value) == napi_ok) {
991         GetValue(env, value, out.macAddress_);
992     }
993 
994     if (napi_get_named_property(env, in, "deviceType", &value) == napi_ok) {
995         GetValue(env, value, out.deviceType_);
996     }
997 
998     if (napi_get_named_property(env, in, "interruptGroupId", &value) == napi_ok) {
999         GetValue(env, value, out.interruptGroupId_);
1000     }
1001 
1002     if (napi_get_named_property(env, in, "volumeGroupId", &value) == napi_ok) {
1003         GetValue(env, value, out.volumeGroupId_);
1004     }
1005 
1006     GetSampleRate(env, in, out.audioStreamInfo_.samplingRate);
1007     GetChannels(env, in, out.audioStreamInfo_.channels);
1008     GetChannelMasks(env, in, out.channelMasks_);
1009     return napi_ok;
1010 }
1011 
GetValue(napi_env env,napi_value in,std::vector<AudioStandard::AudioDeviceDescriptor> & out)1012 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<AudioStandard::AudioDeviceDescriptor>& out)
1013 {
1014     uint32_t length {};
1015     auto status = napi_get_array_length(env, in, &length);
1016     CHECK_RETURN(status == napi_ok, "get array length failed", status);
1017     for (uint32_t i = 0; i < length; ++i) {
1018         napi_value element {};
1019         status = napi_get_element(env, in, i, &element);
1020         CHECK_RETURN((status == napi_ok) && (element != nullptr), "get element failed", status);
1021         AudioStandard::AudioDeviceDescriptor descriptor;
1022         status = GetValue(env, element, descriptor);
1023         out.push_back(descriptor);
1024     }
1025     return napi_ok;
1026 }
1027 
ThrowError(napi_env env,const char * napiMessage,int32_t napiCode)1028 napi_status NapiUtils::ThrowError(napi_env env, const char* napiMessage, int32_t napiCode)
1029 {
1030     napi_value message = nullptr;
1031     napi_value code = nullptr;
1032     napi_value result = nullptr;
1033     napi_create_string_utf8(env, napiMessage, NAPI_AUTO_LENGTH, &message);
1034     napi_create_error(env, nullptr, message, &result);
1035     napi_create_int32(env, napiCode, &code);
1036     napi_set_named_property(env, result, "code", code);
1037     napi_throw(env, result);
1038     return napi_ok;
1039 }
1040 }