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