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