1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "common_napi.h"
17 #include <climits>
18 #include "avcodec_list.h"
19 #include "media_log.h"
20 #include "media_errors.h"
21
22 namespace {
23 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_PLAYER, "CommonNapi"};
24 }
25
26 namespace OHOS {
27 namespace Media {
GetStringArgument(napi_env env,napi_value value,size_t maxLength)28 std::string CommonNapi::GetStringArgument(napi_env env, napi_value value, size_t maxLength)
29 {
30 std::string strValue = "";
31 size_t bufLength = 0;
32 napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &bufLength);
33 if (status == napi_ok && bufLength > 0 && bufLength < maxLength) {
34 char *buffer = static_cast<char *>(malloc((bufLength + 1) * sizeof(char)));
35 CHECK_AND_RETURN_RET_LOG(buffer != nullptr, strValue, "no memory");
36 status = napi_get_value_string_utf8(env, value, buffer, bufLength + 1, &bufLength);
37 if (status == napi_ok) {
38 MEDIA_LOGD("argument = %{public}s", buffer);
39 strValue = buffer;
40 }
41 free(buffer);
42 buffer = nullptr;
43 }
44 return strValue;
45 }
46
GetIntArrayArgument(napi_env env,napi_value value,std::vector<int32_t> & vec,size_t maxLength)47 bool CommonNapi::GetIntArrayArgument(napi_env env, napi_value value, std::vector<int32_t> &vec, size_t maxLength)
48 {
49 napi_valuetype type;
50 napi_status status = napi_typeof(env, value, &type);
51 if (status != napi_ok || type != napi_object) {
52 return false;
53 }
54 uint32_t arrayLength = 0;
55 status = napi_get_array_length(env, value, &arrayLength);
56 if (status != napi_ok || arrayLength == 0 || arrayLength > maxLength) {
57 return false;
58 }
59
60 for (size_t i = 0; i < arrayLength; ++i) {
61 napi_value element;
62 status = napi_get_element(env, value, i, &element);
63 if (status != napi_ok) {
64 return false;
65 }
66 int32_t elementValue = 0;
67 status = napi_get_value_int32(env, element, &elementValue);
68 if (status != napi_ok) {
69 return false;
70 }
71 vec.push_back(elementValue);
72 }
73 return true;
74 }
75
CheckValueType(napi_env env,napi_value arg,napi_valuetype type)76 bool CommonNapi::CheckValueType(napi_env env, napi_value arg, napi_valuetype type)
77 {
78 napi_valuetype valueType = napi_undefined;
79 if (arg != nullptr && napi_typeof(env, arg, &valueType) == napi_ok && valueType == type) {
80 return true;
81 }
82 return false;
83 }
84
CheckhasNamedProperty(napi_env env,napi_value arg,std::string type)85 bool CommonNapi::CheckhasNamedProperty(napi_env env, napi_value arg, std::string type)
86 {
87 bool exist = false;
88 napi_status napiStatus = napi_has_named_property(env, arg, type.c_str(), &exist);
89 return exist && (napiStatus == napi_ok);
90 }
91
GetPropertyInt32(napi_env env,napi_value configObj,const std::string & type,int32_t & result)92 bool CommonNapi::GetPropertyInt32(napi_env env, napi_value configObj, const std::string &type, int32_t &result)
93 {
94 napi_value item = nullptr;
95 bool exist = false;
96 napi_status napiStatus = napi_has_named_property(env, configObj, type.c_str(), &exist);
97 CHECK_AND_RETURN_RET_LOG(napiStatus == napi_ok && exist, false, "can not find %{public}s property", type.c_str());
98 CHECK_AND_RETURN_RET_LOG(napi_get_named_property(env, configObj, type.c_str(), &item) == napi_ok, false,
99 "get %{public}s property fail", type.c_str());
100 CHECK_AND_RETURN_RET_LOG(napi_get_value_int32(env, item, &result) == napi_ok, false,
101 "get %{public}s property value fail", type.c_str());
102 return true;
103 }
104
GetPropertyUint32(napi_env env,napi_value configObj,const std::string & type,uint32_t & result)105 bool CommonNapi::GetPropertyUint32(napi_env env, napi_value configObj, const std::string &type, uint32_t &result)
106 {
107 napi_value item = nullptr;
108 bool exist = false;
109 napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
110 CHECK_AND_RETURN_RET_LOG(status == napi_ok && exist, false, "can not find %{public}s property", type.c_str());
111 CHECK_AND_RETURN_RET_LOG(napi_get_named_property(env, configObj, type.c_str(), &item) == napi_ok, false,
112 "get %{public}s property fail", type.c_str());
113
114 CHECK_AND_RETURN_RET_LOG(napi_get_value_uint32(env, item, &result) == napi_ok, false,
115 "get %{public}s property value fail", type.c_str());
116 return true;
117 }
118
GetPropertyInt64(napi_env env,napi_value configObj,const std::string & type,int64_t & result)119 bool CommonNapi::GetPropertyInt64(napi_env env, napi_value configObj, const std::string &type, int64_t &result)
120 {
121 napi_value item = nullptr;
122 bool exist = false;
123 napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
124 if (status != napi_ok || !exist) {
125 MEDIA_LOGE("can not find %{public}s property", type.c_str());
126 return false;
127 }
128
129 if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
130 MEDIA_LOGE("get %{public}s property fail", type.c_str());
131 return false;
132 }
133
134 if (napi_get_value_int64(env, item, &result) != napi_ok) {
135 MEDIA_LOGE("get %{public}s property value fail", type.c_str());
136 return false;
137 }
138 return true;
139 }
140
GetPropertyDouble(napi_env env,napi_value configObj,const std::string & type,double & result)141 bool CommonNapi::GetPropertyDouble(napi_env env, napi_value configObj, const std::string &type, double &result)
142 {
143 napi_value item = nullptr;
144 bool exist = false;
145 napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
146 if (status != napi_ok || !exist) {
147 MEDIA_LOGE("can not find %{public}s property", type.c_str());
148 return false;
149 }
150
151 if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
152 MEDIA_LOGE("get %{public}s property fail", type.c_str());
153 return false;
154 }
155
156 if (napi_get_value_double(env, item, &result) != napi_ok) {
157 MEDIA_LOGE("get %{public}s property value fail", type.c_str());
158 return false;
159 }
160 return true;
161 }
162
GetPropertyString(napi_env env,napi_value configObj,const std::string & type)163 std::string CommonNapi::GetPropertyString(napi_env env, napi_value configObj, const std::string &type)
164 {
165 std::string invalid = "";
166 bool exist = false;
167 napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
168 if (status != napi_ok || !exist) {
169 MEDIA_LOGE("can not find %{public}s property", type.c_str());
170 return invalid;
171 }
172
173 napi_value item = nullptr;
174 if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
175 MEDIA_LOGE("get %{public}s property fail", type.c_str());
176 return invalid;
177 }
178
179 return GetStringArgument(env, item);
180 }
181
GetPropertyArrayBuffer(napi_env env,napi_value configObj,void ** data,size_t * length)182 bool CommonNapi::GetPropertyArrayBuffer(napi_env env, napi_value configObj, void **data, size_t* length)
183 {
184 if (napi_get_arraybuffer_info(env, configObj, data, length) != napi_ok) {
185 MEDIA_LOGE("get arraybuffer value fail");
186 return false;
187 }
188 return true;
189 }
190
GetPropertyRecord(napi_env env,napi_value configObj,Meta & meta,std::string type)191 napi_status CommonNapi::GetPropertyRecord(napi_env env, napi_value configObj, Meta &meta, std::string type)
192 {
193 bool exist = false;
194 napi_value in = nullptr;
195 napi_valuetype valueType = napi_undefined;
196 napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
197 if (status != napi_ok || !exist) {
198 MEDIA_LOGE("can not find %{public}s property", type.c_str());
199 return napi_invalid_arg;
200 }
201 if (napi_get_named_property(env, configObj, type.c_str(), &in) != napi_ok) {
202 MEDIA_LOGE("get %{public}s property fail", type.c_str());
203 return napi_invalid_arg;
204 }
205 status = napi_typeof(env, in, &valueType);
206 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "get valueType failed");
207 CHECK_AND_RETURN_RET_LOG(valueType != napi_undefined, napi_ok, "PropertyRecord undefined");
208 CHECK_AND_RETURN_RET_LOG(valueType == napi_object, napi_invalid_arg, "invalid arguments");
209
210 napi_value dataList = nullptr;
211 uint32_t count = 0;
212 status = napi_get_property_names(env, in, &dataList);
213 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "get property names failed");
214 status = napi_get_array_length(env, dataList, &count);
215 CHECK_AND_RETURN_RET_LOG(status == napi_ok && count <= MAX_COUNT,
216 napi_invalid_arg, "get length failed or more than 500");
217
218 napi_value jsKey = nullptr;
219 napi_value jsValue = nullptr;
220 for (uint32_t i = 0; i < count; i++) {
221 status = napi_get_element(env, dataList, i, &jsKey);
222 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "get element Key failed");
223 status = napi_typeof(env, jsKey, &valueType);
224 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "get valueType failed");
225 CHECK_AND_RETURN_RET_LOG(valueType == napi_string, napi_invalid_arg, "key not supported type");
226 std::string strKey = GetStringArgument(env, jsKey, CUSTOM_MAX_LENGTH);
227 CHECK_AND_RETURN_RET_LOG(strKey != "", napi_invalid_arg, "key not supported");
228
229 status = napi_get_named_property(env, in, strKey.c_str(), &jsValue);
230 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "get property value failed");
231 status = napi_typeof(env, jsValue, &valueType);
232 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "get valueType failed");
233
234 CHECK_AND_RETURN_RET_LOG(valueType == napi_string, napi_invalid_arg, "value not supported type");
235 std::string strValue = GetStringArgument(env, jsValue, CUSTOM_MAX_LENGTH);
236 CHECK_AND_RETURN_RET_LOG(!strValue.empty(), napi_invalid_arg, "get value failed");
237 meta.SetData(strKey, strValue);
238 }
239 return napi_ok;
240 }
241
GetFdArgument(napi_env env,napi_value value,AVFileDescriptor & rawFd)242 bool CommonNapi::GetFdArgument(napi_env env, napi_value value, AVFileDescriptor &rawFd)
243 {
244 CHECK_AND_RETURN_RET(GetPropertyInt32(env, value, "fd", rawFd.fd) == true, false);
245
246 if (!GetPropertyInt64(env, value, "offset", rawFd.offset)) {
247 rawFd.offset = 0; // use default value
248 }
249
250 if (!GetPropertyInt64(env, value, "length", rawFd.length)) {
251 rawFd.length = -1; // -1 means use default value
252 }
253
254 MEDIA_LOGD("get fd argument, fd = %{public}d, offset = %{public}" PRIi64 ", size = %{public}" PRIi64 "",
255 rawFd.fd, rawFd.offset, rawFd.length);
256
257 return true;
258 }
259
GetPropertyMap(napi_env env,napi_value value,std::map<std::string,std::string> & map)260 bool CommonNapi::GetPropertyMap(napi_env env, napi_value value, std::map<std::string, std::string>& map)
261 {
262 napi_value jsProNameList = nullptr;
263 uint32_t jsProCount = 0;
264 napi_status status = napi_get_property_names(env, value, &jsProNameList);
265 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "get property name failed");
266 status = napi_get_array_length(env, jsProNameList, &jsProCount);
267 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "get subKeys length failed");
268
269 napi_value jsProName = nullptr;
270 napi_value jsProValue = nullptr;
271 for (uint32_t i = 0; i < jsProCount; i++) {
272 status = napi_get_element(env, jsProNameList, i, &jsProName);
273 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "get sub key failed");
274 std::string strProName = GetStringArgument(env, jsProName);
275
276 status = napi_get_named_property(env, value, strProName.c_str(), &jsProValue);
277 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "get sub value failed");
278 std::string strProValue = GetStringArgument(env, jsProValue);
279
280 map.emplace(strProName, strProValue);
281 }
282
283 return true;
284 }
285
GetPlayStrategy(napi_env env,napi_value value,AVPlayStrategyTmp & playStrategy)286 bool CommonNapi::GetPlayStrategy(napi_env env, napi_value value, AVPlayStrategyTmp &playStrategy)
287 {
288 if (!GetPropertyUint32(env, value, "preferredWidth", playStrategy.preferredWidth)) {
289 playStrategy.preferredWidth = 0; // use default value
290 }
291 if (!GetPropertyUint32(env, value, "preferredHeight", playStrategy.preferredHeight)) {
292 playStrategy.preferredHeight = 0; // use default value
293 }
294 if (!GetPropertyUint32(env, value, "preferredBufferDuration", playStrategy.preferredBufferDuration)) {
295 playStrategy.preferredBufferDuration = 0; // use default value
296 }
297 if (!GetPropertyBool(env, value, "preferredHdr", playStrategy.preferredHdr)) {
298 playStrategy.preferredHdr = 0; // use default value
299 }
300 if (!GetPropertyBool(env, value, "showFirstFrameOnPrepare", playStrategy.showFirstFrameOnPrepare)) {
301 playStrategy.showFirstFrameOnPrepare = false; // use default value
302 }
303 if (!GetPropertyBool(env, value, "enableSuperResolution", playStrategy.enableSuperResolution)) {
304 playStrategy.enableSuperResolution = false; // use default value
305 }
306 if (!GetPropertyInt32(env, value, "mutedMediaType", playStrategy.mutedMediaType)) {
307 playStrategy.mutedMediaType = MediaType::MEDIA_TYPE_MAX_COUNT; // use default value
308 }
309 playStrategy.preferredAudioLanguage = GetPropertyString(env, value, "preferredAudioLanguage");
310 playStrategy.preferredSubtitleLanguage = GetPropertyString(env, value, "preferredSubtitleLanguage");
311 if (!GetPropertyDouble(env, value, "preferredBufferDurationForPlaying",
312 playStrategy.preferredBufferDurationForPlaying)) {
313 playStrategy.preferredBufferDurationForPlaying = 0; // use default value
314 playStrategy.isSetBufferDurationForPlaying = false;
315 }
316 if (!GetPropertyDouble(env, value, "thresholdForAutoQuickPlay", playStrategy.thresholdForAutoQuickPlay)) {
317 playStrategy.thresholdForAutoQuickPlay = -1;
318 playStrategy.isSetThresholdForAutoQuickPlay = false;
319 }
320 return true;
321 }
322
GetPlayMediaStreamData(napi_env env,napi_value value,AVPlayMediaStreamTmp & mediaStream)323 bool CommonNapi::GetPlayMediaStreamData(napi_env env, napi_value value, AVPlayMediaStreamTmp &mediaStream)
324 {
325 bool existProperty = CommonNapi::CheckhasNamedProperty(env, value, "url");
326 existProperty &= CommonNapi::CheckhasNamedProperty(env, value, "width");
327 existProperty &= CommonNapi::CheckhasNamedProperty(env, value, "height");
328 existProperty &= CommonNapi::CheckhasNamedProperty(env, value, "bitrate");
329 CHECK_AND_RETURN_RET_LOG(existProperty, false, "property is not complete for AVPlayMediaStream");
330
331 mediaStream.url = GetPropertyString(env, value, "url");
332 GetPropertyUint32(env, value, "width", mediaStream.width);
333 GetPropertyUint32(env, value, "height", mediaStream.height);
334 GetPropertyUint32(env, value, "bitrate", mediaStream.bitrate);
335 return true;
336 }
337
FillErrorArgs(napi_env env,int32_t errCode,const napi_value & args)338 napi_status CommonNapi::FillErrorArgs(napi_env env, int32_t errCode, const napi_value &args)
339 {
340 napi_value codeStr = nullptr;
341 napi_status status = napi_create_string_utf8(env, "code", NAPI_AUTO_LENGTH, &codeStr);
342 CHECK_AND_RETURN_RET_LOG(status == napi_ok && codeStr != nullptr, napi_invalid_arg, "create code str fail");
343
344 napi_value errCodeVal = nullptr;
345 int32_t errCodeInt = errCode;
346 status = napi_create_int32(env, errCodeInt, &errCodeVal);
347 CHECK_AND_RETURN_RET_LOG(status == napi_ok && errCodeVal != nullptr, napi_invalid_arg,
348 "create error code number val fail");
349
350 status = napi_set_property(env, args, codeStr, errCodeVal);
351 CHECK_AND_RETURN_RET_LOG(status == napi_ok, napi_invalid_arg, "set error code property fail");
352
353 napi_value nameStr = nullptr;
354 status = napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &nameStr);
355 CHECK_AND_RETURN_RET_LOG(status == napi_ok && nameStr != nullptr, napi_invalid_arg, "create name str fail");
356
357 napi_value errNameVal = nullptr;
358 status = napi_create_string_utf8(env, "BusinessError", NAPI_AUTO_LENGTH, &errNameVal);
359 CHECK_AND_RETURN_RET_LOG(status == napi_ok && errNameVal != nullptr, napi_invalid_arg,
360 "create BusinessError str fail");
361
362 status = napi_set_property(env, args, nameStr, errNameVal);
363 CHECK_AND_RETURN_RET_LOG(status == napi_ok, napi_invalid_arg, "set error name property fail");
364 return napi_ok;
365 }
366
CreateError(napi_env env,int32_t errCode,const std::string & errMsg,napi_value & errVal)367 napi_status CommonNapi::CreateError(napi_env env, int32_t errCode, const std::string &errMsg, napi_value &errVal)
368 {
369 napi_get_undefined(env, &errVal);
370
371 napi_value msgValStr = nullptr;
372 napi_status nstatus = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &msgValStr);
373 if (nstatus != napi_ok || msgValStr == nullptr) {
374 MEDIA_LOGE("create error message str fail");
375 return napi_invalid_arg;
376 }
377
378 nstatus = napi_create_error(env, nullptr, msgValStr, &errVal);
379 if (nstatus != napi_ok || errVal == nullptr) {
380 MEDIA_LOGE("create error fail");
381 return napi_invalid_arg;
382 }
383
384 napi_value codeStr = nullptr;
385 nstatus = napi_create_string_utf8(env, "code", NAPI_AUTO_LENGTH, &codeStr);
386 if (nstatus != napi_ok || codeStr == nullptr) {
387 MEDIA_LOGE("create code str fail");
388 return napi_invalid_arg;
389 }
390
391 napi_value errCodeVal = nullptr;
392 nstatus = napi_create_int32(env, errCode, &errCodeVal);
393 if (nstatus != napi_ok || errCodeVal == nullptr) {
394 MEDIA_LOGE("create error code number val fail");
395 return napi_invalid_arg;
396 }
397
398 nstatus = napi_set_property(env, errVal, codeStr, errCodeVal);
399 if (nstatus != napi_ok) {
400 MEDIA_LOGE("set error code property fail");
401 return napi_invalid_arg;
402 }
403
404 napi_value nameStr = nullptr;
405 nstatus = napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &nameStr);
406 if (nstatus != napi_ok || nameStr == nullptr) {
407 MEDIA_LOGE("create name str fail");
408 return napi_invalid_arg;
409 }
410
411 napi_value errNameVal = nullptr;
412 nstatus = napi_create_string_utf8(env, "BusinessError", NAPI_AUTO_LENGTH, &errNameVal);
413 if (nstatus != napi_ok || errNameVal == nullptr) {
414 MEDIA_LOGE("create BusinessError str fail");
415 return napi_invalid_arg;
416 }
417
418 nstatus = napi_set_property(env, errVal, nameStr, errNameVal);
419 if (nstatus != napi_ok) {
420 MEDIA_LOGE("set error name property fail");
421 return napi_invalid_arg;
422 }
423
424 return napi_ok;
425 }
426
CreateReference(napi_env env,napi_value arg)427 napi_ref CommonNapi::CreateReference(napi_env env, napi_value arg)
428 {
429 napi_ref ref = nullptr;
430 napi_valuetype valueType = napi_undefined;
431 if (arg != nullptr && napi_typeof(env, arg, &valueType) == napi_ok && valueType == napi_function) {
432 MEDIA_LOGD("napi_create_reference");
433 napi_create_reference(env, arg, 1, &ref);
434 }
435 return ref;
436 }
437
CreatePromise(napi_env env,napi_ref ref,napi_value & result)438 napi_deferred CommonNapi::CreatePromise(napi_env env, napi_ref ref, napi_value &result)
439 {
440 napi_deferred deferred = nullptr;
441 if (ref == nullptr) {
442 MEDIA_LOGD("napi_create_promise");
443 napi_create_promise(env, &deferred, &result);
444 }
445 return deferred;
446 }
447
SetPropertyByValueType(napi_env env,napi_value & obj,std::shared_ptr<Meta> & meta,std::string key)448 bool CommonNapi::SetPropertyByValueType(napi_env env, napi_value &obj, std::shared_ptr<Meta> &meta, std::string key)
449 {
450 CHECK_AND_RETURN_RET(obj != nullptr && meta != nullptr, false);
451 CHECK_AND_RETURN_RET(meta->Find(key) != meta->end(), false);
452
453 bool ret = true;
454 AnyValueType type = meta->GetValueType(key);
455 if (type == AnyValueType::STRING) {
456 std::string sValue;
457 ret = meta->GetData(key, sValue);
458 CHECK_AND_RETURN_RET_LOG(ret, ret, "GetData failed, key %{public}s", key.c_str());
459 ret = CommonNapi::SetPropertyString(env, obj, key, sValue);
460 CHECK_AND_RETURN_RET_LOG(ret, ret, "SetPropertyString failed, key %{public}s", key.c_str());
461 } else if (type == AnyValueType::INT32_T) {
462 int32_t value;
463 ret = meta->GetData(key, value);
464 CHECK_AND_RETURN_RET_LOG(ret, ret, "GetData failed, key %{public}s", key.c_str());
465 ret = CommonNapi::SetPropertyInt32(env, obj, key, value);
466 CHECK_AND_RETURN_RET_LOG(ret, ret, "SetPropertyString failed, key %{public}s", key.c_str());
467 } else if (type == AnyValueType::FLOAT) {
468 float dValue;
469 ret = meta->GetData(key, dValue);
470 CHECK_AND_RETURN_RET_LOG(ret, ret, "GetData failed, key %{public}s", key.c_str());
471 ret = CommonNapi::SetPropertyDouble(env, obj, key, dValue);
472 CHECK_AND_RETURN_RET_LOG(ret, ret, "SetPropertyString failed, key %{public}s", key.c_str());
473 } else {
474 MEDIA_LOGE("not supported value type");
475 }
476 return true;
477 }
478
AddRangeProperty(napi_env env,napi_value obj,const std::string & name,int32_t min,int32_t max)479 bool CommonNapi::AddRangeProperty(napi_env env, napi_value obj, const std::string &name, int32_t min, int32_t max)
480 {
481 CHECK_AND_RETURN_RET(obj != nullptr, false);
482
483 napi_value range = nullptr;
484 napi_status status = napi_create_object(env, &range);
485 CHECK_AND_RETURN_RET(status == napi_ok, false);
486
487 CHECK_AND_RETURN_RET(SetPropertyInt32(env, range, "min", min) == true, false);
488 CHECK_AND_RETURN_RET(SetPropertyInt32(env, range, "max", max) == true, false);
489
490 napi_value nameStr = nullptr;
491 status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &nameStr);
492 CHECK_AND_RETURN_RET(status == napi_ok, false);
493
494 status = napi_set_property(env, obj, nameStr, range);
495 CHECK_AND_RETURN_RET(status == napi_ok, false);
496
497 return true;
498 }
499
AddArrayProperty(napi_env env,napi_value obj,const std::string & name,const std::vector<int32_t> & vec)500 bool CommonNapi::AddArrayProperty(napi_env env, napi_value obj, const std::string &name,
501 const std::vector<int32_t> &vec)
502 {
503 CHECK_AND_RETURN_RET(obj != nullptr, false);
504
505 napi_value array = nullptr;
506 napi_status status = napi_create_array_with_length(env, vec.size(), &array);
507 CHECK_AND_RETURN_RET(status == napi_ok, false);
508
509 for (uint32_t i = 0; i < vec.size(); i++) {
510 napi_value number = nullptr;
511 (void)napi_create_int32(env, vec.at(i), &number);
512 (void)napi_set_element(env, array, i, number);
513 }
514
515 napi_value nameStr = nullptr;
516 status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &nameStr);
517 CHECK_AND_RETURN_RET(status == napi_ok, false);
518
519 status = napi_set_property(env, obj, nameStr, array);
520 CHECK_AND_RETURN_RET(status == napi_ok, false);
521
522 return true;
523 }
524
SetPropertyArrayBuffer(const napi_env & env,napi_value & result,const std::string & fieldStr,size_t bufferLen,uint8_t * bufferData)525 bool CommonNapi::SetPropertyArrayBuffer(
526 const napi_env &env, napi_value &result, const std::string &fieldStr, size_t bufferLen, uint8_t *bufferData)
527 {
528 void *native = nullptr;
529 napi_value arrayBuffer = nullptr;
530 napi_status status = napi_create_arraybuffer(env, bufferLen, &native, &arrayBuffer);
531 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "napi_create_arraybuffer failed");
532 CHECK_AND_RETURN_RET_LOG(memcpy_s(native, bufferLen, bufferData, bufferLen) == 0, false, "memcpy failed");
533
534 status = napi_set_named_property(env, result, fieldStr.c_str(), arrayBuffer);
535 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "napi_set_named_property failed");
536
537 return true;
538 }
539
540
AddArrayInt(napi_env env,napi_value & array,const std::vector<int32_t> & vec)541 bool CommonNapi::AddArrayInt(napi_env env, napi_value &array, const std::vector<int32_t> &vec)
542 {
543 if (vec.size() == 0) {
544 return false;
545 }
546
547 napi_status status = napi_create_array_with_length(env, vec.size(), &array);
548 CHECK_AND_RETURN_RET(status == napi_ok, false);
549
550 for (uint32_t i = 0; i < vec.size(); i++) {
551 napi_value number = nullptr;
552 (void)napi_create_int32(env, vec.at(i), &number);
553 (void)napi_set_element(env, array, i, number);
554 }
555
556 return true;
557 }
558
SetPropertyInt32(napi_env env,napi_value & obj,const std::string & key,int32_t value)559 bool CommonNapi::SetPropertyInt32(napi_env env, napi_value &obj, const std::string &key, int32_t value)
560 {
561 CHECK_AND_RETURN_RET(obj != nullptr, false);
562
563 napi_value keyNapi = nullptr;
564 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
565 CHECK_AND_RETURN_RET(status == napi_ok, false);
566
567 napi_value valueNapi = nullptr;
568 status = napi_create_int32(env, value, &valueNapi);
569 CHECK_AND_RETURN_RET(status == napi_ok, false);
570
571 status = napi_set_property(env, obj, keyNapi, valueNapi);
572 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
573
574 return true;
575 }
576
SetPropertyInt64(napi_env env,napi_value & obj,const std::string & key,int64_t value)577 bool CommonNapi::SetPropertyInt64(napi_env env, napi_value &obj, const std::string &key, int64_t value)
578 {
579 CHECK_AND_RETURN_RET(obj != nullptr, false);
580
581 napi_value keyNapi = nullptr;
582 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
583 CHECK_AND_RETURN_RET(status == napi_ok, false);
584
585 napi_value valueNapi = nullptr;
586 status = napi_create_int64(env, value, &valueNapi);
587 CHECK_AND_RETURN_RET(status == napi_ok, false);
588
589 status = napi_set_property(env, obj, keyNapi, valueNapi);
590 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
591
592 return true;
593 }
594
SetPropertyDouble(napi_env env,napi_value & obj,const std::string & key,double value)595 bool CommonNapi::SetPropertyDouble(napi_env env, napi_value &obj, const std::string &key, double value)
596 {
597 CHECK_AND_RETURN_RET(obj != nullptr, false);
598
599 napi_value keyNapi = nullptr;
600 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
601 CHECK_AND_RETURN_RET(status == napi_ok, false);
602
603 napi_value valueNapi = nullptr;
604 status = napi_create_double(env, value, &valueNapi);
605 CHECK_AND_RETURN_RET(status == napi_ok, false);
606
607 status = napi_set_property(env, obj, keyNapi, valueNapi);
608 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
609
610 return true;
611 }
612
SetPropertyBool(napi_env env,napi_value & obj,const std::string & key,bool value)613 bool CommonNapi::SetPropertyBool(napi_env env, napi_value &obj, const std::string &key, bool value)
614 {
615 CHECK_AND_RETURN_RET(obj != nullptr, false);
616
617 napi_value keyNapi = nullptr;
618 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
619 CHECK_AND_RETURN_RET(status == napi_ok, false);
620
621 napi_value valueNapi = nullptr;
622 status = napi_get_boolean(env, value, &valueNapi);
623 CHECK_AND_RETURN_RET(status == napi_ok, false);
624
625 status = napi_set_property(env, obj, keyNapi, valueNapi);
626 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
627
628 return true;
629 }
630
SetPropertyString(napi_env env,napi_value & obj,const std::string & key,const std::string & value)631 bool CommonNapi::SetPropertyString(napi_env env, napi_value &obj, const std::string &key, const std::string &value)
632 {
633 CHECK_AND_RETURN_RET(obj != nullptr, false);
634
635 napi_value keyNapi = nullptr;
636 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
637 CHECK_AND_RETURN_RET(status == napi_ok, false);
638
639 napi_value valueNapi = nullptr;
640 status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &valueNapi);
641 CHECK_AND_RETURN_RET(status == napi_ok, false);
642
643 status = napi_set_property(env, obj, keyNapi, valueNapi);
644 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
645
646 return true;
647 }
648
CreateFormatBuffer(napi_env env,Format & format)649 napi_value CommonNapi::CreateFormatBuffer(napi_env env, Format &format)
650 {
651 int32_t intValue = 0;
652 size_t bufferLen = 0;
653 std::string strValue;
654 uint8_t *bufferData = nullptr;
655 napi_value buffer = nullptr;
656 napi_status status = napi_create_object(env, &buffer);
657 CHECK_AND_RETURN_RET(status == napi_ok, nullptr);
658
659 for (auto &iter : format.GetFormatMap()) {
660 switch (format.GetValueType(std::string_view(iter.first))) {
661 case FORMAT_TYPE_INT32:
662 if (format.GetIntValue(iter.first, intValue)) {
663 CHECK_AND_RETURN_RET(SetPropertyInt32(env, buffer, iter.first, intValue) == true, nullptr);
664 }
665 break;
666 case FORMAT_TYPE_INT64:
667 int64_t longValue;
668 if (format.GetLongValue(iter.first, longValue) &&
669 longValue >= INT32_MIN && longValue <= INT32_MAX) {
670 intValue = static_cast<int32_t>(longValue);
671 CHECK_AND_RETURN_RET(SetPropertyInt32(env, buffer, iter.first, intValue) == true, nullptr);
672 }
673 break;
674 case FORMAT_TYPE_DOUBLE:
675 double doubleValue;
676 if (format.GetDoubleValue(iter.first, doubleValue) &&
677 doubleValue >= INT32_MIN && doubleValue <= INT32_MAX) {
678 intValue = static_cast<int32_t>(doubleValue);
679 CHECK_AND_RETURN_RET(SetPropertyInt32(env, buffer, iter.first, intValue) == true, nullptr);
680 }
681 break;
682 case FORMAT_TYPE_STRING:
683 if (format.GetStringValue(iter.first, strValue)) {
684 CHECK_AND_RETURN_RET(SetPropertyString(env, buffer, iter.first, strValue) == true, nullptr);
685 }
686 break;
687 case FORMAT_TYPE_ADDR:
688 if (format.GetBuffer(iter.first, &bufferData, bufferLen)) {
689 CHECK_AND_RETURN_RET(
690 SetPropertyArrayBuffer(env, buffer, iter.first, bufferLen, bufferData) == true, nullptr);
691 }
692 break;
693 default:
694 MEDIA_LOGE("format key: %{public}s", iter.first.c_str());
695 break;
696 }
697 }
698
699 return buffer;
700 }
701
CreateFormatBufferByRef(napi_env env,Format & format,napi_value & result)702 bool CommonNapi::CreateFormatBufferByRef(napi_env env, Format &format, napi_value &result)
703 {
704 int32_t intValue = 0;
705 int64_t longValue = 0;
706 std::string strValue = "";
707 napi_status status = napi_create_object(env, &result);
708 CHECK_AND_RETURN_RET(status == napi_ok, false);
709
710 for (auto &iter : format.GetFormatMap()) {
711 switch (format.GetValueType(std::string_view(iter.first))) {
712 case FORMAT_TYPE_INT32:
713 if (format.GetIntValue(iter.first, intValue)) {
714 (void)SetPropertyInt32(env, result, iter.first, intValue);
715 }
716 break;
717 case FORMAT_TYPE_INT64:
718 if (format.GetLongValue(iter.first, longValue)) {
719 (void)SetPropertyInt64(env, result, iter.first, longValue);
720 }
721 break;
722 case FORMAT_TYPE_STRING:
723 if (format.GetStringValue(iter.first, strValue)) {
724 (void)SetPropertyString(env, result, iter.first, strValue);
725 }
726 break;
727 default:
728 MEDIA_LOGE("format key: %{public}s", iter.first.c_str());
729 break;
730 }
731 }
732
733 return true;
734 }
735
AddNumberPropInt32(napi_env env,napi_value obj,const std::string & key,int32_t value)736 bool CommonNapi::AddNumberPropInt32(napi_env env, napi_value obj, const std::string &key, int32_t value)
737 {
738 CHECK_AND_RETURN_RET(obj != nullptr, false);
739
740 napi_value keyNapi = nullptr;
741 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
742 CHECK_AND_RETURN_RET(status == napi_ok, false);
743
744 napi_value valueNapi = nullptr;
745 status = napi_create_int32(env, value, &valueNapi);
746 CHECK_AND_RETURN_RET(status == napi_ok, false);
747
748 status = napi_set_property(env, obj, keyNapi, valueNapi);
749 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
750
751 return true;
752 }
753
AddNumberPropInt64(napi_env env,napi_value obj,const std::string & key,int64_t value)754 bool CommonNapi::AddNumberPropInt64(napi_env env, napi_value obj, const std::string &key, int64_t value)
755 {
756 CHECK_AND_RETURN_RET(obj != nullptr, false);
757
758 napi_value keyNapi = nullptr;
759 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
760 CHECK_AND_RETURN_RET(status == napi_ok, false);
761
762 napi_value valueNapi = nullptr;
763 status = napi_create_int64(env, value, &valueNapi);
764 CHECK_AND_RETURN_RET(status == napi_ok, false);
765
766 status = napi_set_property(env, obj, keyNapi, valueNapi);
767 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
768
769 return true;
770 }
771
GetJsResult(napi_env env,napi_value & result)772 napi_status MediaJsResultStringVector::GetJsResult(napi_env env, napi_value &result)
773 {
774 napi_status status;
775 size_t size = value_.size();
776 napi_create_array_with_length(env, size, &result);
777 for (unsigned int i = 0; i < size; ++i) {
778 std::string format = value_[i];
779 napi_value value = nullptr;
780 status = napi_create_string_utf8(env, format.c_str(), NAPI_AUTO_LENGTH, &value);
781 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
782 "Failed to call napi_create_string_utf8, with element %{public}u", i);
783 status = napi_set_element(env, result, i, value);
784 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
785 "Failed to call napi_set_element, with element %{public}u", i);
786 }
787 return napi_ok;
788 }
789
GetJsResult(napi_env env,napi_value & result)790 napi_status MediaJsResultIntArray::GetJsResult(napi_env env, napi_value &result)
791 {
792 napi_status status;
793 size_t size = value_.size();
794 napi_create_array_with_length(env, size, &result);
795 for (unsigned int i = 0; i < size; ++i) {
796 int32_t index = value_[i];
797 napi_value value = nullptr;
798 status = napi_create_int32(env, index, &value);
799 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
800 "Failed to call napi_create_int32, with element %{public}u", i);
801 status = napi_set_element(env, result, i, value);
802 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
803 "Failed to call napi_set_element, with element %{public}u", i);
804 }
805 return napi_ok;
806 }
807
GetJsResult(napi_env env,napi_value & result)808 napi_status MediaJsResultArray::GetJsResult(napi_env env, napi_value &result)
809 {
810 // create Description
811 napi_status status = napi_create_array(env, &result);
812 if (status != napi_ok) {
813 return napi_cancelled;
814 }
815
816 auto vecSize = value_.size();
817 for (size_t index = 0; index < vecSize; ++index) {
818 napi_value description = nullptr;
819 description = CommonNapi::CreateFormatBuffer(env, value_[index]);
820 if (description == nullptr || napi_set_element(env, result, index, description) != napi_ok) {
821 return napi_cancelled;
822 }
823 }
824 return napi_ok;
825 }
826
MediaAsyncContext(napi_env env)827 MediaAsyncContext::MediaAsyncContext(napi_env env)
828 : env_(env)
829 {
830 MEDIA_LOGD("MediaAsyncContext Create 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
831 }
832
~MediaAsyncContext()833 MediaAsyncContext::~MediaAsyncContext()
834 {
835 MEDIA_LOGD("MediaAsyncContext Destroy 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
836 }
837
SignError(int32_t code,const std::string & message,bool del)838 void MediaAsyncContext::SignError(int32_t code, const std::string &message, bool del)
839 {
840 errMessage = message;
841 errCode = code;
842 errFlag = true;
843 delFlag = del;
844 MEDIA_LOGE("SignError: %{public}s", message.c_str());
845 }
846
ThrowError(napi_env env,const int32_t errCode,const std::string errMsg)847 napi_value CommonNapi::ThrowError(napi_env env, const int32_t errCode, const std::string errMsg)
848 {
849 napi_value result = nullptr;
850 napi_status status = napi_throw_error(env, std::to_string(errCode).c_str(), errMsg.c_str());
851 if (status == napi_ok) {
852 napi_get_undefined(env, &result);
853 }
854 return result;
855 }
856
CompleteCallback(napi_env env,napi_status status,void * data)857 void MediaAsyncContext::CompleteCallback(napi_env env, napi_status status, void *data)
858 {
859 MEDIA_LOGD("CompleteCallback In");
860 auto asyncContext = reinterpret_cast<MediaAsyncContext *>(data);
861 CHECK_AND_RETURN_LOG(asyncContext != nullptr, "asyncContext is nullptr!");
862
863 std::string memoryTag = asyncContext->memoryTagHead + asyncContext->memoryTagTail;
864 MEDIA_LOGD("MediaAsyncContext Create 0x%{public}06" PRIXPTR " memoryTag = %{public}s",
865 FAKE_POINTER(data), memoryTag.c_str());
866
867 if (status != napi_ok) {
868 asyncContext->SignError(MSERR_EXT_UNKNOWN, "napi_create_async_work status != napi_ok");
869 }
870
871 napi_value result = nullptr;
872 napi_get_undefined(env, &result);
873 napi_value args[2] = { nullptr };
874 napi_get_undefined(env, &args[0]);
875 napi_get_undefined(env, &args[1]);
876 if (asyncContext->errFlag) {
877 MEDIA_LOGD("async callback failed");
878 (void)CommonNapi::CreateError(env, asyncContext->errCode, asyncContext->errMessage, result);
879 args[0] = result;
880 } else {
881 MEDIA_LOGD("async callback success");
882 if (asyncContext->JsResult != nullptr) {
883 asyncContext->JsResult->GetJsResult(env, result);
884 CheckCtorResult(env, result, asyncContext, args[0]);
885 }
886 if (!asyncContext->errFlag) {
887 args[1] = result;
888 }
889 }
890
891 Callback(env, asyncContext, args);
892 napi_delete_async_work(env, asyncContext->work);
893
894 if (asyncContext->delFlag) {
895 delete asyncContext;
896 asyncContext = nullptr;
897 }
898 }
899
Callback(napi_env env,const MediaAsyncContext * context,const napi_value * args)900 void MediaAsyncContext::Callback(napi_env env, const MediaAsyncContext *context, const napi_value *args)
901 {
902 if (context->deferred) {
903 if (context->errFlag) {
904 MEDIA_LOGE("promise napi_reject_deferred");
905 napi_reject_deferred(env, context->deferred, args[0]);
906 } else {
907 MEDIA_LOGD("promise napi_resolve_deferred");
908 napi_resolve_deferred(env, context->deferred, args[1]);
909 }
910 } else if (context->callbackRef != nullptr) {
911 MEDIA_LOGD("callback napi_call_function");
912 napi_value callback = nullptr;
913 napi_get_reference_value(env, context->callbackRef, &callback);
914 CHECK_AND_RETURN_LOG(callback != nullptr, "callback is nullptr!");
915 constexpr size_t argCount = 2;
916 napi_value retVal;
917 napi_get_undefined(env, &retVal);
918 napi_call_function(env, nullptr, callback, argCount, args, &retVal);
919 napi_delete_reference(env, context->callbackRef);
920 } else {
921 MEDIA_LOGE("invalid promise and callback");
922 }
923 }
924
CheckCtorResult(napi_env env,napi_value & result,MediaAsyncContext * ctx,napi_value & args)925 void MediaAsyncContext::CheckCtorResult(napi_env env, napi_value &result, MediaAsyncContext *ctx, napi_value &args)
926 {
927 CHECK_AND_RETURN(ctx != nullptr);
928 if (ctx->ctorFlag) {
929 void *instance = nullptr;
930 if (napi_unwrap(env, result, reinterpret_cast<void **>(&instance)) != napi_ok || instance == nullptr) {
931 MEDIA_LOGE("Failed to create instance");
932 ctx->errFlag = true;
933 (void)CommonNapi::CreateError(env, MSERR_EXT_API9_NO_MEMORY,
934 "The instance or memory has reached the upper limit, please recycle background playback", result);
935 args = result;
936 }
937 }
938 }
939
SendCompleteEvent(napi_env env,MediaAsyncContext * asyncContext,napi_event_priority prio)940 napi_status MediaAsyncContext::SendCompleteEvent(napi_env env, MediaAsyncContext *asyncContext,
941 napi_event_priority prio)
942 {
943 auto task = [env, asyncContext]() {
944 MEDIA_LOGD("CompleteCallback In");
945 CHECK_AND_RETURN_LOG(asyncContext != nullptr, "asyncContext is nullptr!");
946
947 std::string memoryTag = asyncContext->memoryTagHead + asyncContext->memoryTagTail;
948 MEDIA_LOGD("MediaAsyncContext 0x%{public}06" PRIXPTR " memoryTag = %{public}s",
949 FAKE_POINTER(asyncContext), memoryTag.c_str());
950
951 napi_value result = nullptr;
952 napi_get_undefined(env, &result);
953 napi_value args[2] = { nullptr };
954 napi_get_undefined(env, &args[0]);
955 napi_get_undefined(env, &args[1]);
956 if (asyncContext->errFlag) {
957 MEDIA_LOGD("async callback failed");
958 (void)CommonNapi::CreateError(env, asyncContext->errCode, asyncContext->errMessage, result);
959 args[0] = result;
960 } else {
961 MEDIA_LOGD("async callback success");
962 if (asyncContext->JsResult != nullptr) {
963 asyncContext->JsResult->GetJsResult(env, result);
964 CheckCtorResult(env, result, asyncContext, args[0]);
965 }
966 if (!asyncContext->errFlag) {
967 args[1] = result;
968 }
969 }
970
971 Callback(env, asyncContext, args);
972 if (asyncContext->delFlag) {
973 delete asyncContext;
974 }
975 };
976 return napi_send_event(env, task, prio);
977 }
978
AddStringProperty(napi_env env,napi_value obj,const std::string & key,const std::string & value)979 bool CommonNapi::AddStringProperty(napi_env env, napi_value obj, const std::string &key, const std::string &value)
980 {
981 CHECK_AND_RETURN_RET(obj != nullptr, false);
982
983 napi_value keyNapi = nullptr;
984 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
985 CHECK_AND_RETURN_RET(status == napi_ok, false);
986
987 napi_value valueNapi = nullptr;
988 status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &valueNapi);
989 CHECK_AND_RETURN_RET(status == napi_ok, false);
990
991 status = napi_set_property(env, obj, keyNapi, valueNapi);
992 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
993
994 return true;
995 }
996
GetPropertyBool(napi_env env,napi_value configObj,const std::string & type,bool & result)997 bool CommonNapi::GetPropertyBool(napi_env env, napi_value configObj, const std::string &type, bool &result)
998 {
999 bool exist = false;
1000 napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
1001 if (status != napi_ok || !exist) {
1002 MEDIA_LOGE("can not find %{public}s property", type.c_str());
1003 return false;
1004 }
1005 napi_value item = nullptr;
1006 if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
1007 MEDIA_LOGE("get %{public}s property fail", type.c_str());
1008 return false;
1009 }
1010 if (napi_get_value_bool(env, item, &result) != napi_ok) {
1011 MEDIA_LOGE("get %{public}s property value fail", type.c_str());
1012 return false;
1013 }
1014 return true;
1015 }
1016
ConvertDeviceInfoToAudioDeviceDescriptor(std::shared_ptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor,const AudioStandard::AudioDeviceDescriptor & deviceInfo)1017 void CommonNapi::ConvertDeviceInfoToAudioDeviceDescriptor(
1018 std::shared_ptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor,
1019 const AudioStandard::AudioDeviceDescriptor &deviceInfo)
1020 {
1021 CHECK_AND_RETURN_LOG(audioDeviceDescriptor != nullptr, "audioDeviceDescriptor is nullptr");
1022 audioDeviceDescriptor->deviceRole_ = deviceInfo.deviceRole_;
1023 audioDeviceDescriptor->deviceType_ = deviceInfo.deviceType_;
1024 audioDeviceDescriptor->deviceId_ = deviceInfo.deviceId_;
1025 audioDeviceDescriptor->channelMasks_ = deviceInfo.channelMasks_;
1026 audioDeviceDescriptor->channelIndexMasks_ = deviceInfo.channelIndexMasks_;
1027 audioDeviceDescriptor->deviceName_ = deviceInfo.deviceName_;
1028 audioDeviceDescriptor->macAddress_ = deviceInfo.macAddress_;
1029 audioDeviceDescriptor->interruptGroupId_ = deviceInfo.interruptGroupId_;
1030 audioDeviceDescriptor->volumeGroupId_ = deviceInfo.volumeGroupId_;
1031 audioDeviceDescriptor->networkId_ = deviceInfo.networkId_;
1032 audioDeviceDescriptor->displayName_ = deviceInfo.displayName_;
1033 audioDeviceDescriptor->audioStreamInfo_.samplingRate = deviceInfo.audioStreamInfo_.samplingRate;
1034 audioDeviceDescriptor->audioStreamInfo_.encoding = deviceInfo.audioStreamInfo_.encoding;
1035 audioDeviceDescriptor->audioStreamInfo_.format = deviceInfo.audioStreamInfo_.format;
1036 audioDeviceDescriptor->audioStreamInfo_.channels = deviceInfo.audioStreamInfo_.channels;
1037 }
1038
SetDeviceDescriptor(const napi_env & env,const AudioStandard::AudioDeviceDescriptor & deviceInfo,napi_value & result)1039 napi_status CommonNapi::SetDeviceDescriptor(const napi_env &env, const AudioStandard::AudioDeviceDescriptor &deviceInfo,
1040 napi_value &result)
1041 {
1042 (void)napi_create_object(env, &result);
1043 SetPropertyInt32(env, result, "deviceRole", static_cast<int32_t>(deviceInfo.deviceRole_));
1044 SetPropertyInt32(env, result, "deviceType", static_cast<int32_t>(deviceInfo.deviceType_));
1045 SetPropertyInt32(env, result, "id", static_cast<int32_t>(deviceInfo.deviceId_));
1046 SetPropertyString(env, result, "name", deviceInfo.deviceName_);
1047 SetPropertyString(env, result, "address", deviceInfo.macAddress_);
1048 SetPropertyString(env, result, "networkId", deviceInfo.networkId_);
1049 SetPropertyString(env, result, "displayName", deviceInfo.displayName_);
1050 SetPropertyInt32(env, result, "interruptGroupId", static_cast<int32_t>(deviceInfo.interruptGroupId_));
1051 SetPropertyInt32(env, result, "volumeGroupId", static_cast<int32_t>(deviceInfo.volumeGroupId_));
1052
1053 napi_value value = nullptr;
1054 napi_value sampleRates;
1055 size_t size = deviceInfo.audioStreamInfo_.samplingRate.size();
1056 napi_create_array_with_length(env, size, &sampleRates);
1057 size_t count = 0;
1058 for (const auto &samplingRate : deviceInfo.audioStreamInfo_.samplingRate) {
1059 napi_create_int32(env, samplingRate, &value);
1060 napi_set_element(env, sampleRates, count, value);
1061 count++;
1062 }
1063 napi_set_named_property(env, result, "sampleRates", sampleRates);
1064
1065 napi_value channelCounts;
1066 size = deviceInfo.audioStreamInfo_.channels.size();
1067 napi_create_array_with_length(env, size, &channelCounts);
1068 count = 0;
1069 for (const auto &channels : deviceInfo.audioStreamInfo_.channels) {
1070 napi_create_int32(env, channels, &value);
1071 napi_set_element(env, channelCounts, count, value);
1072 count++;
1073 }
1074 napi_set_named_property(env, result, "channelCounts", channelCounts);
1075
1076 std::vector<int32_t> channelMasks_;
1077 channelMasks_.push_back(deviceInfo.channelMasks_);
1078 AddArrayProperty(env, result, "channelMasks", channelMasks_);
1079
1080 std::vector<int32_t> channelIndexMasks_;
1081 channelIndexMasks_.push_back(deviceInfo.channelIndexMasks_);
1082 AddArrayProperty(env, result, "channelIndexMasks", channelIndexMasks_);
1083
1084 std::vector<int32_t> encoding;
1085 encoding.push_back(deviceInfo.audioStreamInfo_.encoding);
1086 AddArrayProperty(env, result, "encodingTypes", encoding);
1087
1088 return napi_ok;
1089 }
1090
SetDeviceDescriptors(const napi_env & env,const std::vector<std::shared_ptr<AudioStandard::AudioDeviceDescriptor>> & deviceDescriptors,napi_value & result)1091 napi_status CommonNapi::SetDeviceDescriptors(const napi_env &env,
1092 const std::vector<std::shared_ptr<AudioStandard::AudioDeviceDescriptor>> &deviceDescriptors, napi_value &result)
1093 {
1094 napi_status status = napi_create_array_with_length(env, deviceDescriptors.size(), &result);
1095 for (size_t i = 0; i < deviceDescriptors.size(); i++) {
1096 if (deviceDescriptors[i] != nullptr) {
1097 napi_value valueParam = nullptr;
1098 SetDeviceDescriptor(env, deviceDescriptors[i], valueParam);
1099 napi_set_element(env, result, i, valueParam);
1100 }
1101 }
1102 return status;
1103 }
1104
SetValueDeviceInfo(const napi_env & env,const AudioStandard::AudioDeviceDescriptor & deviceInfo,napi_value & result)1105 napi_status CommonNapi::SetValueDeviceInfo(const napi_env &env, const AudioStandard::AudioDeviceDescriptor &deviceInfo,
1106 napi_value &result)
1107 {
1108 std::vector<std::shared_ptr<AudioStandard::AudioDeviceDescriptor>> deviceDescriptors;
1109 std::shared_ptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor =
1110 std::make_shared<AudioStandard::AudioDeviceDescriptor>();
1111 CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptor != nullptr, napi_generic_failure,
1112 "audioDeviceDescriptor malloc failed");
1113 ConvertDeviceInfoToAudioDeviceDescriptor(audioDeviceDescriptor, deviceInfo);
1114 deviceDescriptors.push_back(std::move(audioDeviceDescriptor));
1115 SetDeviceDescriptors(env, deviceDescriptors, result);
1116 return napi_ok;
1117 }
1118 } // namespace Media
1119 } // namespace OHOS