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