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