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
DoDownloadInCommon(std::shared_ptr<Media::PixelMap> & pixelMap,const std::string uri)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 /* napi_value <-> NapiAVCastPickerOptions */
GetValue(napi_env env,napi_value in,NapiAVCastPickerOptions & out)774 napi_status NapiUtils::GetValue(napi_env env, napi_value in, NapiAVCastPickerOptions& out)
775 {
776 napi_value value {};
777 auto status = napi_get_named_property(env, in, "sessionType", &value);
778 CHECK_RETURN(status == napi_ok, "get sessionType failed", status);
779 status = GetValue(env, value, out.sessionType);
780 CHECK_RETURN(status == napi_ok, "get sessionType value failed", status);
781
782 return napi_ok;
783 }
784
785 template <typename T>
TypedArray2Vector(uint8_t * data,size_t length,napi_typedarray_type type,std::vector<T> & out)786 void TypedArray2Vector(uint8_t* data, size_t length, napi_typedarray_type type, std::vector<T>& out)
787 {
788 auto convert = [&out](auto* data, size_t elements) {
789 for (size_t index = 0; index < elements; index++) {
790 out.push_back(static_cast<T>(data[index]));
791 }
792 };
793
794 switch (type) {
795 case napi_int8_array:
796 convert(reinterpret_cast<int8_t*>(data), length);
797 break;
798 case napi_uint8_array:
799 convert(data, length);
800 break;
801 case napi_uint8_clamped_array:
802 convert(data, length);
803 break;
804 case napi_int16_array:
805 convert(reinterpret_cast<int16_t*>(data), length / sizeof(int16_t));
806 break;
807 case napi_uint16_array:
808 convert(reinterpret_cast<uint16_t*>(data), length / sizeof(uint16_t));
809 break;
810 case napi_int32_array:
811 convert(reinterpret_cast<int32_t*>(data), length / sizeof(int32_t));
812 break;
813 case napi_uint32_array:
814 convert(reinterpret_cast<uint32_t*>(data), length / sizeof(uint32_t));
815 break;
816 case napi_float32_array:
817 convert(reinterpret_cast<float*>(data), length / sizeof(float));
818 break;
819 case napi_float64_array:
820 convert(reinterpret_cast<double*>(data), length / sizeof(double));
821 break;
822 case napi_bigint64_array:
823 convert(reinterpret_cast<int64_t*>(data), length / sizeof(int64_t));
824 break;
825 case napi_biguint64_array:
826 convert(reinterpret_cast<uint64_t*>(data), length / sizeof(uint64_t));
827 break;
828 default:
829 CHECK_RETURN_VOID(false, "[FATAL] invalid napi_typedarray_type!");
830 }
831 }
832
833 /* napi_value <-> std::vector<int32_t> */
GetValue(napi_env env,napi_value in,std::vector<int32_t> & out)834 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<int32_t>& out)
835 {
836 out.clear();
837 SLOGD("napi_value -> std::vector<int32_t> ");
838 napi_typedarray_type type = napi_biguint64_array;
839 size_t length = 0;
840 napi_value buffer = nullptr;
841 size_t offset = 0;
842 uint8_t* data = nullptr;
843 napi_status status = napi_get_typedarray_info(env, in, &type, &length,
844 reinterpret_cast<void**>(&data), &buffer, &offset);
845 SLOGD("array type=%{public}d length=%{public}d offset=%{public}d", static_cast<int>(type), static_cast<int>(length),
846 static_cast<int>(offset));
847 CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
848 CHECK_RETURN(type <= napi_int32_array, "is not int32 supported typed array!", napi_invalid_arg);
849 CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
850 TypedArray2Vector<int32_t>(data, length, type, out);
851 return status;
852 }
853
SetValue(napi_env env,const std::vector<int32_t> & in,napi_value & out)854 napi_status NapiUtils::SetValue(napi_env env, const std::vector<int32_t>& in, napi_value& out)
855 {
856 SLOGD("napi_value <- std::vector<int32_t> ");
857 size_t bytes = in.size() * sizeof(int32_t);
858 CHECK_RETURN(bytes > 0, "invalid std::vector<int32_t>", napi_invalid_arg);
859 void* data = nullptr;
860 napi_value buffer = nullptr;
861 napi_status status = napi_create_arraybuffer(env, bytes, &data, &buffer);
862 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
863
864 if (memcpy_s(data, bytes, in.data(), bytes) != EOK) {
865 SLOGE("memcpy_s not EOK");
866 return napi_invalid_arg;
867 }
868 status = napi_create_typedarray(env, napi_int32_array, in.size(), buffer, 0, &out);
869 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
870 return status;
871 }
872
873 /* napi_value <-> std::vector<uint32_t> */
GetValue(napi_env env,napi_value in,std::vector<uint32_t> & out)874 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<uint32_t>& out)
875 {
876 out.clear();
877 SLOGD("napi_value -> std::vector<uint32_t> ");
878 napi_typedarray_type type = napi_biguint64_array;
879 size_t length = 0;
880 napi_value buffer = nullptr;
881 size_t offset = 0;
882 uint8_t* data = nullptr;
883 napi_status status = napi_get_typedarray_info(env, in, &type, &length,
884 reinterpret_cast<void**>(&data), &buffer, &offset);
885 SLOGD("napi_get_typedarray_info type=%{public}d", static_cast<int>(type));
886 CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
887 CHECK_RETURN((type <= napi_uint16_array) || (type == napi_uint32_array), "invalid type!", napi_invalid_arg);
888 CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
889 TypedArray2Vector<uint32_t>(data, length, type, out);
890 return status;
891 }
892
SetValue(napi_env env,const std::vector<uint32_t> & in,napi_value & out)893 napi_status NapiUtils::SetValue(napi_env env, const std::vector<uint32_t>& in, napi_value& out)
894 {
895 SLOGD("napi_value <- std::vector<uint32_t> ");
896 size_t bytes = in.size() * sizeof(uint32_t);
897 CHECK_RETURN(bytes > 0, "invalid std::vector<uint32_t>", napi_invalid_arg);
898 void* data = nullptr;
899 napi_value buffer = nullptr;
900 napi_status status = napi_create_arraybuffer(env, bytes, &data, &buffer);
901 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
902
903 if (memcpy_s(data, bytes, in.data(), bytes) != EOK) {
904 SLOGE("memcpy_s not EOK");
905 return napi_invalid_arg;
906 }
907 status = napi_create_typedarray(env, napi_uint32_array, in.size(), buffer, 0, &out);
908 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
909 return status;
910 }
911
912 /* napi_value <-> std::vector<int64_t> */
GetValue(napi_env env,napi_value in,std::vector<int64_t> & out)913 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<int64_t>& out)
914 {
915 out.clear();
916 SLOGD("napi_value -> std::vector<int64_t> ");
917 napi_typedarray_type type = napi_biguint64_array;
918 size_t length = 0;
919 napi_value buffer = nullptr;
920 size_t offset = 0;
921 uint8_t* data = nullptr;
922 napi_status status = napi_get_typedarray_info(env, in, &type, &length,
923 reinterpret_cast<void**>(&data), &buffer, &offset);
924 SLOGD("array type=%{public}d length=%{public}d offset=%{public}d", static_cast<int>(type), static_cast<int>(length),
925 static_cast<int>(offset));
926 CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
927 CHECK_RETURN((type <= napi_uint32_array) || (type == napi_bigint64_array), "invalid type!", napi_invalid_arg);
928 CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
929 TypedArray2Vector<int64_t>(data, length, type, out);
930 return status;
931 }
932
SetValue(napi_env env,const std::vector<int64_t> & in,napi_value & out)933 napi_status NapiUtils::SetValue(napi_env env, const std::vector<int64_t>& in, napi_value& out)
934 {
935 SLOGD("napi_value <- std::vector<int64_t> ");
936 size_t bytes = in.size() * sizeof(int64_t);
937 CHECK_RETURN(bytes > 0, "invalid std::vector<uint32_t>", napi_invalid_arg);
938 void* data = nullptr;
939 napi_value buffer = nullptr;
940 napi_status status = napi_create_arraybuffer(env, bytes, &data, &buffer);
941 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
942
943 if (memcpy_s(data, bytes, in.data(), bytes) != EOK) {
944 SLOGE("memcpy_s not EOK");
945 return napi_invalid_arg;
946 }
947 status = napi_create_typedarray(env, napi_bigint64_array, in.size(), buffer, 0, &out);
948 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
949 return status;
950 }
951 /* napi_value <-> std::vector<double> */
GetValue(napi_env env,napi_value in,std::vector<double> & out)952 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<double>& out)
953 {
954 out.clear();
955 bool isTypedArray = false;
956 napi_status status = napi_is_typedarray(env, in, &isTypedArray);
957 SLOGD("napi_value -> std::vector<double> input %{public}s a TypedArray", isTypedArray ? "is" : "is not");
958 CHECK_RETURN((status == napi_ok), "napi_is_typedarray failed!", status);
959 if (isTypedArray) {
960 SLOGD("napi_value -> std::vector<double> ");
961 napi_typedarray_type type = napi_biguint64_array;
962 size_t length = 0;
963 napi_value buffer = nullptr;
964 size_t offset = 0;
965 uint8_t* data = nullptr;
966 status = napi_get_typedarray_info(env, in, &type, &length, reinterpret_cast<void**>(&data), &buffer, &offset);
967 SLOGD("napi_get_typedarray_info status=%{public}d type=%{public}d", status, static_cast<int>(type));
968 CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
969 CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
970 TypedArray2Vector<double>(data, length, type, out);
971 } else {
972 bool isArray = false;
973 status = napi_is_array(env, in, &isArray);
974 SLOGD("napi_value -> std::vector<double> input %{public}s an Array", isArray ? "is" : "is not");
975 CHECK_RETURN((status == napi_ok) && isArray, "invalid data!", napi_invalid_arg);
976 uint32_t length = 0;
977 status = napi_get_array_length(env, in, &length);
978 CHECK_RETURN((status == napi_ok) && (length > 0), "invalid data!", napi_invalid_arg);
979 for (uint32_t i = 0; i < length; ++i) {
980 napi_value item = nullptr;
981 status = napi_get_element(env, in, i, &item);
982 CHECK_RETURN((item != nullptr) && (status == napi_ok), "no element", napi_invalid_arg);
983 double vi = 0.0f;
984 status = napi_get_value_double(env, item, &vi);
985 CHECK_RETURN(status == napi_ok, "element not a double", napi_invalid_arg);
986 out.push_back(vi);
987 }
988 }
989 return status;
990 }
991
SetValue(napi_env env,const std::vector<double> & in,napi_value & out)992 napi_status NapiUtils::SetValue(napi_env env, const std::vector<double>& in, napi_value& out)
993 {
994 SLOGD("napi_value <- std::vector<double> ");
995 (void)(env);
996 (void)(in);
997 (void)(out);
998 CHECK_RETURN(false, "std::vector<double> to napi_value, unsupported!", napi_invalid_arg);
999 return napi_invalid_arg;
1000 }
1001
1002 /* std::vector<AVSessionDescriptor> <-> napi_value */
SetValue(napi_env env,const std::vector<AVSessionDescriptor> & in,napi_value & out)1003 napi_status NapiUtils::SetValue(napi_env env, const std::vector<AVSessionDescriptor>& in, napi_value& out)
1004 {
1005 SLOGD("napi_value <- std::vector<AVSessionDescriptor> %{public}d", static_cast<int>(in.size()));
1006 napi_status status = napi_create_array_with_length(env, in.size(), &out);
1007 CHECK_RETURN((status == napi_ok), "create_array failed!", status);
1008 int index = 0;
1009 for (const auto& item : in) {
1010 napi_value entry = nullptr;
1011 SetValue(env, item, entry);
1012 napi_set_element(env, out, index++, entry);
1013 }
1014 return status;
1015 }
1016
1017 /* std::vector<AVQueueInfo> <-> napi_value */
SetValue(napi_env env,const std::vector<AVQueueInfo> & in,napi_value & out)1018 napi_status NapiUtils::SetValue(napi_env env, const std::vector<AVQueueInfo>& in, napi_value& out)
1019 {
1020 SLOGD("napi_value <- std::vector<AVQueueInfo> %{public}d", static_cast<int>(in.size()));
1021 napi_status status = napi_create_array_with_length(env, in.size(), &out);
1022 CHECK_RETURN((status == napi_ok), "create_array failed!", status);
1023 int index = 0;
1024 for (const auto& item : in) {
1025 napi_value entry = nullptr;
1026 SetValue(env, item, entry);
1027 napi_set_element(env, out, index++, entry);
1028 }
1029 return status;
1030 }
1031
1032 /* napi_value <-> DeviceInfo */
SetValue(napi_env env,const DeviceInfo & in,napi_value & out)1033 napi_status NapiUtils::SetValue(napi_env env, const DeviceInfo& in, napi_value& out)
1034 {
1035 napi_status status = napi_create_object(env, &out);
1036 CHECK_RETURN((status == napi_ok) && (out != nullptr), "create object failed", status);
1037 napi_value property = nullptr;
1038 status = SetValue(env, in.castCategory_, property);
1039 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1040 status = napi_set_named_property(env, out, "castCategory", property);
1041 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1042
1043 status = SetValue(env, in.deviceId_, property);
1044 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1045 status = napi_set_named_property(env, out, "deviceId", property);
1046 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1047
1048 status = SetValue(env, in.manufacturer_, property);
1049 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1050 status = napi_set_named_property(env, out, "manufacturer", property);
1051 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1052
1053 status = SetValue(env, in.modelName_, property);
1054 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1055 status = napi_set_named_property(env, out, "modelName", property);
1056 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1057
1058 status = SetValue(env, in.deviceName_, property);
1059 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1060 status = napi_set_named_property(env, out, "deviceName", property);
1061 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1062
1063 status = SetValue(env, in.deviceType_, property);
1064 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1065 status = napi_set_named_property(env, out, "deviceType", property);
1066 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1067
1068 status = SetValue(env, in.ipAddress_, property);
1069 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1070 status = napi_set_named_property(env, out, "ipAddress", property);
1071 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1072
1073 status = SetValue(env, in.providerId_, property);
1074 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1075 status = napi_set_named_property(env, out, "providerId", property);
1076 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1077
1078 status = SetValue(env, in.supportedProtocols_, property);
1079 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1080 status = napi_set_named_property(env, out, "supportedProtocols", property);
1081 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1082
1083 status = SetValue(env, in.authenticationStatus_, property);
1084 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1085 status = napi_set_named_property(env, out, "authenticationStatus", property);
1086 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1087
1088 status = SetValue(env, in.supportedDrmCapabilities_, property);
1089 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1090 status = napi_set_named_property(env, out, "supportedDrmCapabilities", property);
1091 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1092
1093 status = SetValue(env, in.isLegacy_, property);
1094 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1095 status = napi_set_named_property(env, out, "isLegacy", property);
1096 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1097
1098 status = SetValue(env, in.mediumTypes_, property);
1099 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1100 status = napi_set_named_property(env, out, "mediumTypes", property);
1101 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1102 return napi_ok;
1103 }
1104
1105 /* OutputDeviceInfo <-> napi_value */
SetValue(napi_env env,const OutputDeviceInfo & in,napi_value & out)1106 napi_status NapiUtils::SetValue(napi_env env, const OutputDeviceInfo& in, napi_value& out)
1107 {
1108 SLOGD("napi_value <- OutputDeviceInfo");
1109 napi_value temp {};
1110 napi_create_object(env, &out);
1111
1112 napi_status status = napi_create_array_with_length(env, in.deviceInfos_.size(), &temp);
1113 CHECK_RETURN((status == napi_ok), "create_array failed!", status);
1114 int index = 0;
1115 SLOGD("The length of deviceInfos is %{public}d", static_cast<int32_t>(in.deviceInfos_.size()));
1116 for (const auto& item : in.deviceInfos_) {
1117 napi_value entry = nullptr;
1118 status = SetValue(env, item, entry);
1119 CHECK_RETURN((status == napi_ok) && (entry != nullptr), "create array failed!", status);
1120 napi_set_element(env, temp, index++, entry);
1121 }
1122 status = napi_set_named_property(env, out, "devices", temp);
1123 CHECK_RETURN((status == napi_ok), "set named property devices failed", status);
1124 return status;
1125 }
1126
Unwrap(napi_env env,napi_value in,void ** out,napi_value constructor)1127 napi_status NapiUtils::Unwrap(napi_env env, napi_value in, void** out, napi_value constructor)
1128 {
1129 if (constructor != nullptr) {
1130 bool isInstance = false;
1131 napi_instanceof(env, in, constructor, &isInstance);
1132 if (!isInstance) {
1133 SLOGE("not a instance of *");
1134 return napi_invalid_arg;
1135 }
1136 }
1137 return napi_unwrap(env, in, out);
1138 }
1139
Equals(napi_env env,napi_value value,napi_ref copy)1140 bool NapiUtils::Equals(napi_env env, napi_value value, napi_ref copy)
1141 {
1142 if (copy == nullptr) {
1143 return (value == nullptr);
1144 }
1145
1146 napi_value copyValue = nullptr;
1147 napi_get_reference_value(env, copy, ©Value);
1148 CHECK_RETURN((napi_get_reference_value(env, copy, ©Value) == napi_ok),
1149 "get ref value failed", napi_generic_failure);
1150 bool isEquals = false;
1151 CHECK_RETURN(napi_strict_equals(env, value, copyValue, &isEquals) == napi_ok,
1152 "get equals result failed", napi_generic_failure);
1153 return isEquals;
1154 }
1155
TypeCheck(napi_env env,napi_value value,napi_valuetype expectType)1156 bool NapiUtils::TypeCheck(napi_env env, napi_value value, napi_valuetype expectType)
1157 {
1158 napi_valuetype valueType = napi_undefined;
1159 napi_status status = napi_typeof(env, value, &valueType);
1160 if (status != napi_ok || valueType != expectType) {
1161 return false;
1162 }
1163 return true;
1164 }
1165
GetUndefinedValue(napi_env env)1166 napi_value NapiUtils::GetUndefinedValue(napi_env env)
1167 {
1168 napi_value result {};
1169 napi_get_undefined(env, &result);
1170 return result;
1171 }
1172
GetPropertyNames(napi_env env,napi_value in,std::vector<std::string> & out)1173 napi_status NapiUtils::GetPropertyNames(napi_env env, napi_value in, std::vector<std::string>& out)
1174 {
1175 napi_value names {};
1176 NAPI_CALL_BASE(env, napi_get_property_names(env, in, &names), napi_generic_failure);
1177 uint32_t length = 0;
1178 NAPI_CALL_BASE(env, napi_get_array_length(env, names, &length), napi_generic_failure);
1179
1180 for (uint32_t index = 0; index < length; ++index) {
1181 napi_value name {};
1182 std::string nameString;
1183 if (napi_get_element(env, names, index, &name) != napi_ok) {
1184 continue;
1185 }
1186 if (GetValue(env, name, nameString) != napi_ok) {
1187 continue;
1188 }
1189 out.push_back(nameString);
1190 }
1191
1192 return napi_ok;
1193 }
1194
GetDateValue(napi_env env,napi_value value,double & result)1195 napi_status NapiUtils::GetDateValue(napi_env env, napi_value value, double& result)
1196 {
1197 CHECK_RETURN(env != nullptr, "env is nullptr", napi_invalid_arg);
1198 CHECK_RETURN(value != nullptr, "value is nullptr", napi_invalid_arg);
1199
1200 SLOGD("GetDateValue in");
1201 bool isDate = false;
1202 napi_is_date(env, value, &isDate);
1203 if (isDate) {
1204 napi_status status = napi_get_date_value(env, value, &result);
1205 if (status != napi_ok) {
1206 SLOGE("get date error");
1207 }
1208 SLOGD("GetDateValue out");
1209 return napi_ok;
1210 } else {
1211 SLOGE("value is not date type");
1212 return napi_date_expected;
1213 }
1214 }
1215
SetDateValue(napi_env env,double time,napi_value & result)1216 napi_status NapiUtils::SetDateValue(napi_env env, double time, napi_value& result)
1217 {
1218 CHECK_RETURN(env != nullptr, "env is nullptr", napi_invalid_arg);
1219
1220 SLOGD("SetDateValue in");
1221 napi_status status = napi_create_date(env, time, &result);
1222 if (status != napi_ok) {
1223 SLOGE("create date error");
1224 }
1225 SLOGD("SetDateValue out");
1226 return napi_ok;
1227 }
1228
GetRefByCallback(napi_env env,std::list<napi_ref> callbackList,napi_value callback,napi_ref & callbackRef)1229 napi_status NapiUtils::GetRefByCallback(napi_env env, std::list<napi_ref> callbackList, napi_value callback,
1230 napi_ref& callbackRef)
1231 {
1232 for (auto ref = callbackList.begin(); ref != callbackList.end(); ++ref) {
1233 if (Equals(env, callback, *ref)) {
1234 SLOGD("Callback has been matched");
1235 callbackRef = *ref;
1236 break;
1237 }
1238 }
1239 return napi_ok;
1240 }
1241
1242 /* napi_value is napi stage context */
GetStageElementName(napi_env env,napi_value in,AppExecFwk::ElementName & out)1243 napi_status NapiUtils::GetStageElementName(napi_env env, napi_value in, AppExecFwk::ElementName& out)
1244 {
1245 std::shared_ptr<AbilityRuntime::Context> stageContext = AbilityRuntime::GetStageModeContext(env, in);
1246 CHECK_RETURN(stageContext != nullptr, "get StagContext failed", napi_generic_failure);
1247 std::shared_ptr <AppExecFwk::AbilityInfo> abilityInfo;
1248 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(stageContext);
1249 if (abilityContext != nullptr) {
1250 abilityInfo = abilityContext->GetAbilityInfo();
1251 } else {
1252 auto extensionContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::ExtensionContext>(stageContext);
1253 CHECK_RETURN(extensionContext != nullptr, "context ConvertTo AbilityContext and ExtensionContext fail",
1254 napi_generic_failure);
1255 abilityInfo = extensionContext->GetAbilityInfo();
1256 }
1257 out.SetBundleName(abilityInfo->bundleName);
1258 out.SetAbilityName(abilityInfo->name);
1259 return napi_ok;
1260 }
1261
GetFaElementName(napi_env env,AppExecFwk::ElementName & out)1262 napi_status NapiUtils::GetFaElementName(napi_env env, AppExecFwk::ElementName& out)
1263 {
1264 auto* ability = AbilityRuntime::GetCurrentAbility(env);
1265 CHECK_RETURN(ability != nullptr, "get feature ability failed", napi_generic_failure);
1266 auto want = ability->GetWant();
1267 CHECK_RETURN(want != nullptr, "get want failed", napi_generic_failure);
1268 out = want->GetElement();
1269 return napi_ok;
1270 }
1271
GetValue(napi_env env,napi_value in,AppExecFwk::ElementName & out)1272 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AppExecFwk::ElementName& out)
1273 {
1274 bool isStageMode = false;
1275 CHECK_RETURN(AbilityRuntime::IsStageContext(env, in, isStageMode) == napi_ok, "get context type failed",
1276 napi_generic_failure);
1277 if (isStageMode) {
1278 CHECK_RETURN(GetStageElementName(env, in, out) == napi_ok, "get StagContext failed", napi_generic_failure);
1279 } else {
1280 CHECK_RETURN(GetFaElementName(env, out) == napi_ok, "get FaContext failed", napi_generic_failure);
1281 }
1282 return napi_ok;
1283 }
1284
GetValue(napi_env env,napi_value in,SessionToken & out)1285 napi_status NapiUtils::GetValue(napi_env env, napi_value in, SessionToken& out)
1286 {
1287 napi_value value {};
1288 auto status = napi_get_named_property(env, in, "sessionId", &value);
1289 CHECK_RETURN(status == napi_ok, "get SessionToken sessionId failed", status);
1290 status = GetValue(env, value, out.sessionId);
1291 CHECK_RETURN(status == napi_ok, "get SessionToken sessionId value failed", status);
1292
1293 bool hasPid = false;
1294 NAPI_CALL_BASE(env, napi_has_named_property(env, in, "pid", &hasPid), napi_invalid_arg);
1295 if (hasPid) {
1296 status = napi_get_named_property(env, in, "pid", &value);
1297 CHECK_RETURN(status == napi_ok, "get SessionToken pid failed", status);
1298 status = GetValue(env, value, out.pid);
1299 CHECK_RETURN(status == napi_ok, "get SessionToken pid value failed", status);
1300 } else {
1301 out.pid = 0;
1302 }
1303
1304 bool hasUid = false;
1305 NAPI_CALL_BASE(env, napi_has_named_property(env, in, "uid", &hasUid), napi_invalid_arg);
1306 if (hasUid) {
1307 status = napi_get_named_property(env, in, "uid", &value);
1308 CHECK_RETURN(status == napi_ok, "get SessionToken uid failed", status);
1309 status = GetValue(env, value, out.pid);
1310 CHECK_RETURN(status == napi_ok, "get SessionToken uid value failed", status);
1311 } else {
1312 out.uid = 0;
1313 }
1314 return napi_ok;
1315 }
1316
GetValue(napi_env env,napi_value in,AudioStandard::DeviceRole & out)1317 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AudioStandard::DeviceRole& out)
1318 {
1319 int32_t deviceRole;
1320 auto status = GetValue(env, in, deviceRole);
1321 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceRole failed", status);
1322 out = static_cast<AudioStandard::DeviceRole>(deviceRole);
1323 return napi_ok;
1324 }
1325
GetValue(napi_env env,napi_value in,AudioStandard::DeviceType & out)1326 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AudioStandard::DeviceType& out)
1327 {
1328 int32_t deviceType;
1329 auto status = GetValue(env, in, deviceType);
1330 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceType failed", status);
1331 out = static_cast<AudioStandard::DeviceType>(deviceType);
1332 return napi_ok;
1333 }
1334
GetSampleRate(napi_env env,napi_value in,AudioStandard::AudioSamplingRate & out)1335 napi_status NapiUtils::GetSampleRate(napi_env env, napi_value in, AudioStandard::AudioSamplingRate& out)
1336 {
1337 napi_value value {};
1338 auto status = napi_get_named_property(env, in, "sampleRates", &value);
1339 uint32_t length {};
1340 napi_get_array_length(env, value, &length);
1341 CHECK_RETURN(status == napi_ok, "get array length failed", status);
1342 if (length > 0) {
1343 napi_value element {};
1344 status = napi_get_element(env, value, 0, &element);
1345 CHECK_RETURN((status == napi_ok) && (element != nullptr), "get element failed", status);
1346 int32_t samplingRate;
1347 status = GetValue(env, element, samplingRate);
1348 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor audioStreamInfo_ samplingRate value failed", status);
1349 out = static_cast<AudioStandard::AudioSamplingRate>(samplingRate);
1350 }
1351 return status;
1352 }
1353
GetChannels(napi_env env,napi_value in,AudioStandard::AudioChannel & out)1354 napi_status NapiUtils::GetChannels(napi_env env, napi_value in, AudioStandard::AudioChannel& out)
1355 {
1356 napi_value value {};
1357 auto status = napi_get_named_property(env, in, "channelCounts", &value);
1358 uint32_t length {};
1359 napi_get_array_length(env, value, &length);
1360 CHECK_RETURN(status == napi_ok, "get array length failed", status);
1361 if (length > 0) {
1362 napi_value element {};
1363 status = napi_get_element(env, value, 0, &element);
1364 CHECK_RETURN((status == napi_ok) && (element != nullptr), "get element failed", status);
1365 int32_t channel;
1366 status = GetValue(env, element, channel);
1367 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor audioStreamInfo_ channels value failed", status);
1368 out = static_cast<AudioStandard::AudioChannel>(channel);
1369 }
1370 return status;
1371 }
1372
GetChannelMasks(napi_env env,napi_value in,int32_t & out)1373 napi_status NapiUtils::GetChannelMasks(napi_env env, napi_value in, int32_t& out)
1374 {
1375 napi_value value {};
1376 auto status = napi_get_named_property(env, in, "channelMasks", &value);
1377 uint32_t length {};
1378 napi_get_array_length(env, value, &length);
1379 CHECK_RETURN(status == napi_ok, "get array length failed", status);
1380 if (length > 0) {
1381 napi_value element {};
1382 status = napi_get_element(env, value, 0, &element);
1383 CHECK_RETURN((status == napi_ok) && (element != nullptr), "get element failed", status);
1384 status = GetValue(env, element, out);
1385 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor channelMasks_ value failed", status);
1386 }
1387 return status;
1388 }
1389
GetValue(napi_env env,napi_value in,AudioStandard::AudioDeviceDescriptor & out)1390 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AudioStandard::AudioDeviceDescriptor& out)
1391 {
1392 napi_value value {};
1393 auto status = napi_get_named_property(env, in, "id", &value);
1394 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceId_ failed", status);
1395 status = GetValue(env, value, out.deviceId_);
1396 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceId_ value failed", status);
1397
1398 status = napi_get_named_property(env, in, "name", &value);
1399 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceName_ failed", status);
1400 status = GetValue(env, value, out.deviceName_);
1401 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceName_ value failed", status);
1402
1403 status = napi_get_named_property(env, in, "networkId", &value);
1404 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor networkId failed", status);
1405 status = GetValue(env, value, out.networkId_);
1406 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor networkId value failed", status);
1407
1408 status = napi_get_named_property(env, in, "deviceRole", &value);
1409 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceRole_ failed", status);
1410 status = GetValue(env, value, out.deviceRole_);
1411 CHECK_RETURN(status == napi_ok, "get AudioDeviceDescriptor deviceRole_ value failed", status);
1412
1413 if (napi_get_named_property(env, in, "address", &value) == napi_ok) {
1414 GetValue(env, value, out.macAddress_);
1415 }
1416
1417 if (napi_get_named_property(env, in, "deviceType", &value) == napi_ok) {
1418 GetValue(env, value, out.deviceType_);
1419 }
1420
1421 if (napi_get_named_property(env, in, "interruptGroupId", &value) == napi_ok) {
1422 GetValue(env, value, out.interruptGroupId_);
1423 }
1424
1425 if (napi_get_named_property(env, in, "volumeGroupId", &value) == napi_ok) {
1426 GetValue(env, value, out.volumeGroupId_);
1427 }
1428
1429 AudioStandard::AudioSamplingRate audioSamplingRate;
1430 GetSampleRate(env, in, audioSamplingRate);
1431 out.audioStreamInfo_.samplingRate = {audioSamplingRate};
1432
1433 AudioStandard::AudioChannel audioChannel;
1434 GetChannels(env, in, audioChannel);
1435 out.audioStreamInfo_.channels = {audioChannel};
1436
1437 GetChannelMasks(env, in, out.channelMasks_);
1438 return napi_ok;
1439 }
1440
GetValue(napi_env env,napi_value in,std::vector<AudioStandard::AudioDeviceDescriptor> & out)1441 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::vector<AudioStandard::AudioDeviceDescriptor>& out)
1442 {
1443 uint32_t length {};
1444 auto status = napi_get_array_length(env, in, &length);
1445 CHECK_RETURN(status == napi_ok, "get array length failed", status);
1446 for (uint32_t i = 0; i < length; ++i) {
1447 napi_value element {};
1448 status = napi_get_element(env, in, i, &element);
1449 CHECK_RETURN((status == napi_ok) && (element != nullptr), "get element failed", status);
1450 AudioStandard::AudioDeviceDescriptor descriptor;
1451 status = GetValue(env, element, descriptor);
1452 out.push_back(descriptor);
1453 }
1454 return napi_ok;
1455 }
1456
GetOptionalString(napi_env env,napi_value in,DeviceInfo & out)1457 napi_status NapiUtils::GetOptionalString(napi_env env, napi_value in, DeviceInfo& out)
1458 {
1459 napi_value value {};
1460 bool hasIpAddress = false;
1461 napi_has_named_property(env, in, "ipAddress", &hasIpAddress);
1462 if (hasIpAddress) {
1463 napi_status status = napi_get_named_property(env, in, "ipAddress", &value);
1464 CHECK_RETURN(status == napi_ok, "get DeviceInfo ipAddress failed", status);
1465
1466 napi_valuetype type = napi_undefined;
1467 status = napi_typeof(env, value, &type);
1468 CHECK_RETURN((status == napi_ok) && type == napi_string, "invalid typ for ipAddress", napi_invalid_arg);
1469
1470 size_t maxLen = STR_MAX_LENGTH;
1471 status = napi_get_value_string_utf8(env, value, nullptr, 0, &maxLen);
1472 if (maxLen == 0) {
1473 out.ipAddress_ = "";
1474 } else {
1475 if (maxLen < 0 || maxLen >= STR_MAX_LENGTH) {
1476 return napi_invalid_arg;
1477 }
1478 char buf[STR_MAX_LENGTH + STR_TAIL_LENGTH] {};
1479 size_t len = 0;
1480 status = napi_get_value_string_utf8(env, value, buf, maxLen + STR_TAIL_LENGTH, &len);
1481 if (status == napi_ok) {
1482 out.ipAddress_ = std::string(buf);
1483 }
1484 }
1485 CHECK_RETURN(status == napi_ok, "get DeviceInfo ipAddress value failed", status);
1486 } else {
1487 out.ipAddress_ = "";
1488 }
1489 return napi_ok;
1490 }
1491
1492 /* napi_value -> DeviceInfo */
GetValue(napi_env env,napi_value in,DeviceInfo & out)1493 napi_status NapiUtils::GetValue(napi_env env, napi_value in, DeviceInfo& out)
1494 {
1495 napi_value value {};
1496 auto status = napi_get_named_property(env, in, "castCategory", &value);
1497 CHECK_RETURN(status == napi_ok, "get DeviceInfo castCategory_ failed", status);
1498 status = GetValue(env, value, out.castCategory_);
1499 CHECK_RETURN(status == napi_ok, "get DeviceInfo castCategory_ value failed", status);
1500 status = napi_get_named_property(env, in, "deviceId", &value);
1501 CHECK_RETURN(status == napi_ok, "get DeviceInfo deviceId_ failed", status);
1502 status = GetValue(env, value, out.deviceId_);
1503 CHECK_RETURN(status == napi_ok, "get DeviceInfo deviceId_ value failed", status);
1504 status = napi_get_named_property(env, in, "manufacturer", &value);
1505 CHECK_RETURN(status == napi_ok, "get DeviceInfo manufacturer_ failed", status);
1506 status = GetValue(env, value, out.manufacturer_);
1507 CHECK_RETURN(status == napi_ok, "get DeviceInfo manufacturer_ value failed", status);
1508 status = napi_get_named_property(env, in, "modelName", &value);
1509 CHECK_RETURN(status == napi_ok, "get DeviceInfo modelName_ failed", status);
1510 status = GetValue(env, value, out.modelName_);
1511 CHECK_RETURN(status == napi_ok, "get DeviceInfo modelName_ value failed", status);
1512 status = napi_get_named_property(env, in, "deviceName", &value);
1513 CHECK_RETURN(status == napi_ok, "get DeviceInfo deviceName_ failed", status);
1514 status = GetValue(env, value, out.deviceName_);
1515 CHECK_RETURN(status == napi_ok, "get DeviceInfo deviceName_ value failed", status);
1516 status = napi_get_named_property(env, in, "deviceType", &value);
1517 CHECK_RETURN(status == napi_ok, "get DeviceInfo deviceType_ failed", status);
1518 status = GetValue(env, value, out.deviceType_);
1519 CHECK_RETURN(status == napi_ok, "get DeviceInfo deviceType_ value failed", status);
1520 CHECK_RETURN(GetOptionalString(env, in, out) == napi_ok, "get DeviceInfo ip address value failed", status);
1521
1522 bool hasKey = false;
1523 napi_has_named_property(env, in, "providerId", &hasKey);
1524 if (hasKey) {
1525 status = napi_get_named_property(env, in, "providerId", &value);
1526 CHECK_RETURN(status == napi_ok, "get DeviceInfo providerId failed", status);
1527 status = GetValue(env, value, out.providerId_);
1528 CHECK_RETURN(status == napi_ok, "get DeviceInfo providerId value failed", status);
1529 } else {
1530 out.providerId_ = 0;
1531 }
1532
1533 status = ProcessDeviceInfoParams(env, in, out);
1534 CHECK_RETURN(status == napi_ok, "get DeviceInfo ProcessDeviceInfoParams failed", status);
1535
1536 return napi_ok;
1537 }
1538
ProcessDeviceInfoParams(napi_env env,napi_value in,DeviceInfo & out)1539 napi_status NapiUtils::ProcessDeviceInfoParams(napi_env env, napi_value in, DeviceInfo& out)
1540 {
1541 napi_value value {};
1542 bool hasKey = false;
1543 napi_status status = napi_ok;
1544 napi_has_named_property(env, in, "supportedProtocols", &hasKey);
1545 if (hasKey) {
1546 status = napi_get_named_property(env, in, "supportedProtocols", &value);
1547 CHECK_RETURN(status == napi_ok, "get DeviceInfo supportedProtocols failed", status);
1548 status = GetValue(env, value, out.supportedProtocols_);
1549 CHECK_RETURN(status == napi_ok, "get DeviceInfo supportedProtocols value failed", status);
1550 } else {
1551 out.supportedProtocols_ = ProtocolType::TYPE_CAST_PLUS_STREAM;
1552 }
1553 napi_has_named_property(env, in, "authenticationStatus", &hasKey);
1554 if (hasKey) {
1555 status = napi_get_named_property(env, in, "authenticationStatus", &value);
1556 CHECK_RETURN(status == napi_ok, "get DeviceInfo authenticationStatus failed", status);
1557 status = GetValue(env, value, out.authenticationStatus_);
1558 CHECK_RETURN(status == napi_ok, "get DeviceInfo authenticationStatus value failed", status);
1559 } else {
1560 out.authenticationStatus_ = 0;
1561 }
1562 napi_has_named_property(env, in, "supportedDrmCapabilities", &hasKey);
1563 if (hasKey) {
1564 status = napi_get_named_property(env, in, "supportedDrmCapabilities", &value);
1565 CHECK_RETURN(status == napi_ok, "get DeviceInfo supportedDrmCapabilities failed", status);
1566 status = GetValue(env, value, out.supportedDrmCapabilities_);
1567 CHECK_RETURN(status == napi_ok, "get DeviceInfo supportedDrmCapabilities value failed", status);
1568 }
1569 napi_has_named_property(env, in, "isLegacy", &hasKey);
1570 if (hasKey) {
1571 status = napi_get_named_property(env, in, "isLegacy", &value);
1572 CHECK_RETURN(status == napi_ok, "get DeviceInfo isLegacy failed", status);
1573 status = GetValue(env, value, out.isLegacy_);
1574 CHECK_RETURN(status == napi_ok, "get DeviceInfo isLegacy value failed", status);
1575 } else {
1576 out.isLegacy_ = false;
1577 }
1578 napi_has_named_property(env, in, "mediumTypes", &hasKey);
1579 if (hasKey) {
1580 status = napi_get_named_property(env, in, "mediumTypes", &value);
1581 CHECK_RETURN(status == napi_ok, "get DeviceInfo mediumTypes failed", status);
1582 status = GetValue(env, value, out.mediumTypes_);
1583 CHECK_RETURN(status == napi_ok, "get DeviceInfo mediumTypes value failed", status);
1584 } else {
1585 out.mediumTypes_ = COAP;
1586 }
1587 return napi_ok;
1588 }
1589
1590 /* napi_value -> OutputDeviceInfo */
GetValue(napi_env env,napi_value in,OutputDeviceInfo & out)1591 napi_status NapiUtils::GetValue(napi_env env, napi_value in, OutputDeviceInfo& out)
1592 {
1593 napi_value devices = nullptr;
1594 bool hasProperty = false;
1595 NAPI_CALL_BASE(env, napi_has_named_property(env, in, "devices", &hasProperty), napi_invalid_arg);
1596 if (!hasProperty) {
1597 SLOGE("devices is not exit in OutputDeviceInfo");
1598 return napi_invalid_arg;
1599 }
1600 NAPI_CALL_BASE(env, napi_get_named_property(env, in, "devices", &devices), napi_invalid_arg);
1601 bool isArray = false;
1602 NAPI_CALL_BASE(env, napi_is_array(env, devices, &isArray), napi_invalid_arg);
1603 if (!isArray) {
1604 SLOGE("devices is not array");
1605 return napi_invalid_arg;
1606 }
1607
1608 uint32_t arrLen = 0;
1609 NAPI_CALL_BASE(env, napi_get_array_length(env, devices, &arrLen), napi_invalid_arg);
1610 if (arrLen == 0) {
1611 SLOGE("devices len is invalid");
1612 return napi_invalid_arg;
1613 }
1614
1615 for (uint32_t i = 0; i < arrLen; i++) {
1616 napi_value item = nullptr;
1617 NAPI_CALL_BASE(env, napi_get_element(env, devices, i, &item), napi_invalid_arg);
1618 DeviceInfo deviceInfo;
1619 napi_status status = GetValue(env, item, deviceInfo);
1620 CHECK_RETURN(status == napi_ok, "not is device info", status);
1621 out.deviceInfos_.push_back(deviceInfo);
1622 }
1623 return napi_ok;
1624 }
1625
1626 /* napi_value -> MediaInfoHolder */
GetValue(napi_env env,napi_value in,MediaInfoHolder & out)1627 napi_status NapiUtils::GetValue(napi_env env, napi_value in, MediaInfoHolder& out)
1628 {
1629 return NapiMediaInfoHolder::GetValue(env, in, out);
1630 }
1631
1632 /* napi_value <-> MediaInfoHolder */
SetValue(napi_env env,const MediaInfoHolder & in,napi_value & out)1633 napi_status NapiUtils::SetValue(napi_env env, const MediaInfoHolder& in, napi_value& out)
1634 {
1635 return NapiMediaInfoHolder::SetValue(env, in, out);
1636 }
1637
1638 /* napi_value -> MediaInfo */
GetValue(napi_env env,napi_value in,MediaInfo & out)1639 napi_status NapiUtils::GetValue(napi_env env, napi_value in, MediaInfo& out)
1640 {
1641 napi_value value {};
1642 auto status = napi_get_named_property(env, in, "mediaId", &value);
1643 CHECK_RETURN(status == napi_ok, "get mediaId failed", status);
1644 status = GetValue(env, value, out.mediaId_);
1645 CHECK_RETURN(status == napi_ok, "get mediaId value failed", status);
1646
1647 status = napi_get_named_property(env, in, "mediaUrl", &value);
1648 CHECK_RETURN(status == napi_ok, "get mediaUrl failed", status);
1649 status = GetValue(env, value, out.mediaUrl_);
1650 CHECK_RETURN(status == napi_ok, "get mediaUrl value failed", status);
1651
1652 bool hasStartPosition = false;
1653 napi_has_named_property(env, in, "startPosition", &hasStartPosition);
1654 if (hasStartPosition) {
1655 status = napi_get_named_property(env, in, "startPosition", &value);
1656 CHECK_RETURN(status == napi_ok, "get MediaInfo startPosition failed", status);
1657 status = GetValue(env, value, out.startPosition_);
1658 CHECK_RETURN(status == napi_ok, "get MediaInfo startPosition value failed", status);
1659 } else {
1660 out.startPosition_ = -1;
1661 }
1662 return napi_ok;
1663 }
1664
1665 /* napi_value <- MediaInfo */
SetValue(napi_env env,const MediaInfo & in,napi_value & out)1666 napi_status NapiUtils::SetValue(napi_env env, const MediaInfo& in, napi_value& out)
1667 {
1668 napi_status status = napi_create_object(env, &out);
1669 CHECK_RETURN((status == napi_ok) && (out != nullptr), "create object failed", status);
1670
1671 napi_value property = nullptr;
1672 status = SetValue(env, in.mediaId_, property);
1673 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1674 status = napi_set_named_property(env, out, "mediaId", property);
1675 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1676
1677 status = SetValue(env, in.mediaUrl_, property);
1678 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1679 status = napi_set_named_property(env, out, "mediaUrl", property);
1680 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1681
1682 if (in.startPosition_ != -1) {
1683 status = SetValue(env, in.startPosition_, property);
1684 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1685 status = napi_set_named_property(env, out, "mediaInfo", property);
1686 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1687 }
1688
1689 return napi_ok;
1690 }
1691
1692 /* napi_value -> AVFileDescriptor */
GetValue(napi_env env,napi_value in,AVFileDescriptor & out)1693 napi_status NapiUtils::GetValue(napi_env env, napi_value in, AVFileDescriptor& out)
1694 {
1695 napi_value value {};
1696 auto status = napi_ok;
1697 bool hasFd = false;
1698 napi_has_named_property(env, in, "fd", &hasFd);
1699 if (hasFd) {
1700 status = napi_get_named_property(env, in, "fd", &value);
1701 CHECK_RETURN(status == napi_ok, "get fd failed", status);
1702 status = GetValue(env, value, out.fd_);
1703 CHECK_RETURN(status == napi_ok, "get fd value failed", status);
1704 } else {
1705 out.fd_ = 0;
1706 }
1707
1708 bool hasOffset = false;
1709 napi_has_named_property(env, in, "offset", &hasOffset);
1710 if (hasOffset) {
1711 status = napi_get_named_property(env, in, "offset", &value);
1712 CHECK_RETURN(status == napi_ok, "get offset failed", status);
1713 status = GetValue(env, value, out.offset_);
1714 CHECK_RETURN(status == napi_ok, "get offset value failed", status);
1715 } else {
1716 out.offset_ = 0;
1717 }
1718
1719 bool hasLength = false;
1720 napi_has_named_property(env, in, "length", &hasLength);
1721 if (hasLength) {
1722 status = napi_get_named_property(env, in, "length", &value);
1723 CHECK_RETURN(status == napi_ok, "get length failed", status);
1724 status = GetValue(env, value, out.length_);
1725 CHECK_RETURN(status == napi_ok, "get length value failed", status);
1726 } else {
1727 out.length_ = -1;
1728 }
1729 return napi_ok;
1730 }
1731
1732 /* napi_value <- AVFileDescriptor */
SetValue(napi_env env,const AVFileDescriptor & in,napi_value & out)1733 napi_status NapiUtils::SetValue(napi_env env, const AVFileDescriptor& in, napi_value& out)
1734 {
1735 napi_status status = napi_create_object(env, &out);
1736 CHECK_RETURN((status == napi_ok) && (out != nullptr), "create object failed", status);
1737
1738 napi_value property = nullptr;
1739 status = SetValue(env, in.fd_, property);
1740 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1741 status = napi_set_named_property(env, out, "fd", property);
1742 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1743
1744 if (in.offset_ != 0) {
1745 status = SetValue(env, in.offset_, property);
1746 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1747 status = napi_set_named_property(env, out, "offset", property);
1748 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1749 }
1750
1751 if (in.length_ != -1) {
1752 status = SetValue(env, in.length_, property);
1753 CHECK_RETURN((status == napi_ok) && (property != nullptr), "create object failed", status);
1754 status = napi_set_named_property(env, out, "length", property);
1755 CHECK_RETURN(status == napi_ok, "napi_set_named_property failed", status);
1756 }
1757 return napi_ok;
1758 }
1759
ThrowError(napi_env env,const char * napiMessage,int32_t napiCode)1760 napi_status NapiUtils::ThrowError(napi_env env, const char* napiMessage, int32_t napiCode)
1761 {
1762 napi_value message = nullptr;
1763 napi_value code = nullptr;
1764 napi_value result = nullptr;
1765 napi_create_string_utf8(env, napiMessage, NAPI_AUTO_LENGTH, &message);
1766 napi_create_error(env, nullptr, message, &result);
1767 napi_create_int32(env, napiCode, &code);
1768 napi_set_named_property(env, result, "code", code);
1769 napi_throw(env, result);
1770 return napi_ok;
1771 }
1772 }
1773