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, ©Value);
752 CHECK_RETURN((napi_get_reference_value(env, copy, ©Value) == 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 }