1 /*
2 * Copyright (c) 2023 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 "resource_manager_napi_utils.h"
17
18 #include "hilog/log_cpp.h"
19 #include "securec.h"
20 namespace OHOS {
21 namespace Global {
22 namespace Resource {
23 constexpr int ARRAY_SUBCRIPTOR_ZERO = 0;
24 constexpr int PARAMS_NUM_TWO = 2;
25
26 const std::unordered_map<int32_t, std::string> ResourceManagerNapiUtils::ErrorCodeToMsg {
27 {ERROR_CODE_INVALID_INPUT_PARAMETER, "Invalid input parameter"},
28 {ERROR_CODE_RES_ID_NOT_FOUND, "Invalid resource ID"},
29 {ERROR_CODE_RES_NAME_NOT_FOUND, "Invalid resource name"},
30 {ERROR_CODE_RES_NOT_FOUND_BY_ID, "No matching resource is found based on the resource ID"},
31 {ERROR_CODE_RES_NOT_FOUND_BY_NAME, "No matching resource is found based on the resource name"},
32 {ERROR_CODE_RES_PATH_INVALID, "Invalid relative path"},
33 {ERROR_CODE_RES_REF_TOO_MUCH, "The resource is referenced cyclically"},
34 {ERROR_CODE_RES_ID_FORMAT_ERROR, "Failed to format the resource obtained based on the resource ID"},
35 {ERROR_CODE_RES_NAME_FORMAT_ERROR, "Failed to format the resource obtained based on the resource Name"},
36 {ERROR_CODE_SYSTEM_RES_MANAGER_GET_FAILED, "Failed to access the system resource"},
37 {ERROR_CODE_OVERLAY_RES_PATH_INVALID, "Invalid overlay path"},
38 {ERROR, "Unknow error"}
39 };
40
IsNapiString(napi_env env,napi_callback_info info)41 bool ResourceManagerNapiUtils::IsNapiString(napi_env env, napi_callback_info info)
42 {
43 GET_PARAMS(env, info, PARAMS_NUM_TWO);
44
45 napi_valuetype valueType = napi_valuetype::napi_undefined;
46 napi_typeof(env, argv[ARRAY_SUBCRIPTOR_ZERO], &valueType);
47 if (valueType != napi_string) {
48 RESMGR_HILOGD(RESMGR_JS_TAG, "Parameter type is not napi_string");
49 return false;
50 }
51 return true;
52 }
53
IsNapiNumber(napi_env env,napi_callback_info info)54 bool ResourceManagerNapiUtils::IsNapiNumber(napi_env env, napi_callback_info info)
55 {
56 GET_PARAMS(env, info, PARAMS_NUM_TWO);
57
58 napi_valuetype valueType = napi_valuetype::napi_undefined;
59 napi_typeof(env, argv[ARRAY_SUBCRIPTOR_ZERO], &valueType);
60 if (valueType != napi_number) {
61 return false;
62 }
63 return true;
64 }
65
IsNapiObject(napi_env env,napi_callback_info info)66 bool ResourceManagerNapiUtils::IsNapiObject(napi_env env, napi_callback_info info)
67 {
68 GET_PARAMS(env, info, PARAMS_NUM_TWO);
69
70 napi_valuetype valueType = napi_valuetype::napi_undefined;
71 napi_typeof(env, argv[ARRAY_SUBCRIPTOR_ZERO], &valueType);
72 if (valueType != napi_object) {
73 RESMGR_HILOGI(RESMGR_JS_TAG, "Parameter type is not napi_object");
74 return false;
75 }
76 return true;
77 }
78
GetType(napi_env env,napi_value value)79 napi_valuetype ResourceManagerNapiUtils::GetType(napi_env env, napi_value value)
80 {
81 napi_valuetype valueType = napi_valuetype::napi_undefined;
82 napi_typeof(env, value, &valueType);
83 return valueType;
84 }
85
GetResNameOrPath(napi_env env,size_t argc,napi_value * argv)86 std::string ResourceManagerNapiUtils::GetResNameOrPath(napi_env env, size_t argc, napi_value *argv)
87 {
88 if (argc == 0 || argv == nullptr) {
89 return "";
90 }
91
92 napi_valuetype valuetype;
93 napi_typeof(env, argv[ARRAY_SUBCRIPTOR_ZERO], &valuetype);
94 if (valuetype != napi_string) {
95 RESMGR_HILOGE(RESMGR_JS_TAG, "Invalid param, not string");
96 return "";
97 }
98 size_t len = 0;
99 napi_status status = napi_get_value_string_utf8(env, argv[ARRAY_SUBCRIPTOR_ZERO], nullptr, 0, &len);
100 if (status != napi_ok) {
101 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get resName or rawfile path length");
102 return "";
103 }
104 std::vector<char> buf(len + 1);
105 status = napi_get_value_string_utf8(env, argv[ARRAY_SUBCRIPTOR_ZERO], buf.data(), len + 1, &len);
106 if (status != napi_ok) {
107 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get resName or raw file path");
108 return "";
109 }
110 return buf.data();
111 }
112
GetResId(napi_env env,size_t argc,napi_value * argv)113 uint32_t ResourceManagerNapiUtils::GetResId(napi_env env, size_t argc, napi_value *argv)
114 {
115 if (argc == 0 || argv == nullptr) {
116 return 0;
117 }
118
119 napi_valuetype valuetype;
120 napi_status status = napi_typeof(env, argv[ARRAY_SUBCRIPTOR_ZERO], &valuetype);
121 if (status != napi_ok) {
122 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get value type");
123 return 0;
124 }
125 if (valuetype != napi_number) {
126 RESMGR_HILOGE(RESMGR_JS_TAG, "Invalid param, not number");
127 return 0;
128 }
129 int64_t resId = 0;
130 status = napi_get_value_int64(env, argv[ARRAY_SUBCRIPTOR_ZERO], &resId);
131 if (status != napi_ok || resId < 0 || resId > UINT32_MAX) {
132 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get id number");
133 return 0;
134 }
135
136 return static_cast<uint32_t>(resId);
137 }
138
FindErrMsg(int32_t errCode)139 std::string ResourceManagerNapiUtils::FindErrMsg(int32_t errCode)
140 {
141 auto iter = ResourceManagerNapiUtils::ErrorCodeToMsg.find(errCode);
142 std::string errMsg = iter != ResourceManagerNapiUtils::ErrorCodeToMsg.end() ? iter->second : "";
143 return errMsg;
144 }
145
NapiThrow(napi_env env,int32_t errCode)146 void ResourceManagerNapiUtils::NapiThrow(napi_env env, int32_t errCode)
147 {
148 napi_value code = nullptr;
149 napi_create_string_latin1(env, std::to_string(errCode).c_str(), NAPI_AUTO_LENGTH, &code);
150
151 napi_value message = nullptr;
152 std::string errMsg = FindErrMsg(errCode);
153 napi_create_string_latin1(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message);
154 if (errMsg != "") {
155 napi_value error = nullptr;
156 napi_create_error(env, code, message, &error);
157 napi_throw(env, error);
158 }
159 }
160
CreateJsArray(napi_env env,ResMgrDataContext & dataContext)161 napi_value ResourceManagerNapiUtils::CreateJsArray(napi_env env, ResMgrDataContext &dataContext)
162 {
163 napi_value result;
164 napi_status status = napi_create_array_with_length(env, dataContext.arrayValue_.size(), &result);
165 if (status != napi_ok) {
166 dataContext.SetErrorMsg("Failed to create array");
167 return nullptr;
168 }
169 for (size_t i = 0; i < dataContext.arrayValue_.size(); i++) {
170 napi_value value;
171 status = napi_create_string_utf8(env, dataContext.arrayValue_[i].c_str(), NAPI_AUTO_LENGTH, &value);
172 if (status != napi_ok) {
173 dataContext.SetErrorMsg("Failed to create string item");
174 return nullptr;
175 }
176 status = napi_set_element(env, result, i, value);
177 if (status != napi_ok) {
178 dataContext.SetErrorMsg("Failed to set array item");
179 return nullptr;
180 }
181 }
182 return result;
183 }
184
CreateJsUint8Array(napi_env env,ResMgrDataContext & context)185 napi_value ResourceManagerNapiUtils::CreateJsUint8Array(napi_env env, ResMgrDataContext &context)
186 {
187 napi_value buffer;
188 uint8_t *data;
189 napi_status status = napi_create_arraybuffer(env, context.len_, reinterpret_cast<void **>(&data), &buffer);
190 if (status != napi_ok) {
191 context.SetErrorMsg("Failed to create media array buffer");
192 return nullptr;
193 }
194
195 napi_value result = nullptr;
196 status = napi_create_typedarray(env, napi_uint8_array, context.len_, buffer, 0, &result);
197 if (status != napi_ok) {
198 context.SetErrorMsg("Failed to create media typed array");
199 return nullptr;
200 }
201
202 if (context.len_ == 0) {
203 return result;
204 }
205
206 uint8_t *tempData = context.mediaData.release();
207 int ret = memcpy_s(data, context.len_, tempData, context.len_);
208 delete[] tempData;
209 if (ret != 0) {
210 context.SetErrorMsg("Failed to copy media to buffer");
211 return result;
212 }
213 return result;
214 }
215
CreateJsRawFd(napi_env env,ResMgrDataContext & context)216 napi_value ResourceManagerNapiUtils::CreateJsRawFd(napi_env env, ResMgrDataContext &context)
217 {
218 napi_value result;
219 napi_status status = napi_create_object(env, &result);
220 if (status != napi_ok) {
221 context.SetErrorMsg("Failed to create result");
222 return result;
223 }
224
225 napi_value fd;
226 status = napi_create_int32(env, context.descriptor_.fd, &fd);
227 if (status != napi_ok) {
228 context.SetErrorMsg("Failed to create fd");
229 return result;
230 }
231 status = napi_set_named_property(env, result, "fd", fd);
232 if (status != napi_ok) {
233 context.SetErrorMsg("Failed to set fd");
234 return result;
235 }
236
237 napi_value offset;
238 status = napi_create_int64(env, context.descriptor_.offset, &offset);
239 if (status != napi_ok) {
240 context.SetErrorMsg("Failed to create offset");
241 return result;
242 }
243 status = napi_set_named_property(env, result, "offset", offset);
244 if (status != napi_ok) {
245 context.SetErrorMsg("Failed to set offset");
246 return result;
247 }
248
249 napi_value length;
250 status = napi_create_int64(env, context.descriptor_.length, &length);
251 if (status != napi_ok) {
252 context.SetErrorMsg("Failed to create length");
253 return result;
254 }
255 status = napi_set_named_property(env, result, "length", length);
256 if (status != napi_ok) {
257 context.SetErrorMsg("Failed to set length");
258 return result;
259 }
260 return result;
261 }
262
CloseJsRawFd(napi_env env,ResMgrDataContext & context)263 napi_value ResourceManagerNapiUtils::CloseJsRawFd(napi_env env, ResMgrDataContext& context)
264 {
265 napi_value undefined;
266 if (napi_get_undefined(env, &undefined) != napi_ok) {
267 return nullptr;
268 }
269 RState state = context.addon_->GetResMgr()->CloseRawFileDescriptor(context.path_);
270 if (state != RState::SUCCESS) {
271 context.SetErrorMsg("CloseRawFileDescriptor failed state", true, state);
272 return nullptr;
273 }
274 return undefined;
275 }
276
CreateJsString(napi_env env,ResMgrDataContext & context)277 napi_value ResourceManagerNapiUtils::CreateJsString(napi_env env, ResMgrDataContext& context)
278 {
279 napi_value result;
280 if (napi_create_string_utf8(env, context.value_.c_str(), NAPI_AUTO_LENGTH, &result) != napi_ok) {
281 context.SetErrorMsg("Failed to create result");
282 return result;
283 }
284 return result;
285 }
286
CreateJsNumber(napi_env env,ResMgrDataContext & context)287 napi_value ResourceManagerNapiUtils::CreateJsNumber(napi_env env, ResMgrDataContext& context)
288 {
289 napi_value jsValue = nullptr;
290 napi_status status;
291 if (context.iValue_) {
292 status = napi_create_int32(env, context.iValue_, &jsValue);
293 } else {
294 status = napi_create_double(env, context.fValue_, &jsValue);
295 }
296 if (status != napi_ok) {
297 context.SetErrorMsg("Failed to create js number", true);
298 }
299 return jsValue;
300 }
301
CreateJsBool(napi_env env,ResMgrDataContext & context)302 napi_value ResourceManagerNapiUtils::CreateJsBool(napi_env env, ResMgrDataContext& context)
303 {
304 napi_value jsValue = nullptr;
305 if (napi_get_boolean(env, context.bValue_, &jsValue) != napi_ok) {
306 context.SetErrorMsg("Failed to create result", true);
307 }
308 return jsValue;
309 }
310
GetResourceObjectName(napi_env env,std::shared_ptr<ResourceManager::Resource> & resourcePtr,napi_value & value,int32_t type)311 bool ResourceManagerNapiUtils::GetResourceObjectName(napi_env env,
312 std::shared_ptr<ResourceManager::Resource> &resourcePtr, napi_value &value, int32_t type)
313 {
314 std::string typeName("moduleName");
315 if (type == 0) {
316 typeName = std::string("bundleName");
317 }
318 napi_value name;
319 napi_status status = napi_get_named_property(env, value, typeName.c_str(), &name);
320 if (status != napi_ok || name == nullptr) {
321 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get resource name property");
322 return false;
323 }
324 if (ResourceManagerNapiUtils::GetType(env, name) != napi_string) {
325 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get resource name string");
326 return false;
327 }
328 size_t len = 0;
329 status = napi_get_value_string_utf8(env, name, nullptr, 0, &len);
330 if (status != napi_ok) {
331 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get resource len");
332 return false;
333 }
334 std::vector<char> buf(len + 1);
335 status = napi_get_value_string_utf8(env, name, buf.data(), len + 1, &len);
336 if (status != napi_ok) {
337 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get resource name value");
338 return false;
339 }
340 if (type == 0) {
341 resourcePtr->bundleName = buf.data();
342 } else {
343 resourcePtr->moduleName = buf.data();
344 }
345 return true;
346 }
347
GetResourceObjectId(napi_env env,std::shared_ptr<ResourceManager::Resource> & resourcePtr,napi_value & value)348 bool ResourceManagerNapiUtils::GetResourceObjectId(napi_env env,
349 std::shared_ptr<ResourceManager::Resource> &resourcePtr, napi_value &value)
350 {
351 napi_value id;
352 napi_status status = napi_get_named_property(env, value, "id", &id);
353 if (status != napi_ok || id == nullptr) {
354 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get resource id property");
355 return false;
356 }
357 if (ResourceManagerNapiUtils::GetType(env, id) != napi_number) {
358 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get resource id number");
359 return false;
360 }
361 int64_t resId = 0;
362 status = napi_get_value_int64(env, id, &resId);
363 if (resId == -1) {
364 resourcePtr->id = 0;
365 return true;
366 }
367 if (status != napi_ok || resId < 0 || resId > UINT32_MAX) {
368 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get resource id value");
369 return false;
370 }
371 resourcePtr->id = static_cast<uint32_t>(resId);
372 return true;
373 }
374
GetResourceObject(napi_env env,std::shared_ptr<ResourceManager::Resource> & resourcePtr,napi_value & value)375 int32_t ResourceManagerNapiUtils::GetResourceObject(napi_env env,
376 std::shared_ptr<ResourceManager::Resource> &resourcePtr, napi_value &value)
377 {
378 if (resourcePtr == nullptr) {
379 RESMGR_HILOGE(RESMGR_JS_TAG, "resourcePtr == nullptr");
380 return ERROR;
381 }
382 if (!GetResourceObjectName(env, resourcePtr, value, 0)) {
383 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get bundleName");
384 return ERROR_CODE_INVALID_INPUT_PARAMETER;
385 }
386 if (!GetResourceObjectName(env, resourcePtr, value, 1)) {
387 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get moduleName");
388 return ERROR_CODE_INVALID_INPUT_PARAMETER;
389 }
390 if (!GetResourceObjectId(env, resourcePtr, value)) {
391 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get id");
392 return ERROR_CODE_INVALID_INPUT_PARAMETER;
393 }
394
395 return SUCCESS;
396 }
397
GetHapResourceManager(const ResMgrDataContext * dataContext,std::shared_ptr<ResourceManager> & resMgr,uint32_t & resId)398 bool ResourceManagerNapiUtils::GetHapResourceManager(const ResMgrDataContext* dataContext,
399 std::shared_ptr<ResourceManager> &resMgr, uint32_t &resId)
400 {
401 std::shared_ptr<ResourceManager::Resource> resource = dataContext->resource_;
402 // In fa module, resource is null.
403 if (resource == nullptr) {
404 resMgr = dataContext->addon_->GetResMgr();
405 resId = dataContext->resId_;
406 return true;
407 }
408
409 // In stage module and isSystem is true, resId is the resource object id.
410 if (dataContext->addon_->IsSystem()) {
411 resMgr = dataContext->addon_->GetResMgr();
412 resId = resource->id;
413 return true;
414 }
415
416 resId = resource->id;
417 if (dataContext->addon_->isOverrideAddon()) {
418 resMgr = dataContext->addon_->GetResMgr();
419 return true;
420 }
421 auto context = dataContext->addon_->GetContext();
422 if (context == nullptr) {
423 RESMGR_HILOGE(RESMGR_JS_TAG, "GetHapResourceManager context == nullptr");
424 return false;
425 }
426 std::string bundleName(resource->bundleName);
427 if (bundleName.empty()) {
428 auto applicationInfo = context->GetApplicationInfo();
429 if (applicationInfo != nullptr) {
430 bundleName = applicationInfo->name;
431 }
432 }
433 auto moduleContext = context->CreateModuleContext(bundleName, resource->moduleName);
434 if (moduleContext == nullptr) {
435 RESMGR_HILOGE(RESMGR_JS_TAG, "GetHapResourceManager moduleContext == nullptr, bundleName = %{public}s," \
436 "moduleName = %{public}s", bundleName.c_str(), resource->moduleName.c_str());
437 return false;
438 }
439 resMgr = moduleContext->GetResourceManager();
440 return true;
441 }
442
CreateJsDeviceCap(napi_env env,ResMgrDataContext & context)443 napi_value ResourceManagerNapiUtils::CreateJsDeviceCap(napi_env env, ResMgrDataContext& context)
444 {
445 std::unique_ptr<ResConfig> cfg(CreateResConfig());
446 if (!cfg) {
447 context.SetErrorMsg("Failed to create ResConfig object.");
448 return nullptr;
449 }
450 context.addon_->GetResMgr()->GetResConfig(*cfg);
451
452 napi_value result;
453 napi_status status = napi_create_object(env, &result);
454 if (status != napi_ok) {
455 context.SetErrorMsg("Failed to create GetDeviceCapability object");
456 return nullptr;
457 }
458
459 napi_value deviceType;
460 status = napi_create_int32(env, static_cast<int>(cfg->GetDeviceType()), &deviceType);
461 if (status != napi_ok) {
462 context.SetErrorMsg("Failed to create deviceType");
463 return nullptr;
464 }
465 status = napi_set_named_property(env, result, "deviceType", deviceType);
466 if (status != napi_ok) {
467 context.SetErrorMsg("Failed to set deviceType property");
468 return nullptr;
469 }
470
471 napi_value screenDensity;
472 status = napi_create_int32(env, static_cast<int>(cfg->ConvertDensity(cfg->GetScreenDensity())), &screenDensity);
473 if (status != napi_ok) {
474 context.SetErrorMsg("Failed to create screenDensity");
475 return nullptr;
476 }
477 status = napi_set_named_property(env, result, "screenDensity", screenDensity);
478 if (status != napi_ok) {
479 context.SetErrorMsg("Failed to set screenDensity property");
480 return nullptr;
481 }
482 return result;
483 }
484
485
GetLocale(std::unique_ptr<ResConfig> & cfg)486 std::string ResourceManagerNapiUtils::GetLocale(std::unique_ptr<ResConfig> &cfg)
487 {
488 std::string result;
489 #ifdef SUPPORT_GRAPHICS
490 const icu::Locale *localeInfo = cfg->GetLocaleInfo();
491 if (localeInfo == nullptr) {
492 return result;
493 }
494 const char *lang = localeInfo->getLanguage();
495 if (lang == nullptr) {
496 return result;
497 }
498 result = lang;
499
500 const char *script = localeInfo->getScript();
501 if (script != nullptr) {
502 result += std::string("_") + script;
503 }
504
505 const char *region = localeInfo->getCountry();
506 if (region != nullptr) {
507 result += std::string("_") + region;
508 }
509 #endif
510 return result;
511 }
512
CreateJsConfig(napi_env env,ResMgrDataContext & context)513 napi_value ResourceManagerNapiUtils::CreateJsConfig(napi_env env, ResMgrDataContext& context)
514 {
515 std::unique_ptr<ResConfig> cfg(CreateResConfig());
516 if (!cfg) {
517 context.SetErrorMsg("Failed to create ResConfig object.");
518 return nullptr;
519 }
520 context.addon_->GetResMgr()->GetResConfig(*cfg);
521 return CreateConfig(env, context, cfg);
522 }
523
CreateOverrideJsConfig(napi_env env,ResMgrDataContext & context)524 napi_value ResourceManagerNapiUtils::CreateOverrideJsConfig(napi_env env, ResMgrDataContext& context)
525 {
526 std::unique_ptr<ResConfig> cfg(CreateResConfig());
527 if (!cfg) {
528 context.SetErrorMsg("Failed to create ResConfig object.");
529 return nullptr;
530 }
531 context.addon_->GetResMgr()->GetOverrideResConfig(*cfg);
532 return CreateConfig(env, context, cfg);
533 }
534
CreateConfig(napi_env env,ResMgrDataContext & context,std::unique_ptr<ResConfig> & cfg)535 napi_value ResourceManagerNapiUtils::CreateConfig(napi_env env,
536 ResMgrDataContext& context, std::unique_ptr<ResConfig> &cfg)
537 {
538 napi_value result;
539 napi_status status = napi_create_object(env, &result);
540 if (status != napi_ok) {
541 context.SetErrorMsg("Failed to create Configuration object");
542 return nullptr;
543 }
544
545 // write locale
546 napi_value locale;
547 status = napi_create_string_utf8(env, ResourceManagerNapiUtils::GetLocale(cfg).c_str(), NAPI_AUTO_LENGTH, &locale);
548 if (status != napi_ok) {
549 context.SetErrorMsg("Failed to create locale");
550 return nullptr;
551 }
552 status = napi_set_named_property(env, result, "locale", locale);
553 if (status != napi_ok) {
554 context.SetErrorMsg("Failed to set locale property");
555 return nullptr;
556 }
557
558 // write other int properties
559 SetIntProperty(env, context, result, "direction", static_cast<int>(cfg->GetDirection()));
560 SetIntProperty(env, context, result, "deviceType", static_cast<int>(cfg->GetDeviceType()));
561 SetIntProperty(env, context, result, "screenDensity", static_cast<int>(cfg->GetScreenDensityDpi()));
562 SetIntProperty(env, context, result, "colorMode", static_cast<int>(cfg->GetColorMode()));
563 SetIntProperty(env, context, result, "mcc", static_cast<int>(cfg->GetMcc()));
564 SetIntProperty(env, context, result, "mnc", static_cast<int>(cfg->GetMnc()));
565
566 return result;
567 }
568
SetIntProperty(napi_env env,ResMgrDataContext & context,napi_value & object,const std::string & property,const int & value)569 bool ResourceManagerNapiUtils::SetIntProperty(napi_env env,
570 ResMgrDataContext& context, napi_value &object, const std::string &property, const int &value)
571 {
572 napi_value napi_val;
573 napi_status status = napi_create_int32(env, value, &napi_val);
574 if (status != napi_ok) {
575 context.SetErrorMsg("Failed to create %{public}s", property.c_str());
576 return false;
577 }
578 status = napi_set_named_property(env, object, property.c_str(), napi_val);
579 if (status != napi_ok) {
580 context.SetErrorMsg("Failed to set %{public}s property", property.c_str());
581 return false;
582 }
583 return true;
584 }
585
GetConfigObject(napi_env env,napi_value object,std::unique_ptr<ResMgrDataContext> & dataContext)586 RState ResourceManagerNapiUtils::GetConfigObject(napi_env env,
587 napi_value object, std::unique_ptr<ResMgrDataContext> &dataContext)
588 {
589 napi_valuetype valueType;
590 napi_typeof(env, object, &valueType);
591 if (valueType == napi_undefined || valueType == napi_null) {
592 RESMGR_HILOGD(RESMGR_JS_TAG, "GetConfigObject, no config");
593 return SUCCESS;
594 }
595 if (valueType != napi_object) {
596 RESMGR_HILOGE(RESMGR_JS_TAG, "GetConfigObject, param not object");
597 return ERROR_CODE_INVALID_INPUT_PARAMETER;
598 }
599
600 ResConfig *config = CreateDefaultResConfig();
601 if (config == nullptr) {
602 RESMGR_HILOGE(RESMGR_JS_TAG, "GetConfigObject, new config failed");
603 return ERROR_CODE_INVALID_INPUT_PARAMETER;
604 }
605 dataContext->overrideResConfig_.reset(config);
606
607 if (!GetEnumParamOfConfig(env, dataContext->overrideResConfig_, object)) {
608 return ERROR_CODE_INVALID_INPUT_PARAMETER;
609 }
610 if (!GetLocaleOfConfig(env, dataContext->overrideResConfig_, object)) {
611 return ERROR_CODE_INVALID_INPUT_PARAMETER;
612 }
613
614 return SUCCESS;
615 }
616
GetEnumParamOfConfig(napi_env env,std::shared_ptr<ResConfig> configPtr,napi_value & object)617 bool ResourceManagerNapiUtils::GetEnumParamOfConfig(napi_env env,
618 std::shared_ptr<ResConfig> configPtr, napi_value &object)
619 {
620 std::vector<std::string> properties = {"direction", "deviceType", "screenDensity", "colorMode", "mcc", "mnc"};
621 for (const auto& property : properties) {
622 napi_value napi_val;
623 napi_status status = napi_get_named_property(env, object, property.c_str(), &napi_val);
624 if (status != napi_ok) {
625 RESMGR_HILOGE(RESMGR_JS_TAG, "GetEnumParamOfConfig failed to get property %{public}s", property.c_str());
626 return false;
627 }
628 if (napi_val == nullptr) {
629 RESMGR_HILOGD(RESMGR_JS_TAG, "GetEnumParamOfConfig property %{public}s not set", property.c_str());
630 continue;
631 }
632 if (ResourceManagerNapiUtils::GetType(env, napi_val) != napi_number) {
633 RESMGR_HILOGE(RESMGR_JS_TAG,
634 "GetEnumParamOfConfig type of property %{public}s is not number", property.c_str());
635 return false;
636 }
637 int value;
638 status = napi_get_value_int32(env, napi_val, &value);
639 if (status != napi_ok) {
640 RESMGR_HILOGE(RESMGR_JS_TAG,
641 "GetEnumParamOfConfig failed to get value of property %{public}s", property.c_str());
642 return false;
643 }
644
645 RESMGR_HILOGD(RESMGR_JS_TAG, "GetEnumParamOfConfig, %{public}s = %{public}d", property.c_str(), value);
646 if (property == "direction") {
647 configPtr->SetDirection(static_cast<Direction>(value));
648 } else if (property == "deviceType") {
649 configPtr->SetDeviceType(static_cast<DeviceType>(value));
650 } else if (property == "screenDensity") {
651 configPtr->SetScreenDensityDpi(static_cast<ScreenDensity>(value));
652 } else if (property == "colorMode") {
653 configPtr->SetColorMode(static_cast<ColorMode>(value));
654 } else if (property == "mcc") {
655 configPtr->SetMcc(value);
656 } else if (property == "mnc") {
657 configPtr->SetMnc(value);
658 }
659 }
660 return true;
661 }
662
GetLocaleOfConfig(napi_env env,std::shared_ptr<ResConfig> configPtr,napi_value & object)663 bool ResourceManagerNapiUtils::GetLocaleOfConfig(
664 napi_env env, std::shared_ptr<ResConfig> configPtr, napi_value &object)
665 {
666 #ifdef SUPPORT_GRAPHICS
667 napi_value locale;
668 napi_status status = napi_get_named_property(env, object, "locale", &locale);
669 if (status != napi_ok) {
670 RESMGR_HILOGE(RESMGR_JS_TAG, "GetLocaleOfConfig failed to get property locale");
671 return false;
672 }
673 if (locale == nullptr) {
674 RESMGR_HILOGD(RESMGR_JS_TAG, "GetLocaleOfConfig property locale not set");
675 return true;
676 }
677 if (ResourceManagerNapiUtils::GetType(env, locale) != napi_string) {
678 RESMGR_HILOGE(RESMGR_JS_TAG, "GetLocaleOfConfig type of property locale is not string");
679 return false;
680 }
681
682 size_t len = 0;
683 status = napi_get_value_string_utf8(env, locale, nullptr, 0, &len);
684 if (status != napi_ok) {
685 RESMGR_HILOGE(RESMGR_JS_TAG, "GetLocaleOfConfig failed to get locale len");
686 return false;
687 }
688 if (len == 0) {
689 RESMGR_HILOGD(RESMGR_JS_TAG, "GetLocaleOfConfig locale not set or empty");
690 return true;
691 }
692
693 std::vector<char> buf(len + 1);
694 status = napi_get_value_string_utf8(env, locale, buf.data(), len + 1, &len);
695 if (status != napi_ok) {
696 RESMGR_HILOGE(RESMGR_JS_TAG, "GetLocaleOfConfig failed to get locale value");
697 return false;
698 }
699
700 if (configPtr->SetLocaleInfo(buf.data()) != SUCCESS) {
701 RESMGR_HILOGE(RESMGR_JS_TAG, "GetLocaleOfConfig failed to SetLocaleInfo");
702 return false;
703 }
704 #endif
705 return true;
706 }
707
CreateJsColor(napi_env env,ResMgrDataContext & context)708 napi_value ResourceManagerNapiUtils::CreateJsColor(napi_env env, ResMgrDataContext& context)
709 {
710 napi_value jsColorValue;
711 if (napi_create_uint32(env, context.colorValue_, &jsColorValue) != napi_ok) {
712 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get density");
713 return nullptr;
714 }
715 return jsColorValue;
716 }
717
CreateJsSymbol(napi_env env,ResMgrDataContext & context)718 napi_value ResourceManagerNapiUtils::CreateJsSymbol(napi_env env, ResMgrDataContext& context)
719 {
720 napi_value jsSymbolValue;
721 if (napi_create_uint32(env, context.symbolValue_, &jsSymbolValue) != napi_ok) {
722 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get symbol");
723 return nullptr;
724 }
725 return jsSymbolValue;
726 }
727
GetDataType(napi_env env,napi_value value,uint32_t & density)728 RState ResourceManagerNapiUtils::GetDataType(napi_env env, napi_value value, uint32_t& density)
729 {
730 napi_valuetype valuetype;
731 napi_typeof(env, value, &valuetype);
732 if (valuetype == napi_undefined || valuetype == napi_null) {
733 return SUCCESS;
734 }
735 if (valuetype != napi_number) {
736 RESMGR_HILOGE(RESMGR_JS_TAG, "Invalid param, not number");
737 return ERROR_CODE_INVALID_INPUT_PARAMETER;
738 }
739
740 if (napi_get_value_uint32(env, value, &density) != napi_ok) {
741 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get density");
742 return NOT_FOUND;
743 }
744 return SUCCESS;
745 }
746
GetIncludeSystem(napi_env env,napi_value value,bool & includeSystem)747 RState ResourceManagerNapiUtils::GetIncludeSystem(napi_env env, napi_value value, bool &includeSystem)
748 {
749 napi_valuetype valuetype;
750 napi_typeof(env, value, &valuetype);
751 if (valuetype == napi_undefined || valuetype == napi_null) {
752 return SUCCESS;
753 }
754 if (valuetype != napi_boolean) {
755 RESMGR_HILOGE(RESMGR_JS_TAG, "Invalid param, not boolean");
756 return ERROR_CODE_INVALID_INPUT_PARAMETER;
757 }
758
759 if (napi_get_value_bool(env, value, &includeSystem) != napi_ok) {
760 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get includeSystem");
761 return NOT_FOUND;
762 }
763 return SUCCESS;
764 }
765 } // namespace Resource
766 } // namespace Global
767 } // namespace OHOS