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