• 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 (!GetPropertyInt32(env, value, "mutedMediaType", playStrategy.mutedMediaType)) {
307         playStrategy.mutedMediaType = MediaType::MEDIA_TYPE_MAX_COUNT; // use default value
308     }
309     playStrategy.preferredAudioLanguage = GetPropertyString(env, value, "preferredAudioLanguage");
310     playStrategy.preferredSubtitleLanguage = GetPropertyString(env, value, "preferredSubtitleLanguage");
311     if (!GetPropertyDouble(env, value, "preferredBufferDurationForPlaying",
312         playStrategy.preferredBufferDurationForPlaying)) {
313         playStrategy.preferredBufferDurationForPlaying = 0; // use default value
314         playStrategy.isSetBufferDurationForPlaying = false;
315     }
316     if (!GetPropertyDouble(env, value, "thresholdForAutoQuickPlay", playStrategy.thresholdForAutoQuickPlay)) {
317         playStrategy.thresholdForAutoQuickPlay = -1;
318         playStrategy.isSetThresholdForAutoQuickPlay = false;
319     }
320     return true;
321 }
322 
GetPlayMediaStreamData(napi_env env,napi_value value,AVPlayMediaStreamTmp & mediaStream)323 bool CommonNapi::GetPlayMediaStreamData(napi_env env, napi_value value, AVPlayMediaStreamTmp &mediaStream)
324 {
325     bool existProperty = CommonNapi::CheckhasNamedProperty(env, value, "url");
326     existProperty &= CommonNapi::CheckhasNamedProperty(env, value, "width");
327     existProperty &= CommonNapi::CheckhasNamedProperty(env, value, "height");
328     existProperty &= CommonNapi::CheckhasNamedProperty(env, value, "bitrate");
329     CHECK_AND_RETURN_RET_LOG(existProperty, false, "property is not complete for AVPlayMediaStream");
330 
331     mediaStream.url = GetPropertyString(env, value, "url");
332     GetPropertyUint32(env, value, "width", mediaStream.width);
333     GetPropertyUint32(env, value, "height", mediaStream.height);
334     GetPropertyUint32(env, value, "bitrate", mediaStream.bitrate);
335     return true;
336 }
337 
FillErrorArgs(napi_env env,int32_t errCode,const napi_value & args)338 napi_status CommonNapi::FillErrorArgs(napi_env env, int32_t errCode, const napi_value &args)
339 {
340     napi_value codeStr = nullptr;
341     napi_status status = napi_create_string_utf8(env, "code", NAPI_AUTO_LENGTH, &codeStr);
342     CHECK_AND_RETURN_RET_LOG(status == napi_ok && codeStr != nullptr, napi_invalid_arg, "create code str fail");
343 
344     napi_value errCodeVal = nullptr;
345     int32_t errCodeInt = errCode;
346     status = napi_create_int32(env, errCodeInt, &errCodeVal);
347     CHECK_AND_RETURN_RET_LOG(status == napi_ok && errCodeVal != nullptr, napi_invalid_arg,
348         "create error code number val fail");
349 
350     status = napi_set_property(env, args, codeStr, errCodeVal);
351     CHECK_AND_RETURN_RET_LOG(status == napi_ok, napi_invalid_arg, "set error code property fail");
352 
353     napi_value nameStr = nullptr;
354     status = napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &nameStr);
355     CHECK_AND_RETURN_RET_LOG(status == napi_ok && nameStr != nullptr, napi_invalid_arg, "create name str fail");
356 
357     napi_value errNameVal = nullptr;
358     status = napi_create_string_utf8(env, "BusinessError", NAPI_AUTO_LENGTH, &errNameVal);
359     CHECK_AND_RETURN_RET_LOG(status == napi_ok && errNameVal != nullptr, napi_invalid_arg,
360         "create BusinessError str fail");
361 
362     status = napi_set_property(env, args, nameStr, errNameVal);
363     CHECK_AND_RETURN_RET_LOG(status == napi_ok, napi_invalid_arg, "set error name property fail");
364     return napi_ok;
365 }
366 
CreateError(napi_env env,int32_t errCode,const std::string & errMsg,napi_value & errVal)367 napi_status CommonNapi::CreateError(napi_env env, int32_t errCode, const std::string &errMsg, napi_value &errVal)
368 {
369     napi_get_undefined(env, &errVal);
370 
371     napi_value msgValStr = nullptr;
372     napi_status nstatus = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &msgValStr);
373     if (nstatus != napi_ok || msgValStr == nullptr) {
374         MEDIA_LOGE("create error message str fail");
375         return napi_invalid_arg;
376     }
377 
378     nstatus = napi_create_error(env, nullptr, msgValStr, &errVal);
379     if (nstatus != napi_ok || errVal == nullptr) {
380         MEDIA_LOGE("create error fail");
381         return napi_invalid_arg;
382     }
383 
384     napi_value codeStr = nullptr;
385     nstatus = napi_create_string_utf8(env, "code", NAPI_AUTO_LENGTH, &codeStr);
386     if (nstatus != napi_ok || codeStr == nullptr) {
387         MEDIA_LOGE("create code str fail");
388         return napi_invalid_arg;
389     }
390 
391     napi_value errCodeVal = nullptr;
392     nstatus = napi_create_int32(env, errCode, &errCodeVal);
393     if (nstatus != napi_ok || errCodeVal == nullptr) {
394         MEDIA_LOGE("create error code number val fail");
395         return napi_invalid_arg;
396     }
397 
398     nstatus = napi_set_property(env, errVal, codeStr, errCodeVal);
399     if (nstatus != napi_ok) {
400         MEDIA_LOGE("set error code property fail");
401         return napi_invalid_arg;
402     }
403 
404     napi_value nameStr = nullptr;
405     nstatus = napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &nameStr);
406     if (nstatus != napi_ok || nameStr == nullptr) {
407         MEDIA_LOGE("create name str fail");
408         return napi_invalid_arg;
409     }
410 
411     napi_value errNameVal = nullptr;
412     nstatus = napi_create_string_utf8(env, "BusinessError", NAPI_AUTO_LENGTH, &errNameVal);
413     if (nstatus != napi_ok || errNameVal == nullptr) {
414         MEDIA_LOGE("create BusinessError str fail");
415         return napi_invalid_arg;
416     }
417 
418     nstatus = napi_set_property(env, errVal, nameStr, errNameVal);
419     if (nstatus != napi_ok) {
420         MEDIA_LOGE("set error name property fail");
421         return napi_invalid_arg;
422     }
423 
424     return napi_ok;
425 }
426 
CreateReference(napi_env env,napi_value arg)427 napi_ref CommonNapi::CreateReference(napi_env env, napi_value arg)
428 {
429     napi_ref ref = nullptr;
430     napi_valuetype valueType = napi_undefined;
431     if (arg != nullptr && napi_typeof(env, arg, &valueType) == napi_ok && valueType == napi_function) {
432         MEDIA_LOGD("napi_create_reference");
433         napi_create_reference(env, arg, 1, &ref);
434     }
435     return ref;
436 }
437 
CreatePromise(napi_env env,napi_ref ref,napi_value & result)438 napi_deferred CommonNapi::CreatePromise(napi_env env, napi_ref ref, napi_value &result)
439 {
440     napi_deferred deferred = nullptr;
441     if (ref == nullptr) {
442         MEDIA_LOGD("napi_create_promise");
443         napi_create_promise(env, &deferred, &result);
444     }
445     return deferred;
446 }
447 
SetPropertyByValueType(napi_env env,napi_value & obj,std::shared_ptr<Meta> & meta,std::string key)448 bool CommonNapi::SetPropertyByValueType(napi_env env, napi_value &obj, std::shared_ptr<Meta> &meta, std::string key)
449 {
450     CHECK_AND_RETURN_RET(obj != nullptr && meta != nullptr, false);
451     CHECK_AND_RETURN_RET(meta->Find(key) != meta->end(), false);
452 
453     bool ret = true;
454     AnyValueType type = meta->GetValueType(key);
455     if (type == AnyValueType::STRING) {
456         std::string sValue;
457         ret = meta->GetData(key, sValue);
458         CHECK_AND_RETURN_RET_LOG(ret, ret, "GetData failed, key %{public}s", key.c_str());
459         ret = CommonNapi::SetPropertyString(env, obj, key, sValue);
460         CHECK_AND_RETURN_RET_LOG(ret, ret, "SetPropertyString failed, key %{public}s", key.c_str());
461     } else if (type == AnyValueType::INT32_T) {
462         int32_t value;
463         ret = meta->GetData(key, value);
464         CHECK_AND_RETURN_RET_LOG(ret, ret, "GetData failed, key %{public}s", key.c_str());
465         ret = CommonNapi::SetPropertyInt32(env, obj, key, value);
466         CHECK_AND_RETURN_RET_LOG(ret, ret, "SetPropertyString failed, key %{public}s", key.c_str());
467     } else if (type == AnyValueType::FLOAT) {
468         float dValue;
469         ret = meta->GetData(key, dValue);
470         CHECK_AND_RETURN_RET_LOG(ret, ret, "GetData failed, key %{public}s", key.c_str());
471         ret = CommonNapi::SetPropertyDouble(env, obj, key, dValue);
472         CHECK_AND_RETURN_RET_LOG(ret, ret, "SetPropertyString failed, key %{public}s", key.c_str());
473     } else {
474         MEDIA_LOGE("not supported value type");
475     }
476     return true;
477 }
478 
AddRangeProperty(napi_env env,napi_value obj,const std::string & name,int32_t min,int32_t max)479 bool CommonNapi::AddRangeProperty(napi_env env, napi_value obj, const std::string &name, int32_t min, int32_t max)
480 {
481     CHECK_AND_RETURN_RET(obj != nullptr, false);
482 
483     napi_value range = nullptr;
484     napi_status status = napi_create_object(env, &range);
485     CHECK_AND_RETURN_RET(status == napi_ok, false);
486 
487     CHECK_AND_RETURN_RET(SetPropertyInt32(env, range, "min", min) == true, false);
488     CHECK_AND_RETURN_RET(SetPropertyInt32(env, range, "max", max) == true, false);
489 
490     napi_value nameStr = nullptr;
491     status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &nameStr);
492     CHECK_AND_RETURN_RET(status == napi_ok, false);
493 
494     status = napi_set_property(env, obj, nameStr, range);
495     CHECK_AND_RETURN_RET(status == napi_ok, false);
496 
497     return true;
498 }
499 
AddArrayProperty(napi_env env,napi_value obj,const std::string & name,const std::vector<int32_t> & vec)500 bool CommonNapi::AddArrayProperty(napi_env env, napi_value obj, const std::string &name,
501     const std::vector<int32_t> &vec)
502 {
503     CHECK_AND_RETURN_RET(obj != nullptr, false);
504 
505     napi_value array = nullptr;
506     napi_status status = napi_create_array_with_length(env, vec.size(), &array);
507     CHECK_AND_RETURN_RET(status == napi_ok, false);
508 
509     for (uint32_t i = 0; i < vec.size(); i++) {
510         napi_value number = nullptr;
511         (void)napi_create_int32(env, vec.at(i), &number);
512         (void)napi_set_element(env, array, i, number);
513     }
514 
515     napi_value nameStr = nullptr;
516     status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &nameStr);
517     CHECK_AND_RETURN_RET(status == napi_ok, false);
518 
519     status = napi_set_property(env, obj, nameStr, array);
520     CHECK_AND_RETURN_RET(status == napi_ok, false);
521 
522     return true;
523 }
524 
SetPropertyArrayBuffer(const napi_env & env,napi_value & result,const std::string & fieldStr,size_t bufferLen,uint8_t * bufferData)525 bool CommonNapi::SetPropertyArrayBuffer(
526     const napi_env &env, napi_value &result, const std::string &fieldStr, size_t bufferLen, uint8_t *bufferData)
527 {
528     void *native = nullptr;
529     napi_value arrayBuffer = nullptr;
530     napi_status status = napi_create_arraybuffer(env, bufferLen, &native, &arrayBuffer);
531     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "napi_create_arraybuffer failed");
532     CHECK_AND_RETURN_RET_LOG(memcpy_s(native, bufferLen, bufferData, bufferLen) == 0, false, "memcpy failed");
533 
534     status = napi_set_named_property(env, result, fieldStr.c_str(), arrayBuffer);
535     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "napi_set_named_property failed");
536 
537     return true;
538 }
539 
540 
AddArrayInt(napi_env env,napi_value & array,const std::vector<int32_t> & vec)541 bool CommonNapi::AddArrayInt(napi_env env, napi_value &array, const std::vector<int32_t> &vec)
542 {
543     if (vec.size() == 0) {
544         return false;
545     }
546 
547     napi_status status = napi_create_array_with_length(env, vec.size(), &array);
548     CHECK_AND_RETURN_RET(status == napi_ok, false);
549 
550     for (uint32_t i = 0; i < vec.size(); i++) {
551         napi_value number = nullptr;
552         (void)napi_create_int32(env, vec.at(i), &number);
553         (void)napi_set_element(env, array, i, number);
554     }
555 
556     return true;
557 }
558 
SetPropertyInt32(napi_env env,napi_value & obj,const std::string & key,int32_t value)559 bool CommonNapi::SetPropertyInt32(napi_env env, napi_value &obj, const std::string &key, int32_t value)
560 {
561     CHECK_AND_RETURN_RET(obj != nullptr, false);
562 
563     napi_value keyNapi = nullptr;
564     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
565     CHECK_AND_RETURN_RET(status == napi_ok, false);
566 
567     napi_value valueNapi = nullptr;
568     status = napi_create_int32(env, value, &valueNapi);
569     CHECK_AND_RETURN_RET(status == napi_ok, false);
570 
571     status = napi_set_property(env, obj, keyNapi, valueNapi);
572     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
573 
574     return true;
575 }
576 
SetPropertyInt64(napi_env env,napi_value & obj,const std::string & key,int64_t value)577 bool CommonNapi::SetPropertyInt64(napi_env env, napi_value &obj, const std::string &key, int64_t value)
578 {
579     CHECK_AND_RETURN_RET(obj != nullptr, false);
580 
581     napi_value keyNapi = nullptr;
582     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
583     CHECK_AND_RETURN_RET(status == napi_ok, false);
584 
585     napi_value valueNapi = nullptr;
586     status = napi_create_int64(env, value, &valueNapi);
587     CHECK_AND_RETURN_RET(status == napi_ok, false);
588 
589     status = napi_set_property(env, obj, keyNapi, valueNapi);
590     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
591 
592     return true;
593 }
594 
SetPropertyDouble(napi_env env,napi_value & obj,const std::string & key,double value)595 bool CommonNapi::SetPropertyDouble(napi_env env, napi_value &obj, const std::string &key, double value)
596 {
597     CHECK_AND_RETURN_RET(obj != nullptr, false);
598 
599     napi_value keyNapi = nullptr;
600     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
601     CHECK_AND_RETURN_RET(status == napi_ok, false);
602 
603     napi_value valueNapi = nullptr;
604     status = napi_create_double(env, value, &valueNapi);
605     CHECK_AND_RETURN_RET(status == napi_ok, false);
606 
607     status = napi_set_property(env, obj, keyNapi, valueNapi);
608     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
609 
610     return true;
611 }
612 
SetPropertyBool(napi_env env,napi_value & obj,const std::string & key,bool value)613 bool CommonNapi::SetPropertyBool(napi_env env, napi_value &obj, const std::string &key, bool value)
614 {
615     CHECK_AND_RETURN_RET(obj != nullptr, false);
616 
617     napi_value keyNapi = nullptr;
618     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
619     CHECK_AND_RETURN_RET(status == napi_ok, false);
620 
621     napi_value valueNapi = nullptr;
622     status = napi_get_boolean(env, value, &valueNapi);
623     CHECK_AND_RETURN_RET(status == napi_ok, false);
624 
625     status = napi_set_property(env, obj, keyNapi, valueNapi);
626     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
627 
628     return true;
629 }
630 
SetPropertyString(napi_env env,napi_value & obj,const std::string & key,const std::string & value)631 bool CommonNapi::SetPropertyString(napi_env env, napi_value &obj, const std::string &key, const std::string &value)
632 {
633     CHECK_AND_RETURN_RET(obj != nullptr, false);
634 
635     napi_value keyNapi = nullptr;
636     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
637     CHECK_AND_RETURN_RET(status == napi_ok, false);
638 
639     napi_value valueNapi = nullptr;
640     status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &valueNapi);
641     CHECK_AND_RETURN_RET(status == napi_ok, false);
642 
643     status = napi_set_property(env, obj, keyNapi, valueNapi);
644     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
645 
646     return true;
647 }
648 
CreateFormatBuffer(napi_env env,Format & format)649 napi_value CommonNapi::CreateFormatBuffer(napi_env env, Format &format)
650 {
651     int32_t intValue = 0;
652     size_t bufferLen = 0;
653     std::string strValue;
654     uint8_t *bufferData = nullptr;
655     napi_value buffer = nullptr;
656     napi_status status = napi_create_object(env, &buffer);
657     CHECK_AND_RETURN_RET(status == napi_ok, nullptr);
658 
659     for (auto &iter : format.GetFormatMap()) {
660         switch (format.GetValueType(std::string_view(iter.first))) {
661             case FORMAT_TYPE_INT32:
662                 if (format.GetIntValue(iter.first, intValue)) {
663                     CHECK_AND_RETURN_RET(SetPropertyInt32(env, buffer, iter.first, intValue) == true, nullptr);
664                 }
665                 break;
666             case FORMAT_TYPE_INT64:
667                 int64_t longValue;
668                 if (format.GetLongValue(iter.first, longValue) &&
669                     longValue >= INT32_MIN && longValue <= INT32_MAX) {
670                     intValue = static_cast<int32_t>(longValue);
671                     CHECK_AND_RETURN_RET(SetPropertyInt32(env, buffer, iter.first, intValue) == true, nullptr);
672                 }
673                 break;
674             case FORMAT_TYPE_DOUBLE:
675                 double doubleValue;
676                 if (format.GetDoubleValue(iter.first, doubleValue) &&
677                     doubleValue >= INT32_MIN && doubleValue <= INT32_MAX) {
678                     intValue = static_cast<int32_t>(doubleValue);
679                     CHECK_AND_RETURN_RET(SetPropertyInt32(env, buffer, iter.first, intValue) == true, nullptr);
680                 }
681                 break;
682             case FORMAT_TYPE_STRING:
683                 if (format.GetStringValue(iter.first, strValue)) {
684                     CHECK_AND_RETURN_RET(SetPropertyString(env, buffer, iter.first, strValue) == true, nullptr);
685                 }
686                 break;
687             case FORMAT_TYPE_ADDR:
688                 if (format.GetBuffer(iter.first, &bufferData, bufferLen)) {
689                     CHECK_AND_RETURN_RET(
690                         SetPropertyArrayBuffer(env, buffer, iter.first, bufferLen, bufferData) == true, nullptr);
691                 }
692                 break;
693             default:
694                 MEDIA_LOGE("format key: %{public}s", iter.first.c_str());
695                 break;
696         }
697     }
698 
699     return buffer;
700 }
701 
CreateFormatBufferByRef(napi_env env,Format & format,napi_value & result)702 bool CommonNapi::CreateFormatBufferByRef(napi_env env, Format &format, napi_value &result)
703 {
704     int32_t intValue = 0;
705     int64_t longValue = 0;
706     std::string strValue = "";
707     napi_status status = napi_create_object(env, &result);
708     CHECK_AND_RETURN_RET(status == napi_ok, false);
709 
710     for (auto &iter : format.GetFormatMap()) {
711         switch (format.GetValueType(std::string_view(iter.first))) {
712             case FORMAT_TYPE_INT32:
713                 if (format.GetIntValue(iter.first, intValue)) {
714                     (void)SetPropertyInt32(env, result, iter.first, intValue);
715                 }
716                 break;
717             case FORMAT_TYPE_INT64:
718                 if (format.GetLongValue(iter.first, longValue)) {
719                     (void)SetPropertyInt64(env, result, iter.first, longValue);
720                 }
721                 break;
722             case FORMAT_TYPE_STRING:
723                 if (format.GetStringValue(iter.first, strValue)) {
724                     (void)SetPropertyString(env, result, iter.first, strValue);
725                 }
726                 break;
727             default:
728                 MEDIA_LOGE("format key: %{public}s", iter.first.c_str());
729                 break;
730         }
731     }
732 
733     return true;
734 }
735 
AddNumberPropInt32(napi_env env,napi_value obj,const std::string & key,int32_t value)736 bool CommonNapi::AddNumberPropInt32(napi_env env, napi_value obj, const std::string &key, int32_t value)
737 {
738     CHECK_AND_RETURN_RET(obj != nullptr, false);
739 
740     napi_value keyNapi = nullptr;
741     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
742     CHECK_AND_RETURN_RET(status == napi_ok, false);
743 
744     napi_value valueNapi = nullptr;
745     status = napi_create_int32(env, value, &valueNapi);
746     CHECK_AND_RETURN_RET(status == napi_ok, false);
747 
748     status = napi_set_property(env, obj, keyNapi, valueNapi);
749     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
750 
751     return true;
752 }
753 
AddNumberPropInt64(napi_env env,napi_value obj,const std::string & key,int64_t value)754 bool CommonNapi::AddNumberPropInt64(napi_env env, napi_value obj, const std::string &key, int64_t value)
755 {
756     CHECK_AND_RETURN_RET(obj != nullptr, false);
757 
758     napi_value keyNapi = nullptr;
759     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
760     CHECK_AND_RETURN_RET(status == napi_ok, false);
761 
762     napi_value valueNapi = nullptr;
763     status = napi_create_int64(env, value, &valueNapi);
764     CHECK_AND_RETURN_RET(status == napi_ok, false);
765 
766     status = napi_set_property(env, obj, keyNapi, valueNapi);
767     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
768 
769     return true;
770 }
771 
GetJsResult(napi_env env,napi_value & result)772 napi_status MediaJsResultStringVector::GetJsResult(napi_env env, napi_value &result)
773 {
774     napi_status status;
775     size_t size = value_.size();
776     napi_create_array_with_length(env, size, &result);
777     for (unsigned int i = 0; i < size; ++i) {
778         std::string format = value_[i];
779         napi_value value = nullptr;
780         status = napi_create_string_utf8(env, format.c_str(), NAPI_AUTO_LENGTH, &value);
781         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
782             "Failed to call napi_create_string_utf8, with element %{public}u", i);
783         status = napi_set_element(env, result, i, value);
784         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
785             "Failed to call napi_set_element, with element %{public}u", i);
786     }
787     return napi_ok;
788 }
789 
GetJsResult(napi_env env,napi_value & result)790 napi_status MediaJsResultIntArray::GetJsResult(napi_env env, napi_value &result)
791 {
792     napi_status status;
793     size_t size = value_.size();
794     napi_create_array_with_length(env, size, &result);
795     for (unsigned int i = 0; i < size; ++i) {
796         int32_t index = value_[i];
797         napi_value value = nullptr;
798         status = napi_create_int32(env, index, &value);
799         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
800             "Failed to call napi_create_int32, with element %{public}u", i);
801         status = napi_set_element(env, result, i, value);
802         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
803             "Failed to call napi_set_element, with element %{public}u", i);
804     }
805     return napi_ok;
806 }
807 
GetJsResult(napi_env env,napi_value & result)808 napi_status MediaJsResultArray::GetJsResult(napi_env env, napi_value &result)
809 {
810     // create Description
811     napi_status status = napi_create_array(env, &result);
812     if (status != napi_ok) {
813         return napi_cancelled;
814     }
815 
816     auto vecSize = value_.size();
817     for (size_t index = 0; index < vecSize; ++index) {
818         napi_value description = nullptr;
819         description = CommonNapi::CreateFormatBuffer(env, value_[index]);
820         if (description == nullptr || napi_set_element(env, result, index, description) != napi_ok) {
821             return napi_cancelled;
822         }
823     }
824     return napi_ok;
825 }
826 
MediaAsyncContext(napi_env env)827 MediaAsyncContext::MediaAsyncContext(napi_env env)
828     : env_(env)
829 {
830     MEDIA_LOGD("MediaAsyncContext Create 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
831 }
832 
~MediaAsyncContext()833 MediaAsyncContext::~MediaAsyncContext()
834 {
835     MEDIA_LOGD("MediaAsyncContext Destroy 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
836 }
837 
SignError(int32_t code,const std::string & message,bool del)838 void MediaAsyncContext::SignError(int32_t code, const std::string &message, bool del)
839 {
840     errMessage = message;
841     errCode = code;
842     errFlag = true;
843     delFlag = del;
844     MEDIA_LOGE("SignError: %{public}s", message.c_str());
845 }
846 
ThrowError(napi_env env,const int32_t errCode,const std::string errMsg)847 napi_value CommonNapi::ThrowError(napi_env env, const int32_t errCode, const std::string errMsg)
848 {
849     napi_value result = nullptr;
850     napi_status status = napi_throw_error(env, std::to_string(errCode).c_str(), errMsg.c_str());
851     if (status == napi_ok) {
852         napi_get_undefined(env, &result);
853     }
854     return result;
855 }
856 
CompleteCallback(napi_env env,napi_status status,void * data)857 void MediaAsyncContext::CompleteCallback(napi_env env, napi_status status, void *data)
858 {
859     MEDIA_LOGD("CompleteCallback In");
860     auto asyncContext = reinterpret_cast<MediaAsyncContext *>(data);
861     CHECK_AND_RETURN_LOG(asyncContext != nullptr, "asyncContext is nullptr!");
862 
863     std::string memoryTag = asyncContext->memoryTagHead + asyncContext->memoryTagTail;
864     MEDIA_LOGD("MediaAsyncContext Create 0x%{public}06" PRIXPTR " memoryTag = %{public}s",
865         FAKE_POINTER(data), memoryTag.c_str());
866 
867     if (status != napi_ok) {
868         asyncContext->SignError(MSERR_EXT_UNKNOWN, "napi_create_async_work status != napi_ok");
869     }
870 
871     napi_value result = nullptr;
872     napi_get_undefined(env, &result);
873     napi_value args[2] = { nullptr };
874     napi_get_undefined(env, &args[0]);
875     napi_get_undefined(env, &args[1]);
876     if (asyncContext->errFlag) {
877         MEDIA_LOGD("async callback failed");
878         (void)CommonNapi::CreateError(env, asyncContext->errCode, asyncContext->errMessage, result);
879         args[0] = result;
880     } else {
881         MEDIA_LOGD("async callback success");
882         if (asyncContext->JsResult != nullptr) {
883             asyncContext->JsResult->GetJsResult(env, result);
884             CheckCtorResult(env, result, asyncContext, args[0]);
885         }
886         if (!asyncContext->errFlag) {
887             args[1] = result;
888         }
889     }
890 
891     Callback(env, asyncContext, args);
892     napi_delete_async_work(env, asyncContext->work);
893 
894     if (asyncContext->delFlag) {
895         delete asyncContext;
896         asyncContext = nullptr;
897     }
898 }
899 
Callback(napi_env env,const MediaAsyncContext * context,const napi_value * args)900 void MediaAsyncContext::Callback(napi_env env, const MediaAsyncContext *context, const napi_value *args)
901 {
902     if (context->deferred) {
903         if (context->errFlag) {
904             MEDIA_LOGE("promise napi_reject_deferred");
905             napi_reject_deferred(env, context->deferred, args[0]);
906         } else {
907             MEDIA_LOGD("promise napi_resolve_deferred");
908             napi_resolve_deferred(env, context->deferred, args[1]);
909         }
910     } else if (context->callbackRef != nullptr) {
911         MEDIA_LOGD("callback napi_call_function");
912         napi_value callback = nullptr;
913         napi_get_reference_value(env, context->callbackRef, &callback);
914         CHECK_AND_RETURN_LOG(callback != nullptr, "callback is nullptr!");
915         constexpr size_t argCount = 2;
916         napi_value retVal;
917         napi_get_undefined(env, &retVal);
918         napi_call_function(env, nullptr, callback, argCount, args, &retVal);
919         napi_delete_reference(env, context->callbackRef);
920     } else {
921         MEDIA_LOGE("invalid promise and callback");
922     }
923 }
924 
CheckCtorResult(napi_env env,napi_value & result,MediaAsyncContext * ctx,napi_value & args)925 void MediaAsyncContext::CheckCtorResult(napi_env env, napi_value &result, MediaAsyncContext *ctx, napi_value &args)
926 {
927     CHECK_AND_RETURN(ctx != nullptr);
928     if (ctx->ctorFlag) {
929         void *instance = nullptr;
930         if (napi_unwrap(env, result, reinterpret_cast<void **>(&instance)) != napi_ok || instance == nullptr) {
931             MEDIA_LOGE("Failed to create instance");
932             ctx->errFlag = true;
933             (void)CommonNapi::CreateError(env, MSERR_EXT_API9_NO_MEMORY,
934                 "The instance or memory has reached the upper limit, please recycle background playback", result);
935             args = result;
936         }
937     }
938 }
939 
SendCompleteEvent(napi_env env,MediaAsyncContext * asyncContext,napi_event_priority prio)940 napi_status MediaAsyncContext::SendCompleteEvent(napi_env env, MediaAsyncContext *asyncContext,
941                                                  napi_event_priority prio)
942 {
943     auto task = [env, asyncContext]() {
944         MEDIA_LOGD("CompleteCallback In");
945         CHECK_AND_RETURN_LOG(asyncContext != nullptr, "asyncContext is nullptr!");
946 
947         std::string memoryTag = asyncContext->memoryTagHead + asyncContext->memoryTagTail;
948         MEDIA_LOGD("MediaAsyncContext 0x%{public}06" PRIXPTR " memoryTag = %{public}s",
949             FAKE_POINTER(asyncContext), memoryTag.c_str());
950 
951         napi_value result = nullptr;
952         napi_get_undefined(env, &result);
953         napi_value args[2] = { nullptr };
954         napi_get_undefined(env, &args[0]);
955         napi_get_undefined(env, &args[1]);
956         if (asyncContext->errFlag) {
957             MEDIA_LOGD("async callback failed");
958             (void)CommonNapi::CreateError(env, asyncContext->errCode, asyncContext->errMessage, result);
959             args[0] = result;
960         } else {
961             MEDIA_LOGD("async callback success");
962             if (asyncContext->JsResult != nullptr) {
963                 asyncContext->JsResult->GetJsResult(env, result);
964                 CheckCtorResult(env, result, asyncContext, args[0]);
965             }
966             if (!asyncContext->errFlag) {
967                 args[1] = result;
968             }
969         }
970 
971         Callback(env, asyncContext, args);
972         if (asyncContext->delFlag) {
973             delete asyncContext;
974         }
975     };
976     return napi_send_event(env, task, prio);
977 }
978 
AddStringProperty(napi_env env,napi_value obj,const std::string & key,const std::string & value)979 bool CommonNapi::AddStringProperty(napi_env env, napi_value obj, const std::string &key, const std::string &value)
980 {
981     CHECK_AND_RETURN_RET(obj != nullptr, false);
982 
983     napi_value keyNapi = nullptr;
984     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
985     CHECK_AND_RETURN_RET(status == napi_ok, false);
986 
987     napi_value valueNapi = nullptr;
988     status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &valueNapi);
989     CHECK_AND_RETURN_RET(status == napi_ok, false);
990 
991     status = napi_set_property(env, obj, keyNapi, valueNapi);
992     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
993 
994     return true;
995 }
996 
GetPropertyBool(napi_env env,napi_value configObj,const std::string & type,bool & result)997 bool CommonNapi::GetPropertyBool(napi_env env, napi_value configObj, const std::string &type, bool &result)
998 {
999     bool exist = false;
1000     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
1001     if (status != napi_ok || !exist) {
1002         MEDIA_LOGE("can not find %{public}s property", type.c_str());
1003         return false;
1004     }
1005     napi_value item = nullptr;
1006     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
1007         MEDIA_LOGE("get %{public}s property fail", type.c_str());
1008         return false;
1009     }
1010     if (napi_get_value_bool(env, item, &result) != napi_ok) {
1011         MEDIA_LOGE("get %{public}s property value fail", type.c_str());
1012         return false;
1013     }
1014     return true;
1015 }
1016 
ConvertDeviceInfoToAudioDeviceDescriptor(std::shared_ptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor,const AudioStandard::AudioDeviceDescriptor & deviceInfo)1017 void CommonNapi::ConvertDeviceInfoToAudioDeviceDescriptor(
1018     std::shared_ptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor,
1019     const AudioStandard::AudioDeviceDescriptor &deviceInfo)
1020 {
1021     CHECK_AND_RETURN_LOG(audioDeviceDescriptor != nullptr, "audioDeviceDescriptor is nullptr");
1022     audioDeviceDescriptor->deviceRole_ = deviceInfo.deviceRole_;
1023     audioDeviceDescriptor->deviceType_ = deviceInfo.deviceType_;
1024     audioDeviceDescriptor->deviceId_ = deviceInfo.deviceId_;
1025     audioDeviceDescriptor->channelMasks_ = deviceInfo.channelMasks_;
1026     audioDeviceDescriptor->channelIndexMasks_ = deviceInfo.channelIndexMasks_;
1027     audioDeviceDescriptor->deviceName_ = deviceInfo.deviceName_;
1028     audioDeviceDescriptor->macAddress_ = deviceInfo.macAddress_;
1029     audioDeviceDescriptor->interruptGroupId_ = deviceInfo.interruptGroupId_;
1030     audioDeviceDescriptor->volumeGroupId_ = deviceInfo.volumeGroupId_;
1031     audioDeviceDescriptor->networkId_ = deviceInfo.networkId_;
1032     audioDeviceDescriptor->displayName_ = deviceInfo.displayName_;
1033     audioDeviceDescriptor->audioStreamInfo_.samplingRate = deviceInfo.audioStreamInfo_.samplingRate;
1034     audioDeviceDescriptor->audioStreamInfo_.encoding = deviceInfo.audioStreamInfo_.encoding;
1035     audioDeviceDescriptor->audioStreamInfo_.format = deviceInfo.audioStreamInfo_.format;
1036     audioDeviceDescriptor->audioStreamInfo_.channels = deviceInfo.audioStreamInfo_.channels;
1037 }
1038 
SetDeviceDescriptor(const napi_env & env,const AudioStandard::AudioDeviceDescriptor & deviceInfo,napi_value & result)1039 napi_status CommonNapi::SetDeviceDescriptor(const napi_env &env, const AudioStandard::AudioDeviceDescriptor &deviceInfo,
1040     napi_value &result)
1041 {
1042     (void)napi_create_object(env, &result);
1043     SetPropertyInt32(env, result, "deviceRole", static_cast<int32_t>(deviceInfo.deviceRole_));
1044     SetPropertyInt32(env, result, "deviceType", static_cast<int32_t>(deviceInfo.deviceType_));
1045     SetPropertyInt32(env, result, "id", static_cast<int32_t>(deviceInfo.deviceId_));
1046     SetPropertyString(env, result, "name", deviceInfo.deviceName_);
1047     SetPropertyString(env, result, "address", deviceInfo.macAddress_);
1048     SetPropertyString(env, result, "networkId", deviceInfo.networkId_);
1049     SetPropertyString(env, result, "displayName", deviceInfo.displayName_);
1050     SetPropertyInt32(env, result, "interruptGroupId", static_cast<int32_t>(deviceInfo.interruptGroupId_));
1051     SetPropertyInt32(env, result, "volumeGroupId", static_cast<int32_t>(deviceInfo.volumeGroupId_));
1052 
1053     napi_value value = nullptr;
1054     napi_value sampleRates;
1055     size_t size = deviceInfo.audioStreamInfo_.samplingRate.size();
1056     napi_create_array_with_length(env, size, &sampleRates);
1057     size_t count = 0;
1058     for (const auto &samplingRate : deviceInfo.audioStreamInfo_.samplingRate) {
1059         napi_create_int32(env, samplingRate, &value);
1060         napi_set_element(env, sampleRates, count, value);
1061         count++;
1062     }
1063     napi_set_named_property(env, result, "sampleRates", sampleRates);
1064 
1065     napi_value channelCounts;
1066     size = deviceInfo.audioStreamInfo_.channels.size();
1067     napi_create_array_with_length(env, size, &channelCounts);
1068     count = 0;
1069     for (const auto &channels : deviceInfo.audioStreamInfo_.channels) {
1070         napi_create_int32(env, channels, &value);
1071         napi_set_element(env, channelCounts, count, value);
1072         count++;
1073     }
1074     napi_set_named_property(env, result, "channelCounts", channelCounts);
1075 
1076     std::vector<int32_t> channelMasks_;
1077     channelMasks_.push_back(deviceInfo.channelMasks_);
1078     AddArrayProperty(env, result, "channelMasks", channelMasks_);
1079 
1080     std::vector<int32_t> channelIndexMasks_;
1081     channelIndexMasks_.push_back(deviceInfo.channelIndexMasks_);
1082     AddArrayProperty(env, result, "channelIndexMasks", channelIndexMasks_);
1083 
1084     std::vector<int32_t> encoding;
1085     encoding.push_back(deviceInfo.audioStreamInfo_.encoding);
1086     AddArrayProperty(env, result, "encodingTypes", encoding);
1087 
1088     return napi_ok;
1089 }
1090 
SetDeviceDescriptors(const napi_env & env,const std::vector<std::shared_ptr<AudioStandard::AudioDeviceDescriptor>> & deviceDescriptors,napi_value & result)1091 napi_status CommonNapi::SetDeviceDescriptors(const napi_env &env,
1092     const std::vector<std::shared_ptr<AudioStandard::AudioDeviceDescriptor>> &deviceDescriptors, napi_value &result)
1093 {
1094     napi_status status = napi_create_array_with_length(env, deviceDescriptors.size(), &result);
1095     for (size_t i = 0; i < deviceDescriptors.size(); i++) {
1096         if (deviceDescriptors[i] != nullptr) {
1097             napi_value valueParam = nullptr;
1098             SetDeviceDescriptor(env, deviceDescriptors[i], valueParam);
1099             napi_set_element(env, result, i, valueParam);
1100         }
1101     }
1102     return status;
1103 }
1104 
SetValueDeviceInfo(const napi_env & env,const AudioStandard::AudioDeviceDescriptor & deviceInfo,napi_value & result)1105 napi_status CommonNapi::SetValueDeviceInfo(const napi_env &env, const AudioStandard::AudioDeviceDescriptor &deviceInfo,
1106     napi_value &result)
1107 {
1108     std::vector<std::shared_ptr<AudioStandard::AudioDeviceDescriptor>> deviceDescriptors;
1109     std::shared_ptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor =
1110         std::make_shared<AudioStandard::AudioDeviceDescriptor>();
1111     CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptor != nullptr, napi_generic_failure,
1112         "audioDeviceDescriptor malloc failed");
1113     ConvertDeviceInfoToAudioDeviceDescriptor(audioDeviceDescriptor, deviceInfo);
1114     deviceDescriptors.push_back(std::move(audioDeviceDescriptor));
1115     SetDeviceDescriptors(env, deviceDescriptors, result);
1116     return napi_ok;
1117 }
1118 } // namespace Media
1119 } // namespace OHOS