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