• 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 "resource_manager_impl.h"
17 
18 #include <cmath>
19 #include <cstdarg>
20 #include <cstdlib>
21 #include <cstring>
22 #include <fcntl.h>
23 #include <regex>
24 #include <sstream>
25 #include <sys/types.h>
26 #include <unistd.h>
27 
28 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__)
29 #include "bytrace.h"
30 #endif
31 #include "hilog_wrapper.h"
32 #include "res_config.h"
33 #include "utils/common.h"
34 #include "utils/string_utils.h"
35 #include "utils/utils.h"
36 
37 namespace OHOS {
38 namespace Global {
39 namespace Resource {
40 // default logLevel
41 #ifdef CONFIG_HILOG
42 LogLevel g_logLevel = LOG_INFO;
43 #endif
44 
CreateResourceManager()45 ResourceManager *CreateResourceManager()
46 {
47     ResourceManagerImpl *impl = new (std::nothrow) ResourceManagerImpl;
48     if (impl == nullptr) {
49         HILOG_ERROR("new ResourceManagerImpl failed when CreateResourceManager");
50         return nullptr;
51     }
52     if (impl->Init()) {
53         return impl;
54     } else {
55         delete (impl);
56         return nullptr;
57     }
58 }
59 
~ResourceManager()60 ResourceManager::~ResourceManager()
61 {}
62 
ResourceManagerImpl()63 ResourceManagerImpl::ResourceManagerImpl() : hapManager_(nullptr)
64 {}
65 
Init()66 bool ResourceManagerImpl::Init()
67 {
68     ResConfigImpl *resConfig = new (std::nothrow) ResConfigImpl;
69     if (resConfig == nullptr) {
70         HILOG_ERROR("new ResConfigImpl failed when ResourceManagerImpl::Init");
71         return false;
72     }
73     hapManager_ = new (std::nothrow) HapManager(resConfig);
74     if (hapManager_ == nullptr) {
75         delete (resConfig);
76         HILOG_ERROR("new HapManager failed when ResourceManagerImpl::Init");
77         return false;
78     }
79     AddResource("/data/accounts/account_0/applications/ohos.global.systemres" \
80         "/ohos.global.systemres/assets/entry/resources.index");
81     return true;
82 }
83 
GetStringById(uint32_t id,std::string & outValue)84 RState ResourceManagerImpl::GetStringById(uint32_t id, std::string &outValue)
85 {
86     const IdItem *idItem = hapManager_->FindResourceById(id);
87     return GetString(idItem, outValue);
88 }
89 
GetStringByName(const char * name,std::string & outValue)90 RState ResourceManagerImpl::GetStringByName(const char *name, std::string &outValue)
91 {
92     const IdItem *idItem = hapManager_->FindResourceByName(name, ResType::STRING);
93     return GetString(idItem, outValue);
94 }
95 
GetStringFormatById(std::string & outValue,uint32_t id,...)96 RState ResourceManagerImpl::GetStringFormatById(std::string &outValue, uint32_t id, ...)
97 {
98     const IdItem *idItem = hapManager_->FindResourceById(id);
99     std::string temp;
100     RState rState = GetString(idItem, temp);
101     if (rState != SUCCESS) {
102         return rState;
103     }
104     va_list args;
105     va_start(args, id);
106     outValue = FormatString(temp.c_str(), args);
107     va_end(args);
108     return SUCCESS;
109 }
110 
GetStringFormatByName(std::string & outValue,const char * name,...)111 RState ResourceManagerImpl::GetStringFormatByName(std::string &outValue, const char *name, ...)
112 {
113     const IdItem *idItem = hapManager_->FindResourceByName(name, ResType::STRING);
114     std::string temp;
115     RState rState = GetString(idItem, temp);
116     if (rState != SUCCESS) {
117         return rState;
118     }
119     va_list args;
120     va_start(args, name);
121     outValue = FormatString(temp.c_str(), args);
122     va_end(args);
123     return SUCCESS;
124 }
125 
GetString(const IdItem * idItem,std::string & outValue)126 RState ResourceManagerImpl::GetString(const IdItem *idItem, std::string &outValue)
127 {
128     // not found or type invalid
129     if (idItem == nullptr || idItem->resType_ != ResType::STRING) {
130         return NOT_FOUND;
131     }
132     RState ret = ResolveReference(idItem->value_, outValue);
133     if (ret != SUCCESS) {
134         return ret;
135     }
136     return SUCCESS;
137 }
138 
GetStringArrayById(uint32_t id,std::vector<std::string> & outValue)139 RState ResourceManagerImpl::GetStringArrayById(uint32_t id, std::vector<std::string> &outValue)
140 {
141     const IdItem *idItem = hapManager_->FindResourceById(id);
142     return GetStringArray(idItem, outValue);
143 }
144 
GetStringArrayByName(const char * name,std::vector<std::string> & outValue)145 RState ResourceManagerImpl::GetStringArrayByName(const char *name, std::vector<std::string> &outValue)
146 {
147     const IdItem *idItem = hapManager_->FindResourceByName(name, ResType::STRINGARRAY);
148     return GetStringArray(idItem, outValue);
149 }
150 
GetStringArray(const IdItem * idItem,std::vector<std::string> & outValue)151 RState ResourceManagerImpl::GetStringArray(const IdItem *idItem, std::vector<std::string> &outValue)
152 {
153     // not found or type invalid
154     if (idItem == nullptr || idItem->resType_ != ResType::STRINGARRAY) {
155         return NOT_FOUND;
156     }
157     outValue.clear();
158 
159     for (size_t i = 0; i < idItem->values_.size(); ++i) {
160         std::string resolvedValue;
161         RState rrRet = ResolveReference(idItem->values_[i], resolvedValue);
162         if (rrRet != SUCCESS) {
163             HILOG_ERROR("ResolveReference failed, value:%s", idItem->values_[i].c_str());
164             return ERROR;
165         }
166         outValue.push_back(resolvedValue);
167     }
168     return SUCCESS;
169 }
170 
GetPatternById(uint32_t id,std::map<std::string,std::string> & outValue)171 RState ResourceManagerImpl::GetPatternById(uint32_t id, std::map<std::string, std::string> &outValue)
172 {
173     const IdItem *idItem = hapManager_->FindResourceById(id);
174     return GetPattern(idItem, outValue);
175 }
176 
GetPatternByName(const char * name,std::map<std::string,std::string> & outValue)177 RState ResourceManagerImpl::GetPatternByName(const char *name, std::map<std::string, std::string> &outValue)
178 {
179     const IdItem *idItem = hapManager_->FindResourceByName(name, ResType::PATTERN);
180     return GetPattern(idItem, outValue);
181 }
182 
GetPattern(const IdItem * idItem,std::map<std::string,std::string> & outValue)183 RState ResourceManagerImpl::GetPattern(const IdItem *idItem, std::map<std::string, std::string> &outValue)
184 {
185     // not found or type invalid
186     if (idItem == nullptr || idItem->resType_ != ResType::PATTERN) {
187         return NOT_FOUND;
188     }
189     return ResolveParentReference(idItem, outValue);
190 }
191 
GetPluralStringById(uint32_t id,int quantity,std::string & outValue)192 RState ResourceManagerImpl::GetPluralStringById(uint32_t id, int quantity, std::string &outValue)
193 {
194     const HapResource::ValueUnderQualifierDir *vuqd = hapManager_->FindQualifierValueById(id);
195     return GetPluralString(vuqd, quantity, outValue);
196 }
197 
GetPluralStringByName(const char * name,int quantity,std::string & outValue)198 RState ResourceManagerImpl::GetPluralStringByName(const char *name, int quantity, std::string &outValue)
199 {
200     const HapResource::ValueUnderQualifierDir *vuqd =
201         hapManager_->FindQualifierValueByName(name, ResType::PLURALS);
202     return GetPluralString(vuqd, quantity, outValue);
203 }
204 
GetPluralStringByIdFormat(std::string & outValue,uint32_t id,int quantity,...)205 RState ResourceManagerImpl::GetPluralStringByIdFormat(std::string &outValue, uint32_t id, int quantity, ...)
206 {
207     const HapResource::ValueUnderQualifierDir *vuqd = hapManager_->FindQualifierValueById(id);
208     std::string temp;
209     RState rState = GetPluralString(vuqd, quantity, temp);
210     if (rState != SUCCESS) {
211         return rState;
212     }
213 
214     va_list args;
215     va_start(args, quantity);
216     outValue = FormatString(temp.c_str(), args);
217     va_end(args);
218 
219     return SUCCESS;
220 }
221 
GetPluralStringByNameFormat(std::string & outValue,const char * name,int quantity,...)222 RState ResourceManagerImpl::GetPluralStringByNameFormat(std::string &outValue, const char *name, int quantity, ...)
223 {
224     const HapResource::ValueUnderQualifierDir *vuqd =
225         hapManager_->FindQualifierValueByName(name, ResType::PLURALS);
226     std::string temp;
227     RState rState = GetPluralString(vuqd, quantity, temp);
228     if (rState != SUCCESS) {
229         return rState;
230     }
231 
232     va_list args;
233     va_start(args, quantity);
234     outValue = FormatString(temp.c_str(), args);
235     va_end(args);
236 
237     return SUCCESS;
238 }
239 
GetPluralString(const HapResource::ValueUnderQualifierDir * vuqd,int quantity,std::string & outValue)240 RState ResourceManagerImpl::GetPluralString(const HapResource::ValueUnderQualifierDir *vuqd,
241     int quantity, std::string &outValue)
242 {
243     // not found or type invalid
244     if (vuqd == nullptr) {
245         return NOT_FOUND;
246     }
247     auto idItem = vuqd->GetIdItem();
248     if (idItem == nullptr || idItem->resType_ != ResType::PLURALS) {
249         return NOT_FOUND;
250     }
251     std::map<std::string, std::string> map;
252 
253     size_t startIdx = 0;
254     size_t loop = idItem->values_.size() / 2;
255     for (size_t i = 0; i < loop; ++i) {
256         // 2 means key and value appear in pairs
257         std::string key(idItem->values_[startIdx + i * 2]);
258         std::string value(idItem->values_[startIdx + i * 2 + 1]);
259         auto iter = map.find(key);
260         if (iter == map.end()) {
261             std::string resolvedValue;
262             RState rrRet = ResolveReference(value, resolvedValue);
263             if (rrRet != SUCCESS) {
264                 HILOG_ERROR("ResolveReference failed, value:%s", value.c_str());
265                 return ERROR;
266             }
267             map[key] = resolvedValue;
268         }
269     }
270 
271     std::string converted = hapManager_->GetPluralRulesAndSelect(quantity);
272     auto mapIter = map.find(converted);
273     if (mapIter == map.end()) {
274         mapIter = map.find("other");
275         if (mapIter == map.end()) {
276             return NOT_FOUND;
277         }
278     }
279     outValue = mapIter->second;
280 
281     return SUCCESS;
282 }
283 
ResolveReference(const std::string value,std::string & outValue)284 RState ResourceManagerImpl::ResolveReference(const std::string value, std::string &outValue)
285 {
286     int id;
287     ResType resType;
288     bool isRef = true;
289     int count = 0;
290     std::string refStr(value);
291     while (isRef) {
292         isRef = IdItem::IsRef(refStr, resType, id);
293         if (!isRef) {
294             outValue = refStr;
295             return SUCCESS;
296         }
297 
298         if (IdItem::IsArrayOfType(resType)) {
299             // can't be array
300             HILOG_ERROR("ref %s can't be array", refStr.c_str());
301             return ERROR;
302         }
303         const IdItem *idItem = hapManager_->FindResourceById(id);
304         if (idItem == nullptr) {
305             HILOG_ERROR("ref %s id not found", refStr.c_str());
306             return ERROR;
307         }
308         // unless compile bug
309         if (resType != idItem->resType_) {
310             HILOG_ERROR("impossible. ref %s type mismatch, found type: %d", refStr.c_str(), idItem->resType_);
311             return ERROR;
312         }
313 
314         refStr = idItem->value_;
315 
316         if (++count > MAX_DEPTH_REF_SEARCH) {
317             HILOG_ERROR("ref %s has re-ref too much", value.c_str());
318             return ERROR;
319         }
320     }
321     return SUCCESS;
322 }
323 
ResolveParentReference(const IdItem * idItem,std::map<std::string,std::string> & outValue)324 RState ResourceManagerImpl::ResolveParentReference(const IdItem *idItem, std::map<std::string, std::string> &outValue)
325 {
326     // only pattern and theme
327     // ref always at idx 0
328     // child will cover parent
329     if (idItem == nullptr) {
330         return ERROR;
331     }
332     if (!(idItem->resType_ == THEME || idItem->resType_ == PATTERN)) {
333         HILOG_ERROR("only pattern and theme have parent: %d", idItem->resType_);
334         return ERROR;
335     }
336     outValue.clear();
337 
338     bool haveParent = false;
339     int count = 0;
340     const IdItem *currItem = idItem;
341     do {
342         haveParent = currItem->HaveParent();
343         size_t startIdx = haveParent ? 1 : 0;
344         // add currItem values into map when key is absent
345         // this make sure child covers parent
346         size_t loop = currItem->values_.size() / 2;
347         for (size_t i = 0; i < loop; ++i) {
348             // 2 means key and value appear in pairs
349             std::string key(currItem->values_[startIdx + i * 2]);
350             std::string value(currItem->values_[startIdx + i * 2 + 1]);
351             auto iter = outValue.find(key);
352             if (iter == outValue.end()) {
353                 std::string resolvedValue;
354                 RState rrRet = ResolveReference(value, resolvedValue);
355                 if (rrRet != SUCCESS) {
356                     HILOG_ERROR("ResolveReference failed, value:%s", value.c_str());
357                     return ERROR;
358                 }
359                 outValue[key] = resolvedValue;
360             }
361         }
362         if (haveParent) {
363             // get parent
364             int id;
365             ResType resType;
366             bool isRef = IdItem::IsRef(currItem->values_[0], resType, id);
367             if (!isRef) {
368                 HILOG_ERROR("something wrong, pls check HaveParent(). idItem: %s", idItem->ToString().c_str());
369                 return ERROR;
370             }
371             currItem = hapManager_->FindResourceById(id);
372             if (currItem == nullptr) {
373                 HILOG_ERROR("ref %s id not found", idItem->values_[0].c_str());
374                 return ERROR;
375             }
376         }
377 
378         if (++count > MAX_DEPTH_REF_SEARCH) {
379             HILOG_ERROR(" %u has too many parents", idItem->id_);
380             return ERROR;
381         }
382     } while (haveParent);
383 
384     return SUCCESS;
385 }
386 
GetBooleanById(uint32_t id,bool & outValue)387 RState ResourceManagerImpl::GetBooleanById(uint32_t id, bool &outValue)
388 {
389     const IdItem *idItem = hapManager_->FindResourceById(id);
390     return GetBoolean(idItem, outValue);
391 }
392 
GetBooleanByName(const char * name,bool & outValue)393 RState ResourceManagerImpl::GetBooleanByName(const char *name, bool &outValue)
394 {
395     const IdItem *idItem = hapManager_->FindResourceByName(name, ResType::BOOLEAN);
396     return GetBoolean(idItem, outValue);
397 }
398 
GetBoolean(const IdItem * idItem,bool & outValue)399 RState ResourceManagerImpl::GetBoolean(const IdItem *idItem, bool &outValue)
400 {
401     if (idItem == nullptr || idItem->resType_ != ResType::BOOLEAN) {
402         return NOT_FOUND;
403     }
404     std::string temp;
405     RState state = ResolveReference(idItem->value_, temp);
406     if (state == SUCCESS) {
407         if (strcmp(temp.c_str(), "true") == 0) {
408             outValue = true;
409             return SUCCESS;
410         }
411         if (strcmp(temp.c_str(), "false") == 0) {
412             outValue = false;
413             return SUCCESS;
414         }
415         return ERROR;
416     }
417     return state;
418 }
419 
GetFloatById(uint32_t id,float & outValue)420 RState ResourceManagerImpl::GetFloatById(uint32_t id, float &outValue)
421 {
422     const IdItem *idItem = hapManager_->FindResourceById(id);
423     std::string unit;
424     RState state = GetFloat(idItem, outValue, unit);
425     if (state == SUCCESS) {
426         return RecalculateFloat(unit, outValue);
427     }
428     return state;
429 }
430 
GetFloatById(uint32_t id,float & outValue,std::string & unit)431 RState ResourceManagerImpl::GetFloatById(uint32_t id, float &outValue, std::string &unit)
432 {
433     const IdItem *idItem = hapManager_->FindResourceById(id);
434     return GetFloat(idItem, outValue, unit);
435 }
436 
GetFloatByName(const char * name,float & outValue)437 RState ResourceManagerImpl::GetFloatByName(const char *name, float &outValue)
438 {
439     const IdItem *idItem = hapManager_->FindResourceByName(name, ResType::FLOAT);
440     std::string unit;
441     RState state = GetFloat(idItem, outValue, unit);
442     if (state == SUCCESS) {
443         return RecalculateFloat(unit, outValue);
444     }
445     return state;
446 }
447 
GetFloatByName(const char * name,float & outValue,std::string & unit)448 RState ResourceManagerImpl::GetFloatByName(const char *name, float &outValue, std::string &unit)
449 {
450     const IdItem *idItem = hapManager_->FindResourceByName(name, ResType::FLOAT);
451     return GetFloat(idItem, outValue, unit);
452 }
453 
RecalculateFloat(const std::string & unit,float & result)454 RState ResourceManagerImpl::RecalculateFloat(const std::string &unit, float &result)
455 {
456     ResConfigImpl rc;
457     GetResConfig(rc);
458     ScreenDensity srcDensity = rc.GetScreenDensity();
459     if (srcDensity == SCREEN_DENSITY_NOT_SET) {
460         HILOG_INFO("RecalculateFloat srcDensity SCREEN_DENSITY_NOT_SET ");
461         return SUCCESS;
462     }
463     float density = srcDensity / DEFAULT_DENSITY;
464     if (unit == VIRTUAL_PIXEL) {
465         result = result * density;
466     } else if (unit == FONT_SIZE_PIXEL) {
467         float fontSizeDensity = density * ((fabs(fontRatio_) <= 1E-6) ? 1.0f : fontRatio_);
468         result = result * fontSizeDensity;
469     } else {
470         // no unit
471     }
472     return SUCCESS;
473 }
474 
ParseFloat(const std::string & strValue,float & result,std::string & unit)475 RState ResourceManagerImpl::ParseFloat(const std::string &strValue, float &result, std::string &unit)
476 {
477     std::regex reg("(\\+|-)?\\d+(\\.\\d+)? *(px|vp|fp)?");
478     std::smatch floatMatch;
479     if (!regex_search(strValue, floatMatch, reg)) {
480         HILOG_ERROR("not valid float value %{public}s", strValue.c_str());
481         return ERROR;
482     }
483     std::string matchString(floatMatch.str());
484     unit = floatMatch[floatMatch.size() - 1];
485     std::istringstream stream(matchString.substr(0, matchString.length() - unit.length()));
486     stream >> result;
487     return SUCCESS;
488 }
489 
GetFloat(const IdItem * idItem,float & outValue,std::string & unit)490 RState ResourceManagerImpl::GetFloat(const IdItem *idItem, float &outValue, std::string &unit)
491 {
492     if (idItem == nullptr || idItem->resType_ != ResType::FLOAT) {
493         return NOT_FOUND;
494     }
495     std::string temp;
496     RState state = ResolveReference(idItem->value_, temp);
497     if (state == SUCCESS) {
498         return ParseFloat(temp.c_str(), outValue, unit);
499     }
500     return state;
501 }
502 
GetIntegerById(uint32_t id,int & outValue)503 RState ResourceManagerImpl::GetIntegerById(uint32_t id, int &outValue)
504 {
505     const IdItem *idItem = hapManager_->FindResourceById(id);
506     return GetInteger(idItem, outValue);
507 }
508 
GetIntegerByName(const char * name,int & outValue)509 RState ResourceManagerImpl::GetIntegerByName(const char *name, int &outValue)
510 {
511     const IdItem *idItem = hapManager_->FindResourceByName(name, ResType::INTEGER);
512     return GetInteger(idItem, outValue);
513 }
514 
GetInteger(const IdItem * idItem,int & outValue)515 RState ResourceManagerImpl::GetInteger(const IdItem *idItem, int &outValue)
516 {
517     if (idItem == nullptr || idItem->resType_ != ResType::INTEGER) {
518         return NOT_FOUND;
519     }
520     std::string temp;
521     RState state = ResolveReference(idItem->value_, temp);
522     if (state == SUCCESS) {
523         outValue = atoi(temp.c_str());
524         return SUCCESS;
525     }
526     return state;
527 }
528 
GetColorById(uint32_t id,uint32_t & outValue)529 RState ResourceManagerImpl::GetColorById(uint32_t id, uint32_t &outValue)
530 {
531     const IdItem *idItem = hapManager_->FindResourceById(id);
532     return GetColor(idItem, outValue);
533 }
534 
GetColorByName(const char * name,uint32_t & outValue)535 RState ResourceManagerImpl::GetColorByName(const char *name, uint32_t &outValue)
536 {
537     const IdItem *idItem = hapManager_->FindResourceByName(name, ResType::COLOR);
538     return GetColor(idItem, outValue);
539 }
540 
GetColor(const IdItem * idItem,uint32_t & outValue)541 RState ResourceManagerImpl::GetColor(const IdItem *idItem, uint32_t &outValue)
542 {
543     if (idItem == nullptr || idItem->resType_ != ResType::COLOR) {
544         return NOT_FOUND;
545     }
546     std::string temp;
547     RState state = ResolveReference(idItem->value_, temp);
548     if (state == SUCCESS) {
549         return Utils::ConvertColorToUInt32(temp.c_str(), outValue);
550     }
551     return state;
552 }
553 
GetIntArrayById(uint32_t id,std::vector<int> & outValue)554 RState ResourceManagerImpl::GetIntArrayById(uint32_t id, std::vector<int> &outValue)
555 {
556     const IdItem *idItem = hapManager_->FindResourceById(id);
557     return GetIntArray(idItem, outValue);
558 }
559 
GetIntArrayByName(const char * name,std::vector<int> & outValue)560 RState ResourceManagerImpl::GetIntArrayByName(const char *name, std::vector<int> &outValue)
561 {
562     const IdItem *idItem = hapManager_->FindResourceByName(name, ResType::INTARRAY);
563     return GetIntArray(idItem, outValue);
564 }
565 
GetIntArray(const IdItem * idItem,std::vector<int> & outValue)566 RState ResourceManagerImpl::GetIntArray(const IdItem *idItem, std::vector<int> &outValue)
567 {
568     // not found or type invalid
569     if (idItem == nullptr || idItem->resType_ != ResType::INTARRAY) {
570         return NOT_FOUND;
571     }
572     outValue.clear();
573 
574     for (size_t i = 0; i < idItem->values_.size(); ++i) {
575         std::string resolvedValue;
576         RState rrRet = ResolveReference(idItem->values_[i], resolvedValue);
577         if (rrRet != SUCCESS) {
578             HILOG_ERROR("ResolveReference failed, value:%s", idItem->values_[i].c_str());
579             return ERROR;
580         }
581         outValue.push_back(atoi(resolvedValue.c_str()));
582     }
583     return SUCCESS;
584 }
585 
GetThemeById(uint32_t id,std::map<std::string,std::string> & outValue)586 RState ResourceManagerImpl::GetThemeById(uint32_t id, std::map<std::string, std::string> &outValue)
587 {
588     const IdItem *idItem = hapManager_->FindResourceById(id);
589     return GetTheme(idItem, outValue);
590 }
591 
GetThemeByName(const char * name,std::map<std::string,std::string> & outValue)592 RState ResourceManagerImpl::GetThemeByName(const char *name, std::map<std::string, std::string> &outValue)
593 {
594     const IdItem *idItem = hapManager_->FindResourceByName(name, ResType::THEME);
595     return GetTheme(idItem, outValue);
596 }
597 
GetTheme(const IdItem * idItem,std::map<std::string,std::string> & outValue)598 RState ResourceManagerImpl::GetTheme(const IdItem *idItem, std::map<std::string, std::string> &outValue)
599 {
600 // not found or type invalid
601     if (idItem == nullptr || idItem->resType_ != ResType::THEME) {
602         return NOT_FOUND;
603     }
604     return ResolveParentReference(idItem, outValue);
605 }
606 
GetProfileById(uint32_t id,std::string & outValue)607 RState ResourceManagerImpl::GetProfileById(uint32_t id, std::string &outValue)
608 {
609     auto qd = hapManager_->FindQualifierValueById(id);
610     if (qd == nullptr) {
611         return NOT_FOUND;
612     }
613     return GetRawFile(qd, ResType::PROF, outValue);
614 }
615 
GetProfileByName(const char * name,std::string & outValue)616 RState ResourceManagerImpl::GetProfileByName(const char *name, std::string &outValue)
617 {
618     auto qd = hapManager_->FindQualifierValueByName(name, ResType::PROF);
619     if (qd == nullptr) {
620         return NOT_FOUND;
621     }
622     return GetRawFile(qd, ResType::PROF, outValue);
623 }
624 
GetMediaById(uint32_t id,std::string & outValue)625 RState ResourceManagerImpl::GetMediaById(uint32_t id, std::string &outValue)
626 {
627     auto qd = hapManager_->FindQualifierValueById(id);
628     if (qd == nullptr) {
629         return NOT_FOUND;
630     }
631     return GetRawFile(qd, ResType::MEDIA, outValue);
632 }
633 
GetMediaByName(const char * name,std::string & outValue)634 RState ResourceManagerImpl::GetMediaByName(const char *name, std::string &outValue)
635 {
636     auto qd = hapManager_->FindQualifierValueByName(name, ResType::MEDIA);
637     if (qd == nullptr) {
638         return NOT_FOUND;
639     }
640     return GetRawFile(qd, ResType::MEDIA, outValue);
641 }
642 
GetRawFile(const HapResource::ValueUnderQualifierDir * vuqd,const ResType resType,std::string & outValue)643 RState ResourceManagerImpl::GetRawFile(const HapResource::ValueUnderQualifierDir *vuqd, const ResType resType,
644     std::string &outValue)
645 {
646     // not found or type invalid
647     if (vuqd == nullptr) {
648         return NOT_FOUND;
649     }
650     const IdItem *idItem = vuqd->GetIdItem();
651     if (idItem == nullptr || idItem->resType_ != resType) {
652         return NOT_FOUND;
653     }
654     outValue = vuqd->GetHapResource()->GetResourcePath();
655 #ifdef __IDE_PREVIEW__
656     auto index = idItem->value_.find('/');
657     if (index == std::string::npos) {
658         HILOG_ERROR("resource path format error, %s", idItem->value_.c_str());
659         return NOT_FOUND;
660     }
661     auto nameWithoutModule = idItem->value_.substr(index + 1);
662     outValue.append(nameWithoutModule);
663 #else
664     outValue.append(idItem->value_);
665 #endif
666     return SUCCESS;
667 }
668 
GetRawFilePathByName(const std::string & name,std::string & outValue)669 RState ResourceManagerImpl::GetRawFilePathByName(const std::string &name, std::string &outValue)
670 {
671     return hapManager_->FindRawFile(name, outValue);
672 }
673 
GetRawFileDescriptor(const std::string & name,RawFileDescriptor & descriptor)674 RState ResourceManagerImpl::GetRawFileDescriptor(const std::string &name, RawFileDescriptor &descriptor)
675 {
676     auto it = rawFileDescriptor_.find(name);
677     if (it != rawFileDescriptor_.end()) {
678         descriptor.fd = rawFileDescriptor_[name].fd;
679         descriptor.length = rawFileDescriptor_[name].length;
680         descriptor.offset = rawFileDescriptor_[name].offset;
681         return SUCCESS;
682     }
683     std::string paths = "";
684     RState rState = GetRawFilePathByName(name, paths);
685     if (rState != SUCCESS) {
686         return rState;
687     }
688     int fd = open(paths.c_str(), O_RDONLY);
689     if (fd > 0) {
690         long length = lseek(fd, 0, SEEK_END);
691         if (length == -1) {
692             close(fd);
693             return ERROR;
694         }
695         long begin = lseek(fd, 0, SEEK_SET);
696         if (begin == -1) {
697             close(fd);
698             return ERROR;
699         }
700         descriptor.fd = fd;
701         descriptor.length = length;
702         descriptor.offset = 0;
703         rawFileDescriptor_[name] = descriptor;
704         return SUCCESS;
705     }
706     return ERROR;
707 }
708 
CloseRawFileDescriptor(const std::string & name)709 RState ResourceManagerImpl::CloseRawFileDescriptor(const std::string &name)
710 {
711     auto it = rawFileDescriptor_.find(name);
712     if (it == rawFileDescriptor_.end()) {
713         return SUCCESS;
714     }
715     int fd = rawFileDescriptor_[name].fd;
716     if (fd > 0) {
717         int result = close(fd);
718         if (result == -1) {
719             return ERROR;
720         }
721         rawFileDescriptor_.erase(name);
722         return SUCCESS;
723     }
724     return ERROR;
725 }
726 
~ResourceManagerImpl()727 ResourceManagerImpl::~ResourceManagerImpl()
728 {
729     if (hapManager_ != nullptr) {
730         delete hapManager_;
731     }
732 }
733 
AddResource(const char * path)734 bool ResourceManagerImpl::AddResource(const char *path)
735 {
736 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__)
737     BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__);
738 #endif
739     return this->hapManager_->AddResource(path);
740 }
741 
AddResource(const std::string & path,const std::vector<std::string> & overlayPaths)742 bool ResourceManagerImpl::AddResource(const std::string &path, const std::vector<std::string> &overlayPaths)
743 {
744     return this->hapManager_->AddResource(path, overlayPaths);
745 }
746 
UpdateResConfig(ResConfig & resConfig)747 RState ResourceManagerImpl::UpdateResConfig(ResConfig &resConfig)
748 {
749 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__)
750     BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__);
751 #endif
752     if (resConfig.GetLocaleInfo() == nullptr) {
753         return LOCALEINFO_IS_NULL;
754     }
755     if (resConfig.GetLocaleInfo()->getLanguage() == nullptr) {
756         return LOCALEINFO_IS_NULL;
757     }
758     return this->hapManager_->UpdateResConfig(resConfig);
759 }
760 
GetResConfig(ResConfig & resConfig)761 void ResourceManagerImpl::GetResConfig(ResConfig &resConfig)
762 {
763     this->hapManager_->GetResConfig(resConfig);
764 }
765 
GetResourcePaths()766 std::vector<std::string> ResourceManagerImpl::GetResourcePaths()
767 {
768     return this->hapManager_->GetResourcePaths();
769 }
770 } // namespace Resource
771 } // namespace Global
772 } // namespace OHOS