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 int 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 int resId = 0; 130 status = napi_get_value_int32(env, argv[ARRAY_SUBCRIPTOR_ZERO], &resId); 131 if (status != napi_ok) { 132 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get id number"); 133 return 0; 134 } 135 136 return 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 int32_t resId = 0; 362 status = napi_get_value_int32(env, id, &resId); 363 if (status != napi_ok) { 364 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get resource id value"); 365 return false; 366 } 367 resourcePtr->id = resId; 368 return true; 369 } 370 GetResourceObject(napi_env env,std::shared_ptr<ResourceManager::Resource> & resourcePtr,napi_value & value)371 int32_t ResourceManagerNapiUtils::GetResourceObject(napi_env env, 372 std::shared_ptr<ResourceManager::Resource> &resourcePtr, napi_value &value) 373 { 374 if (resourcePtr == nullptr) { 375 RESMGR_HILOGE(RESMGR_JS_TAG, "resourcePtr == nullptr"); 376 return ERROR; 377 } 378 if (!GetResourceObjectName(env, resourcePtr, value, 0)) { 379 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get bundleName"); 380 return ERROR_CODE_INVALID_INPUT_PARAMETER; 381 } 382 if (!GetResourceObjectName(env, resourcePtr, value, 1)) { 383 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get moduleName"); 384 return ERROR_CODE_INVALID_INPUT_PARAMETER; 385 } 386 if (!GetResourceObjectId(env, resourcePtr, value)) { 387 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get id"); 388 return ERROR_CODE_INVALID_INPUT_PARAMETER; 389 } 390 391 return SUCCESS; 392 } 393 GetHapResourceManager(const ResMgrDataContext * dataContext,std::shared_ptr<ResourceManager> & resMgr,int32_t & resId)394 bool ResourceManagerNapiUtils::GetHapResourceManager(const ResMgrDataContext* dataContext, 395 std::shared_ptr<ResourceManager> &resMgr, int32_t &resId) 396 { 397 std::shared_ptr<ResourceManager::Resource> resource = dataContext->resource_; 398 // In fa module, resource is null. 399 if (resource == nullptr) { 400 resMgr = dataContext->addon_->GetResMgr(); 401 resId = dataContext->resId_; 402 return true; 403 } 404 405 // In stage module and isSystem is true, resId is the resource object id. 406 if (dataContext->addon_->IsSystem()) { 407 resMgr = dataContext->addon_->GetResMgr(); 408 resId = resource->id; 409 return true; 410 } 411 412 resId = resource->id; 413 if (dataContext->addon_->isOverrideAddon()) { 414 resMgr = dataContext->addon_->GetResMgr(); 415 return true; 416 } 417 auto context = dataContext->addon_->GetContext(); 418 if (context == nullptr) { 419 RESMGR_HILOGE(RESMGR_JS_TAG, "GetHapResourceManager context == nullptr"); 420 return false; 421 } 422 std::string bundleName(resource->bundleName); 423 if (bundleName.empty()) { 424 auto applicationInfo = context->GetApplicationInfo(); 425 if (applicationInfo != nullptr) { 426 bundleName = applicationInfo->name; 427 } 428 } 429 auto moduleContext = context->CreateModuleContext(bundleName, resource->moduleName); 430 if (moduleContext == nullptr) { 431 RESMGR_HILOGE(RESMGR_JS_TAG, "GetHapResourceManager moduleContext == nullptr, bundleName = %{public}s," \ 432 "moduleName = %{public}s", bundleName.c_str(), resource->moduleName.c_str()); 433 return false; 434 } 435 resMgr = moduleContext->GetResourceManager(); 436 return true; 437 } 438 CreateJsDeviceCap(napi_env env,ResMgrDataContext & context)439 napi_value ResourceManagerNapiUtils::CreateJsDeviceCap(napi_env env, ResMgrDataContext& context) 440 { 441 std::unique_ptr<ResConfig> cfg(CreateResConfig()); 442 context.addon_->GetResMgr()->GetResConfig(*cfg); 443 444 napi_value result; 445 napi_status status = napi_create_object(env, &result); 446 if (status != napi_ok) { 447 context.SetErrorMsg("Failed to create GetDeviceCapability object"); 448 return nullptr; 449 } 450 451 napi_value deviceType; 452 status = napi_create_int32(env, static_cast<int>(cfg->GetDeviceType()), &deviceType); 453 if (status != napi_ok) { 454 context.SetErrorMsg("Failed to create deviceType"); 455 return nullptr; 456 } 457 status = napi_set_named_property(env, result, "deviceType", deviceType); 458 if (status != napi_ok) { 459 context.SetErrorMsg("Failed to set deviceType property"); 460 return nullptr; 461 } 462 463 napi_value screenDensity; 464 status = napi_create_int32(env, static_cast<int>(cfg->ConvertDensity(cfg->GetScreenDensity())), &screenDensity); 465 if (status != napi_ok) { 466 context.SetErrorMsg("Failed to create screenDensity"); 467 return nullptr; 468 } 469 status = napi_set_named_property(env, result, "screenDensity", screenDensity); 470 if (status != napi_ok) { 471 context.SetErrorMsg("Failed to set screenDensity property"); 472 return nullptr; 473 } 474 return result; 475 } 476 477 GetLocale(std::unique_ptr<ResConfig> & cfg)478 std::string ResourceManagerNapiUtils::GetLocale(std::unique_ptr<ResConfig> &cfg) 479 { 480 std::string result; 481 #ifdef SUPPORT_GRAPHICS 482 const icu::Locale *localeInfo = cfg->GetLocaleInfo(); 483 if (localeInfo == nullptr) { 484 return result; 485 } 486 const char *lang = localeInfo->getLanguage(); 487 if (lang == nullptr) { 488 return result; 489 } 490 result = lang; 491 492 const char *script = localeInfo->getScript(); 493 if (script != nullptr) { 494 result += std::string("_") + script; 495 } 496 497 const char *region = localeInfo->getCountry(); 498 if (region != nullptr) { 499 result += std::string("_") + region; 500 } 501 #endif 502 return result; 503 } 504 CreateJsConfig(napi_env env,ResMgrDataContext & context)505 napi_value ResourceManagerNapiUtils::CreateJsConfig(napi_env env, ResMgrDataContext& context) 506 { 507 std::unique_ptr<ResConfig> cfg(CreateResConfig()); 508 context.addon_->GetResMgr()->GetResConfig(*cfg); 509 return CreateConfig(env, context, cfg); 510 } 511 CreateOverrideJsConfig(napi_env env,ResMgrDataContext & context)512 napi_value ResourceManagerNapiUtils::CreateOverrideJsConfig(napi_env env, ResMgrDataContext& context) 513 { 514 std::unique_ptr<ResConfig> cfg(CreateResConfig()); 515 context.addon_->GetResMgr()->GetOverrideResConfig(*cfg); 516 return CreateConfig(env, context, cfg); 517 } 518 CreateConfig(napi_env env,ResMgrDataContext & context,std::unique_ptr<ResConfig> & cfg)519 napi_value ResourceManagerNapiUtils::CreateConfig(napi_env env, 520 ResMgrDataContext& context, std::unique_ptr<ResConfig> &cfg) 521 { 522 napi_value result; 523 napi_status status = napi_create_object(env, &result); 524 if (status != napi_ok) { 525 context.SetErrorMsg("Failed to create Configuration object"); 526 return nullptr; 527 } 528 529 // write locale 530 napi_value locale; 531 status = napi_create_string_utf8(env, ResourceManagerNapiUtils::GetLocale(cfg).c_str(), NAPI_AUTO_LENGTH, &locale); 532 if (status != napi_ok) { 533 context.SetErrorMsg("Failed to create locale"); 534 return nullptr; 535 } 536 status = napi_set_named_property(env, result, "locale", locale); 537 if (status != napi_ok) { 538 context.SetErrorMsg("Failed to set locale property"); 539 return nullptr; 540 } 541 542 // write other int properties 543 SetIntProperty(env, context, result, "direction", static_cast<int>(cfg->GetDirection())); 544 SetIntProperty(env, context, result, "deviceType", static_cast<int>(cfg->GetDeviceType())); 545 SetIntProperty(env, context, result, "screenDensity", static_cast<int>(cfg->GetScreenDensityDpi())); 546 SetIntProperty(env, context, result, "colorMode", static_cast<int>(cfg->GetColorMode())); 547 SetIntProperty(env, context, result, "mcc", static_cast<int>(cfg->GetMcc())); 548 SetIntProperty(env, context, result, "mnc", static_cast<int>(cfg->GetMnc())); 549 550 return result; 551 } 552 SetIntProperty(napi_env env,ResMgrDataContext & context,napi_value & object,const std::string & property,const int & value)553 bool ResourceManagerNapiUtils::SetIntProperty(napi_env env, 554 ResMgrDataContext& context, napi_value &object, const std::string &property, const int &value) 555 { 556 napi_value napi_val; 557 napi_status status = napi_create_int32(env, value, &napi_val); 558 if (status != napi_ok) { 559 context.SetErrorMsg("Failed to create %{public}s", property.c_str()); 560 return false; 561 } 562 status = napi_set_named_property(env, object, property.c_str(), napi_val); 563 if (status != napi_ok) { 564 context.SetErrorMsg("Failed to set %{public}s property", property.c_str()); 565 return false; 566 } 567 return true; 568 } 569 GetConfigObject(napi_env env,napi_value object,std::unique_ptr<ResMgrDataContext> & dataContext)570 RState ResourceManagerNapiUtils::GetConfigObject(napi_env env, 571 napi_value object, std::unique_ptr<ResMgrDataContext> &dataContext) 572 { 573 napi_valuetype valueType; 574 napi_typeof(env, object, &valueType); 575 if (valueType == napi_undefined || valueType == napi_null) { 576 RESMGR_HILOGD(RESMGR_JS_TAG, "GetConfigObject, no config"); 577 return SUCCESS; 578 } 579 if (valueType != napi_object) { 580 RESMGR_HILOGE(RESMGR_JS_TAG, "GetConfigObject, param not object"); 581 return ERROR_CODE_INVALID_INPUT_PARAMETER; 582 } 583 584 ResConfig *config = CreateDefaultResConfig(); 585 if (config == nullptr) { 586 RESMGR_HILOGE(RESMGR_JS_TAG, "GetConfigObject, new config failed"); 587 return ERROR_CODE_INVALID_INPUT_PARAMETER; 588 } 589 dataContext->overrideResConfig_.reset(config); 590 591 if (!GetEnumParamOfConfig(env, dataContext->overrideResConfig_, object)) { 592 return ERROR_CODE_INVALID_INPUT_PARAMETER; 593 } 594 if (!GetLocaleOfConfig(env, dataContext->overrideResConfig_, object)) { 595 return ERROR_CODE_INVALID_INPUT_PARAMETER; 596 } 597 598 return SUCCESS; 599 } 600 GetEnumParamOfConfig(napi_env env,std::shared_ptr<ResConfig> configPtr,napi_value & object)601 bool ResourceManagerNapiUtils::GetEnumParamOfConfig(napi_env env, 602 std::shared_ptr<ResConfig> configPtr, napi_value &object) 603 { 604 std::vector<std::string> properties = {"direction", "deviceType", "screenDensity", "colorMode", "mcc", "mnc"}; 605 for (const auto& property : properties) { 606 napi_value napi_val; 607 napi_status status = napi_get_named_property(env, object, property.c_str(), &napi_val); 608 if (status != napi_ok) { 609 RESMGR_HILOGE(RESMGR_JS_TAG, "GetEnumParamOfConfig failed to get property %{public}s", property.c_str()); 610 return false; 611 } 612 if (napi_val == nullptr) { 613 RESMGR_HILOGD(RESMGR_JS_TAG, "GetEnumParamOfConfig property %{public}s not set", property.c_str()); 614 continue; 615 } 616 if (ResourceManagerNapiUtils::GetType(env, napi_val) != napi_number) { 617 RESMGR_HILOGE(RESMGR_JS_TAG, 618 "GetEnumParamOfConfig type of property %{public}s is not number", property.c_str()); 619 return false; 620 } 621 int value; 622 status = napi_get_value_int32(env, napi_val, &value); 623 if (status != napi_ok) { 624 RESMGR_HILOGE(RESMGR_JS_TAG, 625 "GetEnumParamOfConfig failed to get value of property %{public}s", property.c_str()); 626 return false; 627 } 628 629 RESMGR_HILOGD(RESMGR_JS_TAG, "GetEnumParamOfConfig, %{public}s = %{public}d", property.c_str(), value); 630 if (property == "direction") { 631 configPtr->SetDirection(static_cast<Direction>(value)); 632 } else if (property == "deviceType") { 633 configPtr->SetDeviceType(static_cast<DeviceType>(value)); 634 } else if (property == "screenDensity") { 635 configPtr->SetScreenDensityDpi(static_cast<ScreenDensity>(value)); 636 } else if (property == "colorMode") { 637 configPtr->SetColorMode(static_cast<ColorMode>(value)); 638 } else if (property == "mcc") { 639 configPtr->SetMcc(value); 640 } else if (property == "mnc") { 641 configPtr->SetMnc(value); 642 } 643 } 644 return true; 645 } 646 GetLocaleOfConfig(napi_env env,std::shared_ptr<ResConfig> configPtr,napi_value & object)647 bool ResourceManagerNapiUtils::GetLocaleOfConfig( 648 napi_env env, std::shared_ptr<ResConfig> configPtr, napi_value &object) 649 { 650 #ifdef SUPPORT_GRAPHICS 651 napi_value locale; 652 napi_status status = napi_get_named_property(env, object, "locale", &locale); 653 if (status != napi_ok) { 654 RESMGR_HILOGE(RESMGR_JS_TAG, "GetLocaleOfConfig failed to get property locale"); 655 return false; 656 } 657 if (locale == nullptr) { 658 RESMGR_HILOGD(RESMGR_JS_TAG, "GetLocaleOfConfig property locale not set"); 659 return true; 660 } 661 if (ResourceManagerNapiUtils::GetType(env, locale) != napi_string) { 662 RESMGR_HILOGE(RESMGR_JS_TAG, "GetLocaleOfConfig type of property locale is not string"); 663 return false; 664 } 665 666 size_t len = 0; 667 status = napi_get_value_string_utf8(env, locale, nullptr, 0, &len); 668 if (status != napi_ok) { 669 RESMGR_HILOGE(RESMGR_JS_TAG, "GetLocaleOfConfig failed to get locale len"); 670 return false; 671 } 672 if (len == 0) { 673 RESMGR_HILOGD(RESMGR_JS_TAG, "GetLocaleOfConfig locale not set or empty"); 674 return true; 675 } 676 677 std::vector<char> buf(len + 1); 678 status = napi_get_value_string_utf8(env, locale, buf.data(), len + 1, &len); 679 if (status != napi_ok) { 680 RESMGR_HILOGE(RESMGR_JS_TAG, "GetLocaleOfConfig failed to get locale value"); 681 return false; 682 } 683 684 if (configPtr->SetLocaleInfo(buf.data()) != SUCCESS) { 685 RESMGR_HILOGE(RESMGR_JS_TAG, "GetLocaleOfConfig failed to SetLocaleInfo"); 686 return false; 687 } 688 #endif 689 return true; 690 } 691 CreateJsColor(napi_env env,ResMgrDataContext & context)692 napi_value ResourceManagerNapiUtils::CreateJsColor(napi_env env, ResMgrDataContext& context) 693 { 694 napi_value jsColorValue; 695 if (napi_create_uint32(env, context.colorValue_, &jsColorValue) != napi_ok) { 696 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get density"); 697 return nullptr; 698 } 699 return jsColorValue; 700 } 701 CreateJsSymbol(napi_env env,ResMgrDataContext & context)702 napi_value ResourceManagerNapiUtils::CreateJsSymbol(napi_env env, ResMgrDataContext& context) 703 { 704 napi_value jsSymbolValue; 705 if (napi_create_uint32(env, context.symbolValue_, &jsSymbolValue) != napi_ok) { 706 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get symbol"); 707 return nullptr; 708 } 709 return jsSymbolValue; 710 } 711 GetDataType(napi_env env,napi_value value,uint32_t & density)712 RState ResourceManagerNapiUtils::GetDataType(napi_env env, napi_value value, uint32_t& density) 713 { 714 napi_valuetype valuetype; 715 napi_typeof(env, value, &valuetype); 716 if (valuetype == napi_undefined || valuetype == napi_null) { 717 return SUCCESS; 718 } 719 if (valuetype != napi_number) { 720 RESMGR_HILOGE(RESMGR_JS_TAG, "Invalid param, not number"); 721 return ERROR_CODE_INVALID_INPUT_PARAMETER; 722 } 723 724 if (napi_get_value_uint32(env, value, &density) != napi_ok) { 725 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get density"); 726 return NOT_FOUND; 727 } 728 return SUCCESS; 729 } 730 GetIncludeSystem(napi_env env,napi_value value,bool & includeSystem)731 RState ResourceManagerNapiUtils::GetIncludeSystem(napi_env env, napi_value value, bool &includeSystem) 732 { 733 napi_valuetype valuetype; 734 napi_typeof(env, value, &valuetype); 735 if (valuetype == napi_undefined || valuetype == napi_null) { 736 return SUCCESS; 737 } 738 if (valuetype != napi_boolean) { 739 RESMGR_HILOGE(RESMGR_JS_TAG, "Invalid param, not boolean"); 740 return ERROR_CODE_INVALID_INPUT_PARAMETER; 741 } 742 743 if (napi_get_value_bool(env, value, &includeSystem) != napi_ok) { 744 RESMGR_HILOGE(RESMGR_JS_TAG, "Failed to get includeSystem"); 745 return NOT_FOUND; 746 } 747 return SUCCESS; 748 } 749 } // namespace Resource 750 } // namespace Global 751 } // namespace OHOS