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 "adapter/ohos/osal/resource_adapter_impl_v2.h"
17 
18 #include <dirent.h>
19 
20 #include "drawable_descriptor.h"
21 #include "resource_adapter_impl_v2.h"
22 
23 #include "adapter/ohos/entrance/ace_container.h"
24 #include "adapter/ohos/osal/resource_convertor.h"
25 #include "base/log/log_wrapper.h"
26 #include "base/utils/device_config.h"
27 #include "base/utils/system_properties.h"
28 #include "base/utils/utils.h"
29 #include "core/components/theme/theme_attributes.h"
30 #include "core/pipeline_ng/pipeline_context.h"
31 namespace OHOS::Ace {
32 namespace {
33 constexpr uint32_t OHOS_THEME_ID = 125829872; // ohos_theme
34 const Color ERROR_VALUE_COLOR = Color(0xff000000);
35 
CheckThemeId(int32_t & themeId)36 void CheckThemeId(int32_t& themeId)
37 {
38     if (themeId >= 0) {
39         return;
40     }
41     themeId = OHOS_THEME_ID;
42 }
43 
44 const char* PATTERN_MAP[] = {
45     THEME_PATTERN_BUTTON,
46     THEME_PATTERN_CAMERA,
47     THEME_PATTERN_LIST_ITEM,
48     THEME_PATTERN_PICKER,
49     THEME_PATTERN_PROGRESS,
50     THEME_PATTERN_SELECT,
51     THEME_PATTERN_STEPPER,
52     THEME_PATTERN_TEXT,
53     THEME_PATTERN_TEXTFIELD,
54     THEME_PATTERN_TEXT_OVERLAY,
55     THEME_PATTERN_CONTAINER_MODAL
56 };
57 
58 // PRELOAD_LIST contain themes that should be preloaded asynchronously
59 const char* PRELOAD_LIST[] = {
60     THEME_BLUR_STYLE_COMMON,
61     THEME_PATTERN_ICON,
62     THEME_PATTERN_SHADOW
63 };
64 
65 constexpr char RESOURCE_TOKEN_PATTERN[] = "\\[.+?\\]\\.(\\S+?\\.\\S+)";
66 
IsDirExist(const std::string & path)67 bool IsDirExist(const std::string& path)
68 {
69     char realPath[PATH_MAX] = { 0x00 };
70     CHECK_NULL_RETURN(realpath(path.c_str(), realPath), false);
71     DIR* dir = opendir(realPath);
72     CHECK_NULL_RETURN(dir, false);
73     closedir(dir);
74     return true;
75 }
76 
ParseDimensionUnit(const std::string & unit)77 DimensionUnit ParseDimensionUnit(const std::string& unit)
78 {
79     if (unit == "px") {
80         return DimensionUnit::PX;
81     } else if (unit == "fp") {
82         return DimensionUnit::FP;
83     } else if (unit == "lpx") {
84         return DimensionUnit::LPX;
85     } else if (unit == "%") {
86         return DimensionUnit::PERCENT;
87     } else {
88         return DimensionUnit::VP;
89     }
90 };
91 } // namespace
92 
CreateV2()93 RefPtr<ResourceAdapter> ResourceAdapter::CreateV2()
94 {
95     return AceType::MakeRefPtr<ResourceAdapterImplV2>();
96 }
97 
CreateNewResourceAdapter(const std::string & bundleName,const std::string & moduleName)98 RefPtr<ResourceAdapter> ResourceAdapter::CreateNewResourceAdapter(
99     const std::string& bundleName, const std::string& moduleName)
100 {
101     auto container = Container::CurrentSafely();
102     CHECK_NULL_RETURN(container, nullptr);
103     auto aceContainer = AceType::DynamicCast<Platform::AceContainer>(container);
104     CHECK_NULL_RETURN(aceContainer, nullptr);
105 
106     RefPtr<ResourceAdapter> newResourceAdapter = nullptr;
107     auto context = aceContainer->GetAbilityContextByModule(bundleName, moduleName);
108     if (context) {
109         auto resourceManager = context->GetResourceManager();
110         auto resourceAdapterV2 = AceType::MakeRefPtr<ResourceAdapterImplV2>(resourceManager);
111         resourceAdapterV2->SetAppHasDarkRes(aceContainer->GetResourceConfiguration().GetAppHasDarkRes());
112         newResourceAdapter = resourceAdapterV2;
113     } else {
114         newResourceAdapter = ResourceAdapter::CreateV2();
115         auto resourceInfo = aceContainer->GetResourceInfo();
116         newResourceAdapter->Init(resourceInfo);
117     }
118 
119     auto resConfig = aceContainer->GetResourceConfiguration();
120     auto pipelineContext = NG::PipelineContext::GetCurrentContext();
121     if (pipelineContext && pipelineContext->GetLocalColorMode() != ColorMode::COLOR_MODE_UNDEFINED) {
122         auto localColorMode = pipelineContext->GetLocalColorMode();
123         resConfig.SetColorMode(localColorMode);
124     }
125     newResourceAdapter->UpdateConfig(resConfig);
126 
127     return newResourceAdapter;
128 }
129 
ResourceAdapterImplV2(std::shared_ptr<Global::Resource::ResourceManager> resourceManager)130 ResourceAdapterImplV2::ResourceAdapterImplV2(std::shared_ptr<Global::Resource::ResourceManager> resourceManager)
131 {
132     sysResourceManager_ = resourceManager;
133 }
134 
ResourceAdapterImplV2(std::shared_ptr<Global::Resource::ResourceManager> resourceManager,const ResourceInfo & resourceInfo)135 ResourceAdapterImplV2::ResourceAdapterImplV2(
136     std::shared_ptr<Global::Resource::ResourceManager> resourceManager, const ResourceInfo& resourceInfo)
137 {
138     std::string resPath = resourceInfo.GetPackagePath();
139     std::string hapPath = resourceInfo.GetHapPath();
140     std::string resIndexPath = hapPath.empty() ? (resPath + "resources.index") : hapPath;
141     packagePathStr_ = (hapPath.empty() || IsDirExist(resPath)) ? resPath : std::string();
142 
143     auto resConfig = ConvertConfigToGlobal(resourceInfo.GetResourceConfiguration());
144     sysResourceManager_ = resourceManager;
145     if (resConfig != nullptr) {
146         sysResourceManager_->UpdateResConfig(*resConfig);
147     }
148     resConfig_ = resConfig;
149     appHasDarkRes_ = resourceInfo.GetResourceConfiguration().GetAppHasDarkRes();
150 }
151 
Init(const ResourceInfo & resourceInfo)152 void ResourceAdapterImplV2::Init(const ResourceInfo& resourceInfo)
153 {
154     std::string resPath = resourceInfo.GetPackagePath();
155     std::string hapPath = resourceInfo.GetHapPath();
156     auto resConfig = ConvertConfigToGlobal(resourceInfo.GetResourceConfiguration());
157     std::shared_ptr<Global::Resource::ResourceManager> newResMgr(Global::Resource::CreateResourceManager());
158     std::string resIndexPath = hapPath.empty() ? (resPath + "resources.index") : hapPath;
159     newResMgr->AddResource(resIndexPath.c_str());
160     if (resConfig != nullptr) {
161         newResMgr->UpdateResConfig(*resConfig);
162     }
163     sysResourceManager_ = newResMgr;
164     packagePathStr_ = (hapPath.empty() || IsDirExist(resPath)) ? resPath : std::string();
165     resConfig_ = resConfig;
166     appHasDarkRes_ = resourceInfo.GetResourceConfiguration().GetAppHasDarkRes();
167 }
168 
NeedUpdateResConfig(const std::shared_ptr<Global::Resource::ResConfig> & oldResConfig,const std::shared_ptr<Global::Resource::ResConfig> & newResConfig)169 bool ResourceAdapterImplV2::NeedUpdateResConfig(const std::shared_ptr<Global::Resource::ResConfig>& oldResConfig,
170     const std::shared_ptr<Global::Resource::ResConfig>& newResConfig)
171 {
172     if (oldResConfig == nullptr) {
173         return true;
174     }
175     auto oldLocaleInfo = oldResConfig->GetLocaleInfo();
176     auto newLocaleInfo = newResConfig->GetLocaleInfo();
177     bool isLocaleChange = false;
178     if (newLocaleInfo == nullptr) {
179         isLocaleChange = false;
180     } else if (oldLocaleInfo == nullptr) {
181         isLocaleChange = true;
182     } else {
183         isLocaleChange = std::string(oldLocaleInfo->getLanguage()) != std::string(newLocaleInfo->getLanguage()) ||
184                          std::string(oldLocaleInfo->getScript()) != std::string(newLocaleInfo->getScript()) ||
185                          std::string(oldLocaleInfo->getCountry()) != std::string(newLocaleInfo->getCountry());
186     }
187 
188     return oldResConfig->GetDeviceType() != newResConfig->GetDeviceType() ||
189            oldResConfig->GetDirection() != newResConfig->GetDirection() ||
190            oldResConfig->GetScreenDensity() != newResConfig->GetScreenDensity() ||
191            oldResConfig->GetColorMode() != newResConfig->GetColorMode() ||
192            oldResConfig->GetInputDevice() != newResConfig->GetInputDevice() || isLocaleChange;
193 }
194 
UpdateConfig(const ResourceConfiguration & config,bool themeFlag)195 void ResourceAdapterImplV2::UpdateConfig(const ResourceConfiguration& config, bool themeFlag)
196 {
197     std::lock_guard<std::mutex> lock(updateResConfigMutex_);
198     auto resConfig = ConvertConfigToGlobal(config);
199     auto needUpdateResConfig = NeedUpdateResConfig(resConfig_, resConfig) || themeFlag;
200     if (sysResourceManager_ && resConfig != nullptr && needUpdateResConfig) {
201         sysResourceManager_->UpdateResConfig(*resConfig, themeFlag);
202     }
203     resConfig_ = resConfig;
204 }
205 
GetTheme(int32_t themeId)206 RefPtr<ThemeStyle> ResourceAdapterImplV2::GetTheme(int32_t themeId)
207 {
208     CheckThemeId(themeId);
209     auto theme = AceType::MakeRefPtr<ResourceThemeStyle>(AceType::Claim(this));
210 
211     constexpr char OHFlag[] = "ohos_"; // fit with resource/base/theme.json and pattern.json
212     {
213         auto manager = GetResourceManager();
214         if (manager) {
215             auto ret = manager->GetThemeById(themeId, theme->rawAttrs_);
216             for (size_t i = 0; i < sizeof(PATTERN_MAP) / sizeof(PATTERN_MAP[0]); i++) {
217                 ResourceThemeStyle::RawAttrMap attrMap;
218                 std::string patternTag = PATTERN_MAP[i];
219                 std::string patternName = std::string(OHFlag) + PATTERN_MAP[i];
220                 ret = manager->GetPatternByName(patternName.c_str(), attrMap);
221                 if (attrMap.empty()) {
222                     continue;
223                 }
224                 theme->patternAttrs_[patternTag] = attrMap;
225             }
226         }
227     }
228 
229     if (theme->patternAttrs_.empty() && theme->rawAttrs_.empty()) {
230         return nullptr;
231     }
232 
233     theme->ParseContent();
234     theme->patternAttrs_.clear();
235 
236     PreloadTheme(themeId, theme);
237     return theme;
238 }
239 
PreloadTheme(int32_t themeId,RefPtr<ResourceThemeStyle> theme)240 void ResourceAdapterImplV2::PreloadTheme(int32_t themeId, RefPtr<ResourceThemeStyle> theme)
241 {
242     auto container = Container::CurrentSafely();
243     CHECK_NULL_VOID(container);
244     auto manager = GetResourceManager();
245     CHECK_NULL_VOID(manager);
246     auto taskExecutor = GetTaskExecutor();
247     CHECK_NULL_VOID(taskExecutor);
248 
249     // post an asynchronous task to preload themes in PRELOAD_LIST
250     auto task = [themeId, manager, resourceThemeStyle = WeakPtr<ResourceThemeStyle>(theme),
251         weak = WeakClaim(this)]() -> void {
252         auto themeStyle = resourceThemeStyle.Upgrade();
253         CHECK_NULL_VOID(themeStyle);
254         auto adapter = weak.Upgrade();
255         CHECK_NULL_VOID(adapter);
256         for (size_t i = 0; i < sizeof(PRELOAD_LIST) / sizeof(PRELOAD_LIST[0]); ++i) {
257             std::string patternName = PRELOAD_LIST[i];
258             themeStyle->PushBackCheckThemeStyleVector(patternName);
259             auto style = adapter->GetPatternByName(patternName);
260             if (style) {
261                 ResValueWrapper value = { .type = ThemeConstantsType::PATTERN, .value = style };
262                 themeStyle->SetAttr(patternName, value);
263             }
264         }
265 
266         themeStyle->SetPromiseValue();
267     };
268 
269     // isolation of loading card themes
270     if (!container->IsFormRender()) {
271         taskExecutor->PostTask(task, TaskExecutor::TaskType::BACKGROUND, "ArkUILoadTheme");
272     }
273 }
274 
GetTaskExecutor()275 RefPtr<TaskExecutor> ResourceAdapterImplV2::GetTaskExecutor()
276 {
277     auto context = NG::PipelineContext::GetCurrentContextSafely();
278     CHECK_NULL_RETURN(context, nullptr);
279     return context->GetTaskExecutor();
280 }
281 
GetPatternByName(const std::string & patternName)282 RefPtr<ThemeStyle> ResourceAdapterImplV2::GetPatternByName(const std::string& patternName)
283 {
284     auto patternStyle = AceType::MakeRefPtr<ResourceThemeStyle>(AceType::Claim(this));
285     patternStyle->SetName(patternName);
286     constexpr char OHFlag[] = "ohos_"; // fit with resource/base/theme.json and pattern.json
287     auto manager = GetResourceManager();
288     if (manager) {
289         ResourceThemeStyle::RawAttrMap attrMap;
290         std::string patternTag = std::string(OHFlag) + patternName;
291         auto state = manager->GetPatternByName(patternTag.c_str(), attrMap);
292         if (state != Global::Resource::SUCCESS) {
293             TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get pattern by name error, name=%{public}s", patternTag.c_str());
294         } else if (attrMap.empty()) {
295             TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get pattern %{public}s empty!", patternTag.c_str());
296         }
297         patternStyle->rawAttrs_ = attrMap;
298         patternStyle->ParseContent();
299     }
300     return patternStyle;
301 }
302 
GetColor(uint32_t resId)303 Color ResourceAdapterImplV2::GetColor(uint32_t resId)
304 {
305     uint32_t result = 0;
306     auto manager = GetResourceManager();
307     CHECK_NULL_RETURN(manager, Color(result));
308     auto state = manager->GetColorById(resId, result);
309     if (state != Global::Resource::SUCCESS) {
310         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get color by id error, id=%{public}u", resId);
311         return ERROR_VALUE_COLOR;
312     }
313     return Color(result);
314 }
315 
GetColorByName(const std::string & resName)316 Color ResourceAdapterImplV2::GetColorByName(const std::string& resName)
317 {
318     uint32_t result = 0;
319     auto actualResName = GetActualResourceName(resName);
320     auto manager = GetResourceManager();
321     CHECK_NULL_RETURN(manager, Color(result));
322     auto state = manager->GetColorByName(actualResName.c_str(), result);
323     if (state != Global::Resource::SUCCESS) {
324         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get color by name error, name=%{public}s, errorCode=%{public}d",
325             resName.c_str(), state);
326     }
327     return Color(result);
328 }
329 
GetDimension(uint32_t resId)330 Dimension ResourceAdapterImplV2::GetDimension(uint32_t resId)
331 {
332     float dimensionFloat = 0.0f;
333 #ifdef NG_BUILD
334     std::string unit;
335     auto manager = GetResourceManager();
336     if (manager) {
337         auto state = manager->GetFloatById(resId, dimensionFloat, unit);
338         if (state != Global::Resource::SUCCESS) {
339             TAG_LOGW(AceLogTag::ACE_RESOURCE, "NG Get dimension by id error, id=%{public}u, errorCode=%{public}d",
340                 resId, state);
341         }
342     }
343     return Dimension(static_cast<double>(dimensionFloat), ParseDimensionUnit(unit));
344 #else
345     if (Container::IsCurrentUseNewPipeline()) {
346         std::string unit;
347         auto manager = GetResourceManager();
348         if (manager) {
349             auto state = manager->GetFloatById(resId, dimensionFloat, unit);
350             if (state != Global::Resource::SUCCESS) {
351                 TAG_LOGW(AceLogTag::ACE_RESOURCE, "NG: Get dimension by id error, id=%{public}u, errorCode=%{public}d",
352                     resId, state);
353             }
354         }
355         return Dimension(static_cast<double>(dimensionFloat), ParseDimensionUnit(unit));
356     }
357 
358     auto manager = GetResourceManager();
359     CHECK_NULL_RETURN(manager, Dimension(static_cast<double>(dimensionFloat)));
360     auto state = manager->GetFloatById(resId, dimensionFloat);
361     if (state != Global::Resource::SUCCESS) {
362         TAG_LOGW(
363             AceLogTag::ACE_RESOURCE, "Get dimension by id error, id=%{public}u, errorCode=%{public}d", resId, state);
364     }
365     return Dimension(static_cast<double>(dimensionFloat));
366 #endif
367 }
368 
GetDimensionByName(const std::string & resName)369 Dimension ResourceAdapterImplV2::GetDimensionByName(const std::string& resName)
370 {
371     float dimensionFloat = 0.0f;
372     auto actualResName = GetActualResourceName(resName);
373     auto manager = GetResourceManager();
374     CHECK_NULL_RETURN(manager, Dimension());
375     std::string unit;
376     auto state = manager->GetFloatByName(actualResName.c_str(), dimensionFloat, unit);
377     if (state != Global::Resource::SUCCESS) {
378         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get dimension by name error, resName=%{public}s, errorCode=%{public}d",
379             resName.c_str(), state);
380     }
381     return Dimension(static_cast<double>(dimensionFloat), ParseDimensionUnit(unit));
382 }
383 
GetString(uint32_t resId)384 std::string ResourceAdapterImplV2::GetString(uint32_t resId)
385 {
386     std::string strResult = "";
387     auto manager = GetResourceManager();
388     CHECK_NULL_RETURN(manager, strResult);
389     auto state = manager->GetStringById(resId, strResult);
390     if (state != Global::Resource::SUCCESS) {
391         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get string by id error, id=%{public}u, errorCode=%{public}d", resId, state);
392     }
393     return strResult;
394 }
395 
GetStringByName(const std::string & resName)396 std::string ResourceAdapterImplV2::GetStringByName(const std::string& resName)
397 {
398     std::string strResult = "";
399     auto actualResName = GetActualResourceName(resName);
400     auto manager = GetResourceManager();
401     CHECK_NULL_RETURN(manager, strResult);
402     auto state = manager->GetStringByName(actualResName.c_str(), strResult);
403     if (state != Global::Resource::SUCCESS) {
404         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get string by name error, resName=%{public}s, errorCode=%{public}d",
405             resName.c_str(), state);
406     }
407     return strResult;
408 }
409 
GetPluralString(uint32_t resId,int quantity)410 std::string ResourceAdapterImplV2::GetPluralString(uint32_t resId, int quantity)
411 {
412     std::string strResult = "";
413     auto manager = GetResourceManager();
414     CHECK_NULL_RETURN(manager, strResult);
415     auto state = manager->GetPluralStringById(resId, quantity, strResult);
416     if (state != Global::Resource::SUCCESS) {
417         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get plural string by id error, id=%{public}u, errorCode=%{public}d", resId,
418             state);
419     }
420     return strResult;
421 }
422 
GetPluralStringByName(const std::string & resName,int quantity)423 std::string ResourceAdapterImplV2::GetPluralStringByName(const std::string& resName, int quantity)
424 {
425     std::string strResult = "";
426     auto actualResName = GetActualResourceName(resName);
427     auto manager = GetResourceManager();
428     CHECK_NULL_RETURN(manager, strResult);
429     auto state = manager->GetPluralStringByName(actualResName.c_str(), quantity, strResult);
430     if (state != Global::Resource::SUCCESS) {
431         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get plural string by name error, resName=%{public}s, errorCode=%{public}d",
432             resName.c_str(), state);
433     }
434     return strResult;
435 }
436 
GetStringArray(uint32_t resId) const437 std::vector<std::string> ResourceAdapterImplV2::GetStringArray(uint32_t resId) const
438 {
439     std::vector<std::string> strResults;
440     auto manager = GetResourceManager();
441     CHECK_NULL_RETURN(manager, strResults);
442     auto state = manager->GetStringArrayById(resId, strResults);
443     if (state != Global::Resource::SUCCESS) {
444         TAG_LOGW(
445             AceLogTag::ACE_RESOURCE, "Get stringArray by id error, id=%{public}u, errorCode=%{public}d", resId, state);
446     }
447     return strResults;
448 }
449 
GetStringArrayByName(const std::string & resName) const450 std::vector<std::string> ResourceAdapterImplV2::GetStringArrayByName(const std::string& resName) const
451 {
452     std::vector<std::string> strResults;
453     auto actualResName = GetActualResourceName(resName);
454     auto manager = GetResourceManager();
455     CHECK_NULL_RETURN(manager, strResults);
456     auto state = manager->GetStringArrayByName(actualResName.c_str(), strResults);
457     if (state != Global::Resource::SUCCESS) {
458         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get stringArray by name error, resName=%{public}s, errorCode=%{public}d",
459             resName.c_str(), state);
460     }
461     return strResults;
462 }
463 
GetDouble(uint32_t resId)464 double ResourceAdapterImplV2::GetDouble(uint32_t resId)
465 {
466     float result = 0.0f;
467     auto manager = GetResourceManager();
468     CHECK_NULL_RETURN(manager, static_cast<double>(result));
469     auto state = manager->GetFloatById(resId, result);
470     if (state != Global::Resource::SUCCESS) {
471         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get double by id error, id=%{public}u, errorCode=%{public}d", resId, state);
472     }
473     return static_cast<double>(result);
474 }
475 
GetDoubleByName(const std::string & resName)476 double ResourceAdapterImplV2::GetDoubleByName(const std::string& resName)
477 {
478     float result = 0.0f;
479     auto actualResName = GetActualResourceName(resName);
480     auto manager = GetResourceManager();
481     CHECK_NULL_RETURN(manager, static_cast<double>(result));
482     auto state = manager->GetFloatByName(actualResName.c_str(), result);
483     if (state != Global::Resource::SUCCESS) {
484         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get double by name error, resName=%{public}s, errorCode=%{public}d",
485             resName.c_str(), state);
486     }
487     return static_cast<double>(result);
488 }
489 
GetInt(uint32_t resId)490 int32_t ResourceAdapterImplV2::GetInt(uint32_t resId)
491 {
492     int32_t result = 0;
493     auto manager = GetResourceManager();
494     CHECK_NULL_RETURN(manager, result);
495     auto state = manager->GetIntegerById(resId, result);
496     if (state != Global::Resource::SUCCESS) {
497         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get int by id error, id=%{public}u, errorCode=%{public}d", resId, state);
498     }
499     return result;
500 }
501 
GetIntByName(const std::string & resName)502 int32_t ResourceAdapterImplV2::GetIntByName(const std::string& resName)
503 {
504     int32_t result = 0;
505     auto actualResName = GetActualResourceName(resName);
506     auto manager = GetResourceManager();
507     CHECK_NULL_RETURN(manager, result);
508     auto state = manager->GetIntegerByName(actualResName.c_str(), result);
509     if (state != Global::Resource::SUCCESS) {
510         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get int by name error, resName=%{public}s, errorCode=%{public}d",
511             resName.c_str(), state);
512     }
513     return result;
514 }
515 
GetIntArray(uint32_t resId) const516 std::vector<uint32_t> ResourceAdapterImplV2::GetIntArray(uint32_t resId) const
517 {
518     std::vector<int> intVectorResult;
519     {
520         auto manager = GetResourceManager();
521         if (manager) {
522             auto state = manager->GetIntArrayById(resId, intVectorResult);
523             if (state != Global::Resource::SUCCESS) {
524                 TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get intArray by id error, id=%{public}u, errorCode=%{public}d",
525                     resId, state);
526             }
527         }
528     }
529 
530     std::vector<uint32_t> result;
531     std::transform(
532         intVectorResult.begin(), intVectorResult.end(), result.begin(), [](int x) { return static_cast<uint32_t>(x); });
533     return result;
534 }
535 
GetIntArrayByName(const std::string & resName) const536 std::vector<uint32_t> ResourceAdapterImplV2::GetIntArrayByName(const std::string& resName) const
537 {
538     std::vector<int> intVectorResult;
539     auto actualResName = GetActualResourceName(resName);
540     auto manager = GetResourceManager();
541     CHECK_NULL_RETURN(manager, {});
542     auto state = manager->GetIntArrayByName(actualResName.c_str(), intVectorResult);
543     if (state != Global::Resource::SUCCESS) {
544         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get intArray by name error, resName=%{public}s, errorCode=%{public}d",
545             resName.c_str(), state);
546     }
547 
548     std::vector<uint32_t> result;
549     std::transform(
550         intVectorResult.begin(), intVectorResult.end(), result.begin(), [](int x) { return static_cast<uint32_t>(x); });
551     return result;
552 }
553 
GetBoolean(uint32_t resId) const554 bool ResourceAdapterImplV2::GetBoolean(uint32_t resId) const
555 {
556     bool result = false;
557     auto manager = GetResourceManager();
558     CHECK_NULL_RETURN(manager, result);
559     auto state = manager->GetBooleanById(resId, result);
560     if (state != Global::Resource::SUCCESS) {
561         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get boolean by id error, id=%{public}u, errorCode=%{public}d", resId, state);
562     }
563     return result;
564 }
565 
GetBooleanByName(const std::string & resName) const566 bool ResourceAdapterImplV2::GetBooleanByName(const std::string& resName) const
567 {
568     bool result = false;
569     auto actualResName = GetActualResourceName(resName);
570     auto manager = GetResourceManager();
571     CHECK_NULL_RETURN(manager, result);
572     auto state = manager->GetBooleanByName(actualResName.c_str(), result);
573     if (state != Global::Resource::SUCCESS) {
574         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get boolean by name error, resName=%{public}s, errorCode=%{public}d",
575             resName.c_str(), state);
576     }
577     return result;
578 }
579 
GetPixelMap(uint32_t resId)580 std::shared_ptr<Media::PixelMap> ResourceAdapterImplV2::GetPixelMap(uint32_t resId)
581 {
582     auto manager = GetResourceManager();
583 
584     CHECK_NULL_RETURN(manager, nullptr);
585     Napi::DrawableDescriptor::DrawableType drawableType;
586     Global::Resource::RState state;
587     auto drawableDescriptor =
588         Napi::DrawableDescriptorFactory::Create(resId, sysResourceManager_, state, drawableType, 0);
589     if (state != Global::Resource::SUCCESS) {
590         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Failed to Create drawableDescriptor by %{public}d, errorCode=%{public}d",
591             resId, state);
592         return nullptr;
593     }
594     CHECK_NULL_RETURN(drawableDescriptor, nullptr);
595     return drawableDescriptor->GetPixelMap();
596 }
597 
GetMediaPath(uint32_t resId)598 std::string ResourceAdapterImplV2::GetMediaPath(uint32_t resId)
599 {
600     std::string mediaPath = "";
601     auto manager = GetResourceManager();
602     CHECK_NULL_RETURN(manager, "");
603     auto state = manager->GetMediaById(resId, mediaPath);
604     if (state != Global::Resource::SUCCESS) {
605         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get media by id error, id=%{public}u, errorCode=%{public}u", resId, state);
606         return "";
607     }
608     if (SystemProperties::GetUnZipHap()) {
609         return "file:///" + mediaPath;
610     }
611     auto pos = mediaPath.find_last_of('.');
612     if (pos == std::string::npos) {
613         return "";
614     }
615     return "resource:///" + std::to_string(resId) + mediaPath.substr(pos);
616 }
617 
GetMediaPathByName(const std::string & resName)618 std::string ResourceAdapterImplV2::GetMediaPathByName(const std::string& resName)
619 {
620     std::string mediaPath = "";
621     auto actualResName = GetActualResourceName(resName);
622     {
623         auto manager = GetResourceManager();
624         CHECK_NULL_RETURN(manager, "");
625         auto state = manager->GetMediaByName(actualResName.c_str(), mediaPath);
626         if (state != Global::Resource::SUCCESS) {
627             TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get media path by name error, resName=%{public}s, errorCode=%{public}u",
628                 resName.c_str(), state);
629             return "";
630         }
631     }
632     if (SystemProperties::GetUnZipHap()) {
633         return "file:///" + mediaPath;
634     }
635     auto pos = mediaPath.find_last_of('.');
636     if (pos == std::string::npos) {
637         return "";
638     }
639     return "resource:///" + actualResName + mediaPath.substr(pos);
640 }
641 
GetRawfile(const std::string & fileName)642 std::string ResourceAdapterImplV2::GetRawfile(const std::string& fileName)
643 {
644     // as web component not support resource format: resource://RAWFILE/{fileName}, use old format
645     if (!packagePathStr_.empty()) {
646         std::string outPath;
647         auto manager = GetResourceManager();
648         CHECK_NULL_RETURN(manager, "");
649         // Adapt to the input like: "file:///index.html?a=1", before the new solution comes.
650         auto it = std::find_if(fileName.begin(), fileName.end(), [](char c) { return (c == '#') || (c == '?'); });
651         std::string params;
652         std::string newFileName = fileName;
653         if (it != fileName.end()) {
654             newFileName = std::string(fileName.begin(), it);
655             params = std::string(it, fileName.end());
656         }
657         auto state = manager->GetRawFilePathByName(newFileName, outPath);
658         if (state != Global::Resource::SUCCESS) {
659             TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get rawFile error, filename:%{public}s, error:%{public}u",
660                 fileName.c_str(), state);
661             return "";
662         }
663         return "file:///" + outPath + params;
664     }
665     std::regex regex(RESOURCE_TOKEN_PATTERN);
666     std::smatch results;
667     std::string newFIleName = fileName;
668     if (std::regex_match(fileName, results, regex)) {
669         newFIleName = results[1];
670     }
671     return "resource://RAWFILE/" + newFIleName;
672 }
673 
GetRawFileData(const std::string & rawFile,size_t & len,std::unique_ptr<uint8_t[]> & dest)674 bool ResourceAdapterImplV2::GetRawFileData(const std::string& rawFile, size_t& len, std::unique_ptr<uint8_t[]>& dest)
675 {
676     auto manager = GetResourceManager();
677     CHECK_NULL_RETURN(manager, false);
678     auto state = manager->GetRawFileFromHap(rawFile, len, dest);
679     if (state != Global::Resource::SUCCESS || !dest) {
680         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get rawFile from hap error, raw filename:%{public}s, error:%{public}u",
681             rawFile.c_str(), state);
682         return false;
683     }
684     return true;
685 }
686 
GetRawFileData(const std::string & rawFile,size_t & len,std::unique_ptr<uint8_t[]> & dest,const std::string & bundleName,const std::string & moduleName)687 bool ResourceAdapterImplV2::GetRawFileData(const std::string& rawFile, size_t& len, std::unique_ptr<uint8_t[]>& dest,
688     const std::string& bundleName, const std::string& moduleName)
689 {
690     auto manager = GetResourceManager();
691     CHECK_NULL_RETURN(manager, false);
692     auto state = manager->GetRawFileFromHap(rawFile, len, dest);
693     if (state != Global::Resource::SUCCESS || !dest) {
694         TAG_LOGW(AceLogTag::ACE_RESOURCE,
695             "Get rawFile from hap error, raw filename:%{public}s, bundleName:%{public}s, moduleName:%{public}s, "
696             "error:%{public}u",
697             rawFile.c_str(), bundleName.c_str(), moduleName.c_str(), state);
698         return false;
699     }
700     return true;
701 }
702 
GetMediaData(uint32_t resId,size_t & len,std::unique_ptr<uint8_t[]> & dest)703 bool ResourceAdapterImplV2::GetMediaData(uint32_t resId, size_t& len, std::unique_ptr<uint8_t[]>& dest)
704 {
705     auto manager = GetResourceManager();
706     CHECK_NULL_RETURN(manager, false);
707     auto state = manager->GetMediaDataById(resId, len, dest);
708     if (state != Global::Resource::SUCCESS) {
709         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get media data by id error, id:%{public}u, error:%{public}u", resId, state);
710         return false;
711     }
712     return true;
713 }
714 
GetMediaData(uint32_t resId,size_t & len,std::unique_ptr<uint8_t[]> & dest,const std::string & bundleName,const std::string & moduleName)715 bool ResourceAdapterImplV2::GetMediaData(uint32_t resId, size_t& len, std::unique_ptr<uint8_t[]>& dest,
716     const std::string& bundleName, const std::string& moduleName)
717 {
718     auto manager = GetResourceManager();
719     CHECK_NULL_RETURN(manager, false);
720     auto state = manager->GetMediaDataById(resId, len, dest);
721     if (state != Global::Resource::SUCCESS) {
722         TAG_LOGW(AceLogTag::ACE_RESOURCE,
723             "Get media data by id error, id:%{public}u, bundleName:%{public}s, moduleName:%{public}s, error:%{public}u",
724             resId, bundleName.c_str(), moduleName.c_str(), state);
725         return false;
726     }
727     return true;
728 }
729 
GetMediaData(const std::string & resName,size_t & len,std::unique_ptr<uint8_t[]> & dest)730 bool ResourceAdapterImplV2::GetMediaData(const std::string& resName, size_t& len, std::unique_ptr<uint8_t[]>& dest)
731 {
732     auto manager = GetResourceManager();
733     CHECK_NULL_RETURN(manager, false);
734     auto state = manager->GetMediaDataByName(resName.c_str(), len, dest);
735     if (state != Global::Resource::SUCCESS) {
736         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get media data by name error, resName:%{public}s, error:%{public}u",
737             resName.c_str(), state);
738         return false;
739     }
740     return true;
741 }
742 
GetMediaData(const std::string & resName,size_t & len,std::unique_ptr<uint8_t[]> & dest,const std::string & bundleName,const std::string & moduleName)743 bool ResourceAdapterImplV2::GetMediaData(const std::string& resName, size_t& len, std::unique_ptr<uint8_t[]>& dest,
744     const std::string& bundleName, const std::string& moduleName)
745 {
746     auto manager = GetResourceManager();
747     CHECK_NULL_RETURN(manager, false);
748     auto state = manager->GetMediaDataByName(resName.c_str(), len, dest);
749     if (state != Global::Resource::SUCCESS) {
750         TAG_LOGW(AceLogTag::ACE_RESOURCE,
751             "Get media data by name error, resName:%{public}s, bundleName:%{public}s, moduleName:%{public}s, "
752             "error:%{public}u",
753             resName.c_str(), bundleName.c_str(), moduleName.c_str(), state);
754         return false;
755     }
756     return true;
757 }
758 
GetRawFileDescription(const std::string & rawfileName,RawfileDescription & rawfileDescription) const759 bool ResourceAdapterImplV2::GetRawFileDescription(
760     const std::string& rawfileName, RawfileDescription& rawfileDescription) const
761 {
762     OHOS::Global::Resource::ResourceManager::RawFileDescriptor descriptor;
763     auto manager = GetResourceManager();
764     CHECK_NULL_RETURN(manager, false);
765     auto state = manager->GetRawFileDescriptorFromHap(rawfileName, descriptor);
766     if (state != Global::Resource::SUCCESS) {
767         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get raw file description error, rawFileName:%{public}s, error:%{public}u",
768             rawfileName.c_str(), state);
769         return false;
770     }
771     rawfileDescription.fd = descriptor.fd;
772     rawfileDescription.offset = descriptor.offset;
773     rawfileDescription.length = descriptor.length;
774     return true;
775 }
776 
CloseRawFileDescription(const std::string & rawfileName) const777 bool ResourceAdapterImplV2::CloseRawFileDescription(const std::string &rawfileName) const
778 {
779     auto manager = GetResourceManager();
780     CHECK_NULL_RETURN(manager, false);
781     auto state = manager->CloseRawFileDescriptor(rawfileName);
782     if (state != Global::Resource::SUCCESS) {
783         LOGE("Close RawFile Description error, error:%{public}u", state);
784         return false;
785     }
786     return true;
787 }
788 
GetMediaById(const int32_t & resId,std::string & mediaPath) const789 bool ResourceAdapterImplV2::GetMediaById(const int32_t& resId, std::string& mediaPath) const
790 {
791     auto manager = GetResourceManager();
792     CHECK_NULL_RETURN(manager, false);
793     auto state = manager->GetMediaById(resId, mediaPath);
794     if (state != Global::Resource::SUCCESS) {
795         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get media by id error, resId:%{public}d, error:%{public}u", resId, state);
796         return false;
797     }
798     return true;
799 }
800 
GetActualResourceName(const std::string & resName) const801 std::string ResourceAdapterImplV2::GetActualResourceName(const std::string& resName) const
802 {
803     auto index = resName.find_last_of('.');
804     if (index == std::string::npos) {
805         return {};
806     }
807     return resName.substr(index + 1, resName.length() - index - 1);
808 }
809 
GetResourceLimitKeys() const810 uint32_t ResourceAdapterImplV2::GetResourceLimitKeys() const
811 {
812     auto manager = GetResourceManager();
813     CHECK_NULL_RETURN(manager, 0);
814     return manager->GetResourceLimitKeys();
815 }
816 
GetSymbolByName(const char * resName) const817 uint32_t ResourceAdapterImplV2::GetSymbolByName(const char* resName) const
818 {
819     uint32_t result = 0;
820     auto actualResName = GetActualResourceName(resName);
821     auto manager = GetResourceManager();
822     CHECK_NULL_RETURN(manager, -1);
823     auto state = manager->GetSymbolByName(actualResName.c_str(), result);
824     if (state != Global::Resource::SUCCESS) {
825         TAG_LOGW(AceLogTag::ACE_RESOURCE, "Get symbol by name error, name=%{public}s, errorCode=%{public}d",
826             resName, state);
827     }
828     return result;
829 }
830 
GetSymbolById(uint32_t resId) const831 uint32_t ResourceAdapterImplV2::GetSymbolById(uint32_t resId) const
832 {
833     uint32_t result = 0;
834     auto manager = GetResourceManager();
835     CHECK_NULL_RETURN(manager, -1);
836     manager->GetSymbolById(resId, result);
837     return result;
838 }
839 
UpdateColorMode(ColorMode colorMode)840 void ResourceAdapterImplV2::UpdateColorMode(ColorMode colorMode)
841 {
842     RefPtr<Container> container = Container::Current();
843     CHECK_NULL_VOID(container);
844     auto aceContainer = AceType::DynamicCast<Platform::AceContainer>(container);
845     CHECK_NULL_VOID(aceContainer);
846 
847     auto resConfig = aceContainer->GetResourceConfiguration();
848     resConfig.SetColorMode(colorMode);
849     UpdateConfig(resConfig, false);
850 }
851 
GetResourceColorMode() const852 ColorMode ResourceAdapterImplV2::GetResourceColorMode() const
853 {
854     CHECK_NULL_RETURN(resConfig_, ColorMode::LIGHT);
855     if (resConfig_->GetColorMode() == OHOS::Global::Resource::ColorMode::DARK && !resConfig_->GetAppColorMode() &&
856         !appHasDarkRes_) {
857         return ColorMode::LIGHT;
858     }
859     return resConfig_->GetColorMode() == OHOS::Global::Resource::ColorMode::DARK ? ColorMode::DARK : ColorMode::LIGHT;
860 }
861 
SetAppHasDarkRes(bool hasDarkRes)862 void ResourceAdapterImplV2::SetAppHasDarkRes(bool hasDarkRes)
863 {
864     appHasDarkRes_ = hasDarkRes;
865 }
866 
GetOverrideResourceAdapter(const ResourceConfiguration & config,const ConfigurationChange & configurationChange)867 RefPtr<ResourceAdapter> ResourceAdapterImplV2::GetOverrideResourceAdapter(
868     const ResourceConfiguration& config, const ConfigurationChange& configurationChange)
869 {
870     CHECK_NULL_RETURN(sysResourceManager_, nullptr);
871     std::shared_ptr<Global::Resource::ResConfig> overrideResConfig(Global::Resource::CreateResConfig());
872     sysResourceManager_->GetOverrideResConfig(*overrideResConfig);
873     if (configurationChange.colorModeUpdate) {
874         overrideResConfig->SetColorMode(ConvertColorModeToGlobal(config.GetColorMode()));
875     }
876     if (configurationChange.directionUpdate) {
877         overrideResConfig->SetDirection(ConvertDirectionToGlobal(config.GetOrientation()));
878     }
879     if (configurationChange.dpiUpdate) {
880         overrideResConfig->SetScreenDensity(config.GetDensity());
881     }
882     auto overrideResMgr = sysResourceManager_->GetOverrideResourceManager(overrideResConfig);
883     return AceType::MakeRefPtr<ResourceAdapterImplV2>(overrideResMgr);
884 }
885 } // namespace OHOS::Ace
886