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