• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "common_napi.h"
17 #include <climits>
18 #include "avcodec_list.h"
19 #include "media_log.h"
20 #include "media_errors.h"
21 
22 namespace {
23     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_PLAYER, "CommonNapi"};
24 }
25 
26 namespace OHOS {
27 namespace Media {
GetStringArgument(napi_env env,napi_value value,size_t maxLength)28 std::string CommonNapi::GetStringArgument(napi_env env, napi_value value, size_t maxLength)
29 {
30     std::string strValue = "";
31     size_t bufLength = 0;
32     napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &bufLength);
33     if (status == napi_ok && bufLength > 0 && bufLength < maxLength) {
34         char *buffer = static_cast<char *>(malloc((bufLength + 1) * sizeof(char)));
35         CHECK_AND_RETURN_RET_LOG(buffer != nullptr, strValue, "no memory");
36         status = napi_get_value_string_utf8(env, value, buffer, bufLength + 1, &bufLength);
37         if (status == napi_ok) {
38             MEDIA_LOGD("argument = %{public}s", buffer);
39             strValue = buffer;
40         }
41         free(buffer);
42         buffer = nullptr;
43     }
44     return strValue;
45 }
46 
GetIntArrayArgument(napi_env env,napi_value value,std::vector<int32_t> & vec,size_t maxLength)47 bool CommonNapi::GetIntArrayArgument(napi_env env, napi_value value, std::vector<int32_t> &vec, size_t maxLength)
48 {
49     napi_valuetype type;
50     napi_status status = napi_typeof(env, value, &type);
51     if (status != napi_ok || type != napi_object) {
52         return false;
53     }
54     uint32_t arrayLength = 0;
55     status = napi_get_array_length(env, value, &arrayLength);
56     if (status != napi_ok || arrayLength == 0 || arrayLength > maxLength) {
57         return false;
58     }
59 
60     for (size_t i = 0; i < arrayLength; ++i) {
61         napi_value element;
62         status = napi_get_element(env, value, i, &element);
63         if (status != napi_ok) {
64             return false;
65         }
66         int32_t elementValue = 0;
67         status = napi_get_value_int32(env, element, &elementValue);
68         if (status != napi_ok) {
69             return false;
70         }
71         vec.push_back(elementValue);
72     }
73     return true;
74 }
75 
CheckValueType(napi_env env,napi_value arg,napi_valuetype type)76 bool CommonNapi::CheckValueType(napi_env env, napi_value arg, napi_valuetype type)
77 {
78     napi_valuetype valueType = napi_undefined;
79     if (arg != nullptr && napi_typeof(env, arg, &valueType) == napi_ok && valueType == type) {
80         return true;
81     }
82     return false;
83 }
84 
CheckhasNamedProperty(napi_env env,napi_value arg,std::string type)85 bool CommonNapi::CheckhasNamedProperty(napi_env env, napi_value arg, std::string type)
86 {
87     bool exist = false;
88     napi_status napiStatus = napi_has_named_property(env, arg, type.c_str(), &exist);
89     return exist && (napiStatus == napi_ok);
90 }
91 
GetPropertyInt32(napi_env env,napi_value configObj,const std::string & type,int32_t & result)92 bool CommonNapi::GetPropertyInt32(napi_env env, napi_value configObj, const std::string &type, int32_t &result)
93 {
94     napi_value item = nullptr;
95     bool exist = false;
96     napi_status napiStatus = napi_has_named_property(env, configObj, type.c_str(), &exist);
97     CHECK_AND_RETURN_RET_LOG(napiStatus == napi_ok && exist, false, "can not find %{public}s property", type.c_str());
98     CHECK_AND_RETURN_RET_LOG(napi_get_named_property(env, configObj, type.c_str(), &item) == napi_ok, false,
99         "get %{public}s property fail", type.c_str());
100     CHECK_AND_RETURN_RET_LOG(napi_get_value_int32(env, item, &result) == napi_ok, false,
101         "get %{public}s property value fail", type.c_str());
102     return true;
103 }
104 
GetPropertyUint32(napi_env env,napi_value configObj,const std::string & type,uint32_t & result)105 bool CommonNapi::GetPropertyUint32(napi_env env, napi_value configObj, const std::string &type, uint32_t &result)
106 {
107     napi_value item = nullptr;
108     bool exist = false;
109     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
110     CHECK_AND_RETURN_RET_LOG(status == napi_ok && exist, false, "can not find %{public}s property", type.c_str());
111     CHECK_AND_RETURN_RET_LOG(napi_get_named_property(env, configObj, type.c_str(), &item) == napi_ok, false,
112         "get %{public}s property fail", type.c_str());
113 
114     CHECK_AND_RETURN_RET_LOG(napi_get_value_uint32(env, item, &result) == napi_ok, false,
115         "get %{public}s property value fail", type.c_str());
116     return true;
117 }
118 
GetPropertyInt64(napi_env env,napi_value configObj,const std::string & type,int64_t & result)119 bool CommonNapi::GetPropertyInt64(napi_env env, napi_value configObj, const std::string &type, int64_t &result)
120 {
121     napi_value item = nullptr;
122     bool exist = false;
123     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
124     if (status != napi_ok || !exist) {
125         MEDIA_LOGE("can not find %{public}s property", type.c_str());
126         return false;
127     }
128 
129     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
130         MEDIA_LOGE("get %{public}s property fail", type.c_str());
131         return false;
132     }
133 
134     if (napi_get_value_int64(env, item, &result) != napi_ok) {
135         MEDIA_LOGE("get %{public}s property value fail", type.c_str());
136         return false;
137     }
138     return true;
139 }
140 
GetPropertyDouble(napi_env env,napi_value configObj,const std::string & type,double & result)141 bool CommonNapi::GetPropertyDouble(napi_env env, napi_value configObj, const std::string &type, double &result)
142 {
143     napi_value item = nullptr;
144     bool exist = false;
145     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
146     if (status != napi_ok || !exist) {
147         MEDIA_LOGE("can not find %{public}s property", type.c_str());
148         return false;
149     }
150 
151     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
152         MEDIA_LOGE("get %{public}s property fail", type.c_str());
153         return false;
154     }
155 
156     if (napi_get_value_double(env, item, &result) != napi_ok) {
157         MEDIA_LOGE("get %{public}s property value fail", type.c_str());
158         return false;
159     }
160     return true;
161 }
162 
GetPropertyString(napi_env env,napi_value configObj,const std::string & type)163 std::string CommonNapi::GetPropertyString(napi_env env, napi_value configObj, const std::string &type)
164 {
165     std::string invalid = "";
166     bool exist = false;
167     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
168     if (status != napi_ok || !exist) {
169         MEDIA_LOGE("can not find %{public}s property", type.c_str());
170         return invalid;
171     }
172 
173     napi_value item = nullptr;
174     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
175         MEDIA_LOGE("get %{public}s property fail", type.c_str());
176         return invalid;
177     }
178 
179     return GetStringArgument(env, item);
180 }
181 
GetPropertyArrayBuffer(napi_env env,napi_value configObj,void ** data,size_t * length)182 bool CommonNapi::GetPropertyArrayBuffer(napi_env env, napi_value configObj, void **data, size_t* length)
183 {
184     if (napi_get_arraybuffer_info(env, configObj, data, length) != napi_ok) {
185         MEDIA_LOGE("get arraybuffer value fail");
186         return false;
187     }
188     return true;
189 }
190 
GetPropertyRecord(napi_env env,napi_value configObj,Meta & meta,std::string type)191 napi_status CommonNapi::GetPropertyRecord(napi_env env, napi_value configObj, Meta &meta, std::string type)
192 {
193     bool exist = false;
194     napi_value in = nullptr;
195     napi_valuetype valueType = napi_undefined;
196     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
197     if (status != napi_ok || !exist) {
198         MEDIA_LOGE("can not find %{public}s property", type.c_str());
199         return napi_invalid_arg;
200     }
201     if (napi_get_named_property(env, configObj, type.c_str(), &in) != napi_ok) {
202         MEDIA_LOGE("get %{public}s property fail", type.c_str());
203         return napi_invalid_arg;
204     }
205     status = napi_typeof(env, in, &valueType);
206     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "get valueType failed");
207     CHECK_AND_RETURN_RET_LOG(valueType != napi_undefined, napi_ok, "PropertyRecord undefined");
208     CHECK_AND_RETURN_RET_LOG(valueType == napi_object, napi_invalid_arg, "invalid arguments");
209 
210     napi_value dataList = nullptr;
211     uint32_t count = 0;
212     status = napi_get_property_names(env, in, &dataList);
213     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "get property names failed");
214     status = napi_get_array_length(env, dataList, &count);
215     CHECK_AND_RETURN_RET_LOG(status == napi_ok && count <= MAX_COUNT,
216         napi_invalid_arg, "get length failed or more than 500");
217 
218     napi_value jsKey = nullptr;
219     napi_value jsValue = nullptr;
220     for (uint32_t i = 0; i < count; i++) {
221         status = napi_get_element(env, dataList, i, &jsKey);
222         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "get element Key failed");
223         status = napi_typeof(env, jsKey, &valueType);
224         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "get valueType failed");
225         CHECK_AND_RETURN_RET_LOG(valueType == napi_string, napi_invalid_arg, "key not supported type");
226         std::string strKey = GetStringArgument(env, jsKey, CUSTOM_MAX_LENGTH);
227         CHECK_AND_RETURN_RET_LOG(strKey != "", napi_invalid_arg, "key not supported");
228 
229         status = napi_get_named_property(env, in, strKey.c_str(), &jsValue);
230         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "get property value failed");
231         status = napi_typeof(env, jsValue, &valueType);
232         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "get valueType failed");
233 
234         CHECK_AND_RETURN_RET_LOG(valueType == napi_string, napi_invalid_arg, "value not supported type");
235         std::string strValue = GetStringArgument(env, jsValue, CUSTOM_MAX_LENGTH);
236         CHECK_AND_RETURN_RET_LOG(!strValue.empty(), napi_invalid_arg, "get value failed");
237         meta.SetData(strKey, strValue);
238     }
239     return napi_ok;
240 }
241 
GetFdArgument(napi_env env,napi_value value,AVFileDescriptor & rawFd)242 bool CommonNapi::GetFdArgument(napi_env env, napi_value value, AVFileDescriptor &rawFd)
243 {
244     CHECK_AND_RETURN_RET(GetPropertyInt32(env, value, "fd", rawFd.fd) == true, false);
245 
246     if (!GetPropertyInt64(env, value, "offset", rawFd.offset)) {
247         rawFd.offset = 0; // use default value
248     }
249 
250     if (!GetPropertyInt64(env, value, "length", rawFd.length)) {
251         rawFd.length = -1; // -1 means use default value
252     }
253 
254     MEDIA_LOGD("get fd argument, fd = %{public}d, offset = %{public}" PRIi64 ", size = %{public}" PRIi64 "",
255         rawFd.fd, rawFd.offset, rawFd.length);
256 
257     return true;
258 }
259 
GetPropertyMap(napi_env env,napi_value value,std::map<std::string,std::string> & map)260 bool CommonNapi::GetPropertyMap(napi_env env, napi_value value, std::map<std::string, std::string>& map)
261 {
262     napi_value jsProNameList = nullptr;
263     uint32_t jsProCount = 0;
264     napi_status status = napi_get_property_names(env, value, &jsProNameList);
265     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "get property name failed");
266     status = napi_get_array_length(env, jsProNameList, &jsProCount);
267     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "get subKeys length failed");
268 
269     napi_value jsProName = nullptr;
270     napi_value jsProValue = nullptr;
271     for (uint32_t i = 0; i < jsProCount; i++) {
272         status = napi_get_element(env, jsProNameList, i, &jsProName);
273         CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "get sub key failed");
274         std::string strProName = GetStringArgument(env, jsProName);
275 
276         status = napi_get_named_property(env, value, strProName.c_str(), &jsProValue);
277         CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "get sub value failed");
278         std::string strProValue = GetStringArgument(env, jsProValue);
279 
280         map.emplace(strProName, strProValue);
281     }
282 
283     return true;
284 }
285 
GetPlayStrategy(napi_env env,napi_value value,AVPlayStrategyTmp & playStrategy)286 bool CommonNapi::GetPlayStrategy(napi_env env, napi_value value, AVPlayStrategyTmp &playStrategy)
287 {
288     if (!GetPropertyUint32(env, value, "preferredWidth", playStrategy.preferredWidth)) {
289         playStrategy.preferredWidth = 0; // use default value
290     }
291     if (!GetPropertyUint32(env, value, "preferredHeight", playStrategy.preferredHeight)) {
292         playStrategy.preferredHeight = 0; // use default value
293     }
294     if (!GetPropertyUint32(env, value, "preferredBufferDuration", playStrategy.preferredBufferDuration)) {
295         playStrategy.preferredBufferDuration = 0; // use default value
296     }
297     if (!GetPropertyBool(env, value, "preferredHdr", playStrategy.preferredHdr)) {
298         playStrategy.preferredHdr = 0; // use default value
299     }
300     if (!GetPropertyBool(env, value, "showFirstFrameOnPrepare", playStrategy.showFirstFrameOnPrepare)) {
301         playStrategy.showFirstFrameOnPrepare = false; // use default value
302     }
303     if (!GetPropertyBool(env, value, "enableSuperResolution", playStrategy.enableSuperResolution)) {
304         playStrategy.enableSuperResolution = false; // use default value
305     }
306     if (!GetPropertyBool(env, value, "enableCameraPostprocessing", playStrategy.enableCameraPostprocessing)) {
307         playStrategy.enableCameraPostprocessing = false; // use default value
308     }
309     if (!GetPropertyInt32(env, value, "mutedMediaType", playStrategy.mutedMediaType)) {
310         playStrategy.mutedMediaType = MediaType::MEDIA_TYPE_MAX_COUNT; // use default value
311     }
312     playStrategy.preferredAudioLanguage = GetPropertyString(env, value, "preferredAudioLanguage");
313     playStrategy.preferredSubtitleLanguage = GetPropertyString(env, value, "preferredSubtitleLanguage");
314     if (!GetPropertyDouble(env, value, "preferredBufferDurationForPlaying",
315         playStrategy.preferredBufferDurationForPlaying)) {
316         playStrategy.preferredBufferDurationForPlaying = 0; // use default value
317         playStrategy.isSetBufferDurationForPlaying = false;
318     } else {
319         playStrategy.isSetBufferDurationForPlaying = true;
320     }
321     if (!GetPropertyDouble(env, value, "thresholdForAutoQuickPlay", playStrategy.thresholdForAutoQuickPlay)) {
322         playStrategy.thresholdForAutoQuickPlay = -1;
323         playStrategy.isSetThresholdForAutoQuickPlay = false;
324     } else {
325         playStrategy.isSetThresholdForAutoQuickPlay = true;
326     }
327 
328     if (!GetPropertyBool(env, value, "keepDecodingOnMute", playStrategy.keepDecodingOnMute)) {
329         playStrategy.keepDecodingOnMute = false; // use default value
330     }
331     return true;
332 }
333 
GetPlayMediaStreamData(napi_env env,napi_value value,AVPlayMediaStreamTmp & mediaStream)334 bool CommonNapi::GetPlayMediaStreamData(napi_env env, napi_value value, AVPlayMediaStreamTmp &mediaStream)
335 {
336     bool existProperty = CommonNapi::CheckhasNamedProperty(env, value, "url");
337     existProperty &= CommonNapi::CheckhasNamedProperty(env, value, "width");
338     existProperty &= CommonNapi::CheckhasNamedProperty(env, value, "height");
339     existProperty &= CommonNapi::CheckhasNamedProperty(env, value, "bitrate");
340     CHECK_AND_RETURN_RET_LOG(existProperty, false, "property is not complete for AVPlayMediaStream");
341 
342     mediaStream.url = GetPropertyString(env, value, "url");
343     GetPropertyUint32(env, value, "width", mediaStream.width);
344     GetPropertyUint32(env, value, "height", mediaStream.height);
345     GetPropertyUint32(env, value, "bitrate", mediaStream.bitrate);
346     return true;
347 }
348 
FillErrorArgs(napi_env env,int32_t errCode,const napi_value & args)349 napi_status CommonNapi::FillErrorArgs(napi_env env, int32_t errCode, const napi_value &args)
350 {
351     napi_value codeStr = nullptr;
352     napi_status status = napi_create_string_utf8(env, "code", NAPI_AUTO_LENGTH, &codeStr);
353     CHECK_AND_RETURN_RET_LOG(status == napi_ok && codeStr != nullptr, napi_invalid_arg, "create code str fail");
354 
355     napi_value errCodeVal = nullptr;
356     int32_t errCodeInt = errCode;
357     status = napi_create_int32(env, errCodeInt, &errCodeVal);
358     CHECK_AND_RETURN_RET_LOG(status == napi_ok && errCodeVal != nullptr, napi_invalid_arg,
359         "create error code number val fail");
360 
361     status = napi_set_property(env, args, codeStr, errCodeVal);
362     CHECK_AND_RETURN_RET_LOG(status == napi_ok, napi_invalid_arg, "set error code property fail");
363 
364     napi_value nameStr = nullptr;
365     status = napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &nameStr);
366     CHECK_AND_RETURN_RET_LOG(status == napi_ok && nameStr != nullptr, napi_invalid_arg, "create name str fail");
367 
368     napi_value errNameVal = nullptr;
369     status = napi_create_string_utf8(env, "BusinessError", NAPI_AUTO_LENGTH, &errNameVal);
370     CHECK_AND_RETURN_RET_LOG(status == napi_ok && errNameVal != nullptr, napi_invalid_arg,
371         "create BusinessError str fail");
372 
373     status = napi_set_property(env, args, nameStr, errNameVal);
374     CHECK_AND_RETURN_RET_LOG(status == napi_ok, napi_invalid_arg, "set error name property fail");
375     return napi_ok;
376 }
377 
CreateError(napi_env env,int32_t errCode,const std::string & errMsg,napi_value & errVal)378 napi_status CommonNapi::CreateError(napi_env env, int32_t errCode, const std::string &errMsg, napi_value &errVal)
379 {
380     napi_get_undefined(env, &errVal);
381 
382     napi_value msgValStr = nullptr;
383     napi_status nstatus = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &msgValStr);
384     if (nstatus != napi_ok || msgValStr == nullptr) {
385         MEDIA_LOGE("create error message str fail");
386         return napi_invalid_arg;
387     }
388 
389     nstatus = napi_create_error(env, nullptr, msgValStr, &errVal);
390     if (nstatus != napi_ok || errVal == nullptr) {
391         MEDIA_LOGE("create error fail");
392         return napi_invalid_arg;
393     }
394 
395     napi_value codeStr = nullptr;
396     nstatus = napi_create_string_utf8(env, "code", NAPI_AUTO_LENGTH, &codeStr);
397     if (nstatus != napi_ok || codeStr == nullptr) {
398         MEDIA_LOGE("create code str fail");
399         return napi_invalid_arg;
400     }
401 
402     napi_value errCodeVal = nullptr;
403     nstatus = napi_create_int32(env, errCode, &errCodeVal);
404     if (nstatus != napi_ok || errCodeVal == nullptr) {
405         MEDIA_LOGE("create error code number val fail");
406         return napi_invalid_arg;
407     }
408 
409     nstatus = napi_set_property(env, errVal, codeStr, errCodeVal);
410     if (nstatus != napi_ok) {
411         MEDIA_LOGE("set error code property fail");
412         return napi_invalid_arg;
413     }
414 
415     napi_value nameStr = nullptr;
416     nstatus = napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &nameStr);
417     if (nstatus != napi_ok || nameStr == nullptr) {
418         MEDIA_LOGE("create name str fail");
419         return napi_invalid_arg;
420     }
421 
422     napi_value errNameVal = nullptr;
423     nstatus = napi_create_string_utf8(env, "BusinessError", NAPI_AUTO_LENGTH, &errNameVal);
424     if (nstatus != napi_ok || errNameVal == nullptr) {
425         MEDIA_LOGE("create BusinessError str fail");
426         return napi_invalid_arg;
427     }
428 
429     nstatus = napi_set_property(env, errVal, nameStr, errNameVal);
430     if (nstatus != napi_ok) {
431         MEDIA_LOGE("set error name property fail");
432         return napi_invalid_arg;
433     }
434 
435     return napi_ok;
436 }
437 
CreateReference(napi_env env,napi_value arg)438 napi_ref CommonNapi::CreateReference(napi_env env, napi_value arg)
439 {
440     napi_ref ref = nullptr;
441     napi_valuetype valueType = napi_undefined;
442     if (arg != nullptr && napi_typeof(env, arg, &valueType) == napi_ok && valueType == napi_function) {
443         MEDIA_LOGD("napi_create_reference");
444         napi_create_reference(env, arg, 1, &ref);
445     }
446     return ref;
447 }
448 
CreatePromise(napi_env env,napi_ref ref,napi_value & result)449 napi_deferred CommonNapi::CreatePromise(napi_env env, napi_ref ref, napi_value &result)
450 {
451     napi_deferred deferred = nullptr;
452     if (ref == nullptr) {
453         MEDIA_LOGD("napi_create_promise");
454         napi_create_promise(env, &deferred, &result);
455     }
456     return deferred;
457 }
458 
SetPropertyByValueType(napi_env env,napi_value & obj,std::shared_ptr<Meta> & meta,std::string key)459 bool CommonNapi::SetPropertyByValueType(napi_env env, napi_value &obj, std::shared_ptr<Meta> &meta, std::string key)
460 {
461     CHECK_AND_RETURN_RET(obj != nullptr && meta != nullptr, false);
462     CHECK_AND_RETURN_RET(meta->Find(key) != meta->end(), false);
463 
464     bool ret = true;
465     AnyValueType type = meta->GetValueType(key);
466     if (type == AnyValueType::STRING) {
467         std::string sValue;
468         ret = meta->GetData(key, sValue);
469         CHECK_AND_RETURN_RET_LOG(ret, ret, "GetData failed, key %{public}s", key.c_str());
470         ret = CommonNapi::SetPropertyString(env, obj, key, sValue);
471         CHECK_AND_RETURN_RET_LOG(ret, ret, "SetPropertyString failed, key %{public}s", key.c_str());
472     } else if (type == AnyValueType::INT32_T) {
473         int32_t value;
474         ret = meta->GetData(key, value);
475         CHECK_AND_RETURN_RET_LOG(ret, ret, "GetData failed, key %{public}s", key.c_str());
476         ret = CommonNapi::SetPropertyInt32(env, obj, key, value);
477         CHECK_AND_RETURN_RET_LOG(ret, ret, "SetPropertyString failed, key %{public}s", key.c_str());
478     } else if (type == AnyValueType::FLOAT) {
479         float dValue;
480         ret = meta->GetData(key, dValue);
481         CHECK_AND_RETURN_RET_LOG(ret, ret, "GetData failed, key %{public}s", key.c_str());
482         ret = CommonNapi::SetPropertyDouble(env, obj, key, dValue);
483         CHECK_AND_RETURN_RET_LOG(ret, ret, "SetPropertyString failed, key %{public}s", key.c_str());
484     } else {
485         MEDIA_LOGE("not supported value type");
486     }
487     return true;
488 }
489 
AddRangeProperty(napi_env env,napi_value obj,const std::string & name,int32_t min,int32_t max)490 bool CommonNapi::AddRangeProperty(napi_env env, napi_value obj, const std::string &name, int32_t min, int32_t max)
491 {
492     CHECK_AND_RETURN_RET(obj != nullptr, false);
493 
494     napi_value range = nullptr;
495     napi_status status = napi_create_object(env, &range);
496     CHECK_AND_RETURN_RET(status == napi_ok, false);
497 
498     CHECK_AND_RETURN_RET(SetPropertyInt32(env, range, "min", min) == true, false);
499     CHECK_AND_RETURN_RET(SetPropertyInt32(env, range, "max", max) == true, false);
500 
501     napi_value nameStr = nullptr;
502     status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &nameStr);
503     CHECK_AND_RETURN_RET(status == napi_ok, false);
504 
505     status = napi_set_property(env, obj, nameStr, range);
506     CHECK_AND_RETURN_RET(status == napi_ok, false);
507 
508     return true;
509 }
510 
AddArrayProperty(napi_env env,napi_value obj,const std::string & name,const std::vector<int32_t> & vec)511 bool CommonNapi::AddArrayProperty(napi_env env, napi_value obj, const std::string &name,
512     const std::vector<int32_t> &vec)
513 {
514     CHECK_AND_RETURN_RET(obj != nullptr, false);
515 
516     napi_value array = nullptr;
517     napi_status status = napi_create_array_with_length(env, vec.size(), &array);
518     CHECK_AND_RETURN_RET(status == napi_ok, false);
519 
520     for (uint32_t i = 0; i < vec.size(); i++) {
521         napi_value number = nullptr;
522         (void)napi_create_int32(env, vec.at(i), &number);
523         (void)napi_set_element(env, array, i, number);
524     }
525 
526     napi_value nameStr = nullptr;
527     status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &nameStr);
528     CHECK_AND_RETURN_RET(status == napi_ok, false);
529 
530     status = napi_set_property(env, obj, nameStr, array);
531     CHECK_AND_RETURN_RET(status == napi_ok, false);
532 
533     return true;
534 }
535 
SetPropertyArrayBuffer(const napi_env & env,napi_value & result,const std::string & fieldStr,size_t bufferLen,uint8_t * bufferData)536 bool CommonNapi::SetPropertyArrayBuffer(
537     const napi_env &env, napi_value &result, const std::string &fieldStr, size_t bufferLen, uint8_t *bufferData)
538 {
539     void *native = nullptr;
540     napi_value arrayBuffer = nullptr;
541     napi_status status = napi_create_arraybuffer(env, bufferLen, &native, &arrayBuffer);
542     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "napi_create_arraybuffer failed");
543     CHECK_AND_RETURN_RET_LOG(memcpy_s(native, bufferLen, bufferData, bufferLen) == 0, false, "memcpy failed");
544 
545     status = napi_set_named_property(env, result, fieldStr.c_str(), arrayBuffer);
546     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "napi_set_named_property failed");
547 
548     return true;
549 }
550 
551 
AddArrayInt(napi_env env,napi_value & array,const std::vector<int32_t> & vec)552 bool CommonNapi::AddArrayInt(napi_env env, napi_value &array, const std::vector<int32_t> &vec)
553 {
554     if (vec.size() == 0) {
555         return false;
556     }
557 
558     napi_status status = napi_create_array_with_length(env, vec.size(), &array);
559     CHECK_AND_RETURN_RET(status == napi_ok, false);
560 
561     for (uint32_t i = 0; i < vec.size(); i++) {
562         napi_value number = nullptr;
563         (void)napi_create_int32(env, vec.at(i), &number);
564         (void)napi_set_element(env, array, i, number);
565     }
566 
567     return true;
568 }
569 
SetPropertyInt32(napi_env env,napi_value & obj,const std::string & key,int32_t value)570 bool CommonNapi::SetPropertyInt32(napi_env env, napi_value &obj, const std::string &key, int32_t value)
571 {
572     CHECK_AND_RETURN_RET(obj != nullptr, false);
573 
574     napi_value keyNapi = nullptr;
575     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
576     CHECK_AND_RETURN_RET(status == napi_ok, false);
577 
578     napi_value valueNapi = nullptr;
579     status = napi_create_int32(env, value, &valueNapi);
580     CHECK_AND_RETURN_RET(status == napi_ok, false);
581 
582     status = napi_set_property(env, obj, keyNapi, valueNapi);
583     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
584 
585     return true;
586 }
587 
SetPropertyInt64(napi_env env,napi_value & obj,const std::string & key,int64_t value)588 bool CommonNapi::SetPropertyInt64(napi_env env, napi_value &obj, const std::string &key, int64_t value)
589 {
590     CHECK_AND_RETURN_RET(obj != nullptr, false);
591 
592     napi_value keyNapi = nullptr;
593     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
594     CHECK_AND_RETURN_RET(status == napi_ok, false);
595 
596     napi_value valueNapi = nullptr;
597     status = napi_create_int64(env, value, &valueNapi);
598     CHECK_AND_RETURN_RET(status == napi_ok, false);
599 
600     status = napi_set_property(env, obj, keyNapi, valueNapi);
601     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
602 
603     return true;
604 }
605 
SetPropertyDouble(napi_env env,napi_value & obj,const std::string & key,double value)606 bool CommonNapi::SetPropertyDouble(napi_env env, napi_value &obj, const std::string &key, double value)
607 {
608     CHECK_AND_RETURN_RET(obj != nullptr, false);
609 
610     napi_value keyNapi = nullptr;
611     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
612     CHECK_AND_RETURN_RET(status == napi_ok, false);
613 
614     napi_value valueNapi = nullptr;
615     status = napi_create_double(env, value, &valueNapi);
616     CHECK_AND_RETURN_RET(status == napi_ok, false);
617 
618     status = napi_set_property(env, obj, keyNapi, valueNapi);
619     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
620 
621     return true;
622 }
623 
SetPropertyBool(napi_env env,napi_value & obj,const std::string & key,bool value)624 bool CommonNapi::SetPropertyBool(napi_env env, napi_value &obj, const std::string &key, bool value)
625 {
626     CHECK_AND_RETURN_RET(obj != nullptr, false);
627 
628     napi_value keyNapi = nullptr;
629     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
630     CHECK_AND_RETURN_RET(status == napi_ok, false);
631 
632     napi_value valueNapi = nullptr;
633     status = napi_get_boolean(env, value, &valueNapi);
634     CHECK_AND_RETURN_RET(status == napi_ok, false);
635 
636     status = napi_set_property(env, obj, keyNapi, valueNapi);
637     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
638 
639     return true;
640 }
641 
SetPropertyString(napi_env env,napi_value & obj,const std::string & key,const std::string & value)642 bool CommonNapi::SetPropertyString(napi_env env, napi_value &obj, const std::string &key, const std::string &value)
643 {
644     CHECK_AND_RETURN_RET(obj != nullptr, false);
645 
646     napi_value keyNapi = nullptr;
647     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
648     CHECK_AND_RETURN_RET(status == napi_ok, false);
649 
650     napi_value valueNapi = nullptr;
651     status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &valueNapi);
652     CHECK_AND_RETURN_RET(status == napi_ok, false);
653 
654     status = napi_set_property(env, obj, keyNapi, valueNapi);
655     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
656 
657     return true;
658 }
659 
CreateFormatBuffer(napi_env env,Format & format)660 napi_value CommonNapi::CreateFormatBuffer(napi_env env, Format &format)
661 {
662     int32_t intValue = 0;
663     size_t bufferLen = 0;
664     std::string strValue;
665     uint8_t *bufferData = nullptr;
666     napi_value buffer = nullptr;
667     napi_status status = napi_create_object(env, &buffer);
668     CHECK_AND_RETURN_RET(status == napi_ok, nullptr);
669 
670     for (auto &iter : format.GetFormatMap()) {
671         switch (format.GetValueType(std::string_view(iter.first))) {
672             case FORMAT_TYPE_INT32:
673                 if (format.GetIntValue(iter.first, intValue)) {
674                     CHECK_AND_RETURN_RET(SetPropertyInt32(env, buffer, iter.first, intValue) == true, nullptr);
675                 }
676                 break;
677             case FORMAT_TYPE_INT64:
678                 int64_t longValue;
679                 if (format.GetLongValue(iter.first, longValue) &&
680                     longValue >= INT32_MIN && longValue <= INT32_MAX) {
681                     intValue = static_cast<int32_t>(longValue);
682                     CHECK_AND_RETURN_RET(SetPropertyInt32(env, buffer, iter.first, intValue) == true, nullptr);
683                 }
684                 break;
685             case FORMAT_TYPE_DOUBLE:
686                 double doubleValue;
687                 if (format.GetDoubleValue(iter.first, doubleValue) &&
688                     doubleValue >= INT32_MIN && doubleValue <= INT32_MAX) {
689                     intValue = static_cast<int32_t>(doubleValue);
690                     CHECK_AND_RETURN_RET(SetPropertyInt32(env, buffer, iter.first, intValue) == true, nullptr);
691                 }
692                 break;
693             case FORMAT_TYPE_STRING:
694                 if (format.GetStringValue(iter.first, strValue)) {
695                     CHECK_AND_RETURN_RET(SetPropertyString(env, buffer, iter.first, strValue) == true, nullptr);
696                 }
697                 break;
698             case FORMAT_TYPE_ADDR:
699                 if (format.GetBuffer(iter.first, &bufferData, bufferLen)) {
700                     CHECK_AND_RETURN_RET(
701                         SetPropertyArrayBuffer(env, buffer, iter.first, bufferLen, bufferData) == true, nullptr);
702                 }
703                 break;
704             default:
705                 MEDIA_LOGE("format key: %{public}s", iter.first.c_str());
706                 break;
707         }
708     }
709 
710     return buffer;
711 }
712 
CreateFormatBufferByRef(napi_env env,Format & format,napi_value & result)713 bool CommonNapi::CreateFormatBufferByRef(napi_env env, Format &format, napi_value &result)
714 {
715     int32_t intValue = 0;
716     int64_t longValue = 0;
717     std::string strValue = "";
718     napi_status status = napi_create_object(env, &result);
719     CHECK_AND_RETURN_RET(status == napi_ok, false);
720 
721     for (auto &iter : format.GetFormatMap()) {
722         switch (format.GetValueType(std::string_view(iter.first))) {
723             case FORMAT_TYPE_INT32:
724                 if (format.GetIntValue(iter.first, intValue)) {
725                     (void)SetPropertyInt32(env, result, iter.first, intValue);
726                 }
727                 break;
728             case FORMAT_TYPE_INT64:
729                 if (format.GetLongValue(iter.first, longValue)) {
730                     (void)SetPropertyInt64(env, result, iter.first, longValue);
731                 }
732                 break;
733             case FORMAT_TYPE_STRING:
734                 if (format.GetStringValue(iter.first, strValue)) {
735                     (void)SetPropertyString(env, result, iter.first, strValue);
736                 }
737                 break;
738             default:
739                 MEDIA_LOGE("format key: %{public}s", iter.first.c_str());
740                 break;
741         }
742     }
743 
744     return true;
745 }
746 
AddNumberPropInt32(napi_env env,napi_value obj,const std::string & key,int32_t value)747 bool CommonNapi::AddNumberPropInt32(napi_env env, napi_value obj, const std::string &key, int32_t value)
748 {
749     CHECK_AND_RETURN_RET(obj != nullptr, false);
750 
751     napi_value keyNapi = nullptr;
752     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
753     CHECK_AND_RETURN_RET(status == napi_ok, false);
754 
755     napi_value valueNapi = nullptr;
756     status = napi_create_int32(env, value, &valueNapi);
757     CHECK_AND_RETURN_RET(status == napi_ok, false);
758 
759     status = napi_set_property(env, obj, keyNapi, valueNapi);
760     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
761 
762     return true;
763 }
764 
AddNumberPropInt64(napi_env env,napi_value obj,const std::string & key,int64_t value)765 bool CommonNapi::AddNumberPropInt64(napi_env env, napi_value obj, const std::string &key, int64_t value)
766 {
767     CHECK_AND_RETURN_RET(obj != nullptr, false);
768 
769     napi_value keyNapi = nullptr;
770     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
771     CHECK_AND_RETURN_RET(status == napi_ok, false);
772 
773     napi_value valueNapi = nullptr;
774     status = napi_create_int64(env, value, &valueNapi);
775     CHECK_AND_RETURN_RET(status == napi_ok, false);
776 
777     status = napi_set_property(env, obj, keyNapi, valueNapi);
778     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
779 
780     return true;
781 }
782 
GetJsResult(napi_env env,napi_value & result)783 napi_status MediaJsResultStringVector::GetJsResult(napi_env env, napi_value &result)
784 {
785     napi_status status;
786     size_t size = value_.size();
787     napi_create_array_with_length(env, size, &result);
788     for (unsigned int i = 0; i < size; ++i) {
789         std::string format = value_[i];
790         napi_value value = nullptr;
791         status = napi_create_string_utf8(env, format.c_str(), NAPI_AUTO_LENGTH, &value);
792         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
793             "Failed to call napi_create_string_utf8, with element %{public}u", i);
794         status = napi_set_element(env, result, i, value);
795         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
796             "Failed to call napi_set_element, with element %{public}u", i);
797     }
798     return napi_ok;
799 }
800 
GetJsResult(napi_env env,napi_value & result)801 napi_status MediaJsResultIntArray::GetJsResult(napi_env env, napi_value &result)
802 {
803     napi_status status;
804     size_t size = value_.size();
805     napi_create_array_with_length(env, size, &result);
806     for (unsigned int i = 0; i < size; ++i) {
807         int32_t index = value_[i];
808         napi_value value = nullptr;
809         status = napi_create_int32(env, index, &value);
810         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
811             "Failed to call napi_create_int32, with element %{public}u", i);
812         status = napi_set_element(env, result, i, value);
813         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
814             "Failed to call napi_set_element, with element %{public}u", i);
815     }
816     return napi_ok;
817 }
818 
GetJsResult(napi_env env,napi_value & result)819 napi_status MediaJsResultArray::GetJsResult(napi_env env, napi_value &result)
820 {
821     // create Description
822     napi_status status = napi_create_array(env, &result);
823     if (status != napi_ok) {
824         return napi_cancelled;
825     }
826 
827     auto vecSize = value_.size();
828     for (size_t index = 0; index < vecSize; ++index) {
829         napi_value description = nullptr;
830         description = CommonNapi::CreateFormatBuffer(env, value_[index]);
831         if (description == nullptr || napi_set_element(env, result, index, description) != napi_ok) {
832             return napi_cancelled;
833         }
834     }
835     return napi_ok;
836 }
837 
MediaAsyncContext(napi_env env)838 MediaAsyncContext::MediaAsyncContext(napi_env env)
839     : env_(env)
840 {
841     MEDIA_LOGD("MediaAsyncContext Create 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
842 }
843 
~MediaAsyncContext()844 MediaAsyncContext::~MediaAsyncContext()
845 {
846     MEDIA_LOGD("MediaAsyncContext Destroy 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
847 }
848 
SignError(int32_t code,const std::string & message,bool del)849 void MediaAsyncContext::SignError(int32_t code, const std::string &message, bool del)
850 {
851     errMessage = message;
852     errCode = code;
853     errFlag = true;
854     delFlag = del;
855     MEDIA_LOGE("SignError: %{public}s", message.c_str());
856 }
857 
ThrowError(napi_env env,const int32_t errCode,const std::string errMsg)858 napi_value CommonNapi::ThrowError(napi_env env, const int32_t errCode, const std::string errMsg)
859 {
860     napi_value result = nullptr;
861     napi_status status = napi_throw_error(env, std::to_string(errCode).c_str(), errMsg.c_str());
862     if (status == napi_ok) {
863         napi_get_undefined(env, &result);
864     }
865     return result;
866 }
867 
CompleteCallback(napi_env env,napi_status status,void * data)868 void MediaAsyncContext::CompleteCallback(napi_env env, napi_status status, void *data)
869 {
870     MEDIA_LOGD("CompleteCallback In");
871     auto asyncContext = reinterpret_cast<MediaAsyncContext *>(data);
872     CHECK_AND_RETURN_LOG(asyncContext != nullptr, "asyncContext is nullptr!");
873 
874     std::string memoryTag = asyncContext->memoryTagHead + asyncContext->memoryTagTail;
875     MEDIA_LOGD("MediaAsyncContext Create 0x%{public}06" PRIXPTR " memoryTag = %{public}s",
876         FAKE_POINTER(data), memoryTag.c_str());
877 
878     if (status != napi_ok) {
879         asyncContext->SignError(MSERR_EXT_UNKNOWN, "napi_create_async_work status != napi_ok");
880     }
881 
882     napi_value result = nullptr;
883     napi_get_undefined(env, &result);
884     napi_value args[2] = { nullptr };
885     napi_get_undefined(env, &args[0]);
886     napi_get_undefined(env, &args[1]);
887     if (asyncContext->errFlag) {
888         MEDIA_LOGD("async callback failed");
889         (void)CommonNapi::CreateError(env, asyncContext->errCode, asyncContext->errMessage, result);
890         args[0] = result;
891     } else {
892         MEDIA_LOGD("async callback success");
893         if (asyncContext->JsResult != nullptr) {
894             asyncContext->JsResult->GetJsResult(env, result);
895             CheckCtorResult(env, result, asyncContext, args[0]);
896         }
897         if (!asyncContext->errFlag) {
898             args[1] = result;
899         }
900     }
901 
902     Callback(env, asyncContext, args);
903     napi_delete_async_work(env, asyncContext->work);
904 
905     if (asyncContext->delFlag) {
906         delete asyncContext;
907         asyncContext = nullptr;
908     }
909 }
910 
Callback(napi_env env,const MediaAsyncContext * context,const napi_value * args)911 void MediaAsyncContext::Callback(napi_env env, const MediaAsyncContext *context, const napi_value *args)
912 {
913     if (context->deferred) {
914         if (context->errFlag) {
915             MEDIA_LOGE("promise napi_reject_deferred");
916             napi_reject_deferred(env, context->deferred, args[0]);
917         } else {
918             MEDIA_LOGD("promise napi_resolve_deferred");
919             napi_resolve_deferred(env, context->deferred, args[1]);
920         }
921     } else if (context->callbackRef != nullptr) {
922         MEDIA_LOGD("callback napi_call_function");
923         napi_value callback = nullptr;
924         napi_get_reference_value(env, context->callbackRef, &callback);
925         CHECK_AND_RETURN_LOG(callback != nullptr, "callback is nullptr!");
926         constexpr size_t argCount = 2;
927         napi_value retVal;
928         napi_get_undefined(env, &retVal);
929         napi_call_function(env, nullptr, callback, argCount, args, &retVal);
930         napi_delete_reference(env, context->callbackRef);
931     } else {
932         MEDIA_LOGE("invalid promise and callback");
933     }
934 }
935 
CheckCtorResult(napi_env env,napi_value & result,MediaAsyncContext * ctx,napi_value & args)936 void MediaAsyncContext::CheckCtorResult(napi_env env, napi_value &result, MediaAsyncContext *ctx, napi_value &args)
937 {
938     CHECK_AND_RETURN(ctx != nullptr);
939     if (ctx->ctorFlag) {
940         void *instance = nullptr;
941         if (napi_unwrap(env, result, reinterpret_cast<void **>(&instance)) != napi_ok || instance == nullptr) {
942             MEDIA_LOGE("Failed to create instance");
943             ctx->errFlag = true;
944             (void)CommonNapi::CreateError(env, MSERR_EXT_API9_NO_MEMORY,
945                 "The instance or memory has reached the upper limit, please recycle background playback", result);
946             args = result;
947         }
948     }
949 }
950 
SendCompleteEvent(napi_env env,MediaAsyncContext * asyncContext,napi_event_priority prio)951 napi_status MediaAsyncContext::SendCompleteEvent(napi_env env, MediaAsyncContext *asyncContext,
952                                                  napi_event_priority prio)
953 {
954     auto task = [env, asyncContext]() {
955         MEDIA_LOGD("CompleteCallback In");
956         CHECK_AND_RETURN_LOG(asyncContext != nullptr, "asyncContext is nullptr!");
957 
958         std::string memoryTag = asyncContext->memoryTagHead + asyncContext->memoryTagTail;
959         MEDIA_LOGD("MediaAsyncContext 0x%{public}06" PRIXPTR " memoryTag = %{public}s",
960             FAKE_POINTER(asyncContext), memoryTag.c_str());
961 
962         napi_value result = nullptr;
963         napi_get_undefined(env, &result);
964         napi_value args[2] = { nullptr };
965         napi_get_undefined(env, &args[0]);
966         napi_get_undefined(env, &args[1]);
967         if (asyncContext->errFlag) {
968             MEDIA_LOGD("async callback failed");
969             (void)CommonNapi::CreateError(env, asyncContext->errCode, asyncContext->errMessage, result);
970             args[0] = result;
971         } else {
972             MEDIA_LOGD("async callback success");
973             if (asyncContext->JsResult != nullptr) {
974                 asyncContext->JsResult->GetJsResult(env, result);
975                 CheckCtorResult(env, result, asyncContext, args[0]);
976             }
977             if (!asyncContext->errFlag) {
978                 args[1] = result;
979             }
980         }
981 
982         Callback(env, asyncContext, args);
983         if (asyncContext->delFlag) {
984             delete asyncContext;
985         }
986     };
987     return napi_send_event(env, task, prio);
988 }
989 
AddStringProperty(napi_env env,napi_value obj,const std::string & key,const std::string & value)990 bool CommonNapi::AddStringProperty(napi_env env, napi_value obj, const std::string &key, const std::string &value)
991 {
992     CHECK_AND_RETURN_RET(obj != nullptr, false);
993 
994     napi_value keyNapi = nullptr;
995     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
996     CHECK_AND_RETURN_RET(status == napi_ok, false);
997 
998     napi_value valueNapi = nullptr;
999     status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &valueNapi);
1000     CHECK_AND_RETURN_RET(status == napi_ok, false);
1001 
1002     status = napi_set_property(env, obj, keyNapi, valueNapi);
1003     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
1004 
1005     return true;
1006 }
1007 
GetPropertyBool(napi_env env,napi_value configObj,const std::string & type,bool & result)1008 bool CommonNapi::GetPropertyBool(napi_env env, napi_value configObj, const std::string &type, bool &result)
1009 {
1010     bool exist = false;
1011     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
1012     if (status != napi_ok || !exist) {
1013         MEDIA_LOGE("can not find %{public}s property", type.c_str());
1014         return false;
1015     }
1016     napi_value item = nullptr;
1017     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
1018         MEDIA_LOGE("get %{public}s property fail", type.c_str());
1019         return false;
1020     }
1021     if (napi_get_value_bool(env, item, &result) != napi_ok) {
1022         MEDIA_LOGE("get %{public}s property value fail", type.c_str());
1023         return false;
1024     }
1025     return true;
1026 }
1027 
ConvertDeviceInfoToAudioDeviceDescriptor(std::shared_ptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor,const AudioStandard::AudioDeviceDescriptor & deviceInfo)1028 void CommonNapi::ConvertDeviceInfoToAudioDeviceDescriptor(
1029     std::shared_ptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor,
1030     const AudioStandard::AudioDeviceDescriptor &deviceInfo)
1031 {
1032     CHECK_AND_RETURN_LOG(audioDeviceDescriptor != nullptr, "audioDeviceDescriptor is nullptr");
1033     audioDeviceDescriptor->deviceRole_ = deviceInfo.deviceRole_;
1034     audioDeviceDescriptor->deviceType_ = deviceInfo.deviceType_;
1035     audioDeviceDescriptor->deviceId_ = deviceInfo.deviceId_;
1036     audioDeviceDescriptor->channelMasks_ = deviceInfo.channelMasks_;
1037     audioDeviceDescriptor->channelIndexMasks_ = deviceInfo.channelIndexMasks_;
1038     audioDeviceDescriptor->deviceName_ = deviceInfo.deviceName_;
1039     audioDeviceDescriptor->macAddress_ = deviceInfo.macAddress_;
1040     audioDeviceDescriptor->interruptGroupId_ = deviceInfo.interruptGroupId_;
1041     audioDeviceDescriptor->volumeGroupId_ = deviceInfo.volumeGroupId_;
1042     audioDeviceDescriptor->networkId_ = deviceInfo.networkId_;
1043     audioDeviceDescriptor->displayName_ = deviceInfo.displayName_;
1044     audioDeviceDescriptor->audioStreamInfo_ = deviceInfo.audioStreamInfo_;
1045 }
1046 
SetDeviceDescriptor(const napi_env & env,const AudioStandard::AudioDeviceDescriptor & deviceInfo,napi_value & result)1047 napi_status CommonNapi::SetDeviceDescriptor(const napi_env &env, const AudioStandard::AudioDeviceDescriptor &deviceInfo,
1048     napi_value &result)
1049 {
1050     (void)napi_create_object(env, &result);
1051     SetPropertyInt32(env, result, "deviceRole", static_cast<int32_t>(deviceInfo.deviceRole_));
1052     SetPropertyInt32(env, result, "deviceType", static_cast<int32_t>(deviceInfo.deviceType_));
1053     SetPropertyInt32(env, result, "id", static_cast<int32_t>(deviceInfo.deviceId_));
1054     SetPropertyString(env, result, "name", deviceInfo.deviceName_);
1055     SetPropertyString(env, result, "address", deviceInfo.macAddress_);
1056     SetPropertyString(env, result, "networkId", deviceInfo.networkId_);
1057     SetPropertyString(env, result, "displayName", deviceInfo.displayName_);
1058     SetPropertyInt32(env, result, "interruptGroupId", static_cast<int32_t>(deviceInfo.interruptGroupId_));
1059     SetPropertyInt32(env, result, "volumeGroupId", static_cast<int32_t>(deviceInfo.volumeGroupId_));
1060 
1061     napi_value value = nullptr;
1062     napi_value sampleRates;
1063     AudioStandard::DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo();
1064     size_t size = audioStreamInfo.samplingRate.size();
1065     napi_create_array_with_length(env, size, &sampleRates);
1066     size_t count = 0;
1067     for (const auto &samplingRate : audioStreamInfo.samplingRate) {
1068         napi_create_int32(env, samplingRate, &value);
1069         napi_set_element(env, sampleRates, count, value);
1070         count++;
1071     }
1072     napi_set_named_property(env, result, "sampleRates", sampleRates);
1073 
1074     napi_value channelCounts;
1075     std::set<AudioStandard::AudioChannel> channelSet = audioStreamInfo.GetChannels();
1076     size = channelSet.size();
1077     napi_create_array_with_length(env, size, &channelCounts);
1078     count = 0;
1079     for (const auto &channels : channelSet) {
1080         napi_create_int32(env, channels, &value);
1081         napi_set_element(env, channelCounts, count, value);
1082         count++;
1083     }
1084     napi_set_named_property(env, result, "channelCounts", channelCounts);
1085 
1086     std::vector<int32_t> channelMasks_;
1087     channelMasks_.push_back(deviceInfo.channelMasks_);
1088     AddArrayProperty(env, result, "channelMasks", channelMasks_);
1089 
1090     std::vector<int32_t> channelIndexMasks_;
1091     channelIndexMasks_.push_back(deviceInfo.channelIndexMasks_);
1092     AddArrayProperty(env, result, "channelIndexMasks", channelIndexMasks_);
1093 
1094     std::vector<int32_t> encoding;
1095     encoding.push_back(audioStreamInfo.encoding);
1096     AddArrayProperty(env, result, "encodingTypes", encoding);
1097 
1098     return napi_ok;
1099 }
1100 
SetDeviceDescriptors(const napi_env & env,const std::vector<std::shared_ptr<AudioStandard::AudioDeviceDescriptor>> & deviceDescriptors,napi_value & result)1101 napi_status CommonNapi::SetDeviceDescriptors(const napi_env &env,
1102     const std::vector<std::shared_ptr<AudioStandard::AudioDeviceDescriptor>> &deviceDescriptors, napi_value &result)
1103 {
1104     napi_status status = napi_create_array_with_length(env, deviceDescriptors.size(), &result);
1105     for (size_t i = 0; i < deviceDescriptors.size(); i++) {
1106         if (deviceDescriptors[i] != nullptr) {
1107             napi_value valueParam = nullptr;
1108             SetDeviceDescriptor(env, deviceDescriptors[i], valueParam);
1109             napi_set_element(env, result, i, valueParam);
1110         }
1111     }
1112     return status;
1113 }
1114 
SetValueDeviceInfo(const napi_env & env,const AudioStandard::AudioDeviceDescriptor & deviceInfo,napi_value & result)1115 napi_status CommonNapi::SetValueDeviceInfo(const napi_env &env, const AudioStandard::AudioDeviceDescriptor &deviceInfo,
1116     napi_value &result)
1117 {
1118     std::vector<std::shared_ptr<AudioStandard::AudioDeviceDescriptor>> deviceDescriptors;
1119     std::shared_ptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor =
1120         std::make_shared<AudioStandard::AudioDeviceDescriptor>();
1121     CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptor != nullptr, napi_generic_failure,
1122         "audioDeviceDescriptor malloc failed");
1123     ConvertDeviceInfoToAudioDeviceDescriptor(audioDeviceDescriptor, deviceInfo);
1124     deviceDescriptors.push_back(std::move(audioDeviceDescriptor));
1125     SetDeviceDescriptors(env, deviceDescriptors, result);
1126     return napi_ok;
1127 }
1128 } // namespace Media
1129 } // namespace OHOS