• 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 
GetPropertyInt32(napi_env env,napi_value configObj,const std::string & type,int32_t & result)47 bool CommonNapi::GetPropertyInt32(napi_env env, napi_value configObj, const std::string &type, int32_t &result)
48 {
49     napi_value item = nullptr;
50     bool exist = false;
51     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
52     if (status != napi_ok || !exist) {
53         MEDIA_LOGE("can not find %{public}s property", type.c_str());
54         return false;
55     }
56 
57     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
58         MEDIA_LOGE("get %{public}s property fail", type.c_str());
59         return false;
60     }
61 
62     if (napi_get_value_int32(env, item, &result) != napi_ok) {
63         MEDIA_LOGE("get %{public}s property value fail", type.c_str());
64         return false;
65     }
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     if (status != napi_ok || !exist) {
75         MEDIA_LOGE("can not find %{public}s property", type.c_str());
76         return false;
77     }
78 
79     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
80         MEDIA_LOGE("get %{public}s property fail", type.c_str());
81         return false;
82     }
83 
84     if (napi_get_value_uint32(env, item, &result) != napi_ok) {
85         MEDIA_LOGE("get %{public}s property value fail", type.c_str());
86         return false;
87     }
88     return true;
89 }
90 
GetPropertyInt64(napi_env env,napi_value configObj,const std::string & type,int64_t & result)91 bool CommonNapi::GetPropertyInt64(napi_env env, napi_value configObj, const std::string &type, int64_t &result)
92 {
93     napi_value item = nullptr;
94     bool exist = false;
95     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
96     if (status != napi_ok || !exist) {
97         MEDIA_LOGE("can not find %{public}s property", type.c_str());
98         return false;
99     }
100 
101     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
102         MEDIA_LOGE("get %{public}s property fail", type.c_str());
103         return false;
104     }
105 
106     if (napi_get_value_int64(env, item, &result) != napi_ok) {
107         MEDIA_LOGE("get %{public}s property value fail", type.c_str());
108         return false;
109     }
110     return true;
111 }
112 
GetPropertyDouble(napi_env env,napi_value configObj,const std::string & type,double & result)113 bool CommonNapi::GetPropertyDouble(napi_env env, napi_value configObj, const std::string &type, double &result)
114 {
115     napi_value item = nullptr;
116     bool exist = false;
117     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
118     if (status != napi_ok || !exist) {
119         MEDIA_LOGE("can not find %{public}s property", type.c_str());
120         return false;
121     }
122 
123     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
124         MEDIA_LOGE("get %{public}s property fail", type.c_str());
125         return false;
126     }
127 
128     if (napi_get_value_double(env, item, &result) != napi_ok) {
129         MEDIA_LOGE("get %{public}s property value fail", type.c_str());
130         return false;
131     }
132     return true;
133 }
134 
GetPropertyString(napi_env env,napi_value configObj,const std::string & type)135 std::string CommonNapi::GetPropertyString(napi_env env, napi_value configObj, const std::string &type)
136 {
137     std::string invalid = "";
138     bool exist = false;
139     napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
140     if (status != napi_ok || !exist) {
141         MEDIA_LOGE("can not find %{public}s property", type.c_str());
142         return invalid;
143     }
144 
145     napi_value item = nullptr;
146     if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
147         MEDIA_LOGE("get %{public}s property fail", type.c_str());
148         return invalid;
149     }
150 
151     return GetStringArgument(env, item);
152 }
153 
GetFdArgument(napi_env env,napi_value value,AVFileDescriptor & rawFd)154 bool CommonNapi::GetFdArgument(napi_env env, napi_value value, AVFileDescriptor &rawFd)
155 {
156     CHECK_AND_RETURN_RET(GetPropertyInt32(env, value, "fd", rawFd.fd) == true, false);
157 
158     if (!GetPropertyInt64(env, value, "offset", rawFd.offset)) {
159         rawFd.offset = 0; // use default value
160     }
161 
162     if (!GetPropertyInt64(env, value, "length", rawFd.length)) {
163         rawFd.length = -1; // -1 means use default value
164     }
165 
166     MEDIA_LOGD("get fd argument, fd = %{public}d, offset = %{public}" PRIi64 ", size = %{public}" PRIi64 "",
167         rawFd.fd, rawFd.offset, rawFd.length);
168 
169     return true;
170 }
171 
FillErrorArgs(napi_env env,int32_t errCode,const napi_value & args)172 napi_status CommonNapi::FillErrorArgs(napi_env env, int32_t errCode, const napi_value &args)
173 {
174     napi_value codeStr = nullptr;
175     napi_status status = napi_create_string_utf8(env, "code", NAPI_AUTO_LENGTH, &codeStr);
176     CHECK_AND_RETURN_RET_LOG(status == napi_ok && codeStr != nullptr, napi_invalid_arg, "create code str fail");
177 
178     napi_value errCodeVal = nullptr;
179     int32_t errCodeInt = errCode;
180     status = napi_create_int32(env, errCodeInt, &errCodeVal);
181     CHECK_AND_RETURN_RET_LOG(status == napi_ok && errCodeVal != nullptr, napi_invalid_arg,
182         "create error code number val fail");
183 
184     status = napi_set_property(env, args, codeStr, errCodeVal);
185     CHECK_AND_RETURN_RET_LOG(status == napi_ok, napi_invalid_arg, "set error code property fail");
186 
187     napi_value nameStr = nullptr;
188     status = napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &nameStr);
189     CHECK_AND_RETURN_RET_LOG(status == napi_ok && nameStr != nullptr, napi_invalid_arg, "create name str fail");
190 
191     napi_value errNameVal = nullptr;
192     status = napi_create_string_utf8(env, "BusinessError", NAPI_AUTO_LENGTH, &errNameVal);
193     CHECK_AND_RETURN_RET_LOG(status == napi_ok && errNameVal != nullptr, napi_invalid_arg,
194         "create BusinessError str fail");
195 
196     status = napi_set_property(env, args, nameStr, errNameVal);
197     CHECK_AND_RETURN_RET_LOG(status == napi_ok, napi_invalid_arg, "set error name property fail");
198     return napi_ok;
199 }
200 
CreateError(napi_env env,int32_t errCode,const std::string & errMsg,napi_value & errVal)201 napi_status CommonNapi::CreateError(napi_env env, int32_t errCode, const std::string &errMsg, napi_value &errVal)
202 {
203     napi_get_undefined(env, &errVal);
204 
205     napi_value msgValStr = nullptr;
206     napi_status nstatus = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &msgValStr);
207     if (nstatus != napi_ok || msgValStr == nullptr) {
208         MEDIA_LOGE("create error message str fail");
209         return napi_invalid_arg;
210     }
211 
212     nstatus = napi_create_error(env, nullptr, msgValStr, &errVal);
213     if (nstatus != napi_ok || errVal == nullptr) {
214         MEDIA_LOGE("create error fail");
215         return napi_invalid_arg;
216     }
217 
218     napi_value codeStr = nullptr;
219     nstatus = napi_create_string_utf8(env, "code", NAPI_AUTO_LENGTH, &codeStr);
220     if (nstatus != napi_ok || codeStr == nullptr) {
221         MEDIA_LOGE("create code str fail");
222         return napi_invalid_arg;
223     }
224 
225     napi_value errCodeVal = nullptr;
226     nstatus = napi_create_int32(env, errCode, &errCodeVal);
227     if (nstatus != napi_ok || errCodeVal == nullptr) {
228         MEDIA_LOGE("create error code number val fail");
229         return napi_invalid_arg;
230     }
231 
232     nstatus = napi_set_property(env, errVal, codeStr, errCodeVal);
233     if (nstatus != napi_ok) {
234         MEDIA_LOGE("set error code property fail");
235         return napi_invalid_arg;
236     }
237 
238     napi_value nameStr = nullptr;
239     nstatus = napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &nameStr);
240     if (nstatus != napi_ok || nameStr == nullptr) {
241         MEDIA_LOGE("create name str fail");
242         return napi_invalid_arg;
243     }
244 
245     napi_value errNameVal = nullptr;
246     nstatus = napi_create_string_utf8(env, "BusinessError", NAPI_AUTO_LENGTH, &errNameVal);
247     if (nstatus != napi_ok || errNameVal == nullptr) {
248         MEDIA_LOGE("create BusinessError str fail");
249         return napi_invalid_arg;
250     }
251 
252     nstatus = napi_set_property(env, errVal, nameStr, errNameVal);
253     if (nstatus != napi_ok) {
254         MEDIA_LOGE("set error name property fail");
255         return napi_invalid_arg;
256     }
257 
258     return napi_ok;
259 }
260 
CreateReference(napi_env env,napi_value arg)261 napi_ref CommonNapi::CreateReference(napi_env env, napi_value arg)
262 {
263     napi_ref ref = nullptr;
264     napi_valuetype valueType = napi_undefined;
265     if (arg != nullptr && napi_typeof(env, arg, &valueType) == napi_ok && valueType == napi_function) {
266         MEDIA_LOGD("napi_create_reference");
267         napi_create_reference(env, arg, 1, &ref);
268     }
269     return ref;
270 }
271 
CreatePromise(napi_env env,napi_ref ref,napi_value & result)272 napi_deferred CommonNapi::CreatePromise(napi_env env, napi_ref ref, napi_value &result)
273 {
274     napi_deferred deferred = nullptr;
275     if (ref == nullptr) {
276         MEDIA_LOGD("napi_create_promise");
277         napi_create_promise(env, &deferred, &result);
278     }
279     return deferred;
280 }
281 
AddRangeProperty(napi_env env,napi_value obj,const std::string & name,int32_t min,int32_t max)282 bool CommonNapi::AddRangeProperty(napi_env env, napi_value obj, const std::string &name, int32_t min, int32_t max)
283 {
284     CHECK_AND_RETURN_RET(obj != nullptr, false);
285 
286     napi_value range = nullptr;
287     napi_status status = napi_create_object(env, &range);
288     CHECK_AND_RETURN_RET(status == napi_ok, false);
289 
290     CHECK_AND_RETURN_RET(SetPropertyInt32(env, range, "min", min) == true, false);
291     CHECK_AND_RETURN_RET(SetPropertyInt32(env, range, "max", max) == true, false);
292 
293     napi_value nameStr = nullptr;
294     status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &nameStr);
295     CHECK_AND_RETURN_RET(status == napi_ok, false);
296 
297     status = napi_set_property(env, obj, nameStr, range);
298     CHECK_AND_RETURN_RET(status == napi_ok, false);
299 
300     return true;
301 }
302 
AddArrayProperty(napi_env env,napi_value obj,const std::string & name,const std::vector<int32_t> & vec)303 bool CommonNapi::AddArrayProperty(napi_env env, napi_value obj, const std::string &name,
304     const std::vector<int32_t> &vec)
305 {
306     CHECK_AND_RETURN_RET(obj != nullptr, false);
307 
308     napi_value array = nullptr;
309     napi_status status = napi_create_array_with_length(env, vec.size(), &array);
310     CHECK_AND_RETURN_RET(status == napi_ok, false);
311 
312     for (uint32_t i = 0; i < vec.size(); i++) {
313         napi_value number = nullptr;
314         (void)napi_create_int32(env, vec.at(i), &number);
315         (void)napi_set_element(env, array, i, number);
316     }
317 
318     napi_value nameStr = nullptr;
319     status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &nameStr);
320     CHECK_AND_RETURN_RET(status == napi_ok, false);
321 
322     status = napi_set_property(env, obj, nameStr, array);
323     CHECK_AND_RETURN_RET(status == napi_ok, false);
324 
325     return true;
326 }
327 
AddArrayInt(napi_env env,napi_value & array,const std::vector<int32_t> & vec)328 bool CommonNapi::AddArrayInt(napi_env env, napi_value &array, const std::vector<int32_t> &vec)
329 {
330     if (vec.size() == 0) {
331         return false;
332     }
333 
334     napi_status status = napi_create_array_with_length(env, vec.size(), &array);
335     CHECK_AND_RETURN_RET(status == napi_ok, false);
336 
337     for (uint32_t i = 0; i < vec.size(); i++) {
338         napi_value number = nullptr;
339         (void)napi_create_int32(env, vec.at(i), &number);
340         (void)napi_set_element(env, array, i, number);
341     }
342 
343     return true;
344 }
345 
SetPropertyInt32(napi_env env,napi_value & obj,const std::string & key,int32_t value)346 bool CommonNapi::SetPropertyInt32(napi_env env, napi_value &obj, const std::string &key, int32_t value)
347 {
348     CHECK_AND_RETURN_RET(obj != nullptr, false);
349 
350     napi_value keyNapi = nullptr;
351     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
352     CHECK_AND_RETURN_RET(status == napi_ok, false);
353 
354     napi_value valueNapi = nullptr;
355     status = napi_create_int32(env, value, &valueNapi);
356     CHECK_AND_RETURN_RET(status == napi_ok, false);
357 
358     status = napi_set_property(env, obj, keyNapi, valueNapi);
359     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
360 
361     return true;
362 }
363 
SetPropertyString(napi_env env,napi_value & obj,const std::string & key,const std::string & value)364 bool CommonNapi::SetPropertyString(napi_env env, napi_value &obj, const std::string &key, const std::string &value)
365 {
366     CHECK_AND_RETURN_RET(obj != nullptr, false);
367 
368     napi_value keyNapi = nullptr;
369     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
370     CHECK_AND_RETURN_RET(status == napi_ok, false);
371 
372     napi_value valueNapi = nullptr;
373     status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &valueNapi);
374     CHECK_AND_RETURN_RET(status == napi_ok, false);
375 
376     status = napi_set_property(env, obj, keyNapi, valueNapi);
377     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
378 
379     return true;
380 }
381 
CreateFormatBuffer(napi_env env,Format & format)382 napi_value CommonNapi::CreateFormatBuffer(napi_env env, Format &format)
383 {
384     napi_value buffer = nullptr;
385     int32_t intValue = 0;
386     std::string strValue;
387     napi_status status = napi_create_object(env, &buffer);
388     CHECK_AND_RETURN_RET(status == napi_ok, nullptr);
389 
390     for (auto &iter : format.GetFormatMap()) {
391         switch (format.GetValueType(std::string_view(iter.first))) {
392             case FORMAT_TYPE_INT32:
393                 if (format.GetIntValue(iter.first, intValue)) {
394                     CHECK_AND_RETURN_RET(SetPropertyInt32(env, buffer, iter.first, intValue) == true, nullptr);
395                 }
396                 break;
397             case FORMAT_TYPE_STRING:
398                 if (format.GetStringValue(iter.first, strValue)) {
399                     CHECK_AND_RETURN_RET(SetPropertyString(env, buffer, iter.first, strValue) == true, nullptr);
400                 }
401                 break;
402             default:
403                 MEDIA_LOGE("format key: %{public}s", iter.first.c_str());
404                 break;
405         }
406     }
407 
408     return buffer;
409 }
410 
CreateFormatBufferByRef(napi_env env,Format & format,napi_value & result)411 bool CommonNapi::CreateFormatBufferByRef(napi_env env, Format &format, napi_value &result)
412 {
413     int32_t intValue = 0;
414     std::string strValue = "";
415     napi_status status = napi_create_object(env, &result);
416     CHECK_AND_RETURN_RET(status == napi_ok, false);
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                     (void)SetPropertyInt32(env, result, iter.first, intValue);
423                 }
424                 break;
425             case FORMAT_TYPE_STRING:
426                 if (format.GetStringValue(iter.first, strValue)) {
427                     (void)SetPropertyString(env, result, iter.first, strValue);
428                 }
429                 break;
430             default:
431                 MEDIA_LOGE("format key: %{public}s", iter.first.c_str());
432                 break;
433         }
434     }
435 
436     return true;
437 }
438 
AddNumberPropInt32(napi_env env,napi_value obj,const std::string & key,int32_t value)439 bool CommonNapi::AddNumberPropInt32(napi_env env, napi_value obj, const std::string &key, int32_t value)
440 {
441     CHECK_AND_RETURN_RET(obj != nullptr, false);
442 
443     napi_value keyNapi = nullptr;
444     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
445     CHECK_AND_RETURN_RET(status == napi_ok, false);
446 
447     napi_value valueNapi = nullptr;
448     status = napi_create_int32(env, value, &valueNapi);
449     CHECK_AND_RETURN_RET(status == napi_ok, false);
450 
451     status = napi_set_property(env, obj, keyNapi, valueNapi);
452     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
453 
454     return true;
455 }
456 
AddNumberPropInt64(napi_env env,napi_value obj,const std::string & key,int64_t value)457 bool CommonNapi::AddNumberPropInt64(napi_env env, napi_value obj, const std::string &key, int64_t value)
458 {
459     CHECK_AND_RETURN_RET(obj != nullptr, false);
460 
461     napi_value keyNapi = nullptr;
462     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
463     CHECK_AND_RETURN_RET(status == napi_ok, false);
464 
465     napi_value valueNapi = nullptr;
466     status = napi_create_int64(env, value, &valueNapi);
467     CHECK_AND_RETURN_RET(status == napi_ok, false);
468 
469     status = napi_set_property(env, obj, keyNapi, valueNapi);
470     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
471 
472     return true;
473 }
474 
GetJsResult(napi_env env,napi_value & result)475 napi_status MediaJsResultStringVector::GetJsResult(napi_env env, napi_value &result)
476 {
477     napi_status status;
478     size_t size = value_.size();
479     napi_create_array_with_length(env, size, &result);
480     for (unsigned int i = 0; i < size; ++i) {
481         std::string format = value_[i];
482         napi_value value = nullptr;
483         status = napi_create_string_utf8(env, format.c_str(), NAPI_AUTO_LENGTH, &value);
484         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
485             "Failed to call napi_create_string_utf8, with element %{public}u", i);
486         status = napi_set_element(env, result, i, value);
487         CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
488             "Failed to call napi_set_element, with element %{public}u", i);
489     }
490     return napi_ok;
491 }
492 
GetJsResult(napi_env env,napi_value & result)493 napi_status MediaJsResultArray::GetJsResult(napi_env env, napi_value &result)
494 {
495     // create Description
496     napi_status status = napi_create_array(env, &result);
497     if (status != napi_ok) {
498         return napi_cancelled;
499     }
500 
501     auto vecSize = value_.size();
502     for (size_t index = 0; index < vecSize; ++index) {
503         napi_value description = nullptr;
504         description = CommonNapi::CreateFormatBuffer(env, value_[index]);
505         if (description == nullptr || napi_set_element(env, result, index, description) != napi_ok) {
506             return napi_cancelled;
507         }
508     }
509     return napi_ok;
510 }
511 
MediaAsyncContext(napi_env env)512 MediaAsyncContext::MediaAsyncContext(napi_env env)
513     : env_(env)
514 {
515     MEDIA_LOGD("MediaAsyncContext Create 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
516 }
517 
~MediaAsyncContext()518 MediaAsyncContext::~MediaAsyncContext()
519 {
520     MEDIA_LOGD("MediaAsyncContext Destroy 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
521 }
522 
SignError(int32_t code,const std::string & message,bool del)523 void MediaAsyncContext::SignError(int32_t code, const std::string &message, bool del)
524 {
525     errMessage = message;
526     errCode = code;
527     errFlag = true;
528     delFlag = del;
529     MEDIA_LOGE("SignError: %{public}s", message.c_str());
530 }
531 
CompleteCallback(napi_env env,napi_status status,void * data)532 void MediaAsyncContext::CompleteCallback(napi_env env, napi_status status, void *data)
533 {
534     MEDIA_LOGD("CompleteCallback In");
535     auto asyncContext = reinterpret_cast<MediaAsyncContext *>(data);
536     CHECK_AND_RETURN_LOG(asyncContext != nullptr, "asyncContext is nullptr!");
537 
538     std::string memoryTag = asyncContext->memoryTagHead + asyncContext->memoryTagTail;
539     MEDIA_LOGD("MediaAsyncContext Create 0x%{public}06" PRIXPTR " memoryTag = %{public}s",
540         FAKE_POINTER(data), memoryTag.c_str());
541 
542     if (status != napi_ok) {
543         asyncContext->SignError(MSERR_EXT_UNKNOWN, "napi_create_async_work status != napi_ok");
544     }
545 
546     napi_value result = nullptr;
547     napi_get_undefined(env, &result);
548     napi_value args[2] = { nullptr };
549     napi_get_undefined(env, &args[0]);
550     napi_get_undefined(env, &args[1]);
551     if (asyncContext->errFlag) {
552         MEDIA_LOGD("async callback failed");
553         (void)CommonNapi::CreateError(env, asyncContext->errCode, asyncContext->errMessage, result);
554         args[0] = result;
555     } else {
556         MEDIA_LOGD("async callback success");
557         if (asyncContext->JsResult != nullptr) {
558             asyncContext->JsResult->GetJsResult(env, result);
559             CheckCtorResult(env, result, asyncContext, args[0]);
560         }
561         if (!asyncContext->errFlag) {
562             args[1] = result;
563         }
564     }
565 
566     Callback(env, asyncContext, args);
567     napi_delete_async_work(env, asyncContext->work);
568 
569     if (asyncContext->delFlag) {
570         delete asyncContext;
571         asyncContext = nullptr;
572     }
573 }
574 
Callback(napi_env env,const MediaAsyncContext * context,const napi_value * args)575 void MediaAsyncContext::Callback(napi_env env, const MediaAsyncContext *context, const napi_value *args)
576 {
577     if (context->deferred) {
578         if (context->errFlag) {
579             MEDIA_LOGE("promise napi_reject_deferred");
580             napi_reject_deferred(env, context->deferred, args[0]);
581         } else {
582             MEDIA_LOGD("promise napi_resolve_deferred");
583             napi_resolve_deferred(env, context->deferred, args[1]);
584         }
585     } else if (context->callbackRef != nullptr) {
586         MEDIA_LOGD("callback napi_call_function");
587         napi_value callback = nullptr;
588         napi_get_reference_value(env, context->callbackRef, &callback);
589         CHECK_AND_RETURN_LOG(callback != nullptr, "callback is nullptr!");
590         constexpr size_t argCount = 2;
591         napi_value retVal;
592         napi_get_undefined(env, &retVal);
593         napi_call_function(env, nullptr, callback, argCount, args, &retVal);
594         napi_delete_reference(env, context->callbackRef);
595     } else {
596         MEDIA_LOGE("invalid promise and callback");
597     }
598 }
599 
CheckCtorResult(napi_env env,napi_value & result,MediaAsyncContext * ctx,napi_value & args)600 void MediaAsyncContext::CheckCtorResult(napi_env env, napi_value &result, MediaAsyncContext *ctx, napi_value &args)
601 {
602     CHECK_AND_RETURN(ctx != nullptr);
603     if (ctx->ctorFlag) {
604         void *instance = nullptr;
605         if (napi_unwrap(env, result, reinterpret_cast<void **>(&instance)) != napi_ok || instance == nullptr) {
606             MEDIA_LOGE("Failed to create instance");
607             ctx->errFlag = true;
608             (void)CommonNapi::CreateError(env, MSERR_EXT_API9_NO_MEMORY,
609                 "The instance or memory has reached the upper limit, please recycle background playback", result);
610             args = result;
611         }
612     }
613 }
614 
AddStringProperty(napi_env env,napi_value obj,const std::string & key,const std::string & value)615 bool CommonNapi::AddStringProperty(napi_env env, napi_value obj, const std::string &key, const std::string &value)
616 {
617     CHECK_AND_RETURN_RET(obj != nullptr, false);
618 
619     napi_value keyNapi = nullptr;
620     napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
621     CHECK_AND_RETURN_RET(status == napi_ok, false);
622 
623     napi_value valueNapi = nullptr;
624     status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &valueNapi);
625     CHECK_AND_RETURN_RET(status == napi_ok, false);
626 
627     status = napi_set_property(env, obj, keyNapi, valueNapi);
628     CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
629 
630     return true;
631 }
632 } // namespace Media
633 } // namespace OHOS
634