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