• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "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(&currentTime, 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