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