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 (!GetPropertyBool(env, value, "enableCameraPostprocessing", playStrategy.enableCameraPostprocessing)) {
307 playStrategy.enableCameraPostprocessing = false; // use default value
308 }
309 if (!GetPropertyInt32(env, value, "mutedMediaType", playStrategy.mutedMediaType)) {
310 playStrategy.mutedMediaType = MediaType::MEDIA_TYPE_MAX_COUNT; // use default value
311 }
312 playStrategy.preferredAudioLanguage = GetPropertyString(env, value, "preferredAudioLanguage");
313 playStrategy.preferredSubtitleLanguage = GetPropertyString(env, value, "preferredSubtitleLanguage");
314 if (!GetPropertyDouble(env, value, "preferredBufferDurationForPlaying",
315 playStrategy.preferredBufferDurationForPlaying)) {
316 playStrategy.preferredBufferDurationForPlaying = 0; // use default value
317 playStrategy.isSetBufferDurationForPlaying = false;
318 } else {
319 playStrategy.isSetBufferDurationForPlaying = true;
320 }
321 if (!GetPropertyDouble(env, value, "thresholdForAutoQuickPlay", playStrategy.thresholdForAutoQuickPlay)) {
322 playStrategy.thresholdForAutoQuickPlay = -1;
323 playStrategy.isSetThresholdForAutoQuickPlay = false;
324 } else {
325 playStrategy.isSetThresholdForAutoQuickPlay = true;
326 }
327
328 if (!GetPropertyBool(env, value, "keepDecodingOnMute", playStrategy.keepDecodingOnMute)) {
329 playStrategy.keepDecodingOnMute = false; // use default value
330 }
331 return true;
332 }
333
GetPlayMediaStreamData(napi_env env,napi_value value,AVPlayMediaStreamTmp & mediaStream)334 bool CommonNapi::GetPlayMediaStreamData(napi_env env, napi_value value, AVPlayMediaStreamTmp &mediaStream)
335 {
336 bool existProperty = CommonNapi::CheckhasNamedProperty(env, value, "url");
337 existProperty &= CommonNapi::CheckhasNamedProperty(env, value, "width");
338 existProperty &= CommonNapi::CheckhasNamedProperty(env, value, "height");
339 existProperty &= CommonNapi::CheckhasNamedProperty(env, value, "bitrate");
340 CHECK_AND_RETURN_RET_LOG(existProperty, false, "property is not complete for AVPlayMediaStream");
341
342 mediaStream.url = GetPropertyString(env, value, "url");
343 GetPropertyUint32(env, value, "width", mediaStream.width);
344 GetPropertyUint32(env, value, "height", mediaStream.height);
345 GetPropertyUint32(env, value, "bitrate", mediaStream.bitrate);
346 return true;
347 }
348
FillErrorArgs(napi_env env,int32_t errCode,const napi_value & args)349 napi_status CommonNapi::FillErrorArgs(napi_env env, int32_t errCode, const napi_value &args)
350 {
351 napi_value codeStr = nullptr;
352 napi_status status = napi_create_string_utf8(env, "code", NAPI_AUTO_LENGTH, &codeStr);
353 CHECK_AND_RETURN_RET_LOG(status == napi_ok && codeStr != nullptr, napi_invalid_arg, "create code str fail");
354
355 napi_value errCodeVal = nullptr;
356 int32_t errCodeInt = errCode;
357 status = napi_create_int32(env, errCodeInt, &errCodeVal);
358 CHECK_AND_RETURN_RET_LOG(status == napi_ok && errCodeVal != nullptr, napi_invalid_arg,
359 "create error code number val fail");
360
361 status = napi_set_property(env, args, codeStr, errCodeVal);
362 CHECK_AND_RETURN_RET_LOG(status == napi_ok, napi_invalid_arg, "set error code property fail");
363
364 napi_value nameStr = nullptr;
365 status = napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &nameStr);
366 CHECK_AND_RETURN_RET_LOG(status == napi_ok && nameStr != nullptr, napi_invalid_arg, "create name str fail");
367
368 napi_value errNameVal = nullptr;
369 status = napi_create_string_utf8(env, "BusinessError", NAPI_AUTO_LENGTH, &errNameVal);
370 CHECK_AND_RETURN_RET_LOG(status == napi_ok && errNameVal != nullptr, napi_invalid_arg,
371 "create BusinessError str fail");
372
373 status = napi_set_property(env, args, nameStr, errNameVal);
374 CHECK_AND_RETURN_RET_LOG(status == napi_ok, napi_invalid_arg, "set error name property fail");
375 return napi_ok;
376 }
377
CreateError(napi_env env,int32_t errCode,const std::string & errMsg,napi_value & errVal)378 napi_status CommonNapi::CreateError(napi_env env, int32_t errCode, const std::string &errMsg, napi_value &errVal)
379 {
380 napi_get_undefined(env, &errVal);
381
382 napi_value msgValStr = nullptr;
383 napi_status nstatus = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &msgValStr);
384 if (nstatus != napi_ok || msgValStr == nullptr) {
385 MEDIA_LOGE("create error message str fail");
386 return napi_invalid_arg;
387 }
388
389 nstatus = napi_create_error(env, nullptr, msgValStr, &errVal);
390 if (nstatus != napi_ok || errVal == nullptr) {
391 MEDIA_LOGE("create error fail");
392 return napi_invalid_arg;
393 }
394
395 napi_value codeStr = nullptr;
396 nstatus = napi_create_string_utf8(env, "code", NAPI_AUTO_LENGTH, &codeStr);
397 if (nstatus != napi_ok || codeStr == nullptr) {
398 MEDIA_LOGE("create code str fail");
399 return napi_invalid_arg;
400 }
401
402 napi_value errCodeVal = nullptr;
403 nstatus = napi_create_int32(env, errCode, &errCodeVal);
404 if (nstatus != napi_ok || errCodeVal == nullptr) {
405 MEDIA_LOGE("create error code number val fail");
406 return napi_invalid_arg;
407 }
408
409 nstatus = napi_set_property(env, errVal, codeStr, errCodeVal);
410 if (nstatus != napi_ok) {
411 MEDIA_LOGE("set error code property fail");
412 return napi_invalid_arg;
413 }
414
415 napi_value nameStr = nullptr;
416 nstatus = napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &nameStr);
417 if (nstatus != napi_ok || nameStr == nullptr) {
418 MEDIA_LOGE("create name str fail");
419 return napi_invalid_arg;
420 }
421
422 napi_value errNameVal = nullptr;
423 nstatus = napi_create_string_utf8(env, "BusinessError", NAPI_AUTO_LENGTH, &errNameVal);
424 if (nstatus != napi_ok || errNameVal == nullptr) {
425 MEDIA_LOGE("create BusinessError str fail");
426 return napi_invalid_arg;
427 }
428
429 nstatus = napi_set_property(env, errVal, nameStr, errNameVal);
430 if (nstatus != napi_ok) {
431 MEDIA_LOGE("set error name property fail");
432 return napi_invalid_arg;
433 }
434
435 return napi_ok;
436 }
437
CreateReference(napi_env env,napi_value arg)438 napi_ref CommonNapi::CreateReference(napi_env env, napi_value arg)
439 {
440 napi_ref ref = nullptr;
441 napi_valuetype valueType = napi_undefined;
442 if (arg != nullptr && napi_typeof(env, arg, &valueType) == napi_ok && valueType == napi_function) {
443 MEDIA_LOGD("napi_create_reference");
444 napi_create_reference(env, arg, 1, &ref);
445 }
446 return ref;
447 }
448
CreatePromise(napi_env env,napi_ref ref,napi_value & result)449 napi_deferred CommonNapi::CreatePromise(napi_env env, napi_ref ref, napi_value &result)
450 {
451 napi_deferred deferred = nullptr;
452 if (ref == nullptr) {
453 MEDIA_LOGD("napi_create_promise");
454 napi_create_promise(env, &deferred, &result);
455 }
456 return deferred;
457 }
458
SetPropertyByValueType(napi_env env,napi_value & obj,std::shared_ptr<Meta> & meta,std::string key)459 bool CommonNapi::SetPropertyByValueType(napi_env env, napi_value &obj, std::shared_ptr<Meta> &meta, std::string key)
460 {
461 CHECK_AND_RETURN_RET(obj != nullptr && meta != nullptr, false);
462 CHECK_AND_RETURN_RET(meta->Find(key) != meta->end(), false);
463
464 bool ret = true;
465 AnyValueType type = meta->GetValueType(key);
466 if (type == AnyValueType::STRING) {
467 std::string sValue;
468 ret = meta->GetData(key, sValue);
469 CHECK_AND_RETURN_RET_LOG(ret, ret, "GetData failed, key %{public}s", key.c_str());
470 ret = CommonNapi::SetPropertyString(env, obj, key, sValue);
471 CHECK_AND_RETURN_RET_LOG(ret, ret, "SetPropertyString failed, key %{public}s", key.c_str());
472 } else if (type == AnyValueType::INT32_T) {
473 int32_t value;
474 ret = meta->GetData(key, value);
475 CHECK_AND_RETURN_RET_LOG(ret, ret, "GetData failed, key %{public}s", key.c_str());
476 ret = CommonNapi::SetPropertyInt32(env, obj, key, value);
477 CHECK_AND_RETURN_RET_LOG(ret, ret, "SetPropertyString failed, key %{public}s", key.c_str());
478 } else if (type == AnyValueType::FLOAT) {
479 float dValue;
480 ret = meta->GetData(key, dValue);
481 CHECK_AND_RETURN_RET_LOG(ret, ret, "GetData failed, key %{public}s", key.c_str());
482 ret = CommonNapi::SetPropertyDouble(env, obj, key, dValue);
483 CHECK_AND_RETURN_RET_LOG(ret, ret, "SetPropertyString failed, key %{public}s", key.c_str());
484 } else {
485 MEDIA_LOGE("not supported value type");
486 }
487 return true;
488 }
489
AddRangeProperty(napi_env env,napi_value obj,const std::string & name,int32_t min,int32_t max)490 bool CommonNapi::AddRangeProperty(napi_env env, napi_value obj, const std::string &name, int32_t min, int32_t max)
491 {
492 CHECK_AND_RETURN_RET(obj != nullptr, false);
493
494 napi_value range = nullptr;
495 napi_status status = napi_create_object(env, &range);
496 CHECK_AND_RETURN_RET(status == napi_ok, false);
497
498 CHECK_AND_RETURN_RET(SetPropertyInt32(env, range, "min", min) == true, false);
499 CHECK_AND_RETURN_RET(SetPropertyInt32(env, range, "max", max) == true, false);
500
501 napi_value nameStr = nullptr;
502 status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &nameStr);
503 CHECK_AND_RETURN_RET(status == napi_ok, false);
504
505 status = napi_set_property(env, obj, nameStr, range);
506 CHECK_AND_RETURN_RET(status == napi_ok, false);
507
508 return true;
509 }
510
AddArrayProperty(napi_env env,napi_value obj,const std::string & name,const std::vector<int32_t> & vec)511 bool CommonNapi::AddArrayProperty(napi_env env, napi_value obj, const std::string &name,
512 const std::vector<int32_t> &vec)
513 {
514 CHECK_AND_RETURN_RET(obj != nullptr, false);
515
516 napi_value array = nullptr;
517 napi_status status = napi_create_array_with_length(env, vec.size(), &array);
518 CHECK_AND_RETURN_RET(status == napi_ok, false);
519
520 for (uint32_t i = 0; i < vec.size(); i++) {
521 napi_value number = nullptr;
522 (void)napi_create_int32(env, vec.at(i), &number);
523 (void)napi_set_element(env, array, i, number);
524 }
525
526 napi_value nameStr = nullptr;
527 status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &nameStr);
528 CHECK_AND_RETURN_RET(status == napi_ok, false);
529
530 status = napi_set_property(env, obj, nameStr, array);
531 CHECK_AND_RETURN_RET(status == napi_ok, false);
532
533 return true;
534 }
535
SetPropertyArrayBuffer(const napi_env & env,napi_value & result,const std::string & fieldStr,size_t bufferLen,uint8_t * bufferData)536 bool CommonNapi::SetPropertyArrayBuffer(
537 const napi_env &env, napi_value &result, const std::string &fieldStr, size_t bufferLen, uint8_t *bufferData)
538 {
539 void *native = nullptr;
540 napi_value arrayBuffer = nullptr;
541 napi_status status = napi_create_arraybuffer(env, bufferLen, &native, &arrayBuffer);
542 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "napi_create_arraybuffer failed");
543 CHECK_AND_RETURN_RET_LOG(memcpy_s(native, bufferLen, bufferData, bufferLen) == 0, false, "memcpy failed");
544
545 status = napi_set_named_property(env, result, fieldStr.c_str(), arrayBuffer);
546 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "napi_set_named_property failed");
547
548 return true;
549 }
550
551
AddArrayInt(napi_env env,napi_value & array,const std::vector<int32_t> & vec)552 bool CommonNapi::AddArrayInt(napi_env env, napi_value &array, const std::vector<int32_t> &vec)
553 {
554 if (vec.size() == 0) {
555 return false;
556 }
557
558 napi_status status = napi_create_array_with_length(env, vec.size(), &array);
559 CHECK_AND_RETURN_RET(status == napi_ok, false);
560
561 for (uint32_t i = 0; i < vec.size(); i++) {
562 napi_value number = nullptr;
563 (void)napi_create_int32(env, vec.at(i), &number);
564 (void)napi_set_element(env, array, i, number);
565 }
566
567 return true;
568 }
569
SetPropertyInt32(napi_env env,napi_value & obj,const std::string & key,int32_t value)570 bool CommonNapi::SetPropertyInt32(napi_env env, napi_value &obj, const std::string &key, int32_t value)
571 {
572 CHECK_AND_RETURN_RET(obj != nullptr, false);
573
574 napi_value keyNapi = nullptr;
575 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
576 CHECK_AND_RETURN_RET(status == napi_ok, false);
577
578 napi_value valueNapi = nullptr;
579 status = napi_create_int32(env, value, &valueNapi);
580 CHECK_AND_RETURN_RET(status == napi_ok, false);
581
582 status = napi_set_property(env, obj, keyNapi, valueNapi);
583 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
584
585 return true;
586 }
587
SetPropertyInt64(napi_env env,napi_value & obj,const std::string & key,int64_t value)588 bool CommonNapi::SetPropertyInt64(napi_env env, napi_value &obj, const std::string &key, int64_t value)
589 {
590 CHECK_AND_RETURN_RET(obj != nullptr, false);
591
592 napi_value keyNapi = nullptr;
593 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
594 CHECK_AND_RETURN_RET(status == napi_ok, false);
595
596 napi_value valueNapi = nullptr;
597 status = napi_create_int64(env, value, &valueNapi);
598 CHECK_AND_RETURN_RET(status == napi_ok, false);
599
600 status = napi_set_property(env, obj, keyNapi, valueNapi);
601 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
602
603 return true;
604 }
605
SetPropertyDouble(napi_env env,napi_value & obj,const std::string & key,double value)606 bool CommonNapi::SetPropertyDouble(napi_env env, napi_value &obj, const std::string &key, double value)
607 {
608 CHECK_AND_RETURN_RET(obj != nullptr, false);
609
610 napi_value keyNapi = nullptr;
611 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
612 CHECK_AND_RETURN_RET(status == napi_ok, false);
613
614 napi_value valueNapi = nullptr;
615 status = napi_create_double(env, value, &valueNapi);
616 CHECK_AND_RETURN_RET(status == napi_ok, false);
617
618 status = napi_set_property(env, obj, keyNapi, valueNapi);
619 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
620
621 return true;
622 }
623
SetPropertyBool(napi_env env,napi_value & obj,const std::string & key,bool value)624 bool CommonNapi::SetPropertyBool(napi_env env, napi_value &obj, const std::string &key, bool value)
625 {
626 CHECK_AND_RETURN_RET(obj != nullptr, false);
627
628 napi_value keyNapi = nullptr;
629 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
630 CHECK_AND_RETURN_RET(status == napi_ok, false);
631
632 napi_value valueNapi = nullptr;
633 status = napi_get_boolean(env, value, &valueNapi);
634 CHECK_AND_RETURN_RET(status == napi_ok, false);
635
636 status = napi_set_property(env, obj, keyNapi, valueNapi);
637 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
638
639 return true;
640 }
641
SetPropertyString(napi_env env,napi_value & obj,const std::string & key,const std::string & value)642 bool CommonNapi::SetPropertyString(napi_env env, napi_value &obj, const std::string &key, const std::string &value)
643 {
644 CHECK_AND_RETURN_RET(obj != nullptr, false);
645
646 napi_value keyNapi = nullptr;
647 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
648 CHECK_AND_RETURN_RET(status == napi_ok, false);
649
650 napi_value valueNapi = nullptr;
651 status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &valueNapi);
652 CHECK_AND_RETURN_RET(status == napi_ok, false);
653
654 status = napi_set_property(env, obj, keyNapi, valueNapi);
655 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "failed to set property");
656
657 return true;
658 }
659
CreateFormatBuffer(napi_env env,Format & format)660 napi_value CommonNapi::CreateFormatBuffer(napi_env env, Format &format)
661 {
662 int32_t intValue = 0;
663 size_t bufferLen = 0;
664 std::string strValue;
665 uint8_t *bufferData = nullptr;
666 napi_value buffer = nullptr;
667 napi_status status = napi_create_object(env, &buffer);
668 CHECK_AND_RETURN_RET(status == napi_ok, nullptr);
669
670 for (auto &iter : format.GetFormatMap()) {
671 switch (format.GetValueType(std::string_view(iter.first))) {
672 case FORMAT_TYPE_INT32:
673 if (format.GetIntValue(iter.first, intValue)) {
674 CHECK_AND_RETURN_RET(SetPropertyInt32(env, buffer, iter.first, intValue) == true, nullptr);
675 }
676 break;
677 case FORMAT_TYPE_INT64:
678 int64_t longValue;
679 if (format.GetLongValue(iter.first, longValue) &&
680 longValue >= INT32_MIN && longValue <= INT32_MAX) {
681 intValue = static_cast<int32_t>(longValue);
682 CHECK_AND_RETURN_RET(SetPropertyInt32(env, buffer, iter.first, intValue) == true, nullptr);
683 }
684 break;
685 case FORMAT_TYPE_DOUBLE:
686 double doubleValue;
687 if (format.GetDoubleValue(iter.first, doubleValue) &&
688 doubleValue >= INT32_MIN && doubleValue <= INT32_MAX) {
689 intValue = static_cast<int32_t>(doubleValue);
690 CHECK_AND_RETURN_RET(SetPropertyInt32(env, buffer, iter.first, intValue) == true, nullptr);
691 }
692 break;
693 case FORMAT_TYPE_STRING:
694 if (format.GetStringValue(iter.first, strValue)) {
695 CHECK_AND_RETURN_RET(SetPropertyString(env, buffer, iter.first, strValue) == true, nullptr);
696 }
697 break;
698 case FORMAT_TYPE_ADDR:
699 if (format.GetBuffer(iter.first, &bufferData, bufferLen)) {
700 CHECK_AND_RETURN_RET(
701 SetPropertyArrayBuffer(env, buffer, iter.first, bufferLen, bufferData) == true, nullptr);
702 }
703 break;
704 default:
705 MEDIA_LOGE("format key: %{public}s", iter.first.c_str());
706 break;
707 }
708 }
709
710 return buffer;
711 }
712
CreateFormatBufferByRef(napi_env env,Format & format,napi_value & result)713 bool CommonNapi::CreateFormatBufferByRef(napi_env env, Format &format, napi_value &result)
714 {
715 int32_t intValue = 0;
716 int64_t longValue = 0;
717 std::string strValue = "";
718 napi_status status = napi_create_object(env, &result);
719 CHECK_AND_RETURN_RET(status == napi_ok, false);
720
721 for (auto &iter : format.GetFormatMap()) {
722 switch (format.GetValueType(std::string_view(iter.first))) {
723 case FORMAT_TYPE_INT32:
724 if (format.GetIntValue(iter.first, intValue)) {
725 (void)SetPropertyInt32(env, result, iter.first, intValue);
726 }
727 break;
728 case FORMAT_TYPE_INT64:
729 if (format.GetLongValue(iter.first, longValue)) {
730 (void)SetPropertyInt64(env, result, iter.first, longValue);
731 }
732 break;
733 case FORMAT_TYPE_STRING:
734 if (format.GetStringValue(iter.first, strValue)) {
735 (void)SetPropertyString(env, result, iter.first, strValue);
736 }
737 break;
738 default:
739 MEDIA_LOGE("format key: %{public}s", iter.first.c_str());
740 break;
741 }
742 }
743
744 return true;
745 }
746
AddNumberPropInt32(napi_env env,napi_value obj,const std::string & key,int32_t value)747 bool CommonNapi::AddNumberPropInt32(napi_env env, napi_value obj, const std::string &key, int32_t value)
748 {
749 CHECK_AND_RETURN_RET(obj != nullptr, false);
750
751 napi_value keyNapi = nullptr;
752 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
753 CHECK_AND_RETURN_RET(status == napi_ok, false);
754
755 napi_value valueNapi = nullptr;
756 status = napi_create_int32(env, value, &valueNapi);
757 CHECK_AND_RETURN_RET(status == napi_ok, false);
758
759 status = napi_set_property(env, obj, keyNapi, valueNapi);
760 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
761
762 return true;
763 }
764
AddNumberPropInt64(napi_env env,napi_value obj,const std::string & key,int64_t value)765 bool CommonNapi::AddNumberPropInt64(napi_env env, napi_value obj, const std::string &key, int64_t value)
766 {
767 CHECK_AND_RETURN_RET(obj != nullptr, false);
768
769 napi_value keyNapi = nullptr;
770 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
771 CHECK_AND_RETURN_RET(status == napi_ok, false);
772
773 napi_value valueNapi = nullptr;
774 status = napi_create_int64(env, value, &valueNapi);
775 CHECK_AND_RETURN_RET(status == napi_ok, false);
776
777 status = napi_set_property(env, obj, keyNapi, valueNapi);
778 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
779
780 return true;
781 }
782
GetJsResult(napi_env env,napi_value & result)783 napi_status MediaJsResultStringVector::GetJsResult(napi_env env, napi_value &result)
784 {
785 napi_status status;
786 size_t size = value_.size();
787 napi_create_array_with_length(env, size, &result);
788 for (unsigned int i = 0; i < size; ++i) {
789 std::string format = value_[i];
790 napi_value value = nullptr;
791 status = napi_create_string_utf8(env, format.c_str(), NAPI_AUTO_LENGTH, &value);
792 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
793 "Failed to call napi_create_string_utf8, with element %{public}u", i);
794 status = napi_set_element(env, result, i, value);
795 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
796 "Failed to call napi_set_element, with element %{public}u", i);
797 }
798 return napi_ok;
799 }
800
GetJsResult(napi_env env,napi_value & result)801 napi_status MediaJsResultIntArray::GetJsResult(napi_env env, napi_value &result)
802 {
803 napi_status status;
804 size_t size = value_.size();
805 napi_create_array_with_length(env, size, &result);
806 for (unsigned int i = 0; i < size; ++i) {
807 int32_t index = value_[i];
808 napi_value value = nullptr;
809 status = napi_create_int32(env, index, &value);
810 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
811 "Failed to call napi_create_int32, with element %{public}u", i);
812 status = napi_set_element(env, result, i, value);
813 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status,
814 "Failed to call napi_set_element, with element %{public}u", i);
815 }
816 return napi_ok;
817 }
818
GetJsResult(napi_env env,napi_value & result)819 napi_status MediaJsResultArray::GetJsResult(napi_env env, napi_value &result)
820 {
821 // create Description
822 napi_status status = napi_create_array(env, &result);
823 if (status != napi_ok) {
824 return napi_cancelled;
825 }
826
827 auto vecSize = value_.size();
828 for (size_t index = 0; index < vecSize; ++index) {
829 napi_value description = nullptr;
830 description = CommonNapi::CreateFormatBuffer(env, value_[index]);
831 if (description == nullptr || napi_set_element(env, result, index, description) != napi_ok) {
832 return napi_cancelled;
833 }
834 }
835 return napi_ok;
836 }
837
MediaAsyncContext(napi_env env)838 MediaAsyncContext::MediaAsyncContext(napi_env env)
839 : env_(env)
840 {
841 MEDIA_LOGD("MediaAsyncContext Create 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
842 }
843
~MediaAsyncContext()844 MediaAsyncContext::~MediaAsyncContext()
845 {
846 MEDIA_LOGD("MediaAsyncContext Destroy 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
847 }
848
SignError(int32_t code,const std::string & message,bool del)849 void MediaAsyncContext::SignError(int32_t code, const std::string &message, bool del)
850 {
851 errMessage = message;
852 errCode = code;
853 errFlag = true;
854 delFlag = del;
855 MEDIA_LOGE("SignError: %{public}s", message.c_str());
856 }
857
ThrowError(napi_env env,const int32_t errCode,const std::string errMsg)858 napi_value CommonNapi::ThrowError(napi_env env, const int32_t errCode, const std::string errMsg)
859 {
860 napi_value result = nullptr;
861 napi_status status = napi_throw_error(env, std::to_string(errCode).c_str(), errMsg.c_str());
862 if (status == napi_ok) {
863 napi_get_undefined(env, &result);
864 }
865 return result;
866 }
867
CompleteCallback(napi_env env,napi_status status,void * data)868 void MediaAsyncContext::CompleteCallback(napi_env env, napi_status status, void *data)
869 {
870 MEDIA_LOGD("CompleteCallback In");
871 auto asyncContext = reinterpret_cast<MediaAsyncContext *>(data);
872 CHECK_AND_RETURN_LOG(asyncContext != nullptr, "asyncContext is nullptr!");
873
874 std::string memoryTag = asyncContext->memoryTagHead + asyncContext->memoryTagTail;
875 MEDIA_LOGD("MediaAsyncContext Create 0x%{public}06" PRIXPTR " memoryTag = %{public}s",
876 FAKE_POINTER(data), memoryTag.c_str());
877
878 if (status != napi_ok) {
879 asyncContext->SignError(MSERR_EXT_UNKNOWN, "napi_create_async_work status != napi_ok");
880 }
881
882 napi_value result = nullptr;
883 napi_get_undefined(env, &result);
884 napi_value args[2] = { nullptr };
885 napi_get_undefined(env, &args[0]);
886 napi_get_undefined(env, &args[1]);
887 if (asyncContext->errFlag) {
888 MEDIA_LOGD("async callback failed");
889 (void)CommonNapi::CreateError(env, asyncContext->errCode, asyncContext->errMessage, result);
890 args[0] = result;
891 } else {
892 MEDIA_LOGD("async callback success");
893 if (asyncContext->JsResult != nullptr) {
894 asyncContext->JsResult->GetJsResult(env, result);
895 CheckCtorResult(env, result, asyncContext, args[0]);
896 }
897 if (!asyncContext->errFlag) {
898 args[1] = result;
899 }
900 }
901
902 Callback(env, asyncContext, args);
903 napi_delete_async_work(env, asyncContext->work);
904
905 if (asyncContext->delFlag) {
906 delete asyncContext;
907 asyncContext = nullptr;
908 }
909 }
910
Callback(napi_env env,const MediaAsyncContext * context,const napi_value * args)911 void MediaAsyncContext::Callback(napi_env env, const MediaAsyncContext *context, const napi_value *args)
912 {
913 if (context->deferred) {
914 if (context->errFlag) {
915 MEDIA_LOGE("promise napi_reject_deferred");
916 napi_reject_deferred(env, context->deferred, args[0]);
917 } else {
918 MEDIA_LOGD("promise napi_resolve_deferred");
919 napi_resolve_deferred(env, context->deferred, args[1]);
920 }
921 } else if (context->callbackRef != nullptr) {
922 MEDIA_LOGD("callback napi_call_function");
923 napi_value callback = nullptr;
924 napi_get_reference_value(env, context->callbackRef, &callback);
925 CHECK_AND_RETURN_LOG(callback != nullptr, "callback is nullptr!");
926 constexpr size_t argCount = 2;
927 napi_value retVal;
928 napi_get_undefined(env, &retVal);
929 napi_call_function(env, nullptr, callback, argCount, args, &retVal);
930 napi_delete_reference(env, context->callbackRef);
931 } else {
932 MEDIA_LOGE("invalid promise and callback");
933 }
934 }
935
CheckCtorResult(napi_env env,napi_value & result,MediaAsyncContext * ctx,napi_value & args)936 void MediaAsyncContext::CheckCtorResult(napi_env env, napi_value &result, MediaAsyncContext *ctx, napi_value &args)
937 {
938 CHECK_AND_RETURN(ctx != nullptr);
939 if (ctx->ctorFlag) {
940 void *instance = nullptr;
941 if (napi_unwrap(env, result, reinterpret_cast<void **>(&instance)) != napi_ok || instance == nullptr) {
942 MEDIA_LOGE("Failed to create instance");
943 ctx->errFlag = true;
944 (void)CommonNapi::CreateError(env, MSERR_EXT_API9_NO_MEMORY,
945 "The instance or memory has reached the upper limit, please recycle background playback", result);
946 args = result;
947 }
948 }
949 }
950
SendCompleteEvent(napi_env env,MediaAsyncContext * asyncContext,napi_event_priority prio)951 napi_status MediaAsyncContext::SendCompleteEvent(napi_env env, MediaAsyncContext *asyncContext,
952 napi_event_priority prio)
953 {
954 auto task = [env, asyncContext]() {
955 MEDIA_LOGD("CompleteCallback In");
956 CHECK_AND_RETURN_LOG(asyncContext != nullptr, "asyncContext is nullptr!");
957
958 std::string memoryTag = asyncContext->memoryTagHead + asyncContext->memoryTagTail;
959 MEDIA_LOGD("MediaAsyncContext 0x%{public}06" PRIXPTR " memoryTag = %{public}s",
960 FAKE_POINTER(asyncContext), memoryTag.c_str());
961
962 napi_value result = nullptr;
963 napi_get_undefined(env, &result);
964 napi_value args[2] = { nullptr };
965 napi_get_undefined(env, &args[0]);
966 napi_get_undefined(env, &args[1]);
967 if (asyncContext->errFlag) {
968 MEDIA_LOGD("async callback failed");
969 (void)CommonNapi::CreateError(env, asyncContext->errCode, asyncContext->errMessage, result);
970 args[0] = result;
971 } else {
972 MEDIA_LOGD("async callback success");
973 if (asyncContext->JsResult != nullptr) {
974 asyncContext->JsResult->GetJsResult(env, result);
975 CheckCtorResult(env, result, asyncContext, args[0]);
976 }
977 if (!asyncContext->errFlag) {
978 args[1] = result;
979 }
980 }
981
982 Callback(env, asyncContext, args);
983 if (asyncContext->delFlag) {
984 delete asyncContext;
985 }
986 };
987 return napi_send_event(env, task, prio);
988 }
989
AddStringProperty(napi_env env,napi_value obj,const std::string & key,const std::string & value)990 bool CommonNapi::AddStringProperty(napi_env env, napi_value obj, const std::string &key, const std::string &value)
991 {
992 CHECK_AND_RETURN_RET(obj != nullptr, false);
993
994 napi_value keyNapi = nullptr;
995 napi_status status = napi_create_string_utf8(env, key.c_str(), NAPI_AUTO_LENGTH, &keyNapi);
996 CHECK_AND_RETURN_RET(status == napi_ok, false);
997
998 napi_value valueNapi = nullptr;
999 status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &valueNapi);
1000 CHECK_AND_RETURN_RET(status == napi_ok, false);
1001
1002 status = napi_set_property(env, obj, keyNapi, valueNapi);
1003 CHECK_AND_RETURN_RET_LOG(status == napi_ok, false, "Failed to set property");
1004
1005 return true;
1006 }
1007
GetPropertyBool(napi_env env,napi_value configObj,const std::string & type,bool & result)1008 bool CommonNapi::GetPropertyBool(napi_env env, napi_value configObj, const std::string &type, bool &result)
1009 {
1010 bool exist = false;
1011 napi_status status = napi_has_named_property(env, configObj, type.c_str(), &exist);
1012 if (status != napi_ok || !exist) {
1013 MEDIA_LOGE("can not find %{public}s property", type.c_str());
1014 return false;
1015 }
1016 napi_value item = nullptr;
1017 if (napi_get_named_property(env, configObj, type.c_str(), &item) != napi_ok) {
1018 MEDIA_LOGE("get %{public}s property fail", type.c_str());
1019 return false;
1020 }
1021 if (napi_get_value_bool(env, item, &result) != napi_ok) {
1022 MEDIA_LOGE("get %{public}s property value fail", type.c_str());
1023 return false;
1024 }
1025 return true;
1026 }
1027
ConvertDeviceInfoToAudioDeviceDescriptor(std::shared_ptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor,const AudioStandard::AudioDeviceDescriptor & deviceInfo)1028 void CommonNapi::ConvertDeviceInfoToAudioDeviceDescriptor(
1029 std::shared_ptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor,
1030 const AudioStandard::AudioDeviceDescriptor &deviceInfo)
1031 {
1032 CHECK_AND_RETURN_LOG(audioDeviceDescriptor != nullptr, "audioDeviceDescriptor is nullptr");
1033 audioDeviceDescriptor->deviceRole_ = deviceInfo.deviceRole_;
1034 audioDeviceDescriptor->deviceType_ = deviceInfo.deviceType_;
1035 audioDeviceDescriptor->deviceId_ = deviceInfo.deviceId_;
1036 audioDeviceDescriptor->channelMasks_ = deviceInfo.channelMasks_;
1037 audioDeviceDescriptor->channelIndexMasks_ = deviceInfo.channelIndexMasks_;
1038 audioDeviceDescriptor->deviceName_ = deviceInfo.deviceName_;
1039 audioDeviceDescriptor->macAddress_ = deviceInfo.macAddress_;
1040 audioDeviceDescriptor->interruptGroupId_ = deviceInfo.interruptGroupId_;
1041 audioDeviceDescriptor->volumeGroupId_ = deviceInfo.volumeGroupId_;
1042 audioDeviceDescriptor->networkId_ = deviceInfo.networkId_;
1043 audioDeviceDescriptor->displayName_ = deviceInfo.displayName_;
1044 audioDeviceDescriptor->audioStreamInfo_ = deviceInfo.audioStreamInfo_;
1045 }
1046
SetDeviceDescriptor(const napi_env & env,const AudioStandard::AudioDeviceDescriptor & deviceInfo,napi_value & result)1047 napi_status CommonNapi::SetDeviceDescriptor(const napi_env &env, const AudioStandard::AudioDeviceDescriptor &deviceInfo,
1048 napi_value &result)
1049 {
1050 (void)napi_create_object(env, &result);
1051 SetPropertyInt32(env, result, "deviceRole", static_cast<int32_t>(deviceInfo.deviceRole_));
1052 SetPropertyInt32(env, result, "deviceType", static_cast<int32_t>(deviceInfo.deviceType_));
1053 SetPropertyInt32(env, result, "id", static_cast<int32_t>(deviceInfo.deviceId_));
1054 SetPropertyString(env, result, "name", deviceInfo.deviceName_);
1055 SetPropertyString(env, result, "address", deviceInfo.macAddress_);
1056 SetPropertyString(env, result, "networkId", deviceInfo.networkId_);
1057 SetPropertyString(env, result, "displayName", deviceInfo.displayName_);
1058 SetPropertyInt32(env, result, "interruptGroupId", static_cast<int32_t>(deviceInfo.interruptGroupId_));
1059 SetPropertyInt32(env, result, "volumeGroupId", static_cast<int32_t>(deviceInfo.volumeGroupId_));
1060
1061 napi_value value = nullptr;
1062 napi_value sampleRates;
1063 AudioStandard::DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo();
1064 size_t size = audioStreamInfo.samplingRate.size();
1065 napi_create_array_with_length(env, size, &sampleRates);
1066 size_t count = 0;
1067 for (const auto &samplingRate : audioStreamInfo.samplingRate) {
1068 napi_create_int32(env, samplingRate, &value);
1069 napi_set_element(env, sampleRates, count, value);
1070 count++;
1071 }
1072 napi_set_named_property(env, result, "sampleRates", sampleRates);
1073
1074 napi_value channelCounts;
1075 std::set<AudioStandard::AudioChannel> channelSet = audioStreamInfo.GetChannels();
1076 size = channelSet.size();
1077 napi_create_array_with_length(env, size, &channelCounts);
1078 count = 0;
1079 for (const auto &channels : channelSet) {
1080 napi_create_int32(env, channels, &value);
1081 napi_set_element(env, channelCounts, count, value);
1082 count++;
1083 }
1084 napi_set_named_property(env, result, "channelCounts", channelCounts);
1085
1086 std::vector<int32_t> channelMasks_;
1087 channelMasks_.push_back(deviceInfo.channelMasks_);
1088 AddArrayProperty(env, result, "channelMasks", channelMasks_);
1089
1090 std::vector<int32_t> channelIndexMasks_;
1091 channelIndexMasks_.push_back(deviceInfo.channelIndexMasks_);
1092 AddArrayProperty(env, result, "channelIndexMasks", channelIndexMasks_);
1093
1094 std::vector<int32_t> encoding;
1095 encoding.push_back(audioStreamInfo.encoding);
1096 AddArrayProperty(env, result, "encodingTypes", encoding);
1097
1098 return napi_ok;
1099 }
1100
SetDeviceDescriptors(const napi_env & env,const std::vector<std::shared_ptr<AudioStandard::AudioDeviceDescriptor>> & deviceDescriptors,napi_value & result)1101 napi_status CommonNapi::SetDeviceDescriptors(const napi_env &env,
1102 const std::vector<std::shared_ptr<AudioStandard::AudioDeviceDescriptor>> &deviceDescriptors, napi_value &result)
1103 {
1104 napi_status status = napi_create_array_with_length(env, deviceDescriptors.size(), &result);
1105 for (size_t i = 0; i < deviceDescriptors.size(); i++) {
1106 if (deviceDescriptors[i] != nullptr) {
1107 napi_value valueParam = nullptr;
1108 SetDeviceDescriptor(env, deviceDescriptors[i], valueParam);
1109 napi_set_element(env, result, i, valueParam);
1110 }
1111 }
1112 return status;
1113 }
1114
SetValueDeviceInfo(const napi_env & env,const AudioStandard::AudioDeviceDescriptor & deviceInfo,napi_value & result)1115 napi_status CommonNapi::SetValueDeviceInfo(const napi_env &env, const AudioStandard::AudioDeviceDescriptor &deviceInfo,
1116 napi_value &result)
1117 {
1118 std::vector<std::shared_ptr<AudioStandard::AudioDeviceDescriptor>> deviceDescriptors;
1119 std::shared_ptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor =
1120 std::make_shared<AudioStandard::AudioDeviceDescriptor>();
1121 CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptor != nullptr, napi_generic_failure,
1122 "audioDeviceDescriptor malloc failed");
1123 ConvertDeviceInfoToAudioDeviceDescriptor(audioDeviceDescriptor, deviceInfo);
1124 deviceDescriptors.push_back(std::move(audioDeviceDescriptor));
1125 SetDeviceDescriptors(env, deviceDescriptors, result);
1126 return napi_ok;
1127 }
1128 } // namespace Media
1129 } // namespace OHOS