• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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