• 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, "CommonNapi"};
24 }
25 
26 namespace OHOS {
27 namespace Media {
GetStringArgument(napi_env env,napi_value value)28 std::string CommonNapi::GetStringArgument(napi_env env, napi_value value)
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 < PATH_MAX) {
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 
CheckValueType(napi_env env,napi_value arg,napi_valuetype type)47 bool CommonNapi::CheckValueType(napi_env env, napi_value arg, napi_valuetype type)
48 {
49     napi_valuetype valueType = napi_undefined;
50     if (arg != nullptr && napi_typeof(env, arg, &valueType) == napi_ok && valueType == type) {
51         return true;
52     }
53     return false;
54 }
55 
GetPropertyInt32(napi_env env,napi_value configObj,const std::string & type,int32_t & result)56 bool CommonNapi::GetPropertyInt32(napi_env env, napi_value configObj, const std::string &type, int32_t &result)
57 {
58     napi_value item = nullptr;
59     bool exist = false;
60     napi_status napiStatus = napi_has_named_property(env, configObj, type.c_str(), &exist);
61     CHECK_AND_RETURN_RET_LOG(napiStatus == napi_ok && exist, false, "can not find %{public}s property", type.c_str());
62     CHECK_AND_RETURN_RET_LOG(napi_get_named_property(env, configObj, type.c_str(), &item) == napi_ok, false,
63         "get %{public}s property fail", type.c_str());
64     CHECK_AND_RETURN_RET_LOG(napi_get_value_int32(env, item, &result) == napi_ok, false,
65         "get %{public}s property value fail", type.c_str());
66     return true;
67 }
68 
GetPropertyUint32(napi_env env,napi_value configObj,const std::string & type,uint32_t & result)69 bool CommonNapi::GetPropertyUint32(napi_env env, napi_value configObj, const std::string &type, uint32_t &result)
70 {
71     napi_value item = nullptr;
72     bool exist = false;
73     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
74     CHECK_AND_RETURN_RET_LOG(status == napi_ok && exist, false, "can not find %{public}s property", type.c_str());
75     CHECK_AND_RETURN_RET_LOG(napi_get_named_property(env, configObj, type.c_str(), &item) == napi_ok, false,
76         "get %{public}s property fail", type.c_str());
77 
78     CHECK_AND_RETURN_RET_LOG(napi_get_value_uint32(env, item, &result) == napi_ok, false,
79         "get %{public}s property value fail", type.c_str());
80     return true;
81 }
82 
GetPropertyInt64(napi_env env,napi_value configObj,const std::string & type,int64_t & result)83 bool CommonNapi::GetPropertyInt64(napi_env env, napi_value configObj, const std::string &type, int64_t &result)
84 {
85     napi_value item = nullptr;
86     bool exist = false;
87     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
88     if (status != napi_ok || !exist) {
89         MEDIA_LOGE("can not find %{public}s property", type.c_str());
90         return false;
91     }
92 
93     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
94         MEDIA_LOGE("get %{public}s property fail", type.c_str());
95         return false;
96     }
97 
98     if (napi_get_value_int64(env, item, &result) != napi_ok) {
99         MEDIA_LOGE("get %{public}s property value fail", type.c_str());
100         return false;
101     }
102     return true;
103 }
104 
GetPropertyDouble(napi_env env,napi_value configObj,const std::string & type,double & result)105 bool CommonNapi::GetPropertyDouble(napi_env env, napi_value configObj, const std::string &type, double &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     if (status != napi_ok || !exist) {
111         MEDIA_LOGE("can not find %{public}s property", type.c_str());
112         return false;
113     }
114 
115     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
116         MEDIA_LOGE("get %{public}s property fail", type.c_str());
117         return false;
118     }
119 
120     if (napi_get_value_double(env, item, &result) != napi_ok) {
121         MEDIA_LOGE("get %{public}s property value fail", type.c_str());
122         return false;
123     }
124     return true;
125 }
126 
GetPropertyString(napi_env env,napi_value configObj,const std::string & type)127 std::string CommonNapi::GetPropertyString(napi_env env, napi_value configObj, const std::string &type)
128 {
129     std::string invalid = "";
130     bool exist = false;
131     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
132     if (status != napi_ok || !exist) {
133         MEDIA_LOGE("can not find %{public}s property", type.c_str());
134         return invalid;
135     }
136 
137     napi_value item = nullptr;
138     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
139         MEDIA_LOGE("get %{public}s property fail", type.c_str());
140         return invalid;
141     }
142 
143     return GetStringArgument(env, item);
144 }
145 
GetFdArgument(napi_env env,napi_value value,AVFileDescriptor & rawFd)146 bool CommonNapi::GetFdArgument(napi_env env, napi_value value, AVFileDescriptor &rawFd)
147 {
148     CHECK_AND_RETURN_RET(GetPropertyInt32(env, value, "fd", rawFd.fd) == true, false);
149 
150     if (!GetPropertyInt64(env, value, "offset", rawFd.offset)) {
151         rawFd.offset = 0; // use default value
152     }
153 
154     if (!GetPropertyInt64(env, value, "length", rawFd.length)) {
155         rawFd.length = -1; // -1 means use default value
156     }
157 
158     MEDIA_LOGD("get fd argument, fd = %{public}d, offset = %{public}" PRIi64 ", size = %{public}" PRIi64 "",
159         rawFd.fd, rawFd.offset, rawFd.length);
160 
161     return true;
162 }
163 
FillErrorArgs(napi_env env,int32_t errCode,const napi_value & args)164 napi_status CommonNapi::FillErrorArgs(napi_env env, int32_t errCode, const napi_value &args)
165 {
166     napi_value codeStr = nullptr;
167     napi_status status = napi_create_string_utf8(env, "code", NAPI_AUTO_LENGTH, &codeStr);
168     CHECK_AND_RETURN_RET_LOG(status == napi_ok && codeStr != nullptr, napi_invalid_arg, "create code str fail");
169 
170     napi_value errCodeVal = nullptr;
171     int32_t errCodeInt = errCode;
172     status = napi_create_int32(env, errCodeInt, &errCodeVal);
173     CHECK_AND_RETURN_RET_LOG(status == napi_ok && errCodeVal != nullptr, napi_invalid_arg,
174         "create error code number val fail");
175 
176     status = napi_set_property(env, args, codeStr, errCodeVal);
177     CHECK_AND_RETURN_RET_LOG(status == napi_ok, napi_invalid_arg, "set error code property fail");
178 
179     napi_value nameStr = nullptr;
180     status = napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &nameStr);
181     CHECK_AND_RETURN_RET_LOG(status == napi_ok && nameStr != nullptr, napi_invalid_arg, "create name str fail");
182 
183     napi_value errNameVal = nullptr;
184     status = napi_create_string_utf8(env, "BusinessError", NAPI_AUTO_LENGTH, &errNameVal);
185     CHECK_AND_RETURN_RET_LOG(status == napi_ok && errNameVal != nullptr, napi_invalid_arg,
186         "create BusinessError str fail");
187 
188     status = napi_set_property(env, args, nameStr, errNameVal);
189     CHECK_AND_RETURN_RET_LOG(status == napi_ok, napi_invalid_arg, "set error name property fail");
190     return napi_ok;
191 }
192 
CreateError(napi_env env,int32_t errCode,const std::string & errMsg,napi_value & errVal)193 napi_status CommonNapi::CreateError(napi_env env, int32_t errCode, const std::string &errMsg, napi_value &errVal)
194 {
195     napi_get_undefined(env, &errVal);
196 
197     napi_value msgValStr = nullptr;
198     napi_status nstatus = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &msgValStr);
199     if (nstatus != napi_ok || msgValStr == nullptr) {
200         MEDIA_LOGE("create error message str fail");
201         return napi_invalid_arg;
202     }
203 
204     nstatus = napi_create_error(env, nullptr, msgValStr, &errVal);
205     if (nstatus != napi_ok || errVal == nullptr) {
206         MEDIA_LOGE("create error fail");
207         return napi_invalid_arg;
208     }
209 
210     napi_value codeStr = nullptr;
211     nstatus = napi_create_string_utf8(env, "code", NAPI_AUTO_LENGTH, &codeStr);
212     if (nstatus != napi_ok || codeStr == nullptr) {
213         MEDIA_LOGE("create code str fail");
214         return napi_invalid_arg;
215     }
216 
217     napi_value errCodeVal = nullptr;
218     nstatus = napi_create_int32(env, errCode, &errCodeVal);
219     if (nstatus != napi_ok || errCodeVal == nullptr) {
220         MEDIA_LOGE("create error code number val fail");
221         return napi_invalid_arg;
222     }
223 
224     nstatus = napi_set_property(env, errVal, codeStr, errCodeVal);
225     if (nstatus != napi_ok) {
226         MEDIA_LOGE("set error code property fail");
227         return napi_invalid_arg;
228     }
229 
230     napi_value nameStr = nullptr;
231     nstatus = napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &nameStr);
232     if (nstatus != napi_ok || nameStr == nullptr) {
233         MEDIA_LOGE("create name str fail");
234         return napi_invalid_arg;
235     }
236 
237     napi_value errNameVal = nullptr;
238     nstatus = napi_create_string_utf8(env, "BusinessError", NAPI_AUTO_LENGTH, &errNameVal);
239     if (nstatus != napi_ok || errNameVal == nullptr) {
240         MEDIA_LOGE("create BusinessError str fail");
241         return napi_invalid_arg;
242     }
243 
244     nstatus = napi_set_property(env, errVal, nameStr, errNameVal);
245     if (nstatus != napi_ok) {
246         MEDIA_LOGE("set error name property fail");
247         return napi_invalid_arg;
248     }
249 
250     return napi_ok;
251 }
252 
CreateReference(napi_env env,napi_value arg)253 napi_ref CommonNapi::CreateReference(napi_env env, napi_value arg)
254 {
255     napi_ref ref = nullptr;
256     napi_valuetype valueType = napi_undefined;
257     if (arg != nullptr && napi_typeof(env, arg, &valueType) == napi_ok && valueType == napi_function) {
258         MEDIA_LOGD("napi_create_reference");
259         napi_create_reference(env, arg, 1, &ref);
260     }
261     return ref;
262 }
263 
CreatePromise(napi_env env,napi_ref ref,napi_value & result)264 napi_deferred CommonNapi::CreatePromise(napi_env env, napi_ref ref, napi_value &result)
265 {
266     napi_deferred deferred = nullptr;
267     if (ref == nullptr) {
268         MEDIA_LOGD("napi_create_promise");
269         napi_create_promise(env, &deferred, &result);
270     }
271     return deferred;
272 }
273 
AddRangeProperty(napi_env env,napi_value obj,const std::string & name,int32_t min,int32_t max)274 bool CommonNapi::AddRangeProperty(napi_env env, napi_value obj, const std::string &name, int32_t min, int32_t max)
275 {
276     CHECK_AND_RETURN_RET(obj != nullptr, false);
277 
278     napi_value range = nullptr;
279     napi_status status = napi_create_object(env, &range);
280     CHECK_AND_RETURN_RET(status == napi_ok, false);
281 
282     CHECK_AND_RETURN_RET(SetPropertyInt32(env, range, "min", min) == true, false);
283     CHECK_AND_RETURN_RET(SetPropertyInt32(env, range, "max", max) == true, false);
284 
285     napi_value nameStr = nullptr;
286     status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &nameStr);
287     CHECK_AND_RETURN_RET(status == napi_ok, false);
288 
289     status = napi_set_property(env, obj, nameStr, range);
290     CHECK_AND_RETURN_RET(status == napi_ok, false);
291 
292     return true;
293 }
294 
AddArrayProperty(napi_env env,napi_value obj,const std::string & name,const std::vector<int32_t> & vec)295 bool CommonNapi::AddArrayProperty(napi_env env, napi_value obj, const std::string &name,
296     const std::vector<int32_t> &vec)
297 {
298     CHECK_AND_RETURN_RET(obj != nullptr, false);
299 
300     napi_value array = nullptr;
301     napi_status status = napi_create_array_with_length(env, vec.size(), &array);
302     CHECK_AND_RETURN_RET(status == napi_ok, false);
303 
304     for (uint32_t i = 0; i < vec.size(); i++) {
305         napi_value number = nullptr;
306         (void)napi_create_int32(env, vec.at(i), &number);
307         (void)napi_set_element(env, array, i, number);
308     }
309 
310     napi_value nameStr = nullptr;
311     status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &nameStr);
312     CHECK_AND_RETURN_RET(status == napi_ok, false);
313 
314     status = napi_set_property(env, obj, nameStr, array);
315     CHECK_AND_RETURN_RET(status == napi_ok, false);
316 
317     return true;
318 }
319 
AddArrayInt(napi_env env,napi_value & array,const std::vector<int32_t> & vec)320 bool CommonNapi::AddArrayInt(napi_env env, napi_value &array, const std::vector<int32_t> &vec)
321 {
322     if (vec.size() == 0) {
323         return false;
324     }
325 
326     napi_status status = napi_create_array_with_length(env, vec.size(), &array);
327     CHECK_AND_RETURN_RET(status == napi_ok, false);
328 
329     for (uint32_t i = 0; i < vec.size(); i++) {
330         napi_value number = nullptr;
331         (void)napi_create_int32(env, vec.at(i), &number);
332         (void)napi_set_element(env, array, i, number);
333     }
334 
335     return true;
336 }
337 
SetPropertyInt32(napi_env env,napi_value & obj,const std::string & key,int32_t value)338 bool CommonNapi::SetPropertyInt32(napi_env env, napi_value &obj, const std::string &key, int32_t value)
339 {
340     CHECK_AND_RETURN_RET(obj != nullptr, false);
341 
342     napi_value keyNapi = nullptr;
343     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
344     CHECK_AND_RETURN_RET(status == napi_ok, false);
345 
346     napi_value valueNapi = nullptr;
347     status = napi_create_int32(env, value, &valueNapi);
348     CHECK_AND_RETURN_RET(status == napi_ok, false);
349 
350     status = napi_set_property(env, obj, keyNapi, valueNapi);
351     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
352 
353     return true;
354 }
355 
SetPropertyDouble(napi_env env,napi_value & obj,const std::string & key,double value)356 bool CommonNapi::SetPropertyDouble(napi_env env, napi_value &obj, const std::string &key, double value)
357 {
358     CHECK_AND_RETURN_RET(obj != nullptr, false);
359 
360     napi_value keyNapi = nullptr;
361     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
362     CHECK_AND_RETURN_RET(status == napi_ok, false);
363 
364     napi_value valueNapi = nullptr;
365     status = napi_create_double(env, value, &valueNapi);
366     CHECK_AND_RETURN_RET(status == napi_ok, false);
367 
368     status = napi_set_property(env, obj, keyNapi, valueNapi);
369     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
370 
371     return true;
372 }
373 
SetPropertyBool(napi_env env,napi_value & obj,const std::string & key,bool value)374 bool CommonNapi::SetPropertyBool(napi_env env, napi_value &obj, const std::string &key, bool value)
375 {
376     CHECK_AND_RETURN_RET(obj != nullptr, false);
377 
378     napi_value keyNapi = nullptr;
379     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
380     CHECK_AND_RETURN_RET(status == napi_ok, false);
381 
382     napi_value valueNapi = nullptr;
383     status = napi_get_boolean(env, value, &valueNapi);
384     CHECK_AND_RETURN_RET(status == napi_ok, false);
385 
386     status = napi_set_property(env, obj, keyNapi, valueNapi);
387     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
388 
389     return true;
390 }
391 
SetPropertyString(napi_env env,napi_value & obj,const std::string & key,const std::string & value)392 bool CommonNapi::SetPropertyString(napi_env env, napi_value &obj, const std::string &key, const std::string &value)
393 {
394     CHECK_AND_RETURN_RET(obj != nullptr, false);
395 
396     napi_value keyNapi = nullptr;
397     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
398     CHECK_AND_RETURN_RET(status == napi_ok, false);
399 
400     napi_value valueNapi = nullptr;
401     status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &valueNapi);
402     CHECK_AND_RETURN_RET(status == napi_ok, false);
403 
404     status = napi_set_property(env, obj, keyNapi, valueNapi);
405     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
406 
407     return true;
408 }
409 
CreateFormatBuffer(napi_env env,Format & format)410 napi_value CommonNapi::CreateFormatBuffer(napi_env env, Format &format)
411 {
412     napi_value buffer = nullptr;
413     int32_t intValue = 0;
414     std::string strValue;
415     napi_status status = napi_create_object(env, &buffer);
416     CHECK_AND_RETURN_RET(status == napi_ok, nullptr);
417 
418     for (auto &iter : format.GetFormatMap()) {
419         switch (format.GetValueType(std::string_view(iter.first))) {
420             case FORMAT_TYPE_INT32:
421                 if (format.GetIntValue(iter.first, intValue)) {
422                     CHECK_AND_RETURN_RET(SetPropertyInt32(env, buffer, iter.first, intValue) == true, nullptr);
423                 }
424                 break;
425             case FORMAT_TYPE_STRING:
426                 if (format.GetStringValue(iter.first, strValue)) {
427                     CHECK_AND_RETURN_RET(SetPropertyString(env, buffer, iter.first, strValue) == true, nullptr);
428                 }
429                 break;
430             default:
431                 MEDIA_LOGE("format key: %{public}s", iter.first.c_str());
432                 break;
433         }
434     }
435 
436     return buffer;
437 }
438 
CreateFormatBufferByRef(napi_env env,Format & format,napi_value & result)439 bool CommonNapi::CreateFormatBufferByRef(napi_env env, Format &format, napi_value &result)
440 {
441     int32_t intValue = 0;
442     std::string strValue = "";
443     napi_status status = napi_create_object(env, &result);
444     CHECK_AND_RETURN_RET(status == napi_ok, false);
445 
446     for (auto &iter : format.GetFormatMap()) {
447         switch (format.GetValueType(std::string_view(iter.first))) {
448             case FORMAT_TYPE_INT32:
449                 if (format.GetIntValue(iter.first, intValue)) {
450                     (void)SetPropertyInt32(env, result, iter.first, intValue);
451                 }
452                 break;
453             case FORMAT_TYPE_STRING:
454                 if (format.GetStringValue(iter.first, strValue)) {
455                     (void)SetPropertyString(env, result, iter.first, strValue);
456                 }
457                 break;
458             default:
459                 MEDIA_LOGE("format key: %{public}s", iter.first.c_str());
460                 break;
461         }
462     }
463 
464     return true;
465 }
466 
AddNumberPropInt32(napi_env env,napi_value obj,const std::string & key,int32_t value)467 bool CommonNapi::AddNumberPropInt32(napi_env env, napi_value obj, const std::string &key, int32_t value)
468 {
469     CHECK_AND_RETURN_RET(obj != nullptr, false);
470 
471     napi_value keyNapi = nullptr;
472     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
473     CHECK_AND_RETURN_RET(status == napi_ok, false);
474 
475     napi_value valueNapi = nullptr;
476     status = napi_create_int32(env, value, &valueNapi);
477     CHECK_AND_RETURN_RET(status == napi_ok, false);
478 
479     status = napi_set_property(env, obj, keyNapi, valueNapi);
480     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
481 
482     return true;
483 }
484 
AddNumberPropInt64(napi_env env,napi_value obj,const std::string & key,int64_t value)485 bool CommonNapi::AddNumberPropInt64(napi_env env, napi_value obj, const std::string &key, int64_t value)
486 {
487     CHECK_AND_RETURN_RET(obj != nullptr, false);
488 
489     napi_value keyNapi = nullptr;
490     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
491     CHECK_AND_RETURN_RET(status == napi_ok, false);
492 
493     napi_value valueNapi = nullptr;
494     status = napi_create_int64(env, value, &valueNapi);
495     CHECK_AND_RETURN_RET(status == napi_ok, false);
496 
497     status = napi_set_property(env, obj, keyNapi, valueNapi);
498     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
499 
500     return true;
501 }
502 
GetJsResult(napi_env env,napi_value & result)503 napi_status MediaJsResultStringVector::GetJsResult(napi_env env, napi_value &result)
504 {
505     napi_status status;
506     size_t size = value_.size();
507     napi_create_array_with_length(env, size, &result);
508     for (unsigned int i = 0; i < size; ++i) {
509         std::string format = value_[i];
510         napi_value value = nullptr;
511         status = napi_create_string_utf8(env, format.c_str(), NAPI_AUTO_LENGTH, &value);
512         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
513             "Failed to call napi_create_string_utf8, with element %{public}u", i);
514         status = napi_set_element(env, result, i, value);
515         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
516             "Failed to call napi_set_element, with element %{public}u", i);
517     }
518     return napi_ok;
519 }
520 
GetJsResult(napi_env env,napi_value & result)521 napi_status MediaJsResultArray::GetJsResult(napi_env env, napi_value &result)
522 {
523     // create Description
524     napi_status status = napi_create_array(env, &result);
525     if (status != napi_ok) {
526         return napi_cancelled;
527     }
528 
529     auto vecSize = value_.size();
530     for (size_t index = 0; index < vecSize; ++index) {
531         napi_value description = nullptr;
532         description = CommonNapi::CreateFormatBuffer(env, value_[index]);
533         if (description == nullptr || napi_set_element(env, result, index, description) != napi_ok) {
534             return napi_cancelled;
535         }
536     }
537     return napi_ok;
538 }
539 
MediaAsyncContext(napi_env env)540 MediaAsyncContext::MediaAsyncContext(napi_env env)
541     : env_(env)
542 {
543     MEDIA_LOGD("MediaAsyncContext Create 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
544 }
545 
~MediaAsyncContext()546 MediaAsyncContext::~MediaAsyncContext()
547 {
548     MEDIA_LOGD("MediaAsyncContext Destroy 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
549 }
550 
SignError(int32_t code,const std::string & message,bool del)551 void MediaAsyncContext::SignError(int32_t code, const std::string &message, bool del)
552 {
553     errMessage = message;
554     errCode = code;
555     errFlag = true;
556     delFlag = del;
557     MEDIA_LOGE("SignError: %{public}s", message.c_str());
558 }
559 
CompleteCallback(napi_env env,napi_status status,void * data)560 void MediaAsyncContext::CompleteCallback(napi_env env, napi_status status, void *data)
561 {
562     MEDIA_LOGD("CompleteCallback In");
563     auto asyncContext = reinterpret_cast<MediaAsyncContext *>(data);
564     CHECK_AND_RETURN_LOG(asyncContext != nullptr, "asyncContext is nullptr!");
565 
566     std::string memoryTag = asyncContext->memoryTagHead + asyncContext->memoryTagTail;
567     MEDIA_LOGD("MediaAsyncContext Create 0x%{public}06" PRIXPTR " memoryTag = %{public}s",
568         FAKE_POINTER(data), memoryTag.c_str());
569 
570     if (status != napi_ok) {
571         asyncContext->SignError(MSERR_EXT_UNKNOWN, "napi_create_async_work status != napi_ok");
572     }
573 
574     napi_value result = nullptr;
575     napi_get_undefined(env, &result);
576     napi_value args[2] = { nullptr };
577     napi_get_undefined(env, &args[0]);
578     napi_get_undefined(env, &args[1]);
579     if (asyncContext->errFlag) {
580         MEDIA_LOGD("async callback failed");
581         (void)CommonNapi::CreateError(env, asyncContext->errCode, asyncContext->errMessage, result);
582         args[0] = result;
583     } else {
584         MEDIA_LOGD("async callback success");
585         if (asyncContext->JsResult != nullptr) {
586             asyncContext->JsResult->GetJsResult(env, result);
587             CheckCtorResult(env, result, asyncContext, args[0]);
588         }
589         if (!asyncContext->errFlag) {
590             args[1] = result;
591         }
592     }
593 
594     Callback(env, asyncContext, args);
595     napi_delete_async_work(env, asyncContext->work);
596 
597     if (asyncContext->delFlag) {
598         delete asyncContext;
599         asyncContext = nullptr;
600     }
601 }
602 
Callback(napi_env env,const MediaAsyncContext * context,const napi_value * args)603 void MediaAsyncContext::Callback(napi_env env, const MediaAsyncContext *context, const napi_value *args)
604 {
605     if (context->deferred) {
606         if (context->errFlag) {
607             MEDIA_LOGE("promise napi_reject_deferred");
608             napi_reject_deferred(env, context->deferred, args[0]);
609         } else {
610             MEDIA_LOGD("promise napi_resolve_deferred");
611             napi_resolve_deferred(env, context->deferred, args[1]);
612         }
613     } else if (context->callbackRef != nullptr) {
614         MEDIA_LOGD("callback napi_call_function");
615         napi_value callback = nullptr;
616         napi_get_reference_value(env, context->callbackRef, &callback);
617         CHECK_AND_RETURN_LOG(callback != nullptr, "callback is nullptr!");
618         constexpr size_t argCount = 2;
619         napi_value retVal;
620         napi_get_undefined(env, &retVal);
621         napi_call_function(env, nullptr, callback, argCount, args, &retVal);
622         napi_delete_reference(env, context->callbackRef);
623     } else {
624         MEDIA_LOGE("invalid promise and callback");
625     }
626 }
627 
CheckCtorResult(napi_env env,napi_value & result,MediaAsyncContext * ctx,napi_value & args)628 void MediaAsyncContext::CheckCtorResult(napi_env env, napi_value &result, MediaAsyncContext *ctx, napi_value &args)
629 {
630     CHECK_AND_RETURN(ctx != nullptr);
631     if (ctx->ctorFlag) {
632         void *instance = nullptr;
633         if (napi_unwrap(env, result, reinterpret_cast<void **>(&instance)) != napi_ok || instance == nullptr) {
634             MEDIA_LOGE("Failed to create instance");
635             ctx->errFlag = true;
636             (void)CommonNapi::CreateError(env, MSERR_EXT_API9_NO_MEMORY,
637                 "The instance or memory has reached the upper limit, please recycle background playback", result);
638             args = result;
639         }
640     }
641 }
642 
AddStringProperty(napi_env env,napi_value obj,const std::string & key,const std::string & value)643 bool CommonNapi::AddStringProperty(napi_env env, napi_value obj, const std::string &key, const std::string &value)
644 {
645     CHECK_AND_RETURN_RET(obj != nullptr, false);
646 
647     napi_value keyNapi = nullptr;
648     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
649     CHECK_AND_RETURN_RET(status == napi_ok, false);
650 
651     napi_value valueNapi = nullptr;
652     status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &valueNapi);
653     CHECK_AND_RETURN_RET(status == napi_ok, false);
654 
655     status = napi_set_property(env, obj, keyNapi, valueNapi);
656     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
657 
658     return true;
659 }
660 
GetPropertyBool(napi_env env,napi_value configObj,const std::string & type,bool & result)661 bool CommonNapi::GetPropertyBool(napi_env env, napi_value configObj, const std::string &type, bool &result)
662 {
663     bool exist = false;
664     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
665     if (status != napi_ok || !exist) {
666         MEDIA_LOGE("can not find %{public}s property", type.c_str());
667         return false;
668     }
669     napi_value item = nullptr;
670     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
671         MEDIA_LOGE("get %{public}s property fail", type.c_str());
672         return false;
673     }
674     if (napi_get_value_bool(env, item, &result) != napi_ok) {
675         MEDIA_LOGE("get %{public}s property value fail", type.c_str());
676         return false;
677     }
678     return true;
679 }
680 
ConvertDeviceInfoToAudioDeviceDescriptor(sptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor,const AudioStandard::DeviceInfo & deviceInfo)681 void CommonNapi::ConvertDeviceInfoToAudioDeviceDescriptor(
682     sptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor, const AudioStandard::DeviceInfo &deviceInfo)
683 {
684     CHECK_AND_RETURN_LOG(audioDeviceDescriptor != nullptr, "audioDeviceDescriptor is nullptr");
685     audioDeviceDescriptor->deviceRole_ = deviceInfo.deviceRole;
686     audioDeviceDescriptor->deviceType_ = deviceInfo.deviceType;
687     audioDeviceDescriptor->deviceId_ = deviceInfo.deviceId;
688     audioDeviceDescriptor->channelMasks_ = deviceInfo.channelMasks;
689     audioDeviceDescriptor->channelIndexMasks_ = deviceInfo.channelIndexMasks;
690     audioDeviceDescriptor->deviceName_ = deviceInfo.deviceName;
691     audioDeviceDescriptor->macAddress_ = deviceInfo.macAddress;
692     audioDeviceDescriptor->interruptGroupId_ = deviceInfo.interruptGroupId;
693     audioDeviceDescriptor->volumeGroupId_ = deviceInfo.volumeGroupId;
694     audioDeviceDescriptor->networkId_ = deviceInfo.networkId;
695     audioDeviceDescriptor->displayName_ = deviceInfo.displayName;
696     audioDeviceDescriptor->audioStreamInfo_.samplingRate = deviceInfo.audioStreamInfo.samplingRate;
697     audioDeviceDescriptor->audioStreamInfo_.encoding = deviceInfo.audioStreamInfo.encoding;
698     audioDeviceDescriptor->audioStreamInfo_.format = deviceInfo.audioStreamInfo.format;
699     audioDeviceDescriptor->audioStreamInfo_.channels = deviceInfo.audioStreamInfo.channels;
700 }
701 
SetDeviceDescriptor(const napi_env & env,const AudioStandard::AudioDeviceDescriptor & deviceInfo,napi_value & result)702 napi_status CommonNapi::SetDeviceDescriptor(const napi_env &env, const AudioStandard::AudioDeviceDescriptor &deviceInfo,
703     napi_value &result)
704 {
705     (void)napi_create_object(env, &result);
706     SetPropertyInt32(env, result, "deviceRole", static_cast<int32_t>(deviceInfo.deviceRole_));
707     SetPropertyInt32(env, result, "deviceType", static_cast<int32_t>(deviceInfo.deviceType_));
708     SetPropertyInt32(env, result, "id", static_cast<int32_t>(deviceInfo.deviceId_));
709     SetPropertyString(env, result, "name", deviceInfo.deviceName_);
710     SetPropertyString(env, result, "address", deviceInfo.macAddress_);
711     SetPropertyString(env, result, "networkId", deviceInfo.networkId_);
712     SetPropertyString(env, result, "displayName", deviceInfo.displayName_);
713     SetPropertyInt32(env, result, "interruptGroupId", static_cast<int32_t>(deviceInfo.interruptGroupId_));
714     SetPropertyInt32(env, result, "volumeGroupId", static_cast<int32_t>(deviceInfo.volumeGroupId_));
715 
716     napi_value value = nullptr;
717     napi_value sampleRates;
718     size_t size = deviceInfo.audioStreamInfo_.samplingRate.size();
719     napi_create_array_with_length(env, size, &sampleRates);
720     size_t count = 0;
721     for (const auto &samplingRate : deviceInfo.audioStreamInfo_.samplingRate) {
722         napi_create_int32(env, samplingRate, &value);
723         napi_set_element(env, sampleRates, count, value);
724         count++;
725     }
726     napi_set_named_property(env, result, "sampleRates", sampleRates);
727 
728     napi_value channelCounts;
729     size = deviceInfo.audioStreamInfo_.channels.size();
730     napi_create_array_with_length(env, size, &channelCounts);
731     count = 0;
732     for (const auto &channels : deviceInfo.audioStreamInfo_.channels) {
733         napi_create_int32(env, channels, &value);
734         napi_set_element(env, channelCounts, count, value);
735         count++;
736     }
737     napi_set_named_property(env, result, "channelCounts", channelCounts);
738 
739     std::vector<int32_t> channelMasks_;
740     channelMasks_.push_back(deviceInfo.channelMasks_);
741     AddArrayProperty(env, result, "channelMasks", channelMasks_);
742 
743     std::vector<int32_t> channelIndexMasks_;
744     channelIndexMasks_.push_back(deviceInfo.channelIndexMasks_);
745     AddArrayProperty(env, result, "channelIndexMasks", channelIndexMasks_);
746 
747     std::vector<int32_t> encoding;
748     encoding.push_back(deviceInfo.audioStreamInfo_.encoding);
749     AddArrayProperty(env, result, "encodingTypes", encoding);
750 
751     return napi_ok;
752 }
753 
SetDeviceDescriptors(const napi_env & env,const std::vector<sptr<AudioStandard::AudioDeviceDescriptor>> & deviceDescriptors,napi_value & result)754 napi_status CommonNapi::SetDeviceDescriptors(const napi_env &env,
755     const std::vector<sptr<AudioStandard::AudioDeviceDescriptor>> &deviceDescriptors, napi_value &result)
756 {
757     napi_status status = napi_create_array_with_length(env, deviceDescriptors.size(), &result);
758     for (size_t i = 0; i < deviceDescriptors.size(); i++) {
759         if (deviceDescriptors[i] != nullptr) {
760             napi_value valueParam = nullptr;
761             SetDeviceDescriptor(env, deviceDescriptors[i], valueParam);
762             napi_set_element(env, result, i, valueParam);
763         }
764     }
765     return status;
766 }
767 
SetValueDeviceInfo(const napi_env & env,const AudioStandard::DeviceInfo & deviceInfo,napi_value & result)768 napi_status CommonNapi::SetValueDeviceInfo(const napi_env &env, const AudioStandard::DeviceInfo &deviceInfo,
769     napi_value &result)
770 {
771     std::vector<sptr<AudioStandard::AudioDeviceDescriptor>> deviceDescriptors;
772     sptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor =
773         new(std::nothrow) AudioStandard::AudioDeviceDescriptor();
774     CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptor != nullptr, napi_generic_failure,
775         "audioDeviceDescriptor malloc failed");
776     ConvertDeviceInfoToAudioDeviceDescriptor(audioDeviceDescriptor, deviceInfo);
777     deviceDescriptors.push_back(std::move(audioDeviceDescriptor));
778     SetDeviceDescriptors(env, deviceDescriptors, result);
779     return napi_ok;
780 }
781 } // namespace Media
782 } // namespace OHOS
783