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 "util.h"
17
18 #include <chrono>
19 #include <cinttypes>
20 #include <cstdarg>
21 #include <fstream>
22 #include <iomanip>
23 #include <thread>
24
25 #include <fcntl.h>
26 #include <sys/prctl.h>
27 #include <sys/stat.h>
28 #include <sys/syscall.h>
29 #include <sys/time.h>
30 #include <sys/types.h>
31 #include <unistd.h>
32
33 #include "config_multimodal.h"
34 #include "define_multimodal.h"
35 #include "error_multimodal.h"
36 #include "mmi_log.h"
37 #include "securec.h"
38 #include "uuid.h"
39
40 namespace OHOS {
41 namespace MMI {
42 namespace {
43 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, MMI_LOG_DOMAIN, "Util"};
44 constexpr int32_t FILE_SIZE_MAX = 0x5000;
45 constexpr int32_t MAX_PRO_FILE_SIZE = 128000;
46 constexpr int32_t KEY_ELEMENT_COUNT = 4;
47 constexpr int32_t INVALID_FILE_SIZE = -1;
48 constexpr int32_t MIN_INTERVALTIME = 50;
49 constexpr int32_t MAX_INTERVALTIME = 500;
50 constexpr int32_t MIN_DELAYTIME = 200;
51 constexpr int32_t MAX_DELAYTIME = 1000;
52 constexpr int32_t COMMENT_SUBSCRIPT = 0;
53 const std::string CONFIG_ITEM_REPEAT = "Key.autorepeat";
54 const std::string CONFIG_ITEM_DELAY = "Key.autorepeat.delaytime";
55 const std::string CONFIG_ITEM_INTERVAL = "Key.autorepeat.intervaltime";
56 const std::string CONFIG_ITEM_TYPE = "Key.keyboard.type";
57 const std::string CURSORSTYLE_PATH = "/system/etc/multimodalinput/mouse_icon/";
58 const std::string DATA_PATH = "/data";
59 const std::string INPUT_PATH = "/system/";
60 const std::string KEY_PATH = "/vendor/etc/keymap/";
61 constexpr size_t BUF_TID_SIZE = 10;
62 constexpr size_t BUF_CMD_SIZE = 512;
63 constexpr size_t PROGRAM_NAME_SIZE = 256;
64 } // namespace
65
66 const std::map<int32_t, std::string> ERROR_STRING_MAP = {
67 {MSG_SEND_FAIL, "Send Message Failed"},
68 {NON_STD_EVENT, "Non-Standardized Event"},
69 {UNKNOWN_EVENT, "Unknown Event"},
70 {UNPROC_MSG, "Unprocessed Message"},
71 {UNKNOWN_MSG_ID, "Unknown Message Id"},
72 {UNKNOWN_DEV, "Unknown Device"},
73 {ERROR_NULL_POINTER, "Null Pointer"},
74 {FILE_OPEN_FAIL, "Open File Failed"},
75 {FILE_READ_FAIL, "Read File Failed"},
76 {FILE_WRITE_FAIL, "Write File Failed"},
77 {API_PARAM_TYPE_FAIL, "API Param Type Error"},
78 {API_OUT_OF_RANGE, "API Out Of Range Error"},
79 {FOCUS_ID_OBTAIN_FAIL, "Obtain FocusID Failed"},
80 };
81
GetMmiErrorTypeDesc(int32_t errorCodeEnum)82 const char *GetMmiErrorTypeDesc(int32_t errorCodeEnum)
83 {
84 auto str = ERROR_STRING_MAP.find(errorCodeEnum);
85 if (str == ERROR_STRING_MAP.end()) {
86 return nullptr;
87 }
88 return str->second.c_str();
89 }
90
GetMicrotime()91 int64_t GetMicrotime()
92 {
93 struct timeval currentTime = {};
94 gettimeofday(¤tTime, nullptr);
95 return currentTime.tv_sec * 1000 * 1000 + currentTime.tv_usec;
96 }
97
GetSysClockTime()98 int64_t GetSysClockTime()
99 {
100 struct timespec ts = { 0, 0 };
101 if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
102 MMI_HILOGD("clock_gettime failed:%{public}d", errno);
103 return 0;
104 }
105 return (ts.tv_sec * 1000 * 1000) + (ts.tv_nsec / 1000);
106 }
107
GetMillisTime()108 int64_t GetMillisTime()
109 {
110 auto timeNow = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
111 auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(timeNow.time_since_epoch());
112 return tmp.count();
113 }
114
UuIdGenerate()115 std::string UuIdGenerate()
116 {
117 static constexpr int32_t uuidBufSize = 64;
118 char buf[uuidBufSize] = {};
119 return buf;
120 }
121
GetUUid()122 std::string GetUUid()
123 {
124 Uuid uid;
125 std::string strUuid;
126 uid.ConvertToStdString(strUuid);
127 return strUuid;
128 }
129
GetThisThreadIdOfString()130 std::string GetThisThreadIdOfString()
131 {
132 thread_local std::string threadLocalId;
133 if (threadLocalId.empty()) {
134 long tid = syscall(SYS_gettid);
135 char buf[BUF_TID_SIZE] = {};
136 const int32_t ret = sprintf_s(buf, BUF_TID_SIZE, "%06d", tid);
137 if (ret < 0) {
138 printf("ERR: in %s, #%d, call sprintf_s failed, ret = %d.", __func__, __LINE__, ret);
139 return threadLocalId;
140 }
141 buf[BUF_TID_SIZE - 1] = '\0';
142 threadLocalId = buf;
143 }
144
145 return threadLocalId;
146 }
147
GetThisThreadId()148 uint64_t GetThisThreadId()
149 {
150 std::string stid = GetThisThreadIdOfString();
151 auto tid = std::stoull(stid);
152 return tid;
153 }
154
StringToken(std::string & str,const std::string & sep,std::string & token)155 size_t StringToken(std::string &str, const std::string &sep, std::string &token)
156 {
157 token = "";
158 if (str.empty()) {
159 return str.npos;
160 }
161 size_t pos = str.npos;
162 size_t tmp = 0;
163 for (auto &item : sep) {
164 tmp = str.find(item);
165 if (str.npos != tmp) {
166 pos = (std::min)(pos, tmp);
167 }
168 }
169 if (str.npos != pos) {
170 token = str.substr(0, pos);
171 if (str.npos != pos + 1) {
172 str = str.substr(pos + 1, str.npos);
173 }
174 if (pos == 0) {
175 return StringToken(str, sep, token);
176 }
177 } else {
178 token = str;
179 str = "";
180 }
181 return token.size();
182 }
183
StringSplit(const std::string & str,const std::string & sep,std::vector<std::string> & vecList)184 size_t StringSplit(const std::string &str, const std::string &sep, std::vector<std::string>&vecList)
185 {
186 size_t size;
187 auto strs = str;
188 std::string token;
189 while (str.npos != (size = StringToken(strs, sep, token))) {
190 vecList.push_back(token);
191 }
192 return vecList.size();
193 }
194
IdsListToString(const std::vector<int32_t> & list,const std::string & sep)195 std::string IdsListToString(const std::vector<int32_t> &list, const std::string &sep)
196 {
197 std::string str;
198 for (const auto &it : list) {
199 str += std::to_string(it) + sep;
200 }
201 if (str.size() > 0) {
202 str.resize(str.size() - sep.size());
203 }
204 return str;
205 }
206
LocalTime(struct tm & t,time_t curTime)207 void LocalTime(struct tm &t, time_t curTime)
208 {
209 time_t curTimeTemp = curTime;
210 if (curTimeTemp == 0) {
211 curTimeTemp = time(nullptr);
212 }
213 auto tm = localtime(&curTimeTemp);
214 if (tm) {
215 t = *tm;
216 }
217 }
218
Strftime(const std::string & format,time_t curTime)219 std::string Strftime(const std::string &format, time_t curTime)
220 {
221 if (format.empty()) {
222 return format;
223 }
224 struct tm t = {};
225 LocalTime(t, curTime);
226 char szDTime[32] = "";
227 (void)strftime(szDTime, sizeof(szDTime), format.c_str(), &t);
228 return szDTime;
229 }
230
PrintEventJoyStickAxisInfo(const std::string & axisName,const EventJoyStickAxisAbsInfo & r)231 static void PrintEventJoyStickAxisInfo(const std::string &axisName, const EventJoyStickAxisAbsInfo &r)
232 {
233 MMI_HILOGD("%{public}s: {code:%{public}d,value:%{public}d,min:%{public}d,max:%{public}d,"
234 "fuzz:%{public}d,flat:%{public}d,resolution:%{public}d,"
235 "standardValue:%{public}lf,isChanged:%{public}d}, ",
236 axisName.c_str(), r.code, r.value, r.minimum, r.maximum, r.fuzz, r.flat, r.resolution,
237 r.standardValue, r.isChanged);
238 }
239
PrintEventJoyStickAxisInfo(const EventJoyStickAxis & r,const int32_t fd,const int32_t abilityId,const int32_t focusId,const int64_t preHandlerTime)240 void PrintEventJoyStickAxisInfo(const EventJoyStickAxis &r, const int32_t fd,
241 const int32_t abilityId, const int32_t focusId, const int64_t preHandlerTime)
242 {
243 MMI_HILOGD("Event dispatcher of server, EventJoyStickAxis:physical:%{public}s,"
244 "fd:%{public}d,preHandlerTime:%{public}" PRId64 ","
245 "time:%{public}" PRId64 ",deviceType:%{public}u,eventType:%{public}d,deviceName:%{public}s",
246 r.physical, fd, preHandlerTime, r.time, r.deviceType,
247 r.eventType, r.deviceName);
248
249 PrintEventJoyStickAxisInfo(std::string("abs_throttle"), r.abs_throttle);
250 PrintEventJoyStickAxisInfo(std::string("abs_hat0x"), r.abs_hat0x);
251 PrintEventJoyStickAxisInfo(std::string("abs_hat0y"), r.abs_hat0y);
252 PrintEventJoyStickAxisInfo(std::string("abs_x"), r.abs_x);
253 PrintEventJoyStickAxisInfo(std::string("abs_y"), r.abs_y);
254 PrintEventJoyStickAxisInfo(std::string("abs_z"), r.abs_z);
255 PrintEventJoyStickAxisInfo(std::string("abs_rx"), r.abs_rx);
256 PrintEventJoyStickAxisInfo(std::string("abs_ry"), r.abs_ry);
257 PrintEventJoyStickAxisInfo(std::string("abs_rz"), r.abs_rz);
258 }
259
PrintWMSInfo(const std::string & str,const int32_t fd,const int32_t abilityId,const int32_t focusId)260 void PrintWMSInfo(const std::string &str, const int32_t fd, const int32_t abilityId, const int32_t focusId)
261 {
262 MMI_HILOGD("MMIWMS:windowId:%{public}s", str.c_str());
263 if (focusId == -1) {
264 MMI_HILOGD("WMS:windowId = ''");
265 } else {
266 MMI_HILOGD("WMS:windowId:%{public}d", focusId);
267 }
268 MMI_HILOGI("CALL_AMS, fd:%{public}d,abilityID:%{public}d", fd, abilityId);
269 }
270
GetPid()271 int32_t GetPid()
272 {
273 return static_cast<int32_t>(getpid());
274 }
275
GetFileName(const std::string & strPath)276 std::string GetFileName(const std::string &strPath)
277 {
278 size_t nPos = strPath.find_last_of('/');
279 if (strPath.npos == nPos) {
280 nPos = strPath.find_last_of('\\');
281 }
282 if (strPath.npos == nPos) {
283 return strPath;
284 }
285 return strPath.substr(nPos + 1, strPath.npos);
286 }
287
GetProgramName()288 const char* GetProgramName()
289 {
290 static char programName[PROGRAM_NAME_SIZE] = {};
291 if (programName[0] != '\0') {
292 return programName;
293 }
294
295 char buf[BUF_CMD_SIZE] = { 0 };
296 if (sprintf_s(buf, BUF_CMD_SIZE, "/proc/%d/cmdline", static_cast<int32_t>(getpid())) == -1) {
297 KMSG_LOGE("GetProcessInfo sprintf_s /proc/.../cmdline error");
298 return "";
299 }
300 FILE *fp = fopen(buf, "rb");
301 if (fp == nullptr) {
302 KMSG_LOGE("The fp is nullptr, filename = %s.", buf);
303 return "";
304 }
305 static constexpr size_t bufLineSize = 512;
306 char bufLine[bufLineSize] = { 0 };
307 if ((fgets(bufLine, bufLineSize, fp) == nullptr)) {
308 KMSG_LOGE("fgets failed.");
309 if (fclose(fp) != 0) {
310 KMSG_LOGW("Close file:%s failed", buf);
311 }
312 fp = nullptr;
313 return "";
314 }
315 if (fclose(fp) != 0) {
316 KMSG_LOGW("Close file:%s failed", buf);
317 }
318 fp = nullptr;
319
320 std::string tempName(bufLine);
321 tempName = GetFileName(tempName);
322 if (tempName.empty()) {
323 KMSG_LOGE("tempName is empty.");
324 return "";
325 }
326 const size_t copySize = std::min(tempName.size(), PROGRAM_NAME_SIZE - 1);
327 if (copySize == 0) {
328 KMSG_LOGE("The copySize is 0.");
329 return "";
330 }
331 errno_t ret = memcpy_s(programName, PROGRAM_NAME_SIZE, tempName.c_str(), copySize);
332 if (ret != EOK) {
333 return "";
334 }
335 KMSG_LOGI("GetProgramName success. programName = %s", programName);
336
337 return programName;
338 }
339
MmiBasename(char * path)340 char* MmiBasename(char* path)
341 {
342 if (path == nullptr) {
343 return nullptr;
344 }
345
346 char* rightSlash = strrchr(path, '/');
347 char* pBasename = nullptr;
348 if (rightSlash != nullptr) {
349 pBasename = (rightSlash + 1);
350 } else {
351 pBasename = path;
352 }
353
354 return pBasename;
355 }
356
SetThreadName(const std::string & name)357 void SetThreadName(const std::string &name)
358 {
359 prctl(PR_SET_NAME, name.c_str());
360 }
361
362 namespace {
363 thread_local std::string g_threadName;
364 } // namespace
GetThreadName()365 const std::string& GetThreadName()
366 {
367 if (!g_threadName.empty()) {
368 return g_threadName;
369 }
370 static constexpr size_t maxThreadNameSize = 16;
371 char thisThreadName[maxThreadNameSize + 1];
372 int32_t ret = prctl(PR_GET_NAME, thisThreadName);
373 if (ret == 0) {
374 thisThreadName[maxThreadNameSize] = '\0';
375 g_threadName = thisThreadName;
376 } else {
377 printf("in GetThreadName, call prctl get name fail, errno: %d.\n", errno);
378 }
379 return g_threadName;
380 }
381
AddId(std::vector<int32_t> & list,int32_t id)382 void AddId(std::vector<int32_t> &list, int32_t id)
383 {
384 if (id <= 0) {
385 return;
386 }
387 auto it = std::find(list.begin(), list.end(), id);
388 if (it != list.end()) {
389 return;
390 }
391 list.push_back(id);
392 }
393
CalculateDifference(const std::vector<int32_t> & list1,std::vector<int32_t> & list2,std::vector<int32_t> & difList)394 size_t CalculateDifference(const std::vector<int32_t> &list1, std::vector<int32_t> &list2,
395 std::vector<int32_t> &difList)
396 {
397 if (list1.empty()) {
398 difList = list2;
399 return difList.size();
400 }
401 if (list2.empty()) {
402 difList = list1;
403 return difList.size();
404 }
405 std::vector<int32_t> l1 = list1;
406 std::sort(l1.begin(), l1.end());
407 std::vector<int32_t> l2 = list2;
408 std::sort(l2.begin(), l2.end());
409 std::set_difference(l1.begin(), l1.end(), l2.begin(), l2.end(), std::back_inserter(difList));
410 return difList.size();
411 }
412
StringFmt(const char * str,...)413 std::string StringFmt(const char* str, ...)
414 {
415 if (str == nullptr) {
416 MMI_HILOGW("Str is nullptr");
417 return "";
418 }
419 va_list args;
420 va_start(args, str);
421 char buf[MAX_PACKET_BUF_SIZE] = {};
422 if (vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, str, args) == -1) {
423 MMI_HILOGE("vsnprintf_s error");
424 va_end(args);
425 return "";
426 }
427 va_end(args);
428 return buf;
429 }
430
IsFileExists(const std::string & fileName)431 static bool IsFileExists(const std::string &fileName)
432 {
433 return (access(fileName.c_str(), F_OK) == 0);
434 }
435
CheckFileExtendName(const std::string & filePath,const std::string & checkExtension)436 static bool CheckFileExtendName(const std::string &filePath, const std::string &checkExtension)
437 {
438 std::string::size_type pos = filePath.find_last_of('.');
439 if (pos == std::string::npos) {
440 MMI_HILOGE("File is not find extension");
441 return false;
442 }
443 return (filePath.substr(pos + 1, filePath.npos) == checkExtension);
444 }
445
GetFileSize(const std::string & filePath)446 static int32_t GetFileSize(const std::string &filePath)
447 {
448 struct stat statbuf = {0};
449 if (stat(filePath.c_str(), &statbuf) != 0) {
450 MMI_HILOGE("Get file size error");
451 return INVALID_FILE_SIZE;
452 }
453 return statbuf.st_size;
454 }
455
ReadFile(const std::string & filePath)456 static std::string ReadFile(const std::string &filePath)
457 {
458 FILE* fp = fopen(filePath.c_str(), "r");
459 CHKPS(fp);
460 std::string dataStr;
461 char buf[256] = {};
462 while (fgets(buf, sizeof(buf), fp) != nullptr) {
463 dataStr += buf;
464 }
465 if (fclose(fp) != 0) {
466 MMI_HILOGW("Close file failed");
467 }
468 return dataStr;
469 }
470
IsValidPath(const std::string & rootDir,const std::string & filePath)471 static bool IsValidPath(const std::string &rootDir, const std::string &filePath)
472 {
473 return (filePath.compare(0, rootDir.size(), rootDir) == 0);
474 }
475
IsValidJsonPath(const std::string & filePath)476 static bool IsValidJsonPath(const std::string &filePath)
477 {
478 return IsValidPath(DATA_PATH, filePath) ||
479 IsValidPath(INPUT_PATH, filePath);
480 }
481
IsValidProPath(const std::string & filePath)482 static bool IsValidProPath(const std::string &filePath)
483 {
484 return IsValidPath(KEY_PATH, filePath);
485 }
486
IsValidTomlPath(const std::string & filePath)487 static bool IsValidTomlPath(const std::string &filePath)
488 {
489 return IsValidPath(KEY_PATH, filePath);
490 }
491
ReadProFile(const std::string & filePath,int32_t deviceId,std::map<int32_t,std::map<int32_t,int32_t>> & configMap)492 void ReadProFile(const std::string &filePath, int32_t deviceId,
493 std::map<int32_t, std::map<int32_t, int32_t>> &configMap)
494 {
495 CALL_DEBUG_ENTER;
496 if (filePath.empty()) {
497 MMI_HILOGE("FilePath is empty");
498 return;
499 }
500 char realPath[PATH_MAX] = {};
501 if (realpath(filePath.c_str(), realPath) == nullptr) {
502 MMI_HILOGE("Path is error");
503 return;
504 }
505 if (!IsValidProPath(realPath)) {
506 MMI_HILOGE("File path is error");
507 return;
508 }
509 if (!IsFileExists(realPath)) {
510 MMI_HILOGE("File is not existent");
511 return;
512 }
513 if (!CheckFileExtendName(realPath, "pro")) {
514 MMI_HILOGE("Unable to parse files other than json format");
515 return;
516 }
517 auto fileSize = GetFileSize(realPath);
518 if ((fileSize == INVALID_FILE_SIZE) || (fileSize >= MAX_PRO_FILE_SIZE)) {
519 MMI_HILOGE("The configuration file size is incorrect");
520 return;
521 }
522 ReadProConfigFile(realPath, deviceId, configMap);
523 }
524
ReadProConfigFile(const std::string & realPath,int32_t deviceId,std::map<int32_t,std::map<int32_t,int32_t>> & configKey)525 void ReadProConfigFile(const std::string &realPath, int32_t deviceId,
526 std::map<int32_t, std::map<int32_t, int32_t>> &configKey)
527 {
528 CALL_DEBUG_ENTER;
529 std::ifstream reader(realPath);
530 if (!reader.is_open()) {
531 MMI_HILOGE("Failed to open config file");
532 return;
533 }
534 std::string strLine;
535 int32_t sysKeyValue;
536 int32_t nativeKeyValue;
537 std::map<int32_t, int32_t> tmpConfigKey;
538 while (std::getline(reader, strLine)) {
539 size_t pos = strLine.find('#');
540 if (pos != strLine.npos && pos != COMMENT_SUBSCRIPT) {
541 MMI_HILOGE("The comment line format is error");
542 reader.close();
543 return;
544 }
545 if (!strLine.empty() && strLine.front() != '#') {
546 std::istringstream stream(strLine);
547 std::array<std::string, KEY_ELEMENT_COUNT> keyElement;
548 stream >> keyElement[0] >> keyElement[1] >> keyElement[2] >> keyElement[3];
549 if (keyElement[0].empty() || keyElement[1].empty() || keyElement[2].empty() || keyElement[3].empty()) {
550 MMI_HILOGE("The key value data is incomplete");
551 reader.close();
552 return;
553 }
554 if (!IsNum(keyElement[1]) || !IsNum(keyElement[2])) {
555 MMI_HILOGE("Get key value is invalid");
556 reader.close();
557 return;
558 }
559 nativeKeyValue = stoi(keyElement[1]);
560 sysKeyValue = stoi(keyElement[2]);
561 tmpConfigKey.insert(std::pair<int32_t, int32_t>(nativeKeyValue, sysKeyValue));
562 }
563 }
564 reader.close();
565 auto iter = configKey.insert(std::make_pair(deviceId, tmpConfigKey));
566 if (!iter.second) {
567 MMI_HILOGE("The file name is duplicated");
568 return;
569 }
570 }
571
ReadJsonFile(const std::string & filePath)572 std::string ReadJsonFile(const std::string &filePath)
573 {
574 if (filePath.empty()) {
575 MMI_HILOGE("FilePath is empty");
576 return "";
577 }
578 char realPath[PATH_MAX] = {};
579 if (realpath(filePath.c_str(), realPath) == nullptr) {
580 MMI_HILOGE("Path is error");
581 return "";
582 }
583 if (!IsValidJsonPath(realPath)) {
584 MMI_HILOGE("File path is error");
585 return "";
586 }
587 if (!CheckFileExtendName(realPath, "json")) {
588 MMI_HILOGE("Unable to parse files other than json format");
589 return "";
590 }
591 if (!IsFileExists(realPath)) {
592 MMI_HILOGE("File is not existent");
593 return "";
594 }
595 int32_t fileSize = GetFileSize(realPath);
596 if ((fileSize <= 0) || (fileSize > FILE_SIZE_MAX)) {
597 MMI_HILOGE("File size out of read range");
598 return "";
599 }
600 return ReadFile(filePath);
601 }
602
ReadTomlFile(const std::string & filePath,DeviceConfig & devConf)603 int32_t ReadTomlFile(const std::string &filePath, DeviceConfig &devConf)
604 {
605 if (filePath.empty()) {
606 MMI_HILOGE("FilePath is empty");
607 return RET_ERR;
608 }
609 char realPath[PATH_MAX] = {};
610 if (realpath(filePath.c_str(), realPath) == nullptr) {
611 MMI_HILOGI("The realpath return nullptr");
612 return RET_ERR;
613 }
614 if (!IsValidTomlPath(realPath)) {
615 MMI_HILOGE("File path is error");
616 return RET_ERR;
617 }
618 if (!IsFileExists(realPath)) {
619 MMI_HILOGE("File is not existent");
620 return RET_ERR;
621 }
622 if (!CheckFileExtendName(realPath, "TOML")) {
623 MMI_HILOGE("Unable to parse files other than json format");
624 return RET_ERR;
625 }
626 int32_t fileSize = GetFileSize(realPath);
627 if ((fileSize <= 0) || (fileSize > FILE_SIZE_MAX)) {
628 MMI_HILOGE("File size out of read range");
629 return RET_ERR;
630 }
631 if (ReadConfigFile(realPath, devConf) == RET_ERR) {
632 MMI_HILOGE("Read device config file failed");
633 return RET_ERR;
634 }
635 return RET_OK;
636 }
637
ReadConfigFile(const std::string & realPath,DeviceConfig & devConf)638 int32_t ReadConfigFile(const std::string &realPath, DeviceConfig &devConf)
639 {
640 CALL_DEBUG_ENTER;
641 std::ifstream cfgFile(realPath);
642 if (!cfgFile.is_open()) {
643 MMI_HILOGE("Failed to open config file");
644 return FILE_OPEN_FAIL;
645 }
646 std::string tmp;
647 while (std::getline(cfgFile, tmp)) {
648 RemoveSpace(tmp);
649 size_t pos = tmp.find('#');
650 if (pos != tmp.npos && pos != COMMENT_SUBSCRIPT) {
651 MMI_HILOGE("File format is error");
652 cfgFile.close();
653 return RET_ERR;
654 }
655 if (tmp.empty() || tmp.front() == '#') {
656 continue;
657 }
658 pos = tmp.find('=');
659 if (pos == (tmp.size() - 1) || pos == tmp.npos) {
660 MMI_HILOGE("Find config item error");
661 cfgFile.close();
662 return RET_ERR;
663 }
664 std::string configItem = tmp.substr(0, pos);
665 std::string value = tmp.substr(pos + 1);
666 if (ConfigItemSwitch(configItem, value, devConf) == RET_ERR) {
667 MMI_HILOGE("Configuration item error");
668 cfgFile.close();
669 return RET_ERR;
670 }
671 }
672 cfgFile.close();
673 return RET_OK;
674 }
675
ConfigItemSwitch(const std::string & configItem,const std::string & value,DeviceConfig & devConf)676 int32_t ConfigItemSwitch(const std::string &configItem, const std::string &value, DeviceConfig &devConf)
677 {
678 CALL_DEBUG_ENTER;
679 if (configItem.empty() || value.empty()) {
680 MMI_HILOGE("Get key config item is invalid");
681 return RET_ERR;
682 }
683 if (!IsNum(value)) {
684 MMI_HILOGE("Get key config item is invalid");
685 return RET_ERR;
686 }
687 if (configItem == CONFIG_ITEM_REPEAT) {
688 devConf.autoSwitch = stoi(value);
689 } else if (configItem == CONFIG_ITEM_DELAY) {
690 devConf.delayTime = stoi(value);
691 if (devConf.delayTime < MIN_DELAYTIME || devConf.delayTime > MAX_DELAYTIME) {
692 MMI_HILOGE("Unusual the delaytime");
693 return RET_ERR;
694 }
695 } else if (configItem == CONFIG_ITEM_INTERVAL) {
696 devConf.intervalTime = stoi(value);
697 if (devConf.intervalTime < MIN_INTERVALTIME || devConf.intervalTime > MAX_INTERVALTIME) {
698 MMI_HILOGE("Unusual the intervaltime");
699 return RET_ERR;
700 }
701 } else if (configItem == CONFIG_ITEM_TYPE) {
702 devConf.keyboardType = stoi(value);
703 }
704 return RET_OK;
705 }
706
ReadCursorStyleFile(const std::string & filePath)707 int32_t ReadCursorStyleFile(const std::string &filePath)
708 {
709 CALL_DEBUG_ENTER;
710 if (filePath.empty()) {
711 MMI_HILOGE("FilePath is empty");
712 return RET_ERR;
713 }
714 if (!IsFileExists(filePath)) {
715 MMI_HILOGE("File is not existent");
716 return RET_ERR;
717 }
718 char realPath[PATH_MAX] = {};
719 if (realpath(filePath.c_str(), realPath) == nullptr) {
720 MMI_HILOGE("Path is error");
721 return RET_ERR;
722 }
723 int32_t fileSize = GetFileSize(realPath);
724 if ((fileSize <= 0) || (fileSize > FILE_SIZE_MAX)) {
725 MMI_HILOGE("File size out of read range");
726 return RET_ERR;
727 }
728 return RET_OK;
729 }
730
StringPrintf(const char * format,...)731 std::string StringPrintf(const char *format, ...)
732 {
733 char space[1024];
734
735 va_list ap;
736 va_start(ap, format);
737 std::string result;
738 int32_t ret = vsnprintf_s(space, sizeof(space), sizeof(space) - 1, format, ap);
739 if (ret >= RET_OK && (size_t)ret < sizeof(space)) {
740 result = space;
741 } else {
742 MMI_HILOGE("The buffer is overflow");
743 }
744 va_end(ap);
745 return result;
746 }
747 } // namespace MMI
748 } // namespace OHOS
749