1c29fa5a6Sopenharmony_ci/* 2c29fa5a6Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3c29fa5a6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4c29fa5a6Sopenharmony_ci * you may not use this file except in compliance with the License. 5c29fa5a6Sopenharmony_ci * You may obtain a copy of the License at 6c29fa5a6Sopenharmony_ci * 7c29fa5a6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8c29fa5a6Sopenharmony_ci * 9c29fa5a6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10c29fa5a6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11c29fa5a6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12c29fa5a6Sopenharmony_ci * See the License for the specific language governing permissions and 13c29fa5a6Sopenharmony_ci * limitations under the License. 14c29fa5a6Sopenharmony_ci */ 15c29fa5a6Sopenharmony_ci 16c29fa5a6Sopenharmony_ci#include "util.h" 17c29fa5a6Sopenharmony_ci 18c29fa5a6Sopenharmony_ci#include <array> 19c29fa5a6Sopenharmony_ci#include <chrono> 20c29fa5a6Sopenharmony_ci#include <cinttypes> 21c29fa5a6Sopenharmony_ci#include <cstdarg> 22c29fa5a6Sopenharmony_ci#include <fstream> 23c29fa5a6Sopenharmony_ci#include <iostream> 24c29fa5a6Sopenharmony_ci 25c29fa5a6Sopenharmony_ci#include <sys/prctl.h> 26c29fa5a6Sopenharmony_ci#include <sys/stat.h> 27c29fa5a6Sopenharmony_ci#include <sys/syscall.h> 28c29fa5a6Sopenharmony_ci#include <sys/time.h> 29c29fa5a6Sopenharmony_ci#include <sys/types.h> 30c29fa5a6Sopenharmony_ci#include <unistd.h> 31c29fa5a6Sopenharmony_ci 32c29fa5a6Sopenharmony_ci#include "aggregator.h" 33c29fa5a6Sopenharmony_ci#include "config_multimodal.h" 34c29fa5a6Sopenharmony_ci#include "define_multimodal.h" 35c29fa5a6Sopenharmony_ci#include "error_multimodal.h" 36c29fa5a6Sopenharmony_ci#include "mmi_log.h" 37c29fa5a6Sopenharmony_ci#include "securec.h" 38c29fa5a6Sopenharmony_ci 39c29fa5a6Sopenharmony_ci#undef MMI_LOG_TAG 40c29fa5a6Sopenharmony_ci#define MMI_LOG_TAG "Util" 41c29fa5a6Sopenharmony_ci 42c29fa5a6Sopenharmony_cinamespace OHOS { 43c29fa5a6Sopenharmony_cinamespace MMI { 44c29fa5a6Sopenharmony_cinamespace { 45c29fa5a6Sopenharmony_ciconstexpr int32_t FILE_SIZE_MAX { 0x6C445 }; 46c29fa5a6Sopenharmony_ciconstexpr int32_t MAX_PRO_FILE_SIZE { 128000 }; 47c29fa5a6Sopenharmony_ciconstexpr int32_t INVALID_FILE_SIZE { -1 }; 48c29fa5a6Sopenharmony_ciconstexpr int32_t MIN_INTERVALTIME { 36 }; 49c29fa5a6Sopenharmony_ciconstexpr int32_t MAX_INTERVALTIME { 100 }; 50c29fa5a6Sopenharmony_ciconstexpr int32_t MIN_DELAYTIME { 300 }; 51c29fa5a6Sopenharmony_ciconstexpr int32_t MAX_DELAYTIME { 1000 }; 52c29fa5a6Sopenharmony_ciconstexpr int32_t COMMENT_SUBSCRIPT { 0 }; 53c29fa5a6Sopenharmony_ciconst std::string CONFIG_ITEM_REPEAT = "Key.autorepeat"; 54c29fa5a6Sopenharmony_ciconst std::string CONFIG_ITEM_DELAY = "Key.autorepeat.delaytime"; 55c29fa5a6Sopenharmony_ciconst std::string CONFIG_ITEM_INTERVAL = "Key.autorepeat.intervaltime"; 56c29fa5a6Sopenharmony_ciconst std::string CONFIG_ITEM_TYPE = "Key.keyboard.type"; 57c29fa5a6Sopenharmony_ciconst std::string CURSORSTYLE_PATH = "/system/etc/multimodalinput/mouse_icon/"; 58c29fa5a6Sopenharmony_ciconst std::string DATA_PATH = "/data"; 59c29fa5a6Sopenharmony_ciconst std::string INPUT_PATH = "/system/"; 60c29fa5a6Sopenharmony_ciconst std::string KEY_PATH = "/vendor/etc/keymap/"; 61c29fa5a6Sopenharmony_ciconstexpr size_t BUF_TID_SIZE { 10 }; 62c29fa5a6Sopenharmony_ciconstexpr size_t BUF_CMD_SIZE { 512 }; 63c29fa5a6Sopenharmony_ciconstexpr size_t PROGRAM_NAME_SIZE { 256 }; 64c29fa5a6Sopenharmony_ciconstexpr int32_t TIME_CONVERSION_UNIT { 1000 }; 65c29fa5a6Sopenharmony_ci} // namespace 66c29fa5a6Sopenharmony_ci 67c29fa5a6Sopenharmony_ciint64_t GetSysClockTime() 68c29fa5a6Sopenharmony_ci{ 69c29fa5a6Sopenharmony_ci struct timespec ts = { 0, 0 }; 70c29fa5a6Sopenharmony_ci if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { 71c29fa5a6Sopenharmony_ci MMI_HILOGD("clock_gettime failed:%{public}d", errno); 72c29fa5a6Sopenharmony_ci return 0; 73c29fa5a6Sopenharmony_ci } 74c29fa5a6Sopenharmony_ci return (ts.tv_sec * TIME_CONVERSION_UNIT * TIME_CONVERSION_UNIT) + (ts.tv_nsec / TIME_CONVERSION_UNIT); 75c29fa5a6Sopenharmony_ci} 76c29fa5a6Sopenharmony_ci 77c29fa5a6Sopenharmony_ciint64_t GetMillisTime() 78c29fa5a6Sopenharmony_ci{ 79c29fa5a6Sopenharmony_ci auto timeNow = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now()); 80c29fa5a6Sopenharmony_ci auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(timeNow.time_since_epoch()); 81c29fa5a6Sopenharmony_ci return tmp.count(); 82c29fa5a6Sopenharmony_ci} 83c29fa5a6Sopenharmony_ci 84c29fa5a6Sopenharmony_cistatic std::string GetThisThreadIdOfString() 85c29fa5a6Sopenharmony_ci{ 86c29fa5a6Sopenharmony_ci thread_local std::string threadLocalId; 87c29fa5a6Sopenharmony_ci if (threadLocalId.empty()) { 88c29fa5a6Sopenharmony_ci long tid = syscall(SYS_gettid); 89c29fa5a6Sopenharmony_ci char buf[BUF_TID_SIZE] = {}; 90c29fa5a6Sopenharmony_ci const int32_t ret = sprintf_s(buf, BUF_TID_SIZE, "%06d", tid); 91c29fa5a6Sopenharmony_ci if (ret < 0) { 92c29fa5a6Sopenharmony_ci printf("ERR: in %s, #%d, call sprintf_s failed, ret = %d", __func__, __LINE__, ret); 93c29fa5a6Sopenharmony_ci return threadLocalId; 94c29fa5a6Sopenharmony_ci } 95c29fa5a6Sopenharmony_ci buf[BUF_TID_SIZE - 1] = '\0'; 96c29fa5a6Sopenharmony_ci threadLocalId = buf; 97c29fa5a6Sopenharmony_ci } 98c29fa5a6Sopenharmony_ci 99c29fa5a6Sopenharmony_ci return threadLocalId; 100c29fa5a6Sopenharmony_ci} 101c29fa5a6Sopenharmony_ci 102c29fa5a6Sopenharmony_ciuint64_t GetThisThreadId() 103c29fa5a6Sopenharmony_ci{ 104c29fa5a6Sopenharmony_ci std::string stid = GetThisThreadIdOfString(); 105c29fa5a6Sopenharmony_ci auto tid = std::atoll(stid.c_str()); 106c29fa5a6Sopenharmony_ci return tid; 107c29fa5a6Sopenharmony_ci} 108c29fa5a6Sopenharmony_ci 109c29fa5a6Sopenharmony_cistatic size_t StringToken(std::string &str, const std::string &sep, std::string &token) 110c29fa5a6Sopenharmony_ci{ 111c29fa5a6Sopenharmony_ci token = ""; 112c29fa5a6Sopenharmony_ci if (str.empty()) { 113c29fa5a6Sopenharmony_ci return str.npos; 114c29fa5a6Sopenharmony_ci } 115c29fa5a6Sopenharmony_ci size_t pos = str.npos; 116c29fa5a6Sopenharmony_ci size_t tmp = 0; 117c29fa5a6Sopenharmony_ci for (auto &item : sep) { 118c29fa5a6Sopenharmony_ci tmp = str.find(item); 119c29fa5a6Sopenharmony_ci if (str.npos != tmp) { 120c29fa5a6Sopenharmony_ci pos = (std::min)(pos, tmp); 121c29fa5a6Sopenharmony_ci } 122c29fa5a6Sopenharmony_ci } 123c29fa5a6Sopenharmony_ci if (str.npos != pos) { 124c29fa5a6Sopenharmony_ci token = str.substr(0, pos); 125c29fa5a6Sopenharmony_ci if (str.npos != pos + 1) { 126c29fa5a6Sopenharmony_ci str = str.substr(pos + 1, str.npos); 127c29fa5a6Sopenharmony_ci } 128c29fa5a6Sopenharmony_ci if (pos == 0) { 129c29fa5a6Sopenharmony_ci return StringToken(str, sep, token); 130c29fa5a6Sopenharmony_ci } 131c29fa5a6Sopenharmony_ci } else { 132c29fa5a6Sopenharmony_ci token = str; 133c29fa5a6Sopenharmony_ci str = ""; 134c29fa5a6Sopenharmony_ci } 135c29fa5a6Sopenharmony_ci return token.size(); 136c29fa5a6Sopenharmony_ci} 137c29fa5a6Sopenharmony_ci 138c29fa5a6Sopenharmony_cisize_t StringSplit(const std::string &str, const std::string &sep, std::vector<std::string> &vecList) 139c29fa5a6Sopenharmony_ci{ 140c29fa5a6Sopenharmony_ci size_t size; 141c29fa5a6Sopenharmony_ci auto strs = str; 142c29fa5a6Sopenharmony_ci std::string token; 143c29fa5a6Sopenharmony_ci while (str.npos != (size = StringToken(strs, sep, token))) { 144c29fa5a6Sopenharmony_ci vecList.push_back(token); 145c29fa5a6Sopenharmony_ci } 146c29fa5a6Sopenharmony_ci return vecList.size(); 147c29fa5a6Sopenharmony_ci} 148c29fa5a6Sopenharmony_ci 149c29fa5a6Sopenharmony_cistd::string IdsListToString(const std::vector<int32_t> &list, const std::string &sep) 150c29fa5a6Sopenharmony_ci{ 151c29fa5a6Sopenharmony_ci std::string str; 152c29fa5a6Sopenharmony_ci for (const auto &it : list) { 153c29fa5a6Sopenharmony_ci str += std::to_string(it) + sep; 154c29fa5a6Sopenharmony_ci } 155c29fa5a6Sopenharmony_ci if (str.size() > 0) { 156c29fa5a6Sopenharmony_ci str.resize(str.size() - sep.size()); 157c29fa5a6Sopenharmony_ci } 158c29fa5a6Sopenharmony_ci return str; 159c29fa5a6Sopenharmony_ci} 160c29fa5a6Sopenharmony_ci 161c29fa5a6Sopenharmony_ciint32_t GetPid() 162c29fa5a6Sopenharmony_ci{ 163c29fa5a6Sopenharmony_ci return static_cast<int32_t>(getpid()); 164c29fa5a6Sopenharmony_ci} 165c29fa5a6Sopenharmony_ci 166c29fa5a6Sopenharmony_cistatic std::string GetFileName(const std::string &strPath) 167c29fa5a6Sopenharmony_ci{ 168c29fa5a6Sopenharmony_ci size_t nPos = strPath.find_last_of('/'); 169c29fa5a6Sopenharmony_ci if (strPath.npos == nPos) { 170c29fa5a6Sopenharmony_ci nPos = strPath.find_last_of('\\'); 171c29fa5a6Sopenharmony_ci } 172c29fa5a6Sopenharmony_ci if (strPath.npos == nPos) { 173c29fa5a6Sopenharmony_ci return strPath; 174c29fa5a6Sopenharmony_ci } 175c29fa5a6Sopenharmony_ci 176c29fa5a6Sopenharmony_ci return strPath.substr(nPos + 1, strPath.npos); 177c29fa5a6Sopenharmony_ci} 178c29fa5a6Sopenharmony_ci 179c29fa5a6Sopenharmony_ciconst char *GetProgramName() 180c29fa5a6Sopenharmony_ci{ 181c29fa5a6Sopenharmony_ci static char programName[PROGRAM_NAME_SIZE] = {}; 182c29fa5a6Sopenharmony_ci if (programName[0] != '\0') { 183c29fa5a6Sopenharmony_ci return programName; 184c29fa5a6Sopenharmony_ci } 185c29fa5a6Sopenharmony_ci 186c29fa5a6Sopenharmony_ci char buf[BUF_CMD_SIZE] = { 0 }; 187c29fa5a6Sopenharmony_ci if (sprintf_s(buf, BUF_CMD_SIZE, "/proc/%d/cmdline", static_cast<int32_t>(getpid())) == -1) { 188c29fa5a6Sopenharmony_ci KMSG_LOGE("GetProcessInfo sprintf_s /proc/.../cmdline error"); 189c29fa5a6Sopenharmony_ci return ""; 190c29fa5a6Sopenharmony_ci } 191c29fa5a6Sopenharmony_ci FILE *fp = fopen(buf, "rb"); 192c29fa5a6Sopenharmony_ci CHKPS(fp); 193c29fa5a6Sopenharmony_ci static constexpr size_t bufLineSize = 512; 194c29fa5a6Sopenharmony_ci char bufLine[bufLineSize] = { 0 }; 195c29fa5a6Sopenharmony_ci if ((fgets(bufLine, bufLineSize, fp) == nullptr)) { 196c29fa5a6Sopenharmony_ci KMSG_LOGE("fgets failed"); 197c29fa5a6Sopenharmony_ci if (fclose(fp) != 0) { 198c29fa5a6Sopenharmony_ci KMSG_LOGW("Close file:%s failed", buf); 199c29fa5a6Sopenharmony_ci } 200c29fa5a6Sopenharmony_ci fp = nullptr; 201c29fa5a6Sopenharmony_ci return ""; 202c29fa5a6Sopenharmony_ci } 203c29fa5a6Sopenharmony_ci if (fclose(fp) != 0) { 204c29fa5a6Sopenharmony_ci KMSG_LOGW("Close file:%s failed", buf); 205c29fa5a6Sopenharmony_ci } 206c29fa5a6Sopenharmony_ci fp = nullptr; 207c29fa5a6Sopenharmony_ci 208c29fa5a6Sopenharmony_ci std::string tempName(bufLine); 209c29fa5a6Sopenharmony_ci tempName = GetFileName(tempName); 210c29fa5a6Sopenharmony_ci if (tempName.empty()) { 211c29fa5a6Sopenharmony_ci KMSG_LOGE("tempName is empty"); 212c29fa5a6Sopenharmony_ci return ""; 213c29fa5a6Sopenharmony_ci } 214c29fa5a6Sopenharmony_ci const size_t copySize = std::min(tempName.size(), PROGRAM_NAME_SIZE - 1); 215c29fa5a6Sopenharmony_ci if (copySize == 0) { 216c29fa5a6Sopenharmony_ci KMSG_LOGE("The copySize is 0"); 217c29fa5a6Sopenharmony_ci return ""; 218c29fa5a6Sopenharmony_ci } 219c29fa5a6Sopenharmony_ci errno_t ret = memcpy_s(programName, PROGRAM_NAME_SIZE, tempName.c_str(), copySize); 220c29fa5a6Sopenharmony_ci if (ret != EOK) { 221c29fa5a6Sopenharmony_ci return ""; 222c29fa5a6Sopenharmony_ci } 223c29fa5a6Sopenharmony_ci KMSG_LOGI("GetProgramName success. programName = %s", programName); 224c29fa5a6Sopenharmony_ci 225c29fa5a6Sopenharmony_ci return programName; 226c29fa5a6Sopenharmony_ci} 227c29fa5a6Sopenharmony_ci 228c29fa5a6Sopenharmony_civoid SetThreadName(const std::string &name) 229c29fa5a6Sopenharmony_ci{ 230c29fa5a6Sopenharmony_ci prctl(PR_SET_NAME, name.c_str()); 231c29fa5a6Sopenharmony_ci} 232c29fa5a6Sopenharmony_ci 233c29fa5a6Sopenharmony_cistatic bool IsFileExists(const std::string &fileName) 234c29fa5a6Sopenharmony_ci{ 235c29fa5a6Sopenharmony_ci return (access(fileName.c_str(), F_OK) == 0); 236c29fa5a6Sopenharmony_ci} 237c29fa5a6Sopenharmony_ci 238c29fa5a6Sopenharmony_cistatic bool CheckFileExtendName(const std::string &filePath, const std::string &checkExtension) 239c29fa5a6Sopenharmony_ci{ 240c29fa5a6Sopenharmony_ci std::string::size_type pos = filePath.find_last_of('.'); 241c29fa5a6Sopenharmony_ci if (pos == std::string::npos) { 242c29fa5a6Sopenharmony_ci MMI_HILOGE("File is not find extension"); 243c29fa5a6Sopenharmony_ci return false; 244c29fa5a6Sopenharmony_ci } 245c29fa5a6Sopenharmony_ci return (filePath.substr(pos + 1, filePath.npos) == checkExtension); 246c29fa5a6Sopenharmony_ci} 247c29fa5a6Sopenharmony_ci 248c29fa5a6Sopenharmony_cistatic int32_t GetFileSize(const std::string &filePath) 249c29fa5a6Sopenharmony_ci{ 250c29fa5a6Sopenharmony_ci struct stat statbuf = { 0 }; 251c29fa5a6Sopenharmony_ci if (stat(filePath.c_str(), &statbuf) != 0) { 252c29fa5a6Sopenharmony_ci MMI_HILOGE("Get file size error"); 253c29fa5a6Sopenharmony_ci return INVALID_FILE_SIZE; 254c29fa5a6Sopenharmony_ci } 255c29fa5a6Sopenharmony_ci return statbuf.st_size; 256c29fa5a6Sopenharmony_ci} 257c29fa5a6Sopenharmony_ci 258c29fa5a6Sopenharmony_cistatic std::string ReadFile(const std::string &filePath) 259c29fa5a6Sopenharmony_ci{ 260c29fa5a6Sopenharmony_ci FILE *fp = fopen(filePath.c_str(), "r"); 261c29fa5a6Sopenharmony_ci CHKPS(fp); 262c29fa5a6Sopenharmony_ci std::string dataStr; 263c29fa5a6Sopenharmony_ci char buf[256] = {}; 264c29fa5a6Sopenharmony_ci while (fgets(buf, sizeof(buf), fp) != nullptr) { 265c29fa5a6Sopenharmony_ci dataStr += buf; 266c29fa5a6Sopenharmony_ci } 267c29fa5a6Sopenharmony_ci if (fclose(fp) != 0) { 268c29fa5a6Sopenharmony_ci MMI_HILOGW("Close file failed"); 269c29fa5a6Sopenharmony_ci } 270c29fa5a6Sopenharmony_ci return dataStr; 271c29fa5a6Sopenharmony_ci} 272c29fa5a6Sopenharmony_ci 273c29fa5a6Sopenharmony_cistatic bool IsValidPath(const std::string &rootDir, const std::string &filePath) 274c29fa5a6Sopenharmony_ci{ 275c29fa5a6Sopenharmony_ci return (filePath.compare(0, rootDir.size(), rootDir) == 0); 276c29fa5a6Sopenharmony_ci} 277c29fa5a6Sopenharmony_ci 278c29fa5a6Sopenharmony_cibool IsValidJsonPath(const std::string &filePath) 279c29fa5a6Sopenharmony_ci{ 280c29fa5a6Sopenharmony_ci return IsValidPath(DATA_PATH, filePath) || IsValidPath(INPUT_PATH, filePath); 281c29fa5a6Sopenharmony_ci} 282c29fa5a6Sopenharmony_ci 283c29fa5a6Sopenharmony_cistatic bool IsValidProPath(const std::string &filePath) 284c29fa5a6Sopenharmony_ci{ 285c29fa5a6Sopenharmony_ci return IsValidPath(KEY_PATH, filePath); 286c29fa5a6Sopenharmony_ci} 287c29fa5a6Sopenharmony_ci 288c29fa5a6Sopenharmony_cistatic bool IsValidTomlPath(const std::string &filePath) 289c29fa5a6Sopenharmony_ci{ 290c29fa5a6Sopenharmony_ci return IsValidPath(KEY_PATH, filePath); 291c29fa5a6Sopenharmony_ci} 292c29fa5a6Sopenharmony_ci 293c29fa5a6Sopenharmony_civoid ReadProFile(const std::string &filePath, int32_t deviceId, 294c29fa5a6Sopenharmony_ci std::map<int32_t, std::map<int32_t, int32_t>> &configMap) 295c29fa5a6Sopenharmony_ci{ 296c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 297c29fa5a6Sopenharmony_ci if (filePath.empty()) { 298c29fa5a6Sopenharmony_ci MMI_HILOGE("FilePath is empty"); 299c29fa5a6Sopenharmony_ci return; 300c29fa5a6Sopenharmony_ci } 301c29fa5a6Sopenharmony_ci char realPath[PATH_MAX] = {}; 302c29fa5a6Sopenharmony_ci CHKPV(realpath(filePath.c_str(), realPath)); 303c29fa5a6Sopenharmony_ci if (!IsValidProPath(realPath)) { 304c29fa5a6Sopenharmony_ci MMI_HILOGE("File path is error"); 305c29fa5a6Sopenharmony_ci return; 306c29fa5a6Sopenharmony_ci } 307c29fa5a6Sopenharmony_ci if (!IsFileExists(realPath)) { 308c29fa5a6Sopenharmony_ci MMI_HILOGE("File is not existent"); 309c29fa5a6Sopenharmony_ci return; 310c29fa5a6Sopenharmony_ci } 311c29fa5a6Sopenharmony_ci if (!CheckFileExtendName(realPath, "pro")) { 312c29fa5a6Sopenharmony_ci MMI_HILOGE("Unable to parse files other than json format"); 313c29fa5a6Sopenharmony_ci return; 314c29fa5a6Sopenharmony_ci } 315c29fa5a6Sopenharmony_ci auto fileSize = GetFileSize(realPath); 316c29fa5a6Sopenharmony_ci if ((fileSize == INVALID_FILE_SIZE) || (fileSize >= MAX_PRO_FILE_SIZE)) { 317c29fa5a6Sopenharmony_ci MMI_HILOGE("The configuration file size is incorrect"); 318c29fa5a6Sopenharmony_ci return; 319c29fa5a6Sopenharmony_ci } 320c29fa5a6Sopenharmony_ci ReadProConfigFile(realPath, deviceId, configMap); 321c29fa5a6Sopenharmony_ci} 322c29fa5a6Sopenharmony_ci 323c29fa5a6Sopenharmony_cistatic inline bool IsNum(const std::string &str) 324c29fa5a6Sopenharmony_ci{ 325c29fa5a6Sopenharmony_ci std::istringstream sin(str); 326c29fa5a6Sopenharmony_ci double num; 327c29fa5a6Sopenharmony_ci return (sin >> num) && sin.eof(); 328c29fa5a6Sopenharmony_ci} 329c29fa5a6Sopenharmony_ci 330c29fa5a6Sopenharmony_civoid ReadProConfigFile(const std::string &realPath, int32_t deviceId, 331c29fa5a6Sopenharmony_ci std::map<int32_t, std::map<int32_t, int32_t>> &configKey) 332c29fa5a6Sopenharmony_ci{ 333c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 334c29fa5a6Sopenharmony_ci std::ifstream reader(realPath); 335c29fa5a6Sopenharmony_ci if (!reader.is_open()) { 336c29fa5a6Sopenharmony_ci MMI_HILOGE("Failed to open config file"); 337c29fa5a6Sopenharmony_ci return; 338c29fa5a6Sopenharmony_ci } 339c29fa5a6Sopenharmony_ci std::string strLine; 340c29fa5a6Sopenharmony_ci int32_t sysKeyValue; 341c29fa5a6Sopenharmony_ci int32_t nativeKeyValue; 342c29fa5a6Sopenharmony_ci int32_t elementKey = 0; 343c29fa5a6Sopenharmony_ci int32_t elementValue = 0; 344c29fa5a6Sopenharmony_ci std::map<int32_t, int32_t> tmpConfigKey; 345c29fa5a6Sopenharmony_ci while (std::getline(reader, strLine)) { 346c29fa5a6Sopenharmony_ci const char* line = strLine.c_str(); 347c29fa5a6Sopenharmony_ci int32_t len = strlen(line); 348c29fa5a6Sopenharmony_ci char* realLine = static_cast<char*>(malloc(len + 1)); 349c29fa5a6Sopenharmony_ci CHKPV(realLine); 350c29fa5a6Sopenharmony_ci if (strcpy_s(realLine, len + 1, line) != EOK) { 351c29fa5a6Sopenharmony_ci MMI_HILOGE("strcpy_s error"); 352c29fa5a6Sopenharmony_ci free(realLine); 353c29fa5a6Sopenharmony_ci realLine = nullptr; 354c29fa5a6Sopenharmony_ci return; 355c29fa5a6Sopenharmony_ci } 356c29fa5a6Sopenharmony_ci *(realLine + len + 1) = '\0'; 357c29fa5a6Sopenharmony_ci int32_t ret = ReadConfigInfo(realLine, len, &elementKey, &elementValue); 358c29fa5a6Sopenharmony_ci free(realLine); 359c29fa5a6Sopenharmony_ci realLine = nullptr; 360c29fa5a6Sopenharmony_ci if (ret != RET_OK) { 361c29fa5a6Sopenharmony_ci MMI_HILOGE("Failed to read from line of config info"); 362c29fa5a6Sopenharmony_ci reader.close(); 363c29fa5a6Sopenharmony_ci return; 364c29fa5a6Sopenharmony_ci } 365c29fa5a6Sopenharmony_ci nativeKeyValue = elementKey; 366c29fa5a6Sopenharmony_ci sysKeyValue = elementValue; 367c29fa5a6Sopenharmony_ci MMI_HILOGD("The nativeKeyValue is:%{public}d, sysKeyValue is:%{public}d", nativeKeyValue, sysKeyValue); 368c29fa5a6Sopenharmony_ci tmpConfigKey.insert(std::pair<int32_t, int32_t>(nativeKeyValue, sysKeyValue)); 369c29fa5a6Sopenharmony_ci } 370c29fa5a6Sopenharmony_ci reader.close(); 371c29fa5a6Sopenharmony_ci auto iter = configKey.insert(std::make_pair(deviceId, tmpConfigKey)); 372c29fa5a6Sopenharmony_ci if (!iter.second) { 373c29fa5a6Sopenharmony_ci MMI_HILOGE("The file name is duplicated"); 374c29fa5a6Sopenharmony_ci return; 375c29fa5a6Sopenharmony_ci } 376c29fa5a6Sopenharmony_ci} 377c29fa5a6Sopenharmony_ci 378c29fa5a6Sopenharmony_cistd::string ReadJsonFile(const std::string &filePath) 379c29fa5a6Sopenharmony_ci{ 380c29fa5a6Sopenharmony_ci if (filePath.empty()) { 381c29fa5a6Sopenharmony_ci MMI_HILOGE("FilePath is empty"); 382c29fa5a6Sopenharmony_ci return ""; 383c29fa5a6Sopenharmony_ci } 384c29fa5a6Sopenharmony_ci char realPath[PATH_MAX] = {}; 385c29fa5a6Sopenharmony_ci CHKPS(realpath(filePath.c_str(), realPath)); 386c29fa5a6Sopenharmony_ci if (!IsValidJsonPath(realPath)) { 387c29fa5a6Sopenharmony_ci MMI_HILOGE("File path is error"); 388c29fa5a6Sopenharmony_ci return ""; 389c29fa5a6Sopenharmony_ci } 390c29fa5a6Sopenharmony_ci if (!CheckFileExtendName(realPath, "json")) { 391c29fa5a6Sopenharmony_ci MMI_HILOGE("Unable to parse files other than json format"); 392c29fa5a6Sopenharmony_ci return ""; 393c29fa5a6Sopenharmony_ci } 394c29fa5a6Sopenharmony_ci if (!IsFileExists(realPath)) { 395c29fa5a6Sopenharmony_ci MMI_HILOGE("File is not existent"); 396c29fa5a6Sopenharmony_ci return ""; 397c29fa5a6Sopenharmony_ci } 398c29fa5a6Sopenharmony_ci int32_t fileSize = GetFileSize(realPath); 399c29fa5a6Sopenharmony_ci if ((fileSize <= 0) || (fileSize > FILE_SIZE_MAX)) { 400c29fa5a6Sopenharmony_ci MMI_HILOGE("File size out of read range"); 401c29fa5a6Sopenharmony_ci return ""; 402c29fa5a6Sopenharmony_ci } 403c29fa5a6Sopenharmony_ci return ReadFile(filePath); 404c29fa5a6Sopenharmony_ci} 405c29fa5a6Sopenharmony_ci 406c29fa5a6Sopenharmony_cistatic int32_t ConfigItemSwitch(const std::string &configItem, const std::string &value, DeviceConfig &devConf) 407c29fa5a6Sopenharmony_ci{ 408c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 409c29fa5a6Sopenharmony_ci if (configItem.empty() || value.empty()) { 410c29fa5a6Sopenharmony_ci MMI_HILOGE("Get key config item is invalid"); 411c29fa5a6Sopenharmony_ci return RET_ERR; 412c29fa5a6Sopenharmony_ci } 413c29fa5a6Sopenharmony_ci if (!IsNum(value)) { 414c29fa5a6Sopenharmony_ci MMI_HILOGE("Get key config item is invalid"); 415c29fa5a6Sopenharmony_ci return RET_ERR; 416c29fa5a6Sopenharmony_ci } 417c29fa5a6Sopenharmony_ci if (configItem == CONFIG_ITEM_REPEAT) { 418c29fa5a6Sopenharmony_ci devConf.autoSwitch = stoi(value); 419c29fa5a6Sopenharmony_ci } else if (configItem == CONFIG_ITEM_DELAY) { 420c29fa5a6Sopenharmony_ci devConf.delayTime = stoi(value); 421c29fa5a6Sopenharmony_ci if (devConf.delayTime < MIN_DELAYTIME || devConf.delayTime > MAX_DELAYTIME) { 422c29fa5a6Sopenharmony_ci MMI_HILOGE("Unusual the delaytime"); 423c29fa5a6Sopenharmony_ci return RET_ERR; 424c29fa5a6Sopenharmony_ci } 425c29fa5a6Sopenharmony_ci } else if (configItem == CONFIG_ITEM_INTERVAL) { 426c29fa5a6Sopenharmony_ci devConf.intervalTime = stoi(value); 427c29fa5a6Sopenharmony_ci if (devConf.intervalTime < MIN_INTERVALTIME || devConf.intervalTime > MAX_INTERVALTIME) { 428c29fa5a6Sopenharmony_ci MMI_HILOGE("Unusual the intervaltime"); 429c29fa5a6Sopenharmony_ci return RET_ERR; 430c29fa5a6Sopenharmony_ci } 431c29fa5a6Sopenharmony_ci } else if (configItem == CONFIG_ITEM_TYPE) { 432c29fa5a6Sopenharmony_ci devConf.keyboardType = stoi(value); 433c29fa5a6Sopenharmony_ci } 434c29fa5a6Sopenharmony_ci return RET_OK; 435c29fa5a6Sopenharmony_ci} 436c29fa5a6Sopenharmony_ci 437c29fa5a6Sopenharmony_cistatic int32_t ReadConfigFile(const std::string &realPath, DeviceConfig &devConf) 438c29fa5a6Sopenharmony_ci{ 439c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 440c29fa5a6Sopenharmony_ci std::ifstream cfgFile(realPath); 441c29fa5a6Sopenharmony_ci if (!cfgFile.is_open()) { 442c29fa5a6Sopenharmony_ci MMI_HILOGE("Failed to open config file"); 443c29fa5a6Sopenharmony_ci return FILE_OPEN_FAIL; 444c29fa5a6Sopenharmony_ci } 445c29fa5a6Sopenharmony_ci std::string tmp; 446c29fa5a6Sopenharmony_ci while (std::getline(cfgFile, tmp)) { 447c29fa5a6Sopenharmony_ci RemoveSpace(tmp); 448c29fa5a6Sopenharmony_ci size_t pos = tmp.find('#'); 449c29fa5a6Sopenharmony_ci if (pos != tmp.npos && pos != COMMENT_SUBSCRIPT) { 450c29fa5a6Sopenharmony_ci MMI_HILOGE("File format is error"); 451c29fa5a6Sopenharmony_ci cfgFile.close(); 452c29fa5a6Sopenharmony_ci return RET_ERR; 453c29fa5a6Sopenharmony_ci } 454c29fa5a6Sopenharmony_ci if (tmp.empty() || tmp.front() == '#') { 455c29fa5a6Sopenharmony_ci continue; 456c29fa5a6Sopenharmony_ci } 457c29fa5a6Sopenharmony_ci pos = tmp.find('='); 458c29fa5a6Sopenharmony_ci if ((pos == std::string::npos) || (tmp.back() == '=')) { 459c29fa5a6Sopenharmony_ci MMI_HILOGE("Find config item error"); 460c29fa5a6Sopenharmony_ci cfgFile.close(); 461c29fa5a6Sopenharmony_ci return RET_ERR; 462c29fa5a6Sopenharmony_ci } 463c29fa5a6Sopenharmony_ci std::string configItem = tmp.substr(0, pos); 464c29fa5a6Sopenharmony_ci std::string value = tmp.substr(pos + 1); 465c29fa5a6Sopenharmony_ci if (ConfigItemSwitch(configItem, value, devConf) == RET_ERR) { 466c29fa5a6Sopenharmony_ci MMI_HILOGE("Configuration item error"); 467c29fa5a6Sopenharmony_ci cfgFile.close(); 468c29fa5a6Sopenharmony_ci return RET_ERR; 469c29fa5a6Sopenharmony_ci } 470c29fa5a6Sopenharmony_ci } 471c29fa5a6Sopenharmony_ci cfgFile.close(); 472c29fa5a6Sopenharmony_ci return RET_OK; 473c29fa5a6Sopenharmony_ci} 474c29fa5a6Sopenharmony_ci 475c29fa5a6Sopenharmony_ciint32_t ReadTomlFile(const std::string &filePath, DeviceConfig &devConf) 476c29fa5a6Sopenharmony_ci{ 477c29fa5a6Sopenharmony_ci if (filePath.empty()) { 478c29fa5a6Sopenharmony_ci MMI_HILOGE("FilePath is empty"); 479c29fa5a6Sopenharmony_ci return RET_ERR; 480c29fa5a6Sopenharmony_ci } 481c29fa5a6Sopenharmony_ci char realPath[PATH_MAX] = {}; 482c29fa5a6Sopenharmony_ci CHKPR(realpath(filePath.c_str(), realPath), RET_ERR); 483c29fa5a6Sopenharmony_ci if (!IsValidTomlPath(realPath)) { 484c29fa5a6Sopenharmony_ci MMI_HILOGE("File path is error"); 485c29fa5a6Sopenharmony_ci return RET_ERR; 486c29fa5a6Sopenharmony_ci } 487c29fa5a6Sopenharmony_ci if (!IsFileExists(realPath)) { 488c29fa5a6Sopenharmony_ci MMI_HILOGE("File is not existent"); 489c29fa5a6Sopenharmony_ci return RET_ERR; 490c29fa5a6Sopenharmony_ci } 491c29fa5a6Sopenharmony_ci if (!CheckFileExtendName(realPath, "TOML")) { 492c29fa5a6Sopenharmony_ci MMI_HILOGE("Unable to parse files other than json format"); 493c29fa5a6Sopenharmony_ci return RET_ERR; 494c29fa5a6Sopenharmony_ci } 495c29fa5a6Sopenharmony_ci int32_t fileSize = GetFileSize(realPath); 496c29fa5a6Sopenharmony_ci if ((fileSize <= 0) || (fileSize > FILE_SIZE_MAX)) { 497c29fa5a6Sopenharmony_ci MMI_HILOGE("File size out of read range"); 498c29fa5a6Sopenharmony_ci return RET_ERR; 499c29fa5a6Sopenharmony_ci } 500c29fa5a6Sopenharmony_ci if (ReadConfigFile(realPath, devConf) == RET_ERR) { 501c29fa5a6Sopenharmony_ci MMI_HILOGE("Read device config file failed"); 502c29fa5a6Sopenharmony_ci return RET_ERR; 503c29fa5a6Sopenharmony_ci } 504c29fa5a6Sopenharmony_ci return RET_OK; 505c29fa5a6Sopenharmony_ci} 506c29fa5a6Sopenharmony_ci 507c29fa5a6Sopenharmony_ciint32_t ReadCursorStyleFile(const std::string &filePath) 508c29fa5a6Sopenharmony_ci{ 509c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 510c29fa5a6Sopenharmony_ci if (filePath.empty()) { 511c29fa5a6Sopenharmony_ci MMI_HILOGE("FilePath is empty"); 512c29fa5a6Sopenharmony_ci return RET_ERR; 513c29fa5a6Sopenharmony_ci } 514c29fa5a6Sopenharmony_ci if (!IsFileExists(filePath)) { 515c29fa5a6Sopenharmony_ci MMI_HILOGE("File is not existent"); 516c29fa5a6Sopenharmony_ci return RET_ERR; 517c29fa5a6Sopenharmony_ci } 518c29fa5a6Sopenharmony_ci char realPath[PATH_MAX] = {}; 519c29fa5a6Sopenharmony_ci CHKPR(realpath(filePath.c_str(), realPath), RET_ERR); 520c29fa5a6Sopenharmony_ci int32_t fileSize = GetFileSize(realPath); 521c29fa5a6Sopenharmony_ci if ((fileSize <= 0) || (fileSize > FILE_SIZE_MAX)) { 522c29fa5a6Sopenharmony_ci MMI_HILOGE("File size out of read range"); 523c29fa5a6Sopenharmony_ci return RET_ERR; 524c29fa5a6Sopenharmony_ci } 525c29fa5a6Sopenharmony_ci return RET_OK; 526c29fa5a6Sopenharmony_ci} 527c29fa5a6Sopenharmony_ci 528c29fa5a6Sopenharmony_cistd::string StringPrintf(const char *format, ...) 529c29fa5a6Sopenharmony_ci{ 530c29fa5a6Sopenharmony_ci char space[1024]; 531c29fa5a6Sopenharmony_ci 532c29fa5a6Sopenharmony_ci va_list ap; 533c29fa5a6Sopenharmony_ci va_start(ap, format); 534c29fa5a6Sopenharmony_ci std::string result; 535c29fa5a6Sopenharmony_ci int32_t ret = vsnprintf_s(space, sizeof(space), sizeof(space) - 1, format, ap); 536c29fa5a6Sopenharmony_ci if (ret >= RET_OK && (size_t)ret < sizeof(space)) { 537c29fa5a6Sopenharmony_ci result = space; 538c29fa5a6Sopenharmony_ci } else { 539c29fa5a6Sopenharmony_ci MMI_HILOGE("The buffer is overflow"); 540c29fa5a6Sopenharmony_ci } 541c29fa5a6Sopenharmony_ci va_end(ap); 542c29fa5a6Sopenharmony_ci return result; 543c29fa5a6Sopenharmony_ci} 544c29fa5a6Sopenharmony_ci 545c29fa5a6Sopenharmony_cistd::string FileVerification(std::string &filePath, const std::string &checkExtension) 546c29fa5a6Sopenharmony_ci{ 547c29fa5a6Sopenharmony_ci if (filePath.empty()) { 548c29fa5a6Sopenharmony_ci MMI_HILOGE("FilePath is empty"); 549c29fa5a6Sopenharmony_ci return ""; 550c29fa5a6Sopenharmony_ci } 551c29fa5a6Sopenharmony_ci char realPath[PATH_MAX] = {}; 552c29fa5a6Sopenharmony_ci CHKPS(realpath(filePath.c_str(), realPath)); 553c29fa5a6Sopenharmony_ci if (!IsFileExists(realPath)) { 554c29fa5a6Sopenharmony_ci MMI_HILOGE("File is not existent"); 555c29fa5a6Sopenharmony_ci return ""; 556c29fa5a6Sopenharmony_ci } 557c29fa5a6Sopenharmony_ci if (!CheckFileExtendName(realPath, checkExtension)) { 558c29fa5a6Sopenharmony_ci MMI_HILOGE("Unable to parse files other than json format"); 559c29fa5a6Sopenharmony_ci return ""; 560c29fa5a6Sopenharmony_ci } 561c29fa5a6Sopenharmony_ci int32_t fileSize = GetFileSize(realPath); 562c29fa5a6Sopenharmony_ci if ((fileSize <= 0) || (fileSize > FILE_SIZE_MAX)) { 563c29fa5a6Sopenharmony_ci MMI_HILOGE("File size out of read range"); 564c29fa5a6Sopenharmony_ci return ""; 565c29fa5a6Sopenharmony_ci } 566c29fa5a6Sopenharmony_ci return realPath; 567c29fa5a6Sopenharmony_ci} 568c29fa5a6Sopenharmony_ci 569c29fa5a6Sopenharmony_ci 570c29fa5a6Sopenharmony_cibool Aggregator::Record(const LogHeader &lh, const std::string &key, const std::string &record) 571c29fa5a6Sopenharmony_ci{ 572c29fa5a6Sopenharmony_ci constexpr int32_t oneSecond = 1000; 573c29fa5a6Sopenharmony_ci if (timerId_ != -1) { 574c29fa5a6Sopenharmony_ci resetTimer_(timerId_); 575c29fa5a6Sopenharmony_ci } else { 576c29fa5a6Sopenharmony_ci timerId_ = addTimer_(oneSecond, 1, [this, lh]() { 577c29fa5a6Sopenharmony_ci FlushRecords(lh); 578c29fa5a6Sopenharmony_ci timerId_ = -1; 579c29fa5a6Sopenharmony_ci }); 580c29fa5a6Sopenharmony_ci } 581c29fa5a6Sopenharmony_ci if (key == key_) { 582c29fa5a6Sopenharmony_ci auto now = std::chrono::system_clock::now(); 583c29fa5a6Sopenharmony_ci records_.push_back({record, now}); 584c29fa5a6Sopenharmony_ci if (records_.size() >= maxRecordCount_) { 585c29fa5a6Sopenharmony_ci FlushRecords(lh); 586c29fa5a6Sopenharmony_ci } 587c29fa5a6Sopenharmony_ci return true; 588c29fa5a6Sopenharmony_ci } else { 589c29fa5a6Sopenharmony_ci FlushRecords(lh, key, record); 590c29fa5a6Sopenharmony_ci key_ = key; 591c29fa5a6Sopenharmony_ci return false; 592c29fa5a6Sopenharmony_ci } 593c29fa5a6Sopenharmony_ci} 594c29fa5a6Sopenharmony_ci 595c29fa5a6Sopenharmony_civoid Aggregator::FlushRecords(const LogHeader &lh, const std::string &key, const std::string &extraRecord) 596c29fa5a6Sopenharmony_ci{ 597c29fa5a6Sopenharmony_ci constexpr uint32_t milliSecondWidth = 3; 598c29fa5a6Sopenharmony_ci constexpr uint32_t microToMilli = 1000; 599c29fa5a6Sopenharmony_ci size_t recordCount = records_.size(); 600c29fa5a6Sopenharmony_ci std::ostringstream oss; 601c29fa5a6Sopenharmony_ci if (!records_.empty()) { 602c29fa5a6Sopenharmony_ci oss << key_; 603c29fa5a6Sopenharmony_ci oss << ", first: " << records_.front().record << "-("; 604c29fa5a6Sopenharmony_ci auto firstTime = records_.front().timestamp; 605c29fa5a6Sopenharmony_ci time_t firstTimeT = std::chrono::system_clock::to_time_t(firstTime); 606c29fa5a6Sopenharmony_ci std::tm *bt = std::localtime(&firstTimeT); 607c29fa5a6Sopenharmony_ci if (bt == nullptr) { 608c29fa5a6Sopenharmony_ci MMI_HILOGE("bt is nullptr, this is a invalid time"); 609c29fa5a6Sopenharmony_ci return; 610c29fa5a6Sopenharmony_ci } 611c29fa5a6Sopenharmony_ci oss << std::put_time(bt, "%Y-%m-%d %H:%M:%S"); 612c29fa5a6Sopenharmony_ci auto since_epoch = firstTime.time_since_epoch(); 613c29fa5a6Sopenharmony_ci auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(since_epoch).count() % microToMilli; 614c29fa5a6Sopenharmony_ci oss << '.' << std::setfill('0') << std::setw(milliSecondWidth) << millis << "ms)"; 615c29fa5a6Sopenharmony_ci 616c29fa5a6Sopenharmony_ci if (records_.size() > 1) { 617c29fa5a6Sopenharmony_ci size_t i = records_.size() - 1; 618c29fa5a6Sopenharmony_ci const auto &recordInfo = records_[i]; 619c29fa5a6Sopenharmony_ci oss << ", " << recordInfo.record; 620c29fa5a6Sopenharmony_ci } 621c29fa5a6Sopenharmony_ci records_.clear(); 622c29fa5a6Sopenharmony_ci oss << ", count: " << recordCount; 623c29fa5a6Sopenharmony_ci } 624c29fa5a6Sopenharmony_ci if (!extraRecord.empty()) { 625c29fa5a6Sopenharmony_ci if (!oss.str().empty()) { 626c29fa5a6Sopenharmony_ci oss << ", last: "; 627c29fa5a6Sopenharmony_ci } 628c29fa5a6Sopenharmony_ci oss << key << ": " << extraRecord; 629c29fa5a6Sopenharmony_ci } 630c29fa5a6Sopenharmony_ci if (!oss.str().empty()) { 631c29fa5a6Sopenharmony_ci MMI_HILOG_HEADER(LOG_INFO, lh, "%{public}s", oss.str().c_str()); 632c29fa5a6Sopenharmony_ci } 633c29fa5a6Sopenharmony_ci} 634c29fa5a6Sopenharmony_ci 635c29fa5a6Sopenharmony_ciAggregator::~Aggregator() 636c29fa5a6Sopenharmony_ci{ 637c29fa5a6Sopenharmony_ci FlushRecords(MMI_LOG_HEADER); 638c29fa5a6Sopenharmony_ci} 639c29fa5a6Sopenharmony_ci 640c29fa5a6Sopenharmony_ci} // namespace MMI 641c29fa5a6Sopenharmony_ci} // namespace OHOS 642