1 /*
2 * Copyright (c) 2022-2023 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 <cstdio>
17
18 #include "napi_utils.h"
19 #include "securec.h"
20 #include "avsession_log.h"
21 #include "av_session.h"
22 #include "napi_avcall_meta_data.h"
23 #include "napi_avcall_state.h"
24 #include "napi_meta_data.h"
25 #include "napi_playback_state.h"
26 #include "napi_media_description.h"
27 #include "napi_queue_item.h"
28 #include "native_engine/native_value.h"
29 #include "native_engine/native_engine.h"
30 #include "extension_context.h"
31 #include "ability_context.h"
32 #include "napi_common_want.h"
33 #include "napi_media_info_holder.h"
34 #include "pixel_map_napi.h"
35 #include "avsession_pixel_map_adapter.h"
36 #include "curl/curl.h"
37 #include "image_source.h"
38 #include "pixel_map.h"
39
40 namespace OHOS::AVSession {
41 static constexpr int32_t STR_MAX_LENGTH = 40960;
42 static constexpr size_t STR_TAIL_LENGTH = 1;
43
WriteCallback(std::uint8_t *ptr, size_t size, size_t nmemb, std::vector<std::uint8_t> *imgBuffer)44 size_t NapiUtils::WriteCallback(std::uint8_t *ptr, size_t size, size_t nmemb, std::vector<std::uint8_t> *imgBuffer)
45 {
46 size_t realsize = size * nmemb;
47 imgBuffer->reserve(realsize + imgBuffer->capacity());
48 for (size_t i = 0; i < realsize; i++) {
49 imgBuffer->push_back(ptr[i]);
50 }
51 return realsize;
52 }
53
CurlSetRequestOptions(std::vector<std::uint8_t>& imgBuffer, const std::string uri)54 bool NapiUtils::CurlSetRequestOptions(std::vector<std::uint8_t>& imgBuffer, const std::string uri)
55 {
56 CURL *easyHandle_ = curl_easy_init();
57 if (easyHandle_) {
58 // set request options
59 curl_easy_setopt(easyHandle_, CURLOPT_URL, uri.c_str());
60 curl_easy_setopt(easyHandle_, CURLOPT_CONNECTTIMEOUT, NapiUtils::TIME_OUT_SECOND);
61 curl_easy_setopt(easyHandle_, CURLOPT_SSL_VERIFYPEER, 0L);
62 curl_easy_setopt(easyHandle_, CURLOPT_SSL_VERIFYHOST, 0L);
63 curl_easy_setopt(easyHandle_, CURLOPT_CAINFO, "/etc/ssl/certs/" "cacert.pem");
64 curl_easy_setopt(easyHandle_, CURLOPT_HTTPGET, 1L);
65 curl_easy_setopt(easyHandle_, CURLOPT_WRITEFUNCTION, WriteCallback);
66 curl_easy_setopt(easyHandle_, CURLOPT_WRITEDATA, &imgBuffer);
67
68 // perform request
69 CURLcode res = curl_easy_perform(easyHandle_);
70 if (res != CURLE_OK) {
71 SLOGI("DoDownload curl easy_perform failure: %{public}s\n", curl_easy_strerror(res));
72 curl_easy_cleanup(easyHandle_);
73 easyHandle_ = nullptr;
74 return false;
75 } else {
76 int64_t httpCode = 0;
77 curl_easy_getinfo(easyHandle_, CURLINFO_RESPONSE_CODE, &httpCode);
78 SLOGI("DoDownload Http result " "%{public}" PRId64, httpCode);
79 CHECK_AND_RETURN_RET_LOG(httpCode < NapiUtils::HTTP_ERROR_CODE, false, "recv Http ERROR");
80 curl_easy_cleanup(easyHandle_);
81 easyHandle_ = nullptr;
82 return true;
83 }
84 }
85 return false;
86 }
87
88 bool NapiUtils::DoDownloadInCommon(std::shared_ptr<Media::PixelMap>& pixelMap, const std::string uri)
89 {
90 SLOGI("DoDownloadInCommon with uri");
91
92 std::vector<std::uint8_t> imgBuffer(0);
93 if (CurlSetRequestOptions(imgBuffer, uri) == true) {
94 std::uint8_t* buffer = (std::uint8_t*) calloc(imgBuffer.size(), sizeof(uint8_t));
95 if (buffer == nullptr) {
96 SLOGE("buffer malloc fail");
97 free(buffer);
98 return false;
99 }
100 std::copy(imgBuffer.begin(), imgBuffer.end(), buffer);
101 uint32_t errorCode = 0;
102 Media::SourceOptions opts;
103 SLOGD("DoDownload get size %{public}d", static_cast<int>(imgBuffer.size()));
104 auto imageSource = Media::ImageSource::CreateImageSource(buffer, imgBuffer.size(), opts, errorCode);
105 free(buffer);
106 if (errorCode || !imageSource) {
107 SLOGE("DoDownload create imageSource fail: %{public}u", errorCode);
108 return false;
109 }
110 Media::DecodeOptions decodeOpts;
111 pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
112 if (errorCode || pixelMap == nullptr) {
113 SLOGE("DoDownload creatPix fail: %{public}u, %{public}d", errorCode, static_cast<int>(pixelMap != nullptr));
114 return false;
115 }
116 return true;
117 }
118 return false;
119 }
120
ConvertSessionType(const std::string& typeString)121 int32_t NapiUtils::ConvertSessionType(const std::string& typeString)
122 {
123 if (typeString == "audio") {
124 return AVSession::SESSION_TYPE_AUDIO;
125 } else if (typeString == "video") {
126 return AVSession::SESSION_TYPE_VIDEO;
127 } else if (typeString == "voice_call") {
128 return AVSession::SESSION_TYPE_VOICE_CALL;
129 } else if (typeString == "video_call") {
130 return AVSession::SESSION_TYPE_VIDEO_CALL;
131 } else {
132 return AVSession::SESSION_TYPE_INVALID;
133 }
134 }
135
ConvertSessionType(int32_t type)136 std::string NapiUtils::ConvertSessionType(int32_t type)
137 {
138 if (type == AVSession::SESSION_TYPE_AUDIO) {
139 return "audio";
140 } else if (type == AVSession::SESSION_TYPE_VIDEO) {
141 return "video";
142 } else if (type == AVSession::SESSION_TYPE_VOICE_CALL) {
143 return "voice_call";
144 } else if (type == AVSession::SESSION_TYPE_VIDEO_CALL) {
145 return "video_call";
146 } else {
147 return "";
148 }
149 }
150
151 /* napi_value <-> bool */
GetValue(napi_env env, napi_value in, bool& out)152 napi_status NapiUtils::GetValue(napi_env env, napi_value in, bool& out)
153 {
154 return napi_get_value_bool(env, in, &out);
155 }
156
SetValue(napi_env env, const bool& in, napi_value& out)157 napi_status NapiUtils::SetValue(napi_env env, const bool& in, napi_value& out)
158 {
159 return napi_get_boolean(env, in, &out);
160 }
161
162 /* napi_value <-> int32_t */
GetValue(napi_env env, napi_value in, int32_t& out)163 napi_status NapiUtils::GetValue(napi_env env, napi_value in, int32_t& out)
164 {
165 return napi_get_value_int32(env, in, &out);
166 }
167
SetValue(napi_env env, const int32_t& in, napi_value& out)168 napi_status NapiUtils::SetValue(napi_env env, const int32_t& in, napi_value& out)
169 {
170 return napi_create_int32(env, in, &out);
171 }
172
173 /* napi_value <-> uint32_t */
GetValue(napi_env env, napi_value in, uint32_t& out)174 napi_status NapiUtils::GetValue(napi_env env, napi_value in, uint32_t& out)
175 {
176 return napi_get_value_uint32(env, in, &out);
177 }
178
SetValue(napi_env env, const uint32_t& in, napi_value& out)179 napi_status NapiUtils::SetValue(napi_env env, const uint32_t& in, napi_value& out)
180 {
181 return napi_create_uint32(env, in, &out);
182 }
183
184 /* napi_value <-> int64_t */
GetValue(napi_env env, napi_value in, int64_t& out)185 napi_status NapiUtils::GetValue(napi_env env, napi_value in, int64_t& out)
186 {
187 return napi_get_value_int64(env, in, &out);
188 }
189
SetValue(napi_env env, const int64_t& in, napi_value& out)190 napi_status NapiUtils::SetValue(napi_env env, const int64_t& in, napi_value& out)
191 {
192 return napi_create_int64(env, in, &out);
193 }
194
195 /* napi_value <-> double */
GetValue(napi_env env, napi_value in, double& out)196 napi_status NapiUtils::GetValue(napi_env env, napi_value in, double& out)
197 {
198 return napi_get_value_double(env, in, &out);
199 }
200
SetValue(napi_env env, const double& in, napi_value& out)201 napi_status NapiUtils::SetValue(napi_env env, const double& in, napi_value& out)
202 {
203 return napi_create_double(env, in, &out);
204 }
205
206 /* napi_value <-> std::string */
GetValue(napi_env env, napi_value in, std::string& out)207 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::string& out)
208 {
209 napi_valuetype type = napi_undefined;
210 napi_status status = napi_typeof(env, in, &type);
211 CHECK_RETURN((status == napi_ok) && (type == napi_string), "invalid type", napi_invalid_arg);
212
213 size_t maxLen = STR_MAX_LENGTH;
214 status = napi_get_value_string_utf8(env, in, nullptr, 0, &maxLen);
215 if (maxLen >= STR_MAX_LENGTH) {
216 return napi_invalid_arg;
217 }
218
219 char buf[STR_MAX_LENGTH + STR_TAIL_LENGTH] {};
220 size_t len = 0;
221 status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len);
222 if (status == napi_ok) {
223 out = std::string(buf);
224 }
225 return status;
226 }
227
SetValue(napi_env env, const std::string& in, napi_value& out)228 napi_status NapiUtils::SetValue(napi_env env, const std::string& in, napi_value& out)
229 {
230 return napi_create_string_utf8(env, in.c_str(), in.size(), &out);
231 }
232
233 /* napi_value <-> AppExecFwk::ElementName */
SetValue(napi_env env, const AppExecFwk::ElementName& in, napi_value& out)234 napi_status NapiUtils::SetValue(napi_env env, const AppExecFwk::ElementName& in, napi_value& out)
235 {
236 napi_status status = napi_create_object(env, &out);
237 CHECK_RETURN((status == napi_ok) && (out != nullptr), "create object failed", status);
238
239 napi_value property = nullptr;
240 status = SetValue(env, in.GetDeviceID(), property);
241 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
242 status = napi_set_named_property(env, out, "deviceId", property);
243 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
244
245 status = SetValue(env, in.GetBundleName(), property);
246 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
247 status = napi_set_named_property(env, out, "bundleName", property);
248 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
249
250 status = SetValue(env, in.GetAbilityName(), property);
251 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
252 status = napi_set_named_property(env, out, "abilityName", property);
253 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
254
255 return napi_ok;
256 }
257
SetOutPutDeviceIdValue(napi_env env, const std::vector<std::string>& in, napi_value& out)258 napi_status NapiUtils::SetOutPutDeviceIdValue(napi_env env, const std::vector<std::string>& in, napi_value& out)
259 {
260 napi_status status = napi_create_array_with_length(env, in.size(), &out);
261 CHECK_RETURN(status == napi_ok, "create array failed!", status);
262 int index = 0;
263 for (auto& item : in) {
264 napi_value element = nullptr;
265 SetValue(env, static_cast<int32_t>(std::stoi(item)), element);
266 status = napi_set_element(env, out, index++, element);
267 CHECK_RETURN((status == napi_ok), "napi_set_element failed!", status);
268 }
269 return status;
270 }
271
272 /* napi_value <-> AVSessionDescriptor */
SetValue(napi_env env, const AVSessionDescriptor& in, napi_value& out)273 napi_status NapiUtils::SetValue(napi_env env, const AVSessionDescriptor& in, napi_value& out)
274 {
275 napi_status status = napi_create_object(env, &out);
276 CHECK_RETURN((status == napi_ok) && (out != nullptr), "create object failed", status);
277
278 napi_value property = nullptr;
279 status = SetValue(env, in.sessionId_, property);
280 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
281 status = napi_set_named_property(env, out, "sessionId", property);
282 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
283
284 status = SetValue(env, ConvertSessionType(in.sessionType_), property);
285 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
286 status = napi_set_named_property(env, out, "type", property);
287 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
288
289 status = SetValue(env, in.sessionTag_, property);
290 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
291 status = napi_set_named_property(env, out, "sessionTag", property);
292 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
293
294 status = SetValue(env, in.elementName_, property);
295 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
296 status = napi_set_named_property(env, out, "elementName", property);
297 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
298
299 status = SetValue(env, in.isActive_, property);
300 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
301 status = napi_set_named_property(env, out, "isActive", property);
302 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
303
304 status = SetValue(env, in.isTopSession_, property);
305 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
306 status = napi_set_named_property(env, out, "isTopSession", property);
307 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
308
309 status = SetValue(env, in.outputDeviceInfo_, property);
310 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
311 status = napi_set_named_property(env, out, "outputDevice", property);
312 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
313
314 return napi_ok;
315 }
316
317 /* napi_value <-> AVQueueInfo */
SetValue(napi_env env, const AVQueueInfo& in, napi_value& out)318 napi_status NapiUtils::SetValue(napi_env env, const AVQueueInfo& in, napi_value& out)
319 {
320 napi_status status = napi_create_object(env, &out);
321 CHECK_RETURN((status == napi_ok) && (out != nullptr), "create object failed", status);
322
323 napi_value property = nullptr;
324 status = SetValue(env, in.GetBundleName(), property);
325 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
326 status = napi_set_named_property(env, out, "bundleName", property);
327 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
328
329 status = SetValue(env, in.GetAVQueueName(), property);
330 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
331 status = napi_set_named_property(env, out, "avQueueName", property);
332 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
333
334 status = SetValue(env, in.GetAVQueueId(), property);
335 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
336 status = napi_set_named_property(env, out, "avQueueId", property);
337 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
338
339 auto pixelMap = in.GetAVQueueImage();
340 if (pixelMap != nullptr) {
341 SLOGD(" napi setvalue has avqueueimage");
342 property = Media::PixelMapNapi::CreatePixelMap(env, AVSessionPixelMapAdapter::ConvertFromInner(pixelMap));
343 status = napi_set_named_property(env, out, "avQueueImage", property);
344 CHECK_RETURN(status == napi_ok, "set property failed", status);
345 }
346
347 auto uri = in.GetAVQueueImageUri();
348 if (!uri.empty()) {
349 SLOGD(" napi setvalue has avqueueimageuri");
350 status = NapiUtils::SetValue(env, uri, property);
351 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
352 status = napi_set_named_property(env, out, "avQueueImage", property);
353 CHECK_RETURN(status == napi_ok, "set property failed", status);
354 }
355
356 return napi_ok;
357 }
358
359 /* napi_value <-> MMI::KeyEvent::KeyItem */
GetValue(napi_env env, napi_value in, MMI::KeyEvent::KeyItem& out)360 napi_status NapiUtils::GetValue(napi_env env, napi_value in, MMI::KeyEvent::KeyItem& out)
361 {
362 int32_t code {};
363 auto status = GetNamedProperty(env, in, "code", code);
364 CHECK_RETURN(status == napi_ok, "get code property failed", status);
365 SLOGI("code=%{public}d", code);
366 out.SetKeyCode(code);
367
368 int64_t pressedTime {};
369 status = GetNamedProperty(env, in, "pressedTime", pressedTime);
370 CHECK_RETURN(status == napi_ok, "get pressedTime property failed", status);
371 SLOGI("pressedTime=%{public}" PRIu64, pressedTime);
372 out.SetDownTime(pressedTime);
373
374 int32_t deviceId {};
375 status = GetNamedProperty(env, in, "deviceId", deviceId);
376 CHECK_RETURN(status == napi_ok, "get deviceId property failed", status);
377 out.SetDeviceId(deviceId);
378 out.SetPressed(true);
379
380 return status;
381 }
382
SetValue(napi_env env, const std::optional<MMI::KeyEvent::KeyItem> in, napi_value& out)383 napi_status NapiUtils::SetValue(napi_env env, const std::optional<MMI::KeyEvent::KeyItem> in, napi_value& out)
384 {
385 auto status = napi_create_object(env, &out);
386 CHECK_RETURN(status == napi_ok, "create object failed", status);
387
388 napi_value code {};
389 status = SetValue(env, in->GetKeyCode(), code);
390 CHECK_RETURN((status == napi_ok) && (code != nullptr), "create property failed", status);
391 status = napi_set_named_property(env, out, "code", code);
392 CHECK_RETURN(status == napi_ok, "set property failed", status);
393
394 napi_value pressedTime {};
395 status = SetValue(env, in->GetDownTime(), pressedTime);
396 CHECK_RETURN((status == napi_ok) && (pressedTime != nullptr), "create property failed", status);
397 status = napi_set_named_property(env, out, "pressedTime", pressedTime);
398 CHECK_RETURN(status == napi_ok, "set property failed", status);
399
400 napi_value deviceId {};
401 status = SetValue(env, in->GetDeviceId(), deviceId);
402 CHECK_RETURN((status == napi_ok) && (deviceId != nullptr), "create property failed", status);
403 status = napi_set_named_property(env, out, "deviceId", deviceId);
404 CHECK_RETURN(status == napi_ok, "set property failed", status);
405
406 return status;
407 }
408
409 /* napi_value <-> MMI::KeyEvent */
GetValue(napi_env env, napi_value in, std::shared_ptr<MMI::KeyEvent>& out)410 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::shared_ptr<MMI::KeyEvent>& out)
411 {
412 napi_valuetype valueType = napi_undefined;
413 auto status = napi_typeof(env, in, &valueType);
414 CHECK_RETURN((status == napi_ok) && (valueType == napi_object), "object type invalid", status);
415
416 out = MMI::KeyEvent::Create();
417 CHECK_RETURN(out != nullptr, "create keyEvent failed", napi_generic_failure);
418
419 int32_t action {};
420 status = GetNamedProperty(env, in, "action", action);
421 CHECK_RETURN(status == napi_ok, "get action property failed", napi_generic_failure);
422 SLOGI("action=%{public}d", action);
423 action += KEYEVENT_ACTION_JS_NATIVE_DELTA;
424 out->SetKeyAction(action);
425
426 MMI::KeyEvent::KeyItem key;
427 status = GetNamedProperty(env, in, "key", key);
428 CHECK_RETURN(status == napi_ok, "get action property failed", napi_generic_failure);
429 out->SetKeyCode(key.GetKeyCode());
430
431 napi_value keyItems {};
432 status = napi_get_named_property(env, in, "keys", &keyItems);
433 CHECK_RETURN((status == napi_ok) && (keyItems != nullptr), "get keys property failed", status);
434
435 uint32_t length {};
436 status = napi_get_array_length(env, keyItems, &length);
437 CHECK_RETURN(status == napi_ok, "get array length failed", status);
438
439 for (uint32_t i = 0; i < length; ++i) {
440 napi_value keyItem {};
441 status = napi_get_element(env, keyItems, i, &keyItem);
442 CHECK_RETURN((status == napi_ok) && (keyItem != nullptr), "get element failed", status);
443 MMI::KeyEvent::KeyItem item;
444 status = GetValue(env, keyItem, item);
445 CHECK_RETURN(status == napi_ok, "get KeyItem failed", status);
446 if ((key.GetKeyCode() == item.GetKeyCode()) && (action == MMI::KeyEvent::KEY_ACTION_UP)) {
447 item.SetPressed(false);
448 }
449 out->AddKeyItem(item);
450 }
451
452 return napi_ok;
453 }
454
SetValue(napi_env env, const std::shared_ptr<MMI::KeyEvent>& in, napi_value& out)455 napi_status NapiUtils::SetValue(napi_env env, const std::shared_ptr<MMI::KeyEvent>& in, napi_value& out)
456 {
457 CHECK_RETURN(in != nullptr, "key event is nullptr", napi_generic_failure);
458
459 auto status = napi_create_object(env, &out);
460 CHECK_RETURN(status == napi_ok, "create object failed", status);
461
462 napi_value action {};
463 status = SetValue(env, in->GetKeyAction() - KEYEVENT_ACTION_JS_NATIVE_DELTA, action);
464 CHECK_RETURN((status == napi_ok) && (action != nullptr), "create action property failed", status);
465 status = napi_set_named_property(env, out, "action", action);
466 CHECK_RETURN(status == napi_ok, "set action property failed", status);
467
468 napi_value key {};
469 CHECK_RETURN(in->GetKeyItem(), "get key item failed", napi_generic_failure);
470 status = SetValue(env, in->GetKeyItem(), key);
471 CHECK_RETURN((status == napi_ok) && (key != nullptr), "create key property failed", status);
472 status = napi_set_named_property(env, out, "key", key);
473 CHECK_RETURN(status == napi_ok, "set key property failed", status);
474
475 napi_value keys {};
476 status = napi_create_array(env, &keys);
477 CHECK_RETURN(status == napi_ok, "create array failed", status);
478
479 uint32_t idx = 0;
480 std::vector<MMI::KeyEvent::KeyItem> keyItems = in->GetKeyItems();
481 for (const auto& keyItem : keyItems) {
482 napi_value item {};
483 status = SetValue(env, keyItem, item);
484 CHECK_RETURN((status == napi_ok) && (item != nullptr), "create keyItem failed", status);
485
486 status = napi_set_element(env, keys, idx, item);
487 CHECK_RETURN(status == napi_ok, "set element failed", status);
488 ++idx;
489 }
490
491 status = napi_set_named_property(env, out, "keys", keys);
492 CHECK_RETURN(status == napi_ok, "set keys property failed", status);
493 return status;
494 }
495
496 /* napi_value <-> AbilityRuntime::WantAgent::WantAgent */
GetValue(napi_env env, napi_value in, AbilityRuntime::WantAgent::WantAgent*& out)497 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AbilityRuntime::WantAgent::WantAgent*& out)
498 {
499 auto status = napi_unwrap(env, in, reinterpret_cast<void**>(&out));
500 CHECK_RETURN(status == napi_ok, "unwrap failed", napi_invalid_arg);
501 return status;
502 }
503
SetValue(napi_env env, AbilityRuntime::WantAgent::WantAgent& in, napi_value& out)504 napi_status NapiUtils::SetValue(napi_env env, AbilityRuntime::WantAgent::WantAgent& in, napi_value& out)
505 {
506 auto status = napi_create_object(env, &out);
507 CHECK_RETURN(status == napi_ok, "create object failed", napi_generic_failure);
508 auto finalizecb = [](napi_env env, void* data, void* hint) {};
509 status = napi_wrap(env, out, static_cast<void*>(&in), finalizecb, nullptr, nullptr);
510 CHECK_RETURN(status == napi_ok, "wrap object failed", napi_generic_failure);
511 return status;
512 }
513
514 /* napi_value <-> AAFwk::WantParams */
GetValue(napi_env env, napi_value in, AAFwk::WantParams& out)515 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AAFwk::WantParams& out)
516 {
517 auto status = AppExecFwk::UnwrapWantParams(env, in, out);
518 CHECK_RETURN(status == true, "unwrap object failed", napi_generic_failure);
519 return napi_ok;
520 }
521
SetValue(napi_env env, const AAFwk::WantParams& in, napi_value& out)522 napi_status NapiUtils::SetValue(napi_env env, const AAFwk::WantParams& in, napi_value& out)
523 {
524 auto status = napi_create_object(env, &out);
525 CHECK_RETURN(status == napi_ok, "create object failed", napi_generic_failure);
526 out = AppExecFwk::WrapWantParams(env, in);
527 return status;
528 }
529
530 /* napi_value <-> AVCallMetaData */
GetValue(napi_env env, napi_value in, AVCallMetaData& out)531 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AVCallMetaData& out)
532 {
533 return NapiAVCallMetaData::GetValue(env, in, out);
534 }
535
SetValue(napi_env env, const AVCallMetaData& in, napi_value& out)536 napi_status NapiUtils::SetValue(napi_env env, const AVCallMetaData& in, napi_value& out)
537 {
538 return NapiAVCallMetaData::SetValue(env, in, out);
539 }
540
541 /* napi_value <-> AVCallState */
GetValue(napi_env env, napi_value in, AVCallState& out)542 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AVCallState& out)
543 {
544 return NapiAVCallState::GetValue(env, in, out);
545 }
546
SetValue(napi_env env, const AVCallState& in, napi_value& out)547 napi_status NapiUtils::SetValue(napi_env env, const AVCallState& in, napi_value& out)
548 {
549 return NapiAVCallState::SetValue(env, in, out);
550 }
551
552 /* napi_value <-> AVMetaData */
GetValue(napi_env env, napi_value in, AVMetaData& out)553 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AVMetaData& out)
554 {
555 return NapiMetaData::GetValue(env, in, out);
556 }
557
SetValue(napi_env env, const AVMetaData& in, napi_value& out)558 napi_status NapiUtils::SetValue(napi_env env, const AVMetaData& in, napi_value& out)
559 {
560 return NapiMetaData::SetValue(env, in, out);
561 }
562
563 /* napi_value <-> AVMediaDescription */
GetValue(napi_env env, napi_value in, AVMediaDescription& out)564 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AVMediaDescription& out)
565 {
566 return NapiMediaDescription::GetValue(env, in, out);
567 }
568
SetValue(napi_env env, const AVMediaDescription& in, napi_value& out)569 napi_status NapiUtils::SetValue(napi_env env, const AVMediaDescription& in, napi_value& out)
570 {
571 return NapiMediaDescription::SetValue(env, in, out);
572 }
573
574 /* napi_value <-> AVQueueItem */
GetValue(napi_env env, napi_value in, AVQueueItem& out)575 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AVQueueItem& out)
576 {
577 return NapiQueueItem::GetValue(env, in, out);
578 }
579
SetValue(napi_env env, const AVQueueItem& in, napi_value& out)580 napi_status NapiUtils::SetValue(napi_env env, const AVQueueItem& in, napi_value& out)
581 {
582 return NapiQueueItem::SetValue(env, in, out);
583 }
584
585 /* napi_value <-> std::vector<AVQueueItem> */
GetValue(napi_env env, napi_value in, std::vector<AVQueueItem>& out)586 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<AVQueueItem>& out)
587 {
588 uint32_t length {};
589 auto status = napi_get_array_length(env, in, &length);
590 CHECK_RETURN(status == napi_ok, "get AVQueueItem array length failed", status);
591 for (uint32_t i = 0; i < length; ++i) {
592 napi_value element {};
593 status = napi_get_element(env, in, i, &element);
594 CHECK_RETURN((status == napi_ok) && (element != nullptr), "get element failed", status);
595 AVQueueItem descriptor;
596 status = GetValue(env, element, descriptor);
597 out.push_back(descriptor);
598 }
599 return status;
600 }
601
SetValue(napi_env env, const std::vector<AVQueueItem>& in, napi_value& out)602 napi_status NapiUtils::SetValue(napi_env env, const std::vector<AVQueueItem>& in, napi_value& out)
603 {
604 SLOGD("napi_value <- std::vector<std::string>");
605 napi_status status = napi_create_array_with_length(env, in.size(), &out);
606 CHECK_RETURN(status == napi_ok, "create AVQueueItem array failed!", status);
607 int index = 0;
608 for (auto& item : in) {
609 napi_value element = nullptr;
610 SetValue(env, item, element);
611 status = napi_set_element(env, out, index++, element);
612 CHECK_RETURN((status == napi_ok), "napi_set_element failed!", status);
613 }
614 return status;
615 }
616
617 /* napi_value <-> AVPlaybackState */
GetValue(napi_env env, napi_value in, AVPlaybackState& out)618 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AVPlaybackState& out)
619 {
620 return NapiPlaybackState::GetValue(env, in, out);
621 }
622
SetValue(napi_env env, const AVPlaybackState& in, napi_value& out)623 napi_status NapiUtils::SetValue(napi_env env, const AVPlaybackState& in, napi_value& out)
624 {
625 return NapiPlaybackState::SetValue(env, in, out);
626 }
627
628 /* napi_value <-> AVCastPlayerState */
GetValue(napi_env env, napi_value in, AVCastPlayerState& out)629 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AVCastPlayerState& out)
630 {
631 napi_valuetype type = napi_undefined;
632 napi_status status = napi_typeof(env, in, &type);
633 CHECK_RETURN((status == napi_ok) && (type == napi_string), "invalid type", napi_invalid_arg);
634
635 size_t maxLen = STR_MAX_LENGTH;
636 status = napi_get_value_string_utf8(env, in, nullptr, 0, &maxLen);
637 if (maxLen >= STR_MAX_LENGTH) {
638 return napi_invalid_arg;
639 }
640
641 char buf[STR_MAX_LENGTH + STR_TAIL_LENGTH] {};
642 size_t len = 0;
643 status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len);
644 if (status == napi_ok) {
645 AVCastPlayerState castPlayerState;
646 castPlayerState.castPlayerState_ = std::string(buf);
647 out = castPlayerState;
648 }
649 return status;
650 }
651
SetValue(napi_env env, const AVCastPlayerState& in, napi_value& out)652 napi_status NapiUtils::SetValue(napi_env env, const AVCastPlayerState& in, napi_value& out)
653 {
654 return napi_create_string_utf8(env, in.castPlayerState_.c_str(), in.castPlayerState_.size(), &out);
655 }
656
657 /* napi_value <-> std::vector<std::string> */
GetValue(napi_env env, napi_value in, std::vector<std::string>& out)658 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<std::string>& out)
659 {
660 SLOGD("napi_value -> std::vector<std::string>");
661 out.clear();
662 bool isArray = false;
663 napi_is_array(env, in, &isArray);
664 CHECK_RETURN(isArray, "not an array", napi_invalid_arg);
665
666 uint32_t length = 0;
667 napi_status status = napi_get_array_length(env, in, &length);
668 CHECK_RETURN((status == napi_ok) && (length > 0 || length == 0), "get_array failed!", napi_invalid_arg);
669 for (uint32_t i = 0; i < length; ++i) {
670 napi_value item = nullptr;
671 status = napi_get_element(env, in, i, &item);
672 CHECK_RETURN((item != nullptr) && (status == napi_ok), "no element", napi_invalid_arg);
673 std::string value;
674 status = GetValue(env, item, value);
675 CHECK_RETURN(status == napi_ok, "not a string", napi_invalid_arg);
676 out.push_back(value);
677 }
678 return status;
679 }
680
SetValue(napi_env env, const std::vector<std::string>& in, napi_value& out)681 napi_status NapiUtils::SetValue(napi_env env, const std::vector<std::string>& in, napi_value& out)
682 {
683 SLOGD("napi_value <- std::vector<std::string>");
684 napi_status status = napi_create_array_with_length(env, in.size(), &out);
685 CHECK_RETURN(status == napi_ok, "create array failed!", status);
686 int index = 0;
687 for (auto& item : in) {
688 napi_value element = nullptr;
689 SetValue(env, item, element);
690 status = napi_set_element(env, out, index++, element);
691 CHECK_RETURN((status == napi_ok), "napi_set_element failed!", status);
692 }
693 return status;
694 }
695
696 /* napi_value <-> std::vector<uint8_t> */
GetValue(napi_env env, napi_value in, std::vector<uint8_t>& out)697 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<uint8_t>& out)
698 {
699 out.clear();
700 SLOGD("napi_value -> std::vector<uint8_t> ");
701 napi_typedarray_type type = napi_biguint64_array;
702 size_t length = 0;
703 napi_value buffer = nullptr;
704 size_t offset = 0;
705 void* data = nullptr;
706 napi_status status = napi_get_typedarray_info(env, in, &type, &length, &data, &buffer, &offset);
707 SLOGD("array type=%{public}d length=%{public}d offset=%{public}d", static_cast<int>(type), static_cast<int>(length),
708 static_cast<int>(offset));
709 CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
710 CHECK_RETURN(type == napi_uint8_array, "is not Uint8Array!", napi_invalid_arg);
711 CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
712 out.assign(static_cast<uint8_t*>(data), static_cast<uint8_t*>(data) + length);
713 return status;
714 }
715
SetValue(napi_env env, const std::vector<uint8_t>& in, napi_value& out)716 napi_status NapiUtils::SetValue(napi_env env, const std::vector<uint8_t>& in, napi_value& out)
717 {
718 SLOGD("napi_value <- std::vector<uint8_t> ");
719 CHECK_RETURN(!in.empty(), "invalid std::vector<uint8_t>", napi_invalid_arg);
720 void* data = nullptr;
721 napi_value buffer = nullptr;
722 napi_status status = napi_create_arraybuffer(env, in.size(), &data, &buffer);
723 CHECK_RETURN((status == napi_ok), "create array buffer failed!", status);
724
725 if (memcpy_s(data, in.size(), in.data(), in.size()) != EOK) {
726 SLOGE("memcpy_s not EOK");
727 return napi_invalid_arg;
728 }
729 status = napi_create_typedarray(env, napi_uint8_array, in.size(), buffer, 0, &out);
730 CHECK_RETURN((status == napi_ok), "napi_value <- std::vector<uint8_t> invalid value", status);
731 return status;
732 }
733
734 /* napi_value <-> CastDisplayInfo */
SetValue(napi_env env, const CastDisplayInfo& in, napi_value& out)735 napi_status NapiUtils::SetValue(napi_env env, const CastDisplayInfo& in, napi_value& out)
736 {
737 auto status = napi_create_object(env, &out);
738 CHECK_RETURN(status == napi_ok, "create object failed", status);
739 napi_value displayState = nullptr;
740 napi_create_int32(env, static_cast<int>(in.displayState), &displayState);
741 status = napi_set_named_property(env, out, "state", displayState);
742 napi_value displayId = nullptr;
743 napi_create_int64(env, in.displayId, &displayId);
744 status = napi_set_named_property(env, out, "id", displayId);
745 napi_value name = nullptr;
746 napi_create_string_utf8(env, in.name.c_str(), in.name.size(), &name);
747 status = napi_set_named_property(env, out, "name", name);
748 napi_value width = nullptr;
749 napi_create_int32(env, in.width, &width);
750 status = napi_set_named_property(env, out, "width", width);
751 napi_value height = nullptr;
752 napi_create_int32(env, in.height, &height);
753 status = napi_set_named_property(env, out, "height", height);
754 CHECK_RETURN(status == napi_ok, "set property failed", status);
755 return status;
756 }
757
758 /* napi_value <-> CastDisplayInfo Array */
SetValue(napi_env env, const std::vector<CastDisplayInfo>& in, napi_value& out)759 napi_status NapiUtils::SetValue(napi_env env, const std::vector<CastDisplayInfo>& in, napi_value& out)
760 {
761 auto status = napi_create_array_with_length(env, in.size(), &out);
762 CHECK_RETURN(status == napi_ok, "create CastDisplayInfo Array failed", status);
763 int index = 0;
764 for (auto& item : in) {
765 napi_value element = nullptr;
766 SetValue(env, item, element);
767 status = napi_set_element(env, out, index++, element);
768 CHECK_RETURN(status == napi_ok, "napi_set_element failed", status);
769 }
770 return status;
771 }
772
773 template <typename T>
TypedArray2Vector(uint8_t* data, size_t length, napi_typedarray_type type, std::vector<T>& out)774 void TypedArray2Vector(uint8_t* data, size_t length, napi_typedarray_type type, std::vector<T>& out)
775 {
776 auto convert = [&out](auto* data, size_t elements) {
777 for (size_t index = 0; index < elements; index++) {
778 out.push_back(static_cast<T>(data[index]));
779 }
780 };
781
782 switch (type) {
783 case napi_int8_array:
784 convert(reinterpret_cast<int8_t*>(data), length);
785 break;
786 case napi_uint8_array:
787 convert(data, length);
788 break;
789 case napi_uint8_clamped_array:
790 convert(data, length);
791 break;
792 case napi_int16_array:
793 convert(reinterpret_cast<int16_t*>(data), length / sizeof(int16_t));
794 break;
795 case napi_uint16_array:
796 convert(reinterpret_cast<uint16_t*>(data), length / sizeof(uint16_t));
797 break;
798 case napi_int32_array:
799 convert(reinterpret_cast<int32_t*>(data), length / sizeof(int32_t));
800 break;
801 case napi_uint32_array:
802 convert(reinterpret_cast<uint32_t*>(data), length / sizeof(uint32_t));
803 break;
804 case napi_float32_array:
805 convert(reinterpret_cast<float*>(data), length / sizeof(float));
806 break;
807 case napi_float64_array:
808 convert(reinterpret_cast<double*>(data), length / sizeof(double));
809 break;
810 case napi_bigint64_array:
811 convert(reinterpret_cast<int64_t*>(data), length / sizeof(int64_t));
812 break;
813 case napi_biguint64_array:
814 convert(reinterpret_cast<uint64_t*>(data), length / sizeof(uint64_t));
815 break;
816 default:
817 CHECK_RETURN_VOID(false, "[FATAL] invalid napi_typedarray_type!");
818 }
819 }
820
821 /* napi_value <-> std::vector<int32_t> */
GetValue(napi_env env, napi_value in, std::vector<int32_t>& out)822 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<int32_t>& out)
823 {
824 out.clear();
825 SLOGD("napi_value -> std::vector<int32_t> ");
826 napi_typedarray_type type = napi_biguint64_array;
827 size_t length = 0;
828 napi_value buffer = nullptr;
829 size_t offset = 0;
830 uint8_t* data = nullptr;
831 napi_status status = napi_get_typedarray_info(env, in, &type, &length,
832 reinterpret_cast<void**>(&data), &buffer, &offset);
833 SLOGD("array type=%{public}d length=%{public}d offset=%{public}d", static_cast<int>(type), static_cast<int>(length),
834 static_cast<int>(offset));
835 CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
836 CHECK_RETURN(type <= napi_int32_array, "is not int32 supported typed array!", napi_invalid_arg);
837 CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
838 TypedArray2Vector<int32_t>(data, length, type, out);
839 return status;
840 }
841
SetValue(napi_env env, const std::vector<int32_t>& in, napi_value& out)842 napi_status NapiUtils::SetValue(napi_env env, const std::vector<int32_t>& in, napi_value& out)
843 {
844 SLOGD("napi_value <- std::vector<int32_t> ");
845 size_t bytes = in.size() * sizeof(int32_t);
846 CHECK_RETURN(bytes > 0, "invalid std::vector<int32_t>", napi_invalid_arg);
847 void* data = nullptr;
848 napi_value buffer = nullptr;
849 napi_status status = napi_create_arraybuffer(env, bytes, &data, &buffer);
850 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
851
852 if (memcpy_s(data, bytes, in.data(), bytes) != EOK) {
853 SLOGE("memcpy_s not EOK");
854 return napi_invalid_arg;
855 }
856 status = napi_create_typedarray(env, napi_int32_array, in.size(), buffer, 0, &out);
857 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
858 return status;
859 }
860
861 /* napi_value <-> std::vector<uint32_t> */
GetValue(napi_env env, napi_value in, std::vector<uint32_t>& out)862 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<uint32_t>& out)
863 {
864 out.clear();
865 SLOGD("napi_value -> std::vector<uint32_t> ");
866 napi_typedarray_type type = napi_biguint64_array;
867 size_t length = 0;
868 napi_value buffer = nullptr;
869 size_t offset = 0;
870 uint8_t* data = nullptr;
871 napi_status status = napi_get_typedarray_info(env, in, &type, &length,
872 reinterpret_cast<void**>(&data), &buffer, &offset);
873 SLOGD("napi_get_typedarray_info type=%{public}d", static_cast<int>(type));
874 CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
875 CHECK_RETURN((type <= napi_uint16_array) || (type == napi_uint32_array), "invalid type!", napi_invalid_arg);
876 CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
877 TypedArray2Vector<uint32_t>(data, length, type, out);
878 return status;
879 }
880
SetValue(napi_env env, const std::vector<uint32_t>& in, napi_value& out)881 napi_status NapiUtils::SetValue(napi_env env, const std::vector<uint32_t>& in, napi_value& out)
882 {
883 SLOGD("napi_value <- std::vector<uint32_t> ");
884 size_t bytes = in.size() * sizeof(uint32_t);
885 CHECK_RETURN(bytes > 0, "invalid std::vector<uint32_t>", napi_invalid_arg);
886 void* data = nullptr;
887 napi_value buffer = nullptr;
888 napi_status status = napi_create_arraybuffer(env, bytes, &data, &buffer);
889 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
890
891 if (memcpy_s(data, bytes, in.data(), bytes) != EOK) {
892 SLOGE("memcpy_s not EOK");
893 return napi_invalid_arg;
894 }
895 status = napi_create_typedarray(env, napi_uint32_array, in.size(), buffer, 0, &out);
896 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
897 return status;
898 }
899
900 /* napi_value <-> std::vector<int64_t> */
GetValue(napi_env env, napi_value in, std::vector<int64_t>& out)901 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<int64_t>& out)
902 {
903 out.clear();
904 SLOGD("napi_value -> std::vector<int64_t> ");
905 napi_typedarray_type type = napi_biguint64_array;
906 size_t length = 0;
907 napi_value buffer = nullptr;
908 size_t offset = 0;
909 uint8_t* data = nullptr;
910 napi_status status = napi_get_typedarray_info(env, in, &type, &length,
911 reinterpret_cast<void**>(&data), &buffer, &offset);
912 SLOGD("array type=%{public}d length=%{public}d offset=%{public}d", static_cast<int>(type), static_cast<int>(length),
913 static_cast<int>(offset));
914 CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
915 CHECK_RETURN((type <= napi_uint32_array) || (type == napi_bigint64_array), "invalid type!", napi_invalid_arg);
916 CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
917 TypedArray2Vector<int64_t>(data, length, type, out);
918 return status;
919 }
920
SetValue(napi_env env, const std::vector<int64_t>& in, napi_value& out)921 napi_status NapiUtils::SetValue(napi_env env, const std::vector<int64_t>& in, napi_value& out)
922 {
923 SLOGD("napi_value <- std::vector<int64_t> ");
924 size_t bytes = in.size() * sizeof(int64_t);
925 CHECK_RETURN(bytes > 0, "invalid std::vector<uint32_t>", napi_invalid_arg);
926 void* data = nullptr;
927 napi_value buffer = nullptr;
928 napi_status status = napi_create_arraybuffer(env, bytes, &data, &buffer);
929 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
930
931 if (memcpy_s(data, bytes, in.data(), bytes) != EOK) {
932 SLOGE("memcpy_s not EOK");
933 return napi_invalid_arg;
934 }
935 status = napi_create_typedarray(env, napi_bigint64_array, in.size(), buffer, 0, &out);
936 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
937 return status;
938 }
939 /* napi_value <-> std::vector<double> */
GetValue(napi_env env, napi_value in, std::vector<double>& out)940 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<double>& out)
941 {
942 out.clear();
943 bool isTypedArray = false;
944 napi_status status = napi_is_typedarray(env, in, &isTypedArray);
945 SLOGD("napi_value -> std::vector<double> input %{public}s a TypedArray", isTypedArray ? "is" : "is not");
946 CHECK_RETURN((status == napi_ok), "napi_is_typedarray failed!", status);
947 if (isTypedArray) {
948 SLOGD("napi_value -> std::vector<double> ");
949 napi_typedarray_type type = napi_biguint64_array;
950 size_t length = 0;
951 napi_value buffer = nullptr;
952 size_t offset = 0;
953 uint8_t* data = nullptr;
954 status = napi_get_typedarray_info(env, in, &type, &length, reinterpret_cast<void**>(&data), &buffer, &offset);
955 SLOGD("napi_get_typedarray_info status=%{public}d type=%{public}d", status, static_cast<int>(type));
956 CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
957 CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
958 TypedArray2Vector<double>(data, length, type, out);
959 } else {
960 bool isArray = false;
961 status = napi_is_array(env, in, &isArray);
962 SLOGD("napi_value -> std::vector<double> input %{public}s an Array", isArray ? "is" : "is not");
963 CHECK_RETURN((status == napi_ok) && isArray, "invalid data!", napi_invalid_arg);
964 uint32_t length = 0;
965 status = napi_get_array_length(env, in, &length);
966 CHECK_RETURN((status == napi_ok) && (length > 0), "invalid data!", napi_invalid_arg);
967 for (uint32_t i = 0; i < length; ++i) {
968 napi_value item = nullptr;
969 status = napi_get_element(env, in, i, &item);
970 CHECK_RETURN((item != nullptr) && (status == napi_ok), "no element", napi_invalid_arg);
971 double vi = 0.0f;
972 status = napi_get_value_double(env, item, &vi);
973 CHECK_RETURN(status == napi_ok, "element not a double", napi_invalid_arg);
974 out.push_back(vi);
975 }
976 }
977 return status;
978 }
979
SetValue(napi_env env, const std::vector<double>& in, napi_value& out)980 napi_status NapiUtils::SetValue(napi_env env, const std::vector<double>& in, napi_value& out)
981 {
982 SLOGD("napi_value <- std::vector<double> ");
983 (void)(env);
984 (void)(in);
985 (void)(out);
986 CHECK_RETURN(false, "std::vector<double> to napi_value, unsupported!", napi_invalid_arg);
987 return napi_invalid_arg;
988 }
989
990 /* std::vector<AVSessionDescriptor> <-> napi_value */
SetValue(napi_env env, const std::vector<AVSessionDescriptor>& in, napi_value& out)991 napi_status NapiUtils::SetValue(napi_env env, const std::vector<AVSessionDescriptor>& in, napi_value& out)
992 {
993 SLOGD("napi_value <- std::vector<AVSessionDescriptor> %{public}d", static_cast<int>(in.size()));
994 napi_status status = napi_create_array_with_length(env, in.size(), &out);
995 CHECK_RETURN((status == napi_ok), "create_array failed!", status);
996 int index = 0;
997 for (const auto& item : in) {
998 napi_value entry = nullptr;
999 SetValue(env, item, entry);
1000 napi_set_element(env, out, index++, entry);
1001 }
1002 return status;
1003 }
1004
1005 /* std::vector<AVQueueInfo> <-> napi_value */
SetValue(napi_env env, const std::vector<AVQueueInfo>& in, napi_value& out)1006 napi_status NapiUtils::SetValue(napi_env env, const std::vector<AVQueueInfo>& in, napi_value& out)
1007 {
1008 SLOGD("napi_value <- std::vector<AVQueueInfo> %{public}d", static_cast<int>(in.size()));
1009 napi_status status = napi_create_array_with_length(env, in.size(), &out);
1010 CHECK_RETURN((status == napi_ok), "create_array failed!", status);
1011 int index = 0;
1012 for (const auto& item : in) {
1013 napi_value entry = nullptr;
1014 SetValue(env, item, entry);
1015 napi_set_element(env, out, index++, entry);
1016 }
1017 return status;
1018 }
1019
1020 /* napi_value <-> DeviceInfo */
SetValue(napi_env env, const DeviceInfo& in, napi_value& out)1021 napi_status NapiUtils::SetValue(napi_env env, const DeviceInfo& in, napi_value& out)
1022 {
1023 napi_status status = napi_create_object(env, &out);
1024 CHECK_RETURN((status == napi_ok) && (out != nullptr), "create object failed", status);
1025 napi_value property = nullptr;
1026 status = SetValue(env, in.castCategory_, property);
1027 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1028 status = napi_set_named_property(env, out, "castCategory", property);
1029 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1030
1031 status = SetValue(env, in.deviceId_, property);
1032 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1033 status = napi_set_named_property(env, out, "deviceId", property);
1034 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1035
1036 status = SetValue(env, in.manufacturer_, property);
1037 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1038 status = napi_set_named_property(env, out, "manufacturer", property);
1039 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1040
1041 status = SetValue(env, in.modelName_, property);
1042 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1043 status = napi_set_named_property(env, out, "modelName", property);
1044 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1045
1046 status = SetValue(env, in.deviceName_, property);
1047 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1048 status = napi_set_named_property(env, out, "deviceName", property);
1049 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1050
1051 status = SetValue(env, in.deviceType_, property);
1052 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1053 status = napi_set_named_property(env, out, "deviceType", property);
1054 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1055
1056 status = SetValue(env, in.ipAddress_, property);
1057 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1058 status = napi_set_named_property(env, out, "ipAddress", property);
1059 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1060
1061 status = SetValue(env, in.providerId_, property);
1062 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1063 status = napi_set_named_property(env, out, "providerId", property);
1064 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1065
1066 status = SetValue(env, in.supportedProtocols_, property);
1067 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1068 status = napi_set_named_property(env, out, "supportedProtocols", property);
1069 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1070
1071 status = SetValue(env, in.authenticationStatus_, property);
1072 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1073 status = napi_set_named_property(env, out, "authenticationStatus", property);
1074 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1075
1076 status = SetValue(env, in.supportedDrmCapabilities_, property);
1077 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1078 status = napi_set_named_property(env, out, "supportedDrmCapabilities", property);
1079 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1080
1081 status = SetValue(env, in.isLegacy_, property);
1082 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1083 status = napi_set_named_property(env, out, "isLegacy", property);
1084 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1085
1086 status = SetValue(env, in.mediumTypes_, property);
1087 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1088 status = napi_set_named_property(env, out, "mediumTypes", property);
1089 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1090 return napi_ok;
1091 }
1092
1093 /* OutputDeviceInfo <-> napi_value */
SetValue(napi_env env, const OutputDeviceInfo& in, napi_value& out)1094 napi_status NapiUtils::SetValue(napi_env env, const OutputDeviceInfo& in, napi_value& out)
1095 {
1096 SLOGD("napi_value <- OutputDeviceInfo");
1097 napi_value temp {};
1098 napi_create_object(env, &out);
1099
1100 napi_status status = napi_create_array_with_length(env, in.deviceInfos_.size(), &temp);
1101 CHECK_RETURN((status == napi_ok), "create_array failed!", status);
1102 int index = 0;
1103 SLOGD("The length of deviceInfos is %{public}d", static_cast<int32_t>(in.deviceInfos_.size()));
1104 for (const auto& item : in.deviceInfos_) {
1105 napi_value entry = nullptr;
1106 status = SetValue(env, item, entry);
1107 CHECK_RETURN((status == napi_ok) && (entry != nullptr), "create array failed!", status);
1108 napi_set_element(env, temp, index++, entry);
1109 }
1110 status = napi_set_named_property(env, out, "devices", temp);
1111 CHECK_RETURN((status == napi_ok), "set named property devices failed", status);
1112 return status;
1113 }
1114
Unwrap(napi_env env, napi_value in, void** out, napi_value constructor)1115 napi_status NapiUtils::Unwrap(napi_env env, napi_value in, void** out, napi_value constructor)
1116 {
1117 if (constructor != nullptr) {
1118 bool isInstance = false;
1119 napi_instanceof(env, in, constructor, &isInstance);
1120 if (!isInstance) {
1121 SLOGE("not a instance of *");
1122 return napi_invalid_arg;
1123 }
1124 }
1125 return napi_unwrap(env, in, out);
1126 }
1127
Equals(napi_env env, napi_value value, napi_ref copy)1128 bool NapiUtils::Equals(napi_env env, napi_value value, napi_ref copy)
1129 {
1130 if (copy == nullptr) {
1131 return (value == nullptr);
1132 }
1133
1134 napi_value copyValue = nullptr;
1135 napi_get_reference_value(env, copy, ©Value);
1136 CHECK_RETURN((napi_get_reference_value(env, copy, ©Value) == napi_ok),
1137 "get ref value failed", napi_generic_failure);
1138 bool isEquals = false;
1139 CHECK_RETURN(napi_strict_equals(env, value, copyValue, &isEquals) == napi_ok,
1140 "get equals result failed", napi_generic_failure);
1141 return isEquals;
1142 }
1143
TypeCheck(napi_env env, napi_value value, napi_valuetype expectType)1144 bool NapiUtils::TypeCheck(napi_env env, napi_value value, napi_valuetype expectType)
1145 {
1146 napi_valuetype valueType = napi_undefined;
1147 napi_status status = napi_typeof(env, value, &valueType);
1148 if (status != napi_ok || valueType != expectType) {
1149 return false;
1150 }
1151 return true;
1152 }
1153
GetUndefinedValue(napi_env env)1154 napi_value NapiUtils::GetUndefinedValue(napi_env env)
1155 {
1156 napi_value result {};
1157 napi_get_undefined(env, &result);
1158 return result;
1159 }
1160
GetPropertyNames(napi_env env, napi_value in, std::vector<std::string>& out)1161 napi_status NapiUtils::GetPropertyNames(napi_env env, napi_value in, std::vector<std::string>& out)
1162 {
1163 napi_value names {};
1164 NAPI_CALL_BASE(env, napi_get_property_names(env, in, &names), napi_generic_failure);
1165 uint32_t length = 0;
1166 NAPI_CALL_BASE(env, napi_get_array_length(env, names, &length), napi_generic_failure);
1167
1168 for (uint32_t index = 0; index < length; ++index) {
1169 napi_value name {};
1170 std::string nameString;
1171 if (napi_get_element(env, names, index, &name) != napi_ok) {
1172 continue;
1173 }
1174 if (GetValue(env, name, nameString) != napi_ok) {
1175 continue;
1176 }
1177 out.push_back(nameString);
1178 }
1179
1180 return napi_ok;
1181 }
1182
GetDateValue(napi_env env, napi_value value, double& result)1183 napi_status NapiUtils::GetDateValue(napi_env env, napi_value value, double& result)
1184 {
1185 CHECK_RETURN(env != nullptr, "env is nullptr", napi_invalid_arg);
1186 CHECK_RETURN(value != nullptr, "value is nullptr", napi_invalid_arg);
1187
1188 SLOGD("GetDateValue in");
1189 bool isDate = false;
1190 napi_is_date(env, value, &isDate);
1191 if (isDate) {
1192 napi_status status = napi_get_date_value(env, value, &result);
1193 if (status != napi_ok) {
1194 SLOGE("get date error");
1195 }
1196 SLOGD("GetDateValue out");
1197 return napi_ok;
1198 } else {
1199 SLOGE("value is not date type");
1200 return napi_date_expected;
1201 }
1202 }
1203
SetDateValue(napi_env env, double time, napi_value& result)1204 napi_status NapiUtils::SetDateValue(napi_env env, double time, napi_value& result)
1205 {
1206 CHECK_RETURN(env != nullptr, "env is nullptr", napi_invalid_arg);
1207
1208 SLOGD("SetDateValue in");
1209 napi_status status = napi_create_date(env, time, &result);
1210 if (status != napi_ok) {
1211 SLOGE("create date error");
1212 }
1213 SLOGD("SetDateValue out");
1214 return napi_ok;
1215 }
1216
GetRefByCallback(napi_env env, std::list<napi_ref> callbackList, napi_value callback, napi_ref& callbackRef)1217 napi_status NapiUtils::GetRefByCallback(napi_env env, std::list<napi_ref> callbackList, napi_value callback,
1218 napi_ref& callbackRef)
1219 {
1220 for (auto ref = callbackList.begin(); ref != callbackList.end(); ++ref) {
1221 if (Equals(env, callback, *ref)) {
1222 SLOGD("Callback has been matched");
1223 callbackRef = *ref;
1224 break;
1225 }
1226 }
1227 return napi_ok;
1228 }
1229
1230 /* napi_value is napi stage context */
GetStageElementName(napi_env env, napi_value in, AppExecFwk::ElementName& out)1231 napi_status NapiUtils::GetStageElementName(napi_env env, napi_value in, AppExecFwk::ElementName& out)
1232 {
1233 std::shared_ptr<AbilityRuntime::Context> stageContext = AbilityRuntime::GetStageModeContext(env, in);
1234 CHECK_RETURN(stageContext != nullptr, "get StagContext failed", napi_generic_failure);
1235 std::shared_ptr <AppExecFwk::AbilityInfo> abilityInfo;
1236 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(stageContext);
1237 if (abilityContext != nullptr) {
1238 abilityInfo = abilityContext->GetAbilityInfo();
1239 } else {
1240 auto extensionContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::ExtensionContext>(stageContext);
1241 CHECK_RETURN(extensionContext != nullptr, "context ConvertTo AbilityContext and ExtensionContext fail",
1242 napi_generic_failure);
1243 abilityInfo = extensionContext->GetAbilityInfo();
1244 }
1245 out.SetBundleName(abilityInfo->bundleName);
1246 out.SetAbilityName(abilityInfo->name);
1247 return napi_ok;
1248 }
1249
GetFaElementName(napi_env env, AppExecFwk::ElementName& out)1250 napi_status NapiUtils::GetFaElementName(napi_env env, AppExecFwk::ElementName& out)
1251 {
1252 auto* ability = AbilityRuntime::GetCurrentAbility(env);
1253 CHECK_RETURN(ability != nullptr, "get feature ability failed", napi_generic_failure);
1254 auto want = ability->GetWant();
1255 CHECK_RETURN(want != nullptr, "get want failed", napi_generic_failure);
1256 out = want->GetElement();
1257 return napi_ok;
1258 }
1259
GetValue(napi_env env, napi_value in, AppExecFwk::ElementName& out)1260 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AppExecFwk::ElementName& out)
1261 {
1262 bool isStageMode = false;
1263 CHECK_RETURN(AbilityRuntime::IsStageContext(env, in, isStageMode) == napi_ok, "get context type failed",
1264 napi_generic_failure);
1265 if (isStageMode) {
1266 CHECK_RETURN(GetStageElementName(env, in, out) == napi_ok, "get StagContext failed", napi_generic_failure);
1267 } else {
1268 CHECK_RETURN(GetFaElementName(env, out) == napi_ok, "get FaContext failed", napi_generic_failure);
1269 }
1270 return napi_ok;
1271 }
1272
GetValue(napi_env env, napi_value in, SessionToken& out)1273 napi_status NapiUtils::GetValue(napi_env env, napi_value in, SessionToken& out)
1274 {
1275 napi_value value {};
1276 auto status = napi_get_named_property(env, in, "sessionId", &value);
1277 CHECK_RETURN(status == napi_ok, "get SessionToken sessionId failed", status);
1278 status = GetValue(env, value, out.sessionId);
1279 CHECK_RETURN(status == napi_ok, "get SessionToken sessionId value failed", status);
1280
1281 bool hasPid = false;
1282 NAPI_CALL_BASE(env, napi_has_named_property(env, in, "pid", &hasPid), napi_invalid_arg);
1283 if (hasPid) {
1284 status = napi_get_named_property(env, in, "pid", &value);
1285 CHECK_RETURN(status == napi_ok, "get SessionToken pid failed", status);
1286 status = GetValue(env, value, out.pid);
1287 CHECK_RETURN(status == napi_ok, "get SessionToken pid value failed", status);
1288 } else {
1289 out.pid = 0;
1290 }
1291
1292 bool hasUid = false;
1293 NAPI_CALL_BASE(env, napi_has_named_property(env, in, "uid", &hasUid), napi_invalid_arg);
1294 if (hasUid) {
1295 status = napi_get_named_property(env, in, "uid", &value);
1296 CHECK_RETURN(status == napi_ok, "get SessionToken uid failed", status);
1297 status = GetValue(env, value, out.pid);
1298 CHECK_RETURN(status == napi_ok, "get SessionToken uid value failed", status);
1299 } else {
1300 out.uid = 0;
1301 }
1302 return napi_ok;
1303 }
1304
GetValue(napi_env env, napi_value in, AudioStandard::DeviceRole& out)1305 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AudioStandard::DeviceRole& out)
1306 {
1307 int32_t deviceRole;
1308 auto status = GetValue(env, in, deviceRole);
1309 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceRole failed", status);
1310 out = static_cast<AudioStandard::DeviceRole>(deviceRole);
1311 return napi_ok;
1312 }
1313
GetValue(napi_env env, napi_value in, AudioStandard::DeviceType& out)1314 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AudioStandard::DeviceType& out)
1315 {
1316 int32_t deviceType;
1317 auto status = GetValue(env, in, deviceType);
1318 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceType failed", status);
1319 out = static_cast<AudioStandard::DeviceType>(deviceType);
1320 return napi_ok;
1321 }
1322
GetSampleRate(napi_env env, napi_value in, AudioStandard::AudioSamplingRate& out)1323 napi_status NapiUtils::GetSampleRate(napi_env env, napi_value in, AudioStandard::AudioSamplingRate& out)
1324 {
1325 napi_value value {};
1326 auto status = napi_get_named_property(env, in, "sampleRates", &value);
1327 uint32_t length {};
1328 napi_get_array_length(env, value, &length);
1329 CHECK_RETURN(status == napi_ok, "get array length failed", status);
1330 if (length > 0) {
1331 napi_value element {};
1332 status = napi_get_element(env, value, 0, &element);
1333 CHECK_RETURN((status == napi_ok) && (element != nullptr), "get element failed", status);
1334 int32_t samplingRate;
1335 status = GetValue(env, element, samplingRate);
1336 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor audioStreamInfo_ samplingRate value failed", status);
1337 out = static_cast<AudioStandard::AudioSamplingRate>(samplingRate);
1338 }
1339 return status;
1340 }
1341
GetChannels(napi_env env, napi_value in, AudioStandard::AudioChannel& out)1342 napi_status NapiUtils::GetChannels(napi_env env, napi_value in, AudioStandard::AudioChannel& out)
1343 {
1344 napi_value value {};
1345 auto status = napi_get_named_property(env, in, "channelCounts", &value);
1346 uint32_t length {};
1347 napi_get_array_length(env, value, &length);
1348 CHECK_RETURN(status == napi_ok, "get array length failed", status);
1349 if (length > 0) {
1350 napi_value element {};
1351 status = napi_get_element(env, value, 0, &element);
1352 CHECK_RETURN((status == napi_ok) && (element != nullptr), "get element failed", status);
1353 int32_t channel;
1354 status = GetValue(env, element, channel);
1355 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor audioStreamInfo_ channels value failed", status);
1356 out = static_cast<AudioStandard::AudioChannel>(channel);
1357 }
1358 return status;
1359 }
1360
GetChannelMasks(napi_env env, napi_value in, int32_t& out)1361 napi_status NapiUtils::GetChannelMasks(napi_env env, napi_value in, int32_t& out)
1362 {
1363 napi_value value {};
1364 auto status = napi_get_named_property(env, in, "channelMasks", &value);
1365 uint32_t length {};
1366 napi_get_array_length(env, value, &length);
1367 CHECK_RETURN(status == napi_ok, "get array length failed", status);
1368 if (length > 0) {
1369 napi_value element {};
1370 status = napi_get_element(env, value, 0, &element);
1371 CHECK_RETURN((status == napi_ok) && (element != nullptr), "get element failed", status);
1372 status = GetValue(env, element, out);
1373 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor channelMasks_ value failed", status);
1374 }
1375 return status;
1376 }
1377
GetValue(napi_env env, napi_value in, AudioStandard::AudioDeviceDescriptor& out)1378 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AudioStandard::AudioDeviceDescriptor& out)
1379 {
1380 napi_value value {};
1381 auto status = napi_get_named_property(env, in, "id", &value);
1382 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceId_ failed", status);
1383 status = GetValue(env, value, out.deviceId_);
1384 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceId_ value failed", status);
1385
1386 status = napi_get_named_property(env, in, "name", &value);
1387 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceName_ failed", status);
1388 status = GetValue(env, value, out.deviceName_);
1389 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceName_ value failed", status);
1390
1391 status = napi_get_named_property(env, in, "networkId", &value);
1392 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor networkId failed", status);
1393 status = GetValue(env, value, out.networkId_);
1394 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor networkId value failed", status);
1395
1396 status = napi_get_named_property(env, in, "deviceRole", &value);
1397 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceRole_ failed", status);
1398 status = GetValue(env, value, out.deviceRole_);
1399 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceRole_ value failed", status);
1400
1401 if (napi_get_named_property(env, in, "address", &value) == napi_ok) {
1402 GetValue(env, value, out.macAddress_);
1403 }
1404
1405 if (napi_get_named_property(env, in, "deviceType", &value) == napi_ok) {
1406 GetValue(env, value, out.deviceType_);
1407 }
1408
1409 if (napi_get_named_property(env, in, "interruptGroupId", &value) == napi_ok) {
1410 GetValue(env, value, out.interruptGroupId_);
1411 }
1412
1413 if (napi_get_named_property(env, in, "volumeGroupId", &value) == napi_ok) {
1414 GetValue(env, value, out.volumeGroupId_);
1415 }
1416
1417 AudioStandard::AudioSamplingRate audioSamplingRate;
1418 GetSampleRate(env, in, audioSamplingRate);
1419 out.audioStreamInfo_.samplingRate = {audioSamplingRate};
1420
1421 AudioStandard::AudioChannel audioChannel;
1422 GetChannels(env, in, audioChannel);
1423 out.audioStreamInfo_.channels = {audioChannel};
1424
1425 GetChannelMasks(env, in, out.channelMasks_);
1426 return napi_ok;
1427 }
1428
GetValue(napi_env env, napi_value in, std::vector<AudioStandard::AudioDeviceDescriptor>& out)1429 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<AudioStandard::AudioDeviceDescriptor>& out)
1430 {
1431 uint32_t length {};
1432 auto status = napi_get_array_length(env, in, &length);
1433 CHECK_RETURN(status == napi_ok, "get array length failed", status);
1434 for (uint32_t i = 0; i < length; ++i) {
1435 napi_value element {};
1436 status = napi_get_element(env, in, i, &element);
1437 CHECK_RETURN((status == napi_ok) && (element != nullptr), "get element failed", status);
1438 AudioStandard::AudioDeviceDescriptor descriptor;
1439 status = GetValue(env, element, descriptor);
1440 out.push_back(descriptor);
1441 }
1442 return napi_ok;
1443 }
1444
GetOptionalString(napi_env env, napi_value in, DeviceInfo& out)1445 napi_status NapiUtils::GetOptionalString(napi_env env, napi_value in, DeviceInfo& out)
1446 {
1447 napi_value value {};
1448 bool hasIpAddress = false;
1449 napi_has_named_property(env, in, "ipAddress", &hasIpAddress);
1450 if (hasIpAddress) {
1451 napi_status status = napi_get_named_property(env, in, "ipAddress", &value);
1452 CHECK_RETURN(status == napi_ok, "get DeviceInfo ipAddress failed", status);
1453
1454 napi_valuetype type = napi_undefined;
1455 status = napi_typeof(env, value, &type);
1456 CHECK_RETURN((status == napi_ok) && type == napi_string, "invalid typ for ipAddress", napi_invalid_arg);
1457
1458 size_t maxLen = STR_MAX_LENGTH;
1459 status = napi_get_value_string_utf8(env, value, nullptr, 0, &maxLen);
1460 if (maxLen == 0) {
1461 out.ipAddress_ = "";
1462 } else {
1463 if (maxLen < 0 || maxLen >= STR_MAX_LENGTH) {
1464 return napi_invalid_arg;
1465 }
1466 char buf[STR_MAX_LENGTH + STR_TAIL_LENGTH] {};
1467 size_t len = 0;
1468 status = napi_get_value_string_utf8(env, value, buf, maxLen + STR_TAIL_LENGTH, &len);
1469 if (status == napi_ok) {
1470 out.ipAddress_ = std::string(buf);
1471 }
1472 }
1473 CHECK_RETURN(status == napi_ok, "get DeviceInfo ipAddress value failed", status);
1474 } else {
1475 out.ipAddress_ = "";
1476 }
1477 return napi_ok;
1478 }
1479
1480 /* napi_value -> DeviceInfo */
GetValue(napi_env env, napi_value in, DeviceInfo& out)1481 napi_status NapiUtils::GetValue(napi_env env, napi_value in, DeviceInfo& out)
1482 {
1483 napi_value value {};
1484 auto status = napi_get_named_property(env, in, "castCategory", &value);
1485 CHECK_RETURN(status == napi_ok, "get DeviceInfo castCategory_ failed", status);
1486 status = GetValue(env, value, out.castCategory_);
1487 CHECK_RETURN(status == napi_ok, "get DeviceInfo castCategory_ value failed", status);
1488 status = napi_get_named_property(env, in, "deviceId", &value);
1489 CHECK_RETURN(status == napi_ok, "get DeviceInfo deviceId_ failed", status);
1490 status = GetValue(env, value, out.deviceId_);
1491 CHECK_RETURN(status == napi_ok, "get DeviceInfo deviceId_ value failed", status);
1492 status = napi_get_named_property(env, in, "manufacturer", &value);
1493 CHECK_RETURN(status == napi_ok, "get DeviceInfo manufacturer_ failed", status);
1494 status = GetValue(env, value, out.manufacturer_);
1495 CHECK_RETURN(status == napi_ok, "get DeviceInfo manufacturer_ value failed", status);
1496 status = napi_get_named_property(env, in, "modelName", &value);
1497 CHECK_RETURN(status == napi_ok, "get DeviceInfo modelName_ failed", status);
1498 status = GetValue(env, value, out.modelName_);
1499 CHECK_RETURN(status == napi_ok, "get DeviceInfo modelName_ value failed", status);
1500 status = napi_get_named_property(env, in, "deviceName", &value);
1501 CHECK_RETURN(status == napi_ok, "get DeviceInfo deviceName_ failed", status);
1502 status = GetValue(env, value, out.deviceName_);
1503 CHECK_RETURN(status == napi_ok, "get DeviceInfo deviceName_ value failed", status);
1504 status = napi_get_named_property(env, in, "deviceType", &value);
1505 CHECK_RETURN(status == napi_ok, "get DeviceInfo deviceType_ failed", status);
1506 status = GetValue(env, value, out.deviceType_);
1507 CHECK_RETURN(status == napi_ok, "get DeviceInfo deviceType_ value failed", status);
1508 CHECK_RETURN(GetOptionalString(env, in, out) == napi_ok, "get DeviceInfo ip address value failed", status);
1509
1510 bool hasKey = false;
1511 napi_has_named_property(env, in, "providerId", &hasKey);
1512 if (hasKey) {
1513 status = napi_get_named_property(env, in, "providerId", &value);
1514 CHECK_RETURN(status == napi_ok, "get DeviceInfo providerId failed", status);
1515 status = GetValue(env, value, out.providerId_);
1516 CHECK_RETURN(status == napi_ok, "get DeviceInfo providerId value failed", status);
1517 } else {
1518 out.providerId_ = 0;
1519 }
1520
1521 status = ProcessDeviceInfoParams(env, in, out);
1522 CHECK_RETURN(status == napi_ok, "get DeviceInfo ProcessDeviceInfoParams failed", status);
1523
1524 return napi_ok;
1525 }
1526
ProcessDeviceInfoParams(napi_env env, napi_value in, DeviceInfo& out)1527 napi_status NapiUtils::ProcessDeviceInfoParams(napi_env env, napi_value in, DeviceInfo& out)
1528 {
1529 napi_value value {};
1530 bool hasKey = false;
1531 napi_status status = napi_ok;
1532 napi_has_named_property(env, in, "supportedProtocols", &hasKey);
1533 if (hasKey) {
1534 status = napi_get_named_property(env, in, "supportedProtocols", &value);
1535 CHECK_RETURN(status == napi_ok, "get DeviceInfo supportedProtocols failed", status);
1536 status = GetValue(env, value, out.supportedProtocols_);
1537 CHECK_RETURN(status == napi_ok, "get DeviceInfo supportedProtocols value failed", status);
1538 } else {
1539 out.supportedProtocols_ = ProtocolType::TYPE_CAST_PLUS_STREAM;
1540 }
1541 napi_has_named_property(env, in, "authenticationStatus", &hasKey);
1542 if (hasKey) {
1543 status = napi_get_named_property(env, in, "authenticationStatus", &value);
1544 CHECK_RETURN(status == napi_ok, "get DeviceInfo authenticationStatus failed", status);
1545 status = GetValue(env, value, out.authenticationStatus_);
1546 CHECK_RETURN(status == napi_ok, "get DeviceInfo authenticationStatus value failed", status);
1547 } else {
1548 out.authenticationStatus_ = 0;
1549 }
1550 napi_has_named_property(env, in, "supportedDrmCapabilities", &hasKey);
1551 if (hasKey) {
1552 status = napi_get_named_property(env, in, "supportedDrmCapabilities", &value);
1553 CHECK_RETURN(status == napi_ok, "get DeviceInfo supportedDrmCapabilities failed", status);
1554 status = GetValue(env, value, out.supportedDrmCapabilities_);
1555 CHECK_RETURN(status == napi_ok, "get DeviceInfo supportedDrmCapabilities value failed", status);
1556 }
1557 napi_has_named_property(env, in, "isLegacy", &hasKey);
1558 if (hasKey) {
1559 status = napi_get_named_property(env, in, "isLegacy", &value);
1560 CHECK_RETURN(status == napi_ok, "get DeviceInfo isLegacy failed", status);
1561 status = GetValue(env, value, out.isLegacy_);
1562 CHECK_RETURN(status == napi_ok, "get DeviceInfo isLegacy value failed", status);
1563 } else {
1564 out.isLegacy_ = false;
1565 }
1566 napi_has_named_property(env, in, "mediumTypes", &hasKey);
1567 if (hasKey) {
1568 status = napi_get_named_property(env, in, "mediumTypes", &value);
1569 CHECK_RETURN(status == napi_ok, "get DeviceInfo mediumTypes failed", status);
1570 status = GetValue(env, value, out.mediumTypes_);
1571 CHECK_RETURN(status == napi_ok, "get DeviceInfo mediumTypes value failed", status);
1572 } else {
1573 out.mediumTypes_ = COAP;
1574 }
1575 return napi_ok;
1576 }
1577
1578 /* napi_value -> OutputDeviceInfo */
GetValue(napi_env env, napi_value in, OutputDeviceInfo& out)1579 napi_status NapiUtils::GetValue(napi_env env, napi_value in, OutputDeviceInfo& out)
1580 {
1581 napi_value devices = nullptr;
1582 bool hasProperty = false;
1583 NAPI_CALL_BASE(env, napi_has_named_property(env, in, "devices", &hasProperty), napi_invalid_arg);
1584 if (!hasProperty) {
1585 SLOGE("devices is not exit in OutputDeviceInfo");
1586 return napi_invalid_arg;
1587 }
1588 NAPI_CALL_BASE(env, napi_get_named_property(env, in, "devices", &devices), napi_invalid_arg);
1589 bool isArray = false;
1590 NAPI_CALL_BASE(env, napi_is_array(env, devices, &isArray), napi_invalid_arg);
1591 if (!isArray) {
1592 SLOGE("devices is not array");
1593 return napi_invalid_arg;
1594 }
1595
1596 uint32_t arrLen = 0;
1597 NAPI_CALL_BASE(env, napi_get_array_length(env, devices, &arrLen), napi_invalid_arg);
1598 if (arrLen == 0) {
1599 SLOGE("devices len is invalid");
1600 return napi_invalid_arg;
1601 }
1602
1603 for (uint32_t i = 0; i < arrLen; i++) {
1604 napi_value item = nullptr;
1605 NAPI_CALL_BASE(env, napi_get_element(env, devices, i, &item), napi_invalid_arg);
1606 DeviceInfo deviceInfo;
1607 napi_status status = GetValue(env, item, deviceInfo);
1608 CHECK_RETURN(status == napi_ok, "not is device info", status);
1609 out.deviceInfos_.push_back(deviceInfo);
1610 }
1611 return napi_ok;
1612 }
1613
1614 /* napi_value -> MediaInfoHolder */
GetValue(napi_env env, napi_value in, MediaInfoHolder& out)1615 napi_status NapiUtils::GetValue(napi_env env, napi_value in, MediaInfoHolder& out)
1616 {
1617 return NapiMediaInfoHolder::GetValue(env, in, out);
1618 }
1619
1620 /* napi_value <-> MediaInfoHolder */
SetValue(napi_env env, const MediaInfoHolder& in, napi_value& out)1621 napi_status NapiUtils::SetValue(napi_env env, const MediaInfoHolder& in, napi_value& out)
1622 {
1623 return NapiMediaInfoHolder::SetValue(env, in, out);
1624 }
1625
1626 /* napi_value -> MediaInfo */
GetValue(napi_env env, napi_value in, MediaInfo& out)1627 napi_status NapiUtils::GetValue(napi_env env, napi_value in, MediaInfo& out)
1628 {
1629 napi_value value {};
1630 auto status = napi_get_named_property(env, in, "mediaId", &value);
1631 CHECK_RETURN(status == napi_ok, "get mediaId failed", status);
1632 status = GetValue(env, value, out.mediaId_);
1633 CHECK_RETURN(status == napi_ok, "get mediaId value failed", status);
1634
1635 status = napi_get_named_property(env, in, "mediaUrl", &value);
1636 CHECK_RETURN(status == napi_ok, "get mediaUrl failed", status);
1637 status = GetValue(env, value, out.mediaUrl_);
1638 CHECK_RETURN(status == napi_ok, "get mediaUrl value failed", status);
1639
1640 bool hasStartPosition = false;
1641 napi_has_named_property(env, in, "startPosition", &hasStartPosition);
1642 if (hasStartPosition) {
1643 status = napi_get_named_property(env, in, "startPosition", &value);
1644 CHECK_RETURN(status == napi_ok, "get MediaInfo startPosition failed", status);
1645 status = GetValue(env, value, out.startPosition_);
1646 CHECK_RETURN(status == napi_ok, "get MediaInfo startPosition value failed", status);
1647 } else {
1648 out.startPosition_ = -1;
1649 }
1650 return napi_ok;
1651 }
1652
1653 /* napi_value <- MediaInfo */
SetValue(napi_env env, const MediaInfo& in, napi_value& out)1654 napi_status NapiUtils::SetValue(napi_env env, const MediaInfo& in, napi_value& out)
1655 {
1656 napi_status status = napi_create_object(env, &out);
1657 CHECK_RETURN((status == napi_ok) && (out != nullptr), "create object failed", status);
1658
1659 napi_value property = nullptr;
1660 status = SetValue(env, in.mediaId_, property);
1661 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1662 status = napi_set_named_property(env, out, "mediaId", property);
1663 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1664
1665 status = SetValue(env, in.mediaUrl_, property);
1666 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1667 status = napi_set_named_property(env, out, "mediaUrl", property);
1668 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1669
1670 if (in.startPosition_ != -1) {
1671 status = SetValue(env, in.startPosition_, property);
1672 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1673 status = napi_set_named_property(env, out, "mediaInfo", property);
1674 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1675 }
1676
1677 return napi_ok;
1678 }
1679
1680 /* napi_value -> AVFileDescriptor */
GetValue(napi_env env, napi_value in, AVFileDescriptor& out)1681 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AVFileDescriptor& out)
1682 {
1683 napi_value value {};
1684 auto status = napi_ok;
1685 bool hasFd = false;
1686 napi_has_named_property(env, in, "fd", &hasFd);
1687 if (hasFd) {
1688 status = napi_get_named_property(env, in, "fd", &value);
1689 CHECK_RETURN(status == napi_ok, "get fd failed", status);
1690 status = GetValue(env, value, out.fd_);
1691 CHECK_RETURN(status == napi_ok, "get fd value failed", status);
1692 } else {
1693 out.fd_ = 0;
1694 }
1695
1696 bool hasOffset = false;
1697 napi_has_named_property(env, in, "offset", &hasOffset);
1698 if (hasOffset) {
1699 status = napi_get_named_property(env, in, "offset", &value);
1700 CHECK_RETURN(status == napi_ok, "get offset failed", status);
1701 status = GetValue(env, value, out.offset_);
1702 CHECK_RETURN(status == napi_ok, "get offset value failed", status);
1703 } else {
1704 out.offset_ = 0;
1705 }
1706
1707 bool hasLength = false;
1708 napi_has_named_property(env, in, "length", &hasLength);
1709 if (hasLength) {
1710 status = napi_get_named_property(env, in, "length", &value);
1711 CHECK_RETURN(status == napi_ok, "get length failed", status);
1712 status = GetValue(env, value, out.length_);
1713 CHECK_RETURN(status == napi_ok, "get length value failed", status);
1714 } else {
1715 out.length_ = -1;
1716 }
1717 return napi_ok;
1718 }
1719
1720 /* napi_value <- AVFileDescriptor */
SetValue(napi_env env, const AVFileDescriptor& in, napi_value& out)1721 napi_status NapiUtils::SetValue(napi_env env, const AVFileDescriptor& in, napi_value& out)
1722 {
1723 napi_status status = napi_create_object(env, &out);
1724 CHECK_RETURN((status == napi_ok) && (out != nullptr), "create object failed", status);
1725
1726 napi_value property = nullptr;
1727 status = SetValue(env, in.fd_, property);
1728 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1729 status = napi_set_named_property(env, out, "fd", property);
1730 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1731
1732 if (in.offset_ != 0) {
1733 status = SetValue(env, in.offset_, property);
1734 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1735 status = napi_set_named_property(env, out, "offset", property);
1736 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1737 }
1738
1739 if (in.length_ != -1) {
1740 status = SetValue(env, in.length_, property);
1741 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1742 status = napi_set_named_property(env, out, "length", property);
1743 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1744 }
1745 return napi_ok;
1746 }
1747
ThrowError(napi_env env, const char* napiMessage, int32_t napiCode)1748 napi_status NapiUtils::ThrowError(napi_env env, const char* napiMessage, int32_t napiCode)
1749 {
1750 napi_value message = nullptr;
1751 napi_value code = nullptr;
1752 napi_value result = nullptr;
1753 napi_create_string_utf8(env, napiMessage, NAPI_AUTO_LENGTH, &message);
1754 napi_create_error(env, nullptr, message, &result);
1755 napi_create_int32(env, napiCode, &code);
1756 napi_set_named_property(env, result, "code", code);
1757 napi_throw(env, result);
1758 return napi_ok;
1759 }
1760 }
1761