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_parser.h"
17
18 #include <cstdlib>
19 #include <string>
20 #include <fcntl.h>
21 #include <unzip.h>
22 #include <unistd.h>
23 #include <set>
24
25 #include "hilog_wrapper.h"
26 #include "locale_matcher.h"
27 #if defined(__WINNT__)
28 #include <cstring>
29 #else
30 #include "securec.h"
31 #endif
32 #include "utils/errors.h"
33 #include "utils/string_utils.h"
34 #include "utils/utils.h"
35
36 namespace OHOS {
37 namespace Global {
38 namespace Resource {
39 const char *HapParser::RES_FILE_NAME = "/resources.index";
40
LocateFile(unzFile & uf,const char * fileName)41 int32_t LocateFile(unzFile &uf, const char *fileName)
42 {
43 if (unzLocateFile2(uf, fileName, 1)) { // try to locate file inside zip, 1 = case sensitive
44 return UNKNOWN_ERROR;
45 }
46 return OK;
47 }
48
GetCurrentFileInfo(unzFile & uf,unz_file_info & fileInfo)49 int32_t GetCurrentFileInfo(unzFile &uf, unz_file_info &fileInfo)
50 {
51 // obtained the necessary details about file inside zip
52 char filenameInzip[256]; // for unzGetCurrentFileInfo
53 int err = unzGetCurrentFileInfo(uf, &fileInfo, filenameInzip, sizeof(filenameInzip), nullptr, 0, nullptr, 0);
54 if (err != UNZ_OK) {
55 HILOG_ERROR("GetCurrentFileInfo failed");
56 return UNKNOWN_ERROR;
57 }
58 return OK;
59 }
60
ReadCurrentFile(unzFile & uf,unz_file_info & fileInfo,std::unique_ptr<uint8_t[]> & buffer,size_t & bufLen)61 int32_t ReadCurrentFile(unzFile &uf, unz_file_info &fileInfo, std::unique_ptr<uint8_t[]> &buffer,
62 size_t &bufLen)
63 {
64 buffer = std::make_unique<uint8_t[]>(fileInfo.uncompressed_size);
65 bufLen = fileInfo.uncompressed_size;
66 if (buffer == nullptr) {
67 HILOG_ERROR("Error allocating memory for read buffer");
68 return UNKNOWN_ERROR;
69 }
70
71 int err = unzOpenCurrentFilePassword(uf, nullptr);
72 if (err != UNZ_OK) {
73 HILOG_ERROR("Error %d in unzOpenCurrentFilePassword.", err);
74 return UNKNOWN_ERROR;
75 } // file inside the zip is open
76
77 err = unzReadCurrentFile(uf, buffer.get(), bufLen);
78 if (err < 0) {
79 HILOG_ERROR("Error %d in unzReadCurrentFile", err);
80 return UNKNOWN_ERROR;
81 }
82
83 return OK;
84 }
85
ReadFileFromZip(unzFile & uf,const char * fileName,std::unique_ptr<uint8_t[]> & buffer,size_t & bufLen)86 int32_t HapParser::ReadFileFromZip(unzFile &uf, const char *fileName, std::unique_ptr<uint8_t[]> &buffer,
87 size_t &bufLen)
88 {
89 unz_file_info fileInfo;
90 if (LocateFile(uf, fileName) != OK) {
91 return UNKNOWN_ERROR;
92 }
93 if (GetCurrentFileInfo(uf, fileInfo) != OK) {
94 return UNKNOWN_ERROR;
95 }
96 if (ReadCurrentFile(uf, fileInfo, buffer, bufLen) != OK) {
97 return UNKNOWN_ERROR;
98 }
99 return OK;
100 }
101
GetModuleName(const char * configStr,size_t len)102 std::string GetModuleName(const char *configStr, size_t len)
103 {
104 if (configStr == nullptr) {
105 return std::string();
106 }
107 std::string config(configStr, len);
108 static const char *key = "\"moduleName\"";
109 auto idx = config.find(key);
110 if (idx == std::string::npos) {
111 return std::string();
112 }
113 auto start = config.find("\"", idx + strlen(key));
114 if (start == std::string::npos) {
115 return std::string();
116 }
117 auto end = config.find("\"", start + 1);
118 if (end == std::string::npos) {
119 return std::string();
120 }
121
122 std::string retStr = std::string(configStr + start + 1, end - start - 1);
123 return retStr;
124 }
125
IsStageMode(unzFile & uf)126 bool HapParser::IsStageMode(unzFile &uf)
127 {
128 // stage mode contains "module.json", The 1 means the case sensitive
129 if (unzLocateFile2(uf, "module.json", 1) != UNZ_OK) {
130 return false;
131 }
132 return true;
133 }
134
ParseModuleNameFromHap(unzFile & uf)135 std::string ParseModuleNameFromHap(unzFile &uf)
136 {
137 std::unique_ptr<uint8_t[]> tmpBuf;
138 int32_t ret = UNZ_OK;
139 size_t tmpLen;
140 ret = HapParser::ReadFileFromZip(uf, "config.json", tmpBuf, tmpLen);
141 if (ret != OK) {
142 HILOG_ERROR("read config.json error");
143 return std::string();
144 }
145 // parse config.json
146 std::string mName = GetModuleName(reinterpret_cast<char *>(tmpBuf.get()), tmpLen);
147 if (mName.size() == 0) {
148 HILOG_ERROR("parse moduleName from config.json error");
149 return std::string();
150 }
151 return mName;
152 }
153
GetIndexFilePath(unzFile uf)154 std::string GetIndexFilePath(unzFile uf)
155 {
156 std::string mName = ParseModuleNameFromHap(uf);
157 std::string indexFilePath = std::string("assets/");
158 indexFilePath.append(mName);
159 indexFilePath.append("/resources.index");
160 return indexFilePath;
161 }
162
ReadFileInfoFromZip(unzFile & uf,const char * fileName,std::unique_ptr<uint8_t[]> & buffer,size_t & bufLen)163 int32_t ReadFileInfoFromZip(unzFile &uf, const char *fileName, std::unique_ptr<uint8_t[]> &buffer, size_t &bufLen)
164 {
165 int err = HapParser::ReadFileFromZip(uf, fileName, buffer, bufLen);
166 if (err < 0) {
167 unzClose(uf);
168 return UNKNOWN_ERROR;
169 }
170 unzClose(uf);
171 return OK;
172 }
173
ReadIndexFromFile(const char * zipFile,std::unique_ptr<uint8_t[]> & buffer,size_t & bufLen)174 int32_t HapParser::ReadIndexFromFile(const char *zipFile, std::unique_ptr<uint8_t[]> &buffer,
175 size_t &bufLen)
176 {
177 unzFile uf = unzOpen64(zipFile);
178 if (uf == nullptr) {
179 HILOG_ERROR("Error open %{public}s in ReadIndexFromFile %{public}d", zipFile, errno);
180 return UNKNOWN_ERROR;
181 } // file is open
182 if (IsStageMode(uf)) {
183 return ReadFileInfoFromZip(uf, "resources.index", buffer, bufLen);
184 }
185 std::string indexFilePath = GetIndexFilePath(uf);
186 return ReadFileInfoFromZip(uf, indexFilePath.c_str(), buffer, bufLen);
187 }
188
GetPath(const std::string & filePath,std::string & rawFilePath)189 std::string HapParser::GetPath(const std::string &filePath, std::string &rawFilePath)
190 {
191 std::string tempName = filePath;
192 const std::string rawFileDirName = "rawfile/";
193 if (tempName.length() <= rawFileDirName.length()
194 || (tempName.compare(0, rawFileDirName.length(), rawFileDirName) != 0)) {
195 tempName = rawFileDirName + tempName;
196 }
197 rawFilePath.append(tempName);
198 return rawFilePath;
199 }
200
201 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
ParseModuleName(std::shared_ptr<AbilityBase::Extractor> & extractor)202 std::string HapParser::ParseModuleName(std::shared_ptr<AbilityBase::Extractor> &extractor)
203 {
204 if (extractor == nullptr) {
205 return std::string();
206 }
207 std::unique_ptr<uint8_t[]> configBuf;
208 size_t len;
209 bool ret = extractor->ExtractToBufByName("config.json", configBuf, len);
210 if (!ret) {
211 HILOG_ERROR("failed to get config data from ability");
212 return std::string();
213 }
214 // parse config.json
215 std::string mName = GetModuleName(reinterpret_cast<char *>(configBuf.get()), len);
216 if (mName.size() == 0) {
217 HILOG_ERROR("parse moduleName from config.json error");
218 return std::string();
219 }
220 return mName;
221 }
222
GetRawFilePathFromFA(std::shared_ptr<AbilityBase::Extractor> & extractor,const std::string & filePath)223 std::string GetRawFilePathFromFA(std::shared_ptr<AbilityBase::Extractor> &extractor,
224 const std::string &filePath)
225 {
226 std::string moduleName = HapParser::ParseModuleName(extractor);
227 std::string rawFilePath("assets/");
228 rawFilePath.append(moduleName);
229 rawFilePath.append("/resources/");
230 HapParser::GetPath(filePath, rawFilePath);
231 return rawFilePath;
232 }
233
GetRawFilePathFromStage(const std::string & filePath)234 std::string GetRawFilePathFromStage(const std::string &filePath)
235 {
236 std::string rawFilePath("resources/");
237 HapParser::GetPath(filePath, rawFilePath);
238 return rawFilePath;
239 }
240
GetRawFilePath(std::shared_ptr<AbilityBase::Extractor> & extractor,const std::string & rawFileName)241 std::string HapParser::GetRawFilePath(std::shared_ptr<AbilityBase::Extractor> &extractor,
242 const std::string &rawFileName)
243 {
244 std::string rawfilePath;
245 if (extractor->IsStageModel()) {
246 rawfilePath = GetRawFilePathFromStage(rawFileName);
247 } else {
248 rawfilePath = GetRawFilePathFromFA(extractor, rawFileName);
249 }
250 return rawfilePath;
251 }
252 #endif
253
ReadRawFileFromHap(const std::string & hapPath,const std::string & rawFileName,size_t & len,std::unique_ptr<uint8_t[]> & outValue)254 RState HapParser::ReadRawFileFromHap(const std::string &hapPath, const std::string &rawFileName, size_t &len,
255 std::unique_ptr<uint8_t[]> &outValue)
256 {
257 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
258 bool isNewExtractor = false;
259 auto extractor = AbilityBase::ExtractorUtil::GetExtractor(hapPath, isNewExtractor);
260 if (extractor == nullptr) {
261 HILOG_ERROR("failed to get extractor hapPath, %{public}s", hapPath.c_str());
262 return NOT_FOUND;
263 }
264 std::string rawfilePath = HapParser::GetRawFilePath(extractor, rawFileName);
265 if (!extractor->HasEntry(rawfilePath)) {
266 HILOG_ERROR("the rawfile file %{public}s is not exist in %{public}s", rawfilePath.c_str(), hapPath.c_str());
267 return ERROR_CODE_RES_PATH_INVALID;
268 }
269 bool ret = extractor->ExtractToBufByName(rawfilePath, outValue, len);
270 if (!ret) {
271 HILOG_ERROR("failed to get rawfile data rawfilePath, %{public}s, hapPath, %{public}s",
272 rawfilePath.c_str(), hapPath.c_str());
273 return NOT_FOUND;
274 }
275 #endif
276 return SUCCESS;
277 }
278
ReadRawFileDescriptor(const char * hapPath,const std::string & rawFileName,ResourceManager::RawFileDescriptor & descriptor)279 RState HapParser::ReadRawFileDescriptor(const char *hapPath, const std::string &rawFileName,
280 ResourceManager::RawFileDescriptor &descriptor)
281 {
282 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
283 char outPath[PATH_MAX + 1] = {0};
284 Utils::CanonicalizePath(hapPath, outPath, PATH_MAX);
285 int zipFd = open(outPath, O_RDONLY);
286 if (zipFd < 0) {
287 HILOG_ERROR("failed open file %{public}s", outPath);
288 return NOT_FOUND;
289 }
290 bool isNewExtractor = false;
291 auto extractor = AbilityBase::ExtractorUtil::GetExtractor(outPath, isNewExtractor);
292 if (extractor == nullptr) {
293 HILOG_ERROR("failed to get extractor in ReadRawFileDescriptor hapPath, %{public}s", outPath);
294 return NOT_FOUND;
295 }
296 std::string rawfilePath = HapParser::GetRawFilePath(extractor, rawFileName);
297 if (!extractor->HasEntry(rawfilePath)) {
298 HILOG_ERROR("the rawfile file %{public}s is not exist in %{public}s", rawfilePath.c_str(), hapPath);
299 return ERROR_CODE_RES_PATH_INVALID;
300 }
301 AbilityBase::FileInfo fileInfo;
302 bool ret = extractor->GetFileInfo(rawfilePath, fileInfo);
303 if (!ret) {
304 HILOG_ERROR("failed to get rawFileDescriptor rawfilePath, %{public}s", rawfilePath.c_str());
305 return NOT_FOUND;
306 }
307 descriptor.offset = static_cast<long>(fileInfo.offset);
308 descriptor.length = static_cast<long>(fileInfo.length);
309 descriptor.fd = zipFd;
310 #endif
311 return SUCCESS;
312 }
313
GetRawFileList(const std::string & hapPath,const std::string & rawDirPath,std::vector<std::string> & fileList)314 RState HapParser::GetRawFileList(const std::string &hapPath, const std::string &rawDirPath,
315 std::vector<std::string>& fileList)
316 {
317 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
318 bool isNewExtractor = false;
319 auto extractor = AbilityBase::ExtractorUtil::GetExtractor(hapPath, isNewExtractor);
320 if (extractor == nullptr) {
321 HILOG_ERROR("failed to get extractor from ability in GetRawFileList hapPath, %{public}s", hapPath.c_str());
322 return NOT_FOUND;
323 }
324 std::set<std::string> fileSet;
325 std::string rawfilePath = HapParser::GetRawFilePath(extractor, rawDirPath);
326 if (!extractor->IsDirExist(rawfilePath)) {
327 HILOG_ERROR("the rawfile dir %{public}s is not exist in %{public}s", rawfilePath.c_str(), hapPath.c_str());
328 return ERROR_CODE_RES_PATH_INVALID;
329 }
330 bool ret = extractor->GetFileList(rawfilePath, fileSet);
331 if (!ret) {
332 HILOG_ERROR("failed to get fileSet from ability rawfilePath, %{public}s", rawfilePath.c_str());
333 return ERROR_CODE_RES_PATH_INVALID;
334 }
335 for (auto it = fileSet.begin(); it != fileSet.end(); it++) {
336 fileList.emplace_back(*it);
337 }
338 #endif
339 return SUCCESS;
340 }
341
342 /**
343 *
344 * @param buffer
345 * @param offset
346 * @param id
347 * @param includeTemi dose length include '\0'
348 * @return OK or ERROR
349 */
ParseString(const char * buffer,uint32_t & offset,std::string & id,bool includeTemi=true)350 int32_t ParseString(const char *buffer, uint32_t &offset, std::string &id, bool includeTemi = true)
351 {
352 uint16_t strLen;
353 errno_t eret = memcpy_s(&strLen, sizeof(strLen), buffer + offset, 2);
354 if (eret != OK || (includeTemi && strLen == 0)) {
355 return SYS_ERROR;
356 }
357 offset += 2;
358 std::string tmp = std::string(const_cast<char *>(buffer) + offset, includeTemi ? (strLen - 1) : strLen);
359 offset += includeTemi ? strLen : (strLen + 1);
360 id = tmp;
361 return OK;
362 }
363
364 /**
365 *
366 * @param buffer
367 * @param offset
368 * @param values
369 * @return
370 */
ParseStringArray(const char * buffer,uint32_t & offset,std::vector<std::string> & values)371 int32_t ParseStringArray(const char *buffer, uint32_t &offset, std::vector<std::string> &values)
372 {
373 uint16_t arrLen;
374 errno_t eret = memcpy_s(&arrLen, sizeof(arrLen), buffer + offset, 2);
375 if (eret != OK) {
376 return SYS_ERROR;
377 }
378 offset += 2;
379 // next arrLen bytes are several strings. then after, is one '\0'
380 uint32_t startOffset = offset;
381 while (true) {
382 std::string value;
383 int32_t ret = ParseString(buffer, offset, value, false);
384 if (ret != OK) {
385 return ret;
386 }
387 values.push_back(value);
388
389 uint32_t readSize = offset - startOffset;
390 if (readSize + 1 == arrLen) {
391 offset += 1; // after arrLen, got '\0'
392 break;
393 }
394 if (readSize + 1 > arrLen) {
395 // size not match, cannot > arrLen
396 return SYS_ERROR;
397 }
398 }
399
400 return OK;
401 }
402
ParseIdItem(const char * buffer,uint32_t & offset,IdItem * idItem)403 int32_t ParseIdItem(const char *buffer, uint32_t &offset, IdItem *idItem)
404 {
405 errno_t eret = memcpy_s(idItem, sizeof(IdItem), buffer + offset, IdItem::HEADER_LEN);
406 if (eret != OK) {
407 return SYS_ERROR;
408 }
409 offset += IdItem::HEADER_LEN;
410
411 idItem->JudgeArray();
412 if (idItem->isArray_) {
413 int32_t ret = ParseStringArray(buffer, offset, idItem->values_);
414 if (ret != OK) {
415 return ret;
416 }
417 } else {
418 std::string value;
419 int32_t ret = ParseString(buffer, offset, value);
420 if (ret != OK) {
421 return ret;
422 }
423 idItem->value_ = std::string(value);
424 idItem->valueLen_ = value.size();
425 }
426 std::string name;
427 int32_t ret = ParseString(buffer, offset, name);
428 if (ret != OK) {
429 return ret;
430 }
431 idItem->name_ = std::string(name);
432 return OK;
433 }
434
ParseId(const char * buffer,uint32_t & offset,ResId * id)435 int32_t ParseId(const char *buffer, uint32_t &offset, ResId *id)
436 {
437 errno_t eret = memcpy_s(id, sizeof(ResId), buffer + offset, ResId::RESID_HEADER_LEN);
438 if (eret != OK) {
439 return SYS_ERROR;
440 }
441 offset += ResId::RESID_HEADER_LEN;
442 if (id->tag_[0] != 'I' || id->tag_[1] != 'D'
443 || id->tag_[2] != 'S' || id->tag_[3] != 'S') {
444 return -1;
445 }
446 for (uint32_t i = 0; i < id->count_; ++i) {
447 IdParam *ip = new (std::nothrow) IdParam();
448 if (ip == nullptr) {
449 HILOG_ERROR("new IdParam failed when ParseId");
450 return SYS_ERROR;
451 }
452 errno_t eret = memcpy_s(ip, sizeof(IdParam), buffer + offset, ResId::IDPARAM_HEADER_LEN);
453 if (eret != OK) {
454 delete (ip);
455 return SYS_ERROR;
456 }
457 offset += ResId::IDPARAM_HEADER_LEN;
458 IdItem *idItem = new (std::nothrow) IdItem();
459 if (idItem == nullptr) {
460 HILOG_ERROR("new IdItem failed when ParseId");
461 delete (ip);
462 return SYS_ERROR;
463 }
464 uint32_t ipOffset = ip->offset_;
465 int32_t ret = ParseIdItem(buffer, ipOffset, idItem);
466 if (ret != OK) {
467 delete (ip);
468 delete (idItem);
469 return ret;
470 }
471 ip->idItem_ = idItem;
472 id->idParams_.push_back(ip);
473 }
474
475 return OK;
476 }
477
IsLocaleMatch(const ResConfigImpl * defaultConfig,const std::vector<KeyParam * > & keyParams)478 bool IsLocaleMatch(const ResConfigImpl *defaultConfig, const std::vector<KeyParam *> &keyParams)
479 {
480 if (defaultConfig == nullptr) {
481 return true;
482 }
483 ResConfigImpl *config = HapParser::CreateResConfigFromKeyParams(keyParams);
484 if (config == nullptr) {
485 return false;
486 }
487 if (LocaleMatcher::Match(defaultConfig->GetResLocale(), config->GetResLocale())) {
488 delete (config);
489 return true;
490 }
491 HILOG_DEBUG("mismatch, do not parse %s", HapParser::ToFolderPath(keyParams).c_str());
492 delete (config);
493 return false;
494 }
495
ParseKey(const char * buffer,uint32_t & offset,ResKey * key,bool & match,const ResConfigImpl * defaultConfig)496 int32_t ParseKey(const char *buffer, uint32_t &offset, ResKey *key,
497 bool &match, const ResConfigImpl *defaultConfig)
498 {
499 errno_t eret = memcpy_s(key, sizeof(ResKey), buffer + offset, ResKey::RESKEY_HEADER_LEN);
500 if (eret != OK) {
501 return SYS_ERROR;
502 }
503 offset += ResKey::RESKEY_HEADER_LEN;
504 if (key->tag_[0] != 'K' || key->tag_[1] != 'E'
505 || key->tag_[2] != 'Y' || key->tag_[3] != 'S') {
506 return -1;
507 }
508 for (uint32_t i = 0; i < key->keyParamsCount_; ++i) {
509 KeyParam *kp = new (std::nothrow) KeyParam();
510 if (kp == nullptr) {
511 HILOG_ERROR("new KeyParam failed when ParseKey");
512 return SYS_ERROR;
513 }
514 errno_t eret = memcpy_s(kp, sizeof(KeyParam), buffer + offset, ResKey::KEYPARAM_HEADER_LEN);
515 if (eret != OK) {
516 delete (kp);
517 return SYS_ERROR;
518 }
519 offset += ResKey::KEYPARAM_HEADER_LEN;
520 kp->InitStr();
521 key->keyParams_.push_back(kp);
522 }
523 uint32_t idOffset = key->offset_;
524 ResId *id = new (std::nothrow) ResId();
525 if (id == nullptr) {
526 HILOG_ERROR("new ResId failed when ParseKey");
527 return SYS_ERROR;
528 }
529 int32_t ret = ParseId(buffer, idOffset, id);
530 if (ret != OK) {
531 delete (id);
532 return ret;
533 }
534 key->resId_ = id;
535 return OK;
536 }
537
538
ParseResHex(const char * buffer,const size_t bufLen,ResDesc & resDesc,const ResConfigImpl * defaultConfig)539 int32_t HapParser::ParseResHex(const char *buffer, const size_t bufLen, ResDesc &resDesc,
540 const ResConfigImpl *defaultConfig)
541 {
542 ResHeader *resHeader = new (std::nothrow) ResHeader();
543 if (resHeader == nullptr) {
544 HILOG_ERROR("new ResHeader failed when ParseResHex");
545 return SYS_ERROR;
546 }
547 uint32_t offset = 0;
548 errno_t eret = memcpy_s(resHeader, sizeof(ResHeader), buffer + offset, RES_HEADER_LEN);
549 if (eret != OK) {
550 delete (resHeader);
551 return SYS_ERROR;
552 }
553 offset += RES_HEADER_LEN;
554 if (resHeader->keyCount_ == 0 || resHeader->length_ == 0) {
555 delete (resHeader);
556 return UNKNOWN_ERROR;
557 }
558
559 resDesc.resHeader_ = resHeader;
560 for (uint32_t i = 0; i < resHeader->keyCount_; i++) {
561 ResKey *key = new (std::nothrow) ResKey();
562 if (key == nullptr) {
563 HILOG_ERROR("new ResKey failed when ParseResHex");
564 return SYS_ERROR;
565 }
566 bool match = true;
567 int32_t ret = ParseKey(buffer, offset, key, match, defaultConfig);
568 if (ret != OK) {
569 delete (key);
570 return ret;
571 }
572 if (match) {
573 resDesc.keys_.push_back(key);
574 } else {
575 delete (key);
576 }
577 }
578 return OK;
579 }
580
CreateResConfigFromKeyParams(const std::vector<KeyParam * > & keyParams)581 ResConfigImpl *HapParser::CreateResConfigFromKeyParams(const std::vector<KeyParam *> &keyParams)
582 {
583 ResConfigImpl *resConfig = new (std::nothrow) ResConfigImpl;
584 if (resConfig == nullptr) {
585 HILOG_ERROR("new ResConfigImpl failed when CreateResConfigFromKeyParams");
586 return nullptr;
587 }
588 size_t len = keyParams.size();
589 // default path
590 if (len == 0) {
591 resConfig->SetColorMode(COLOR_MODE_NOT_SET);
592 return resConfig;
593 }
594 delete resConfig;
595 size_t i = 0;
596 ResConfigKey configKey;
597 for (i = 0; i < len; ++i) {
598 const KeyParam *kp = keyParams.at(i);
599 if (kp->type_ == LANGUAGES) {
600 configKey.language = kp->GetStr().c_str();
601 } else if (kp->type_ == REGION) {
602 configKey.region = kp->GetStr().c_str();
603 } else if (kp->type_ == SCRIPT) {
604 configKey.script = kp->GetStr().c_str();
605 } else if (kp->type_ == SCREEN_DENSITY) {
606 configKey.screenDensity = GetScreenDensity(kp->value_);
607 } else if (kp->type_ == DEVICETYPE) {
608 configKey.deviceType = GetDeviceType(kp->value_);
609 } else if (kp->type_ == DIRECTION) {
610 if (kp->value_ == 0) {
611 configKey.direction = DIRECTION_VERTICAL;
612 } else {
613 configKey.direction = DIRECTION_HORIZONTAL;
614 }
615 } else if (kp->type_ == INPUTDEVICE) {
616 configKey.inputDevice = GetInputDevice(kp->value_);
617 } else if (kp->type_ == COLORMODE) {
618 configKey.colorMode = GetColorMode(kp->value_);
619 } else if (kp->type_ == MCC) {
620 configKey.mcc = GetMcc(kp->value_);
621 } else if (kp->type_ == MNC) {
622 configKey.mnc = GetMnc(kp->value_);
623 }
624 }
625
626 return BuildResConfig(&configKey);
627 }
628
BuildResConfig(ResConfigKey * configKey)629 ResConfigImpl *HapParser::BuildResConfig(ResConfigKey *configKey)
630 {
631 if (configKey == nullptr) {
632 HILOG_ERROR("configKey is null");
633 return nullptr;
634 }
635 ResConfigImpl *resConfig = new (std::nothrow) ResConfigImpl;
636 if (resConfig == nullptr) {
637 HILOG_ERROR("new ResConfigImpl failed when BuildResConfig");
638 return nullptr;
639 }
640 resConfig->SetDeviceType(configKey->deviceType);
641 resConfig->SetDirection(configKey->direction);
642 resConfig->SetColorMode(configKey->colorMode);
643 resConfig->SetMcc(configKey->mcc);
644 resConfig->SetMnc(configKey->mnc);
645 resConfig->SetInputDevice(configKey->inputDevice);
646 resConfig->SetScreenDensity((configKey->screenDensity) / Utils::DPI_BASE);
647 RState r = resConfig->SetLocaleInfo(configKey->language, configKey->script, configKey->region);
648 if (r != SUCCESS) {
649 HILOG_ERROR("error set locale,lang %s,script %s,region %s", configKey->language, configKey->script,
650 configKey->region);
651 }
652
653 return resConfig;
654 }
655
GetDeviceType(uint32_t value)656 DeviceType HapParser::GetDeviceType(uint32_t value)
657 {
658 DeviceType deviceType = DEVICE_NOT_SET;
659 if (value == DEVICE_CAR) {
660 deviceType = DEVICE_CAR;
661 } else if (value == DEVICE_PAD) {
662 deviceType = DEVICE_PAD;
663 } else if (value == DEVICE_PHONE) {
664 deviceType = DEVICE_PHONE;
665 } else if (value == DEVICE_TABLET) {
666 deviceType = DEVICE_TABLET;
667 } else if (value == DEVICE_TV) {
668 deviceType = DEVICE_TV;
669 } else if (value == DEVICE_WEARABLE) {
670 deviceType = DEVICE_WEARABLE;
671 }
672 return deviceType;
673 }
674
GetMcc(uint32_t value)675 uint32_t HapParser::GetMcc(uint32_t value)
676 {
677 return value;
678 }
679
GetMnc(uint32_t value)680 uint32_t HapParser::GetMnc(uint32_t value)
681 {
682 return value;
683 }
684
GetColorMode(uint32_t value)685 ColorMode HapParser::GetColorMode(uint32_t value)
686 {
687 ColorMode colorMode = COLOR_MODE_NOT_SET;
688 if (value == DARK) {
689 colorMode = DARK;
690 } else {
691 colorMode = LIGHT;
692 }
693 return colorMode;
694 }
695
GetInputDevice(uint32_t value)696 InputDevice HapParser::GetInputDevice(uint32_t value)
697 {
698 InputDevice inputDevice = INPUTDEVICE_NOT_SET;
699 if (value == INPUTDEVICE_POINTINGDEVICE) {
700 inputDevice = INPUTDEVICE_POINTINGDEVICE;
701 }
702 return inputDevice;
703 }
704
GetScreenDensity(uint32_t value)705 ScreenDensity HapParser::GetScreenDensity(uint32_t value)
706 {
707 ScreenDensity screenDensity = SCREEN_DENSITY_NOT_SET;
708 if (value == SCREEN_DENSITY_SDPI) {
709 screenDensity = SCREEN_DENSITY_SDPI;
710 } else if (value == SCREEN_DENSITY_MDPI) {
711 screenDensity = SCREEN_DENSITY_MDPI;
712 } else if (value == SCREEN_DENSITY_LDPI) {
713 screenDensity = SCREEN_DENSITY_LDPI;
714 } else if (value == SCREEN_DENSITY_XLDPI) {
715 screenDensity = SCREEN_DENSITY_XLDPI;
716 } else if (value == SCREEN_DENSITY_XXLDPI) {
717 screenDensity = SCREEN_DENSITY_XXLDPI;
718 } else if (value == SCREEN_DENSITY_XXXLDPI) {
719 screenDensity = SCREEN_DENSITY_XXXLDPI;
720 }
721 return screenDensity;
722 }
723
PathAppend(std::string & path,const std::string & append,const std::string & connector)724 void PathAppend(std::string &path, const std::string &append, const std::string &connector)
725 {
726 if (append.size() > 0) {
727 if (path.size() > 0) {
728 path.append(connector);
729 }
730 path.append(append);
731 }
732 }
733
ToFolderPath(const std::vector<KeyParam * > & keyParams)734 std::string HapParser::ToFolderPath(const std::vector<KeyParam *> &keyParams)
735 {
736 if (keyParams.size() == 0) {
737 return std::string("default");
738 }
739 // mcc-mnc-language_script_region-direction-deviceType-colorMode-inputDevice-screenDensity
740 Determiner determiner;
741 for (size_t i = 0; i < keyParams.size(); ++i) {
742 KeyParam *keyParam = keyParams[i];
743 switch (keyParam->type_) {
744 case KeyType::LANGUAGES:
745 determiner.language = keyParam->GetStr();
746 break;
747 case KeyType::SCRIPT:
748 determiner.script = keyParam->GetStr();
749 break;
750 case KeyType::REGION:
751 determiner.region = keyParam->GetStr();
752 break;
753 case KeyType::DIRECTION:
754 determiner.direction = keyParam->GetStr();
755 break;
756 case KeyType::DEVICETYPE:
757 determiner.deviceType = keyParam->GetStr();
758 break;
759 case KeyType::COLORMODE:
760 determiner.colorMode = keyParam->GetStr();
761 break;
762 case KeyType::INPUTDEVICE:
763 determiner.inputDevice = keyParam->GetStr();
764 break;
765 case KeyType::MCC:
766 determiner.mcc = keyParam->GetStr();
767 break;
768 case KeyType::MNC:
769 determiner.mnc = keyParam->GetStr();
770 break;
771 case KeyType::SCREEN_DENSITY:
772 determiner.screenDensity = keyParam->GetStr();
773 break;
774 default:
775 break;
776 }
777 }
778
779 return BuildFolderPath(&determiner);
780 }
781
BuildFolderPath(Determiner * determiner)782 std::string HapParser::BuildFolderPath(Determiner *determiner)
783 {
784 std::string path;
785 if (determiner == nullptr) {
786 HILOG_ERROR("determiner is null");
787 return path;
788 }
789 std::string connecter1("_");
790 std::string connecter2("-");
791 if (determiner->mcc.size() > 0) {
792 path.append(determiner->mcc);
793 if (determiner->mnc.size() > 0) {
794 PathAppend(path, determiner->mnc, connecter1);
795 }
796 if (determiner->language.size() > 0) {
797 PathAppend(path, determiner->language, connecter2);
798 }
799 } else {
800 if (determiner->language.size() > 0) {
801 path.append(determiner->language);
802 }
803 }
804 PathAppend(path, determiner->script, connecter1);
805 PathAppend(path, determiner->region, connecter1);
806 PathAppend(path, determiner->direction, connecter2);
807 PathAppend(path, determiner->deviceType, connecter2);
808 PathAppend(path, determiner->colorMode, connecter2);
809 PathAppend(path, determiner->inputDevice, connecter2);
810 PathAppend(path, determiner->screenDensity, connecter2);
811
812 return path;
813 }
814 } // namespace Resource
815 } // namespace Global
816 } // namespace OHOS