1 /*
2 * Copyright (c) 2021-2022 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 "hap_resource.h"
17
18 #include <algorithm>
19 #include <climits>
20 #include <cstdlib>
21 #include <fstream>
22 #include "utils/utils.h"
23 #include <set>
24 #ifdef __WINNT__
25 #include <shlwapi.h>
26 #include <windows.h>
27 #endif
28
29 #ifdef __LINUX__
30 #include <cstring>
31 #endif
32
33 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
34 #include "hitrace_meter.h"
35 #include "file_mapper.h"
36 #include "extractor.h"
37 #endif
38 #include "hap_parser.h"
39 #include "hilog_wrapper.h"
40 #include "utils/errors.h"
41
42 namespace OHOS {
43 namespace Global {
44 namespace Resource {
ValueUnderQualifierDir(const std::shared_ptr<ResKey> & resKey,const std::shared_ptr<IdItem> & idItem,const std::pair<std::string,std::string> & resPath,bool isOverlay,bool systemResource)45 HapResource::ValueUnderQualifierDir::ValueUnderQualifierDir(const std::shared_ptr<ResKey> &resKey,
46 const std::shared_ptr<IdItem> &idItem, const std::pair<std::string, std::string> &resPath, bool isOverlay,
47 bool systemResource) : keyParams_(resKey->keyParams_), resConfig_(resKey->resConfig_), idItem_(idItem),
48 indexPath_(resPath.first), resourcePath_(resPath.second), isOverlay_(isOverlay), isSystemResource_(systemResource)
49 {}
50
~ValueUnderQualifierDir()51 HapResource::ValueUnderQualifierDir::~ValueUnderQualifierDir()
52 {}
53
54 // IdValues
~IdValues()55 HapResource::IdValues::~IdValues()
56 {}
57
58 // HapResource
HapResource(const std::string path,time_t lastModTime,std::shared_ptr<ResDesc> resDes,bool isSystem,bool isOverlay)59 HapResource::HapResource(const std::string path, time_t lastModTime, std::shared_ptr<ResDesc> resDes,
60 bool isSystem, bool isOverlay) : indexPath_(path), lastModTime_(lastModTime), resDesc_(resDes),
61 isSystem_(isSystem), isOverlay_(isOverlay), isThemeSystemResEnable_(false)
62 {}
63
~HapResource()64 HapResource::~HapResource()
65 {
66 lastModTime_ = 0;
67 }
68
Load(const char * path,std::shared_ptr<ResConfigImpl> & defaultConfig,bool isSystem,bool isOverlay,const uint32_t & selectedTypes)69 const std::shared_ptr<HapResource> HapResource::Load(const char *path,
70 std::shared_ptr<ResConfigImpl> &defaultConfig, bool isSystem, bool isOverlay, const uint32_t &selectedTypes)
71 {
72 if (Utils::ContainsTail(path, Utils::tailSet)) {
73 return LoadFromHap(path, defaultConfig, isSystem, isOverlay, selectedTypes);
74 } else {
75 return LoadFromIndex(path, defaultConfig, isSystem, isOverlay, selectedTypes);
76 }
77 }
78
LoadFromIndex(const char * path,std::shared_ptr<ResConfigImpl> & defaultConfig,bool isSystem,bool isOverlay,const uint32_t & selectedTypes)79 const std::shared_ptr<HapResource> HapResource::LoadFromIndex(const char *path,
80 std::shared_ptr<ResConfigImpl> &defaultConfig, bool isSystem, bool isOverlay, const uint32_t &selectedTypes)
81 {
82 char outPath[PATH_MAX + 1] = {0};
83 Utils::CanonicalizePath(path, outPath, PATH_MAX);
84 std::ifstream inFile(outPath, std::ios::binary | std::ios::in);
85 if (!inFile.good()) {
86 return nullptr;
87 }
88 inFile.seekg(0, std::ios::end);
89 int bufLen = inFile.tellg();
90 if (bufLen <= 0) {
91 RESMGR_HILOGE(RESMGR_TAG, "file size is zero");
92 inFile.close();
93 return nullptr;
94 }
95 void *buf = malloc(bufLen);
96 if (buf == nullptr) {
97 RESMGR_HILOGE(RESMGR_TAG, "Error allocating memory");
98 inFile.close();
99 return nullptr;
100 }
101 inFile.seekg(0, std::ios::beg);
102 inFile.read(static_cast<char *>(buf), bufLen);
103 inFile.close();
104
105 RESMGR_HILOGD(RESMGR_TAG, "extract success, bufLen:%d", bufLen);
106
107 std::shared_ptr<ResDesc> resDesc = std::make_shared<ResDesc>();
108 if (resDesc == nullptr) {
109 RESMGR_HILOGE(RESMGR_TAG, "new ResDesc failed when LoadFromIndex");
110 free(buf);
111 return nullptr;
112 }
113 int32_t out = HapParser::ParseResHex(static_cast<char *>(buf), bufLen, *resDesc, defaultConfig, selectedTypes);
114 if (out != OK) {
115 free(buf);
116 RESMGR_HILOGE(RESMGR_TAG, "ParseResHex failed! retcode:%d", out);
117 return nullptr;
118 }
119 free(buf);
120
121 std::shared_ptr<HapResource> pResource = std::make_shared<HapResource>(std::string(path),
122 0, resDesc, isSystem, isOverlay);
123 if (pResource == nullptr) {
124 RESMGR_HILOGE(RESMGR_TAG, "new HapResource failed when LoadFromIndex");
125 return nullptr;
126 }
127 if (!pResource->Init(defaultConfig)) {
128 return nullptr;
129 }
130 return pResource;
131 }
132
133 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
GetIndexFilePath(std::shared_ptr<AbilityBase::Extractor> & extractor)134 std::string GetIndexFilePath(std::shared_ptr<AbilityBase::Extractor> &extractor)
135 {
136 std::string mName = HapParser::ParseModuleName(extractor);
137 std::string indexFilePath = std::string("assets/");
138 indexFilePath.append(mName);
139 indexFilePath.append("/resources.index");
140 return indexFilePath;
141 }
142 #endif
143
GetIndexData(const char * path,std::unique_ptr<uint8_t[]> & tmpBuf,size_t & len)144 bool GetIndexData(const char *path, std::unique_ptr<uint8_t[]> &tmpBuf, size_t &len)
145 {
146 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
147 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
148 bool isNewExtractor = false;
149 std::shared_ptr<AbilityBase::Extractor> extractor = AbilityBase::ExtractorUtil::GetExtractor(path, isNewExtractor);
150 if (extractor == nullptr) {
151 return false;
152 }
153 std::string indexFilePath;
154 if (extractor->IsStageModel()) {
155 indexFilePath = "resources.index";
156 } else {
157 indexFilePath = GetIndexFilePath(extractor);
158 }
159 bool ret = extractor->ExtractToBufByName(indexFilePath, tmpBuf, len);
160 if (!ret) {
161 RESMGR_HILOGE(RESMGR_TAG, "failed to get buf data indexFilePath, %{public}s", indexFilePath.c_str());
162 return false;
163 }
164 #endif
165 return true;
166 }
167
LoadFromHap(const char * path,std::shared_ptr<ResConfigImpl> & defaultConfig,bool isSystem,bool isOverlay,const uint32_t & selectedTypes)168 const std::shared_ptr<HapResource> HapResource::LoadFromHap(const char *path,
169 std::shared_ptr<ResConfigImpl> &defaultConfig, bool isSystem, bool isOverlay, const uint32_t &selectedTypes)
170 {
171 std::unique_ptr<uint8_t[]> tmpBuf;
172 size_t tmpLen = 0;
173 bool ret = GetIndexData(path, tmpBuf, tmpLen);
174 if (!ret) {
175 RESMGR_HILOGE(RESMGR_TAG, "read Index from file failed path, %{public}s", path);
176 return nullptr;
177 }
178 std::shared_ptr<ResDesc> resDesc = std::make_shared<ResDesc>();
179 if (resDesc == nullptr) {
180 RESMGR_HILOGE(RESMGR_TAG, "new ResDesc failed when LoadFromHap");
181 return nullptr;
182 }
183 int32_t out = HapParser::ParseResHex(
184 reinterpret_cast<char *>(tmpBuf.get()), tmpLen, *resDesc, defaultConfig, selectedTypes);
185 if (out != OK) {
186 RESMGR_HILOGE(RESMGR_TAG, "ParseResHex failed! retcode:%d", out);
187 return nullptr;
188 }
189
190 auto pResource = std::make_shared<HapResource>(path, 0, resDesc, isSystem, isOverlay);
191 if (pResource == nullptr) {
192 return nullptr;
193 }
194
195 if (!pResource->Init(defaultConfig)) {
196 return nullptr;
197 }
198 return pResource;
199 }
200
LoadOverlays(const std::string & path,const std::vector<std::string> & overlayPaths,std::shared_ptr<ResConfigImpl> & defaultConfig,bool isSystem)201 const std::unordered_map<std::string, std::shared_ptr<HapResource>> HapResource::LoadOverlays(const std::string &path,
202 const std::vector<std::string> &overlayPaths, std::shared_ptr<ResConfigImpl> &defaultConfig, bool isSystem)
203 {
204 std::unordered_map<std::string, std::shared_ptr<HapResource>> result;
205 do {
206 const std::shared_ptr<HapResource> targetResource = Load(path.c_str(), defaultConfig, isSystem);
207 if (targetResource == nullptr) {
208 RESMGR_HILOGE(RESMGR_TAG, "load target failed");
209 break;
210 }
211 result[path] = targetResource;
212 bool success = true;
213 std::unordered_map<std::string, std::unordered_map<ResType, uint32_t>> mapping =
214 targetResource->BuildNameTypeIdMapping();
215 for (auto iter = overlayPaths.begin(); iter != overlayPaths.end(); iter++) {
216 // load overlay hap, the isOverlay flag set true.
217 const std::shared_ptr<HapResource> overlayResource = Load(iter->c_str(), defaultConfig, isSystem, true);
218 if (overlayResource == nullptr) {
219 success = false;
220 break;
221 }
222 result[*iter] = overlayResource;
223 }
224
225 if (!success) {
226 RESMGR_HILOGE(RESMGR_TAG, "load overlay failed");
227 break;
228 }
229
230 for (auto iter = result.begin(); iter != result.end(); iter++) {
231 auto index = iter->first.find(path);
232 if (index == std::string::npos) {
233 iter->second->UpdateOverlayInfo(mapping);
234 }
235 }
236 return result;
237 } while (false);
238
239 result.clear();
240 return std::unordered_map<std::string, std::shared_ptr<HapResource>>();
241 }
242
BuildNameTypeIdMapping() const243 std::unordered_map<std::string, std::unordered_map<ResType, uint32_t>> HapResource::BuildNameTypeIdMapping() const
244 {
245 std::unordered_map<std::string, std::unordered_map<ResType, uint32_t>> result;
246 for (auto iter = idValuesMap_.begin(); iter != idValuesMap_.end(); iter++) {
247 const std::vector<std::shared_ptr<ValueUnderQualifierDir>> &limitPaths = iter->second->GetLimitPathsConst();
248 if (limitPaths.size() > 0) {
249 std::shared_ptr<ValueUnderQualifierDir> value = limitPaths[0];
250 result[value->idItem_->name_][value->idItem_->resType_] = value->idItem_->id_;
251 }
252 }
253 return result;
254 }
255
UpdateOverlayInfo(std::unordered_map<std::string,std::unordered_map<ResType,uint32_t>> & nameTypeId)256 void HapResource::UpdateOverlayInfo(std::unordered_map<std::string, std::unordered_map<ResType, uint32_t>> &nameTypeId)
257 {
258 std::map<uint32_t, std::shared_ptr<IdValues>> newIdValuesMap;
259 for (auto iter = idValuesMap_.begin(); iter != idValuesMap_.end(); iter++) {
260 const std::vector<std::shared_ptr<ValueUnderQualifierDir>> &limitPaths = iter->second->GetLimitPathsConst();
261 if (limitPaths.size() > 0) {
262 std::shared_ptr<ValueUnderQualifierDir> value = limitPaths[0];
263 std::string name = value->idItem_->name_;
264 ResType type = value->idItem_->resType_;
265 if (nameTypeId.find(name) == nameTypeId.end()) {
266 continue;
267 }
268 auto &typeId = nameTypeId[name];
269 if (typeId.find(type) == typeId.end()) {
270 continue;
271 }
272 uint32_t newId = typeId[type];
273 for_each(limitPaths.begin(), limitPaths.end(), [&](auto &item) {
274 item->idItem_->id_ = newId;
275 });
276 newIdValuesMap[newId] = iter->second;
277 }
278 }
279 idValuesMap_.swap(newIdValuesMap);
280 }
281
Init(std::shared_ptr<ResConfigImpl> & defaultConfig)282 bool HapResource::Init(std::shared_ptr<ResConfigImpl> &defaultConfig)
283 {
284 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
285 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
286 #endif
287 #ifdef __WINNT__
288 char separator = '\\';
289 #else
290 char separator = '/';
291 #endif
292 auto index = indexPath_.rfind(separator);
293 if (index == std::string::npos) {
294 RESMGR_HILOGE(RESMGR_TAG, "index path format error, %s", indexPath_.c_str());
295 return false;
296 }
297 #if defined(__IDE_PREVIEW__) || defined(__ARKUI_CROSS__)
298 resourcePath_ = indexPath_.substr(0, index + 1);
299 #else
300 if (index < 1) {
301 return false;
302 }
303 index = indexPath_.rfind(separator, index - 1);
304 if (index == std::string::npos) {
305 RESMGR_HILOGE(RESMGR_TAG, "index path format error, %s", indexPath_.c_str());
306 return false;
307 }
308 resourcePath_ = indexPath_.substr(0, index + 1);
309 #endif
310 for (int i = 0; i < ResType::MAX_RES_TYPE; ++i) {
311 auto mptr = std::make_shared<std::map<std::string, std::shared_ptr<IdValues>>>();
312 idValuesNameMap_.push_back(mptr);
313 }
314 return InitIdList(defaultConfig);
315 }
316
InitMap(const std::shared_ptr<ResKey> & resKey,const std::pair<std::string,std::string> & resPath,std::shared_ptr<ResConfigImpl> & defaultConfig)317 bool HapResource::InitMap(const std::shared_ptr<ResKey> &resKey, const std::pair<std::string, std::string> &resPath,
318 std::shared_ptr<ResConfigImpl> &defaultConfig)
319 {
320 for (size_t j = 0; j < resKey->resId_->idParams_.size(); ++j) {
321 std::shared_ptr<IdParam> idParam = resKey->resId_->idParams_[j];
322 uint32_t id = idParam->id_;
323 std::map<uint32_t, std::shared_ptr<IdValues>>::iterator iter = idValuesMap_.find(id);
324 if (iter == idValuesMap_.end()) {
325 auto idValues = std::make_shared<HapResource::IdValues>();
326 if (idValues == nullptr) {
327 RESMGR_HILOGE(RESMGR_TAG, "new IdValues failed in HapResource::InitIdList");
328 return false;
329 }
330 auto limitPath = std::make_shared<HapResource::ValueUnderQualifierDir>(resKey,
331 idParam->idItem_, resPath, isOverlay_, isSystem_);
332 if (limitPath == nullptr) {
333 RESMGR_HILOGE(RESMGR_TAG, "new ValueUnderQualifierDir failed in HapResource::InitIdList");
334 return false;
335 }
336 idValues->AddLimitPath(limitPath);
337 HapResource::IsAppDarkRes(limitPath, defaultConfig);
338 idValuesMap_.insert(std::make_pair(id, idValues));
339 std::string name = std::string(idParam->idItem_->name_);
340 idValuesNameMap_[idParam->idItem_->resType_]->insert(std::make_pair(name, idValues));
341 if (name == "system_color_change" && idParam->idItem_->value_ == "true") {
342 isThemeSystemResEnable_ = true;
343 }
344 } else {
345 std::shared_ptr<HapResource::IdValues> idValues = iter->second;
346 auto limitPath = std::make_shared<HapResource::ValueUnderQualifierDir>(resKey,
347 idParam->idItem_, resPath, isOverlay_, isSystem_);
348 if (limitPath == nullptr) {
349 RESMGR_HILOGE(RESMGR_TAG, "new ValueUnderQualifierDir failed in HapResource::InitIdList");
350 return false;
351 }
352 idValues->AddLimitPath(limitPath);
353 HapResource::IsAppDarkRes(limitPath, defaultConfig);
354 }
355 }
356 return true;
357 }
358
InitIdList(std::shared_ptr<ResConfigImpl> & defaultConfig)359 bool HapResource::InitIdList(std::shared_ptr<ResConfigImpl> &defaultConfig)
360 {
361 if (resDesc_ == nullptr) {
362 RESMGR_HILOGE(RESMGR_TAG, "resDesc_ is null ! InitIdList failed");
363 return false;
364 }
365 const auto resPath = std::make_pair(indexPath_, resourcePath_);
366 for (size_t i = 0; i < resDesc_->keys_.size(); i++) {
367 const auto resKey = resDesc_->keys_[i];
368 if (!HapResource::InitMap(resKey, resPath, defaultConfig)) {
369 return false;
370 }
371 }
372 return true;
373 };
374
GetIdValues(const uint32_t id) const375 const std::shared_ptr<HapResource::IdValues> HapResource::GetIdValues(const uint32_t id) const
376 {
377 if (idValuesMap_.empty()) {
378 RESMGR_HILOGE(RESMGR_TAG, "idValuesMap_ is empty");
379 return nullptr;
380 }
381 uint32_t uid = id;
382 std::map<uint32_t, std::shared_ptr<IdValues>>::const_iterator iter = idValuesMap_.find(uid);
383 if (iter == idValuesMap_.end()) {
384 return nullptr;
385 }
386
387 return iter->second;
388 }
389
GetIdValuesByName(const std::string name,const ResType resType) const390 const std::shared_ptr<HapResource::IdValues> HapResource::GetIdValuesByName(
391 const std::string name, const ResType resType) const
392 {
393 const auto map = idValuesNameMap_[resType];
394 std::map<std::string, std::shared_ptr<IdValues>>::const_iterator iter = map->find(name);
395 if (iter == map->end()) {
396 return nullptr;
397 }
398
399 return iter->second;
400 }
401
GetIdByName(const char * name,const ResType resType) const402 int HapResource::GetIdByName(const char *name, const ResType resType) const
403 {
404 if (name == nullptr) {
405 return -1;
406 }
407 const auto map = idValuesNameMap_[resType];
408 std::map<std::string, std::shared_ptr<IdValues>>::const_iterator iter = map->find(name);
409 if (iter == map->end()) {
410 return OBJ_NOT_FOUND;
411 }
412 const std::shared_ptr<IdValues> ids = iter->second;
413
414 if (ids->GetLimitPathsConst().size() == 0) {
415 RESMGR_HILOGE(RESMGR_TAG, "limitPaths empty");
416 return UNKNOWN_ERROR;
417 }
418
419 if (ids->GetLimitPathsConst()[0]->GetIdItem()->resType_ != resType) {
420 RESMGR_HILOGE(RESMGR_TAG, "ResType mismatch");
421 return UNKNOWN_ERROR;
422 }
423 return ids->GetLimitPathsConst()[0]->GetIdItem()->id_;
424 }
425
GetQualifiers() const426 const std::vector<std::string> HapResource::GetQualifiers() const
427 {
428 std::vector<std::string> result;
429 for (size_t i = 0; i < resDesc_->keys_.size(); i++) {
430 result.push_back(resDesc_->keys_[i]->ToString());
431 }
432 return result;
433 }
434
GetResourceLimitKeys() const435 uint32_t HapResource::GetResourceLimitKeys() const
436 {
437 uint32_t limitKeyValue = 0;
438 std::vector<bool> keyTypes(KeyType::KEY_TYPE_MAX - 1, false);
439 for (auto iter = idValuesMap_.begin(); iter != idValuesMap_.end(); iter++) {
440 if (iter->second == nullptr) {
441 continue;
442 }
443 const std::vector<std::shared_ptr<ValueUnderQualifierDir>> &limitPaths = iter->second->GetLimitPathsConst();
444 if (limitPaths.size() <= 0) {
445 continue;
446 }
447 limitKeyValue |= GetLimitPathsKeys(limitPaths, keyTypes);
448 }
449 return limitKeyValue;
450 }
451
GetLimitPathsKeys(const std::vector<std::shared_ptr<ValueUnderQualifierDir>> & limitPaths,std::vector<bool> & keyTypes) const452 uint32_t HapResource::GetLimitPathsKeys(const std::vector<std::shared_ptr<ValueUnderQualifierDir>> &limitPaths,
453 std::vector<bool> &keyTypes) const
454 {
455 uint32_t limitKeyValue = 0;
456 const uint32_t limitKeysBase = 0x00000001;
457 for_each(limitPaths.begin(), limitPaths.end(), [&](auto &item) {
458 const std::vector<std::shared_ptr<KeyParam>> &keyParams = item->keyParams_;
459 for_each(keyParams.begin(), keyParams.end(), [&](auto &keyParam) {
460 uint32_t typeValue = static_cast<uint32_t>(keyParam->type_);
461 if (keyParam->type_ < KeyType::KEY_TYPE_MAX && !keyTypes[typeValue]) {
462 keyTypes[typeValue] = true;
463 limitKeyValue |= limitKeysBase << typeValue;
464 }
465 });
466 });
467 return limitKeyValue;
468 }
469
GetLocales(std::set<std::string> & outValue,bool includeSystem)470 void HapResource::GetLocales(std::set<std::string> &outValue, bool includeSystem)
471 {
472 if ((!includeSystem && isSystem_) || (!isSystem_ && isOverlay_)) {
473 return;
474 }
475 for (size_t i = 0; i < resDesc_->keys_.size(); i++) {
476 GetKeyParamsLocales(resDesc_->keys_[i]->keyParams_, outValue);
477 }
478 }
479
GetKeyParamsLocales(const std::vector<std::shared_ptr<KeyParam>> keyParams,std::set<std::string> & outValue)480 void HapResource::GetKeyParamsLocales(const std::vector<std::shared_ptr<KeyParam>> keyParams,
481 std::set<std::string> &outValue)
482 {
483 std::string locale;
484 bool isLocale = false;
485 for (size_t i = 0; i < keyParams.size(); i++) {
486 KeyType keyType = keyParams[i]->type_;
487 if (keyType == KeyType::MCC || keyType == KeyType::MNC) {
488 continue;
489 }
490 if (keyType == KeyType::LANGUAGES) {
491 locale = keyParams[i]->GetStr();
492 isLocale = true;
493 continue;
494 }
495 if (keyType == KeyType::SCRIPT) {
496 locale.append("-");
497 locale.append(keyParams[i]->GetStr());
498 continue;
499 }
500 if (keyType == KeyType::REGION) {
501 locale.append("-");
502 locale.append(keyParams[i]->GetStr());
503 break;
504 }
505 break;
506 }
507 if (isLocale) {
508 outValue.emplace(locale);
509 }
510 }
IsThemeSystemResEnable() const511 bool HapResource::IsThemeSystemResEnable() const
512 {
513 return this->isThemeSystemResEnable_;
514 }
515
IsAppDarkRes(const std::shared_ptr<HapResource::ValueUnderQualifierDir> & limitPath,std::shared_ptr<ResConfigImpl> & defaultConfig)516 void HapResource::IsAppDarkRes(const std::shared_ptr<HapResource::ValueUnderQualifierDir> &limitPath,
517 std::shared_ptr<ResConfigImpl> &defaultConfig)
518 {
519 if (!defaultConfig) {
520 return;
521 }
522 if (isSystem_ || isOverlay_ || defaultConfig->GetAppDarkRes()) {
523 return;
524 }
525
526 if (limitPath->GetResConfig()->GetColorMode() == ColorMode::DARK) {
527 defaultConfig->SetAppDarkRes(true);
528 }
529 }
530 } // namespace Resource
531 } // namespace Global
532 } // namespace OHOS
533