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