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 #include <chrono>
18 #include <cstdarg>
19 #include <iomanip>
20 #include <sstream>
21 #include <thread>
22 #include <fcntl.h>
23 #include <cinttypes>
24 #include <sys/prctl.h>
25 #include <sys/stat.h>
26 #include <sys/syscall.h>
27 #include <sys/time.h>
28 #include <sys/types.h>
29 #include <unistd.h>
30
31 #include "config_multimodal.h"
32 #include "define_multimodal.h"
33 #include "error_multimodal.h"
34 #include "mmi_log.h"
35 #include "securec.h"
36 #include "uuid.h"
37
38 namespace OHOS {
39 namespace MMI {
40 namespace {
41 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, MMI_LOG_DOMAIN, "Util"};
42 }
43
44 const std::map<int32_t, std::string> ERROR_STRING_MAP = {
45 {MSG_SEND_FAIL, "Send Message Failed"},
46 {NON_STD_EVENT, "Non-Standardized Event"},
47 {UNKNOWN_EVENT, "Unknown Event"},
48 {UNPROC_MSG, "Unprocessed Message"},
49 {UNKNOWN_MSG_ID, "Unknown Message Id"},
50 {UNKNOWN_DEV, "Unknown Device"},
51 {ERROR_NULL_POINTER, "Null Pointer"},
52 {FILE_OPEN_FAIL, "Open File Failed"},
53 {FILE_READ_FAIL, "Read File Failed"},
54 {FILE_WRITE_FAIL, "Write File Failed"},
55 {API_PARAM_TYPE_FAIL, "API Param Type Error"},
56 {API_OUT_OF_RANGE, "API Out Of Range Error"},
57 {FOCUS_ID_OBTAIN_FAIL, "Obtain FocusID Failed"},
58 };
59
GetMmiErrorTypeDesc(int32_t errorCodeEnum)60 const char *GetMmiErrorTypeDesc(int32_t errorCodeEnum)
61 {
62 auto str = ERROR_STRING_MAP.find(errorCodeEnum);
63 if (str == ERROR_STRING_MAP.end()) {
64 return nullptr;
65 }
66 return str->second.c_str();
67 }
68
GetEnv(const std::string & name)69 std::string GetEnv(const std::string &name)
70 {
71 CHKR(!name.empty(), PARAM_INPUT_INVALID, "");
72 return "";
73 }
GetMicrotime()74 int64_t GetMicrotime()
75 {
76 struct timeval currentTime = {};
77 gettimeofday(¤tTime, nullptr);
78 return currentTime.tv_sec * 1000 * 1000 + currentTime.tv_usec;
79 }
80
GetSysClockTime()81 int64_t GetSysClockTime()
82 {
83 struct timespec ts = { 0, 0 };
84 if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
85 MMI_LOGD("clock_gettime failed:%{public}d", errno);
86 return 0;
87 }
88 return (ts.tv_sec * 1000 * 1000) + (ts.tv_nsec / 1000);
89 }
90
GetMillisTime()91 int64_t GetMillisTime()
92 {
93 auto timeNow = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
94 auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(timeNow.time_since_epoch());
95 return tmp.count();
96 }
97
UuIdGenerate()98 std::string UuIdGenerate()
99 {
100 constexpr int32_t UUID_BUF_SIZE = 64;
101 char buf[UUID_BUF_SIZE] = {};
102 return buf;
103 }
104
GetUUid()105 std::string GetUUid()
106 {
107 Uuid uid;
108 std::string strUuid;
109 uid.ConvertToStdString(strUuid);
110 return strUuid;
111 }
112
GetThisThreadIdOfString()113 std::string GetThisThreadIdOfString()
114 {
115 thread_local std::string threadLocalId;
116 if (threadLocalId.empty()) {
117 long tid = syscall(SYS_gettid);
118 constexpr size_t bufSize = 10;
119 char buf[bufSize] = {};
120 const int32_t ret = sprintf_s(buf, bufSize, "%06d", tid);
121 if (ret < 0) {
122 printf("ERR: in %s, #%d, call sprintf_s fail, ret = %d.", __func__, __LINE__, ret);
123 return threadLocalId;
124 }
125 buf[bufSize - 1] = '\0';
126 threadLocalId = buf;
127 }
128
129 return threadLocalId;
130 }
131
GetThisThreadIdOfLL()132 uint64_t GetThisThreadIdOfLL()
133 {
134 std::string stid = GetThisThreadIdOfString();
135 auto tid = std::stoull(stid);
136 return tid;
137 }
138
StringToken(std::string & str,const std::string & sep,std::string & token)139 size_t StringToken(std::string &str, const std::string &sep, std::string &token)
140 {
141 token = "";
142 if (str.empty()) {
143 return str.npos;
144 }
145 size_t pos = str.npos;
146 size_t tmp = 0;
147 for (auto &item : sep) {
148 tmp = str.find(item);
149 if (str.npos != tmp) {
150 pos = (std::min)(pos, tmp);
151 }
152 }
153 if (str.npos != pos) {
154 token = str.substr(0, pos);
155 if (str.npos != pos + 1) {
156 str = str.substr(pos + 1, str.npos);
157 }
158 if (pos == 0) {
159 return StringToken(str, sep, token);
160 }
161 } else {
162 token = str;
163 str = "";
164 }
165 return token.size();
166 }
167
StringSplit(const std::string & str,const std::string & sep,std::vector<std::string> & vecList)168 size_t StringSplit(const std::string &str, const std::string &sep, std::vector<std::string>&vecList)
169 {
170 size_t size;
171 auto strs = str;
172 std::string token;
173 while (str.npos != (size = StringToken(strs, sep, token))) {
174 vecList.push_back(token);
175 }
176 return vecList.size();
177 }
178
IdsListToString(const std::vector<int32_t> & list,const std::string & sep)179 std::string IdsListToString(const std::vector<int32_t> &list, const std::string &sep)
180 {
181 std::string str;
182 for (const auto &it : list) {
183 str += std::to_string(it) + sep;
184 }
185 if (str.size() > 0) {
186 str.resize(str.size() - sep.size());
187 }
188 return str;
189 }
190
LocalTime(struct tm & t,time_t curTime)191 void LocalTime(struct tm &t, time_t curTime)
192 {
193 time_t curTimeTemp = curTime;
194 if (curTimeTemp == 0) {
195 curTimeTemp = time(nullptr);
196 }
197 auto tm = localtime(&curTimeTemp);
198 if (tm) {
199 t = *tm;
200 }
201 }
202
Strftime(const std::string & format,time_t curTime)203 std::string Strftime(const std::string &format, time_t curTime)
204 {
205 if (format.empty()) {
206 return format;
207 }
208 struct tm t = {};
209 LocalTime(t, curTime);
210 char szDTime[32] = "";
211 (void)strftime(szDTime, sizeof(szDTime), format.c_str(), &t);
212 return szDTime;
213 }
214
PrintEventJoyStickAxisInfo(const std::string & axisName,const EventJoyStickAxisAbsInfo & r)215 static void PrintEventJoyStickAxisInfo(const std::string &axisName, const EventJoyStickAxisAbsInfo &r)
216 {
217 MMI_LOGD("%{public}s: {code:%{public}d,value:%{public}d,min:%{public}d,max:%{public}d,"
218 "fuzz:%{public}d,flat:%{public}d,resolution:%{public}d,"
219 "standardValue:%{public}lf,isChanged:%{public}d}, ",
220 axisName.c_str(), r.code, r.value, r.minimum, r.maximum, r.fuzz, r.flat, r.resolution,
221 r.standardValue, r.isChanged);
222 }
223
PrintEventJoyStickAxisInfo(const EventJoyStickAxis & r,const int32_t fd,const int32_t abilityId,const int32_t focusId,const int64_t preHandlerTime)224 void PrintEventJoyStickAxisInfo(const EventJoyStickAxis& r, const int32_t fd,
225 const int32_t abilityId, const int32_t focusId, const int64_t preHandlerTime)
226 {
227 MMI_LOGD("4.event dispatcher of server, EventJoyStickAxis:physical:%{public}s,"
228 "fd:%{public}d,preHandlerTime:%{public}" PRId64 ","
229 "time:%{public}" PRId64 ",deviceType:%{public}u,eventType:%{public}d,deviceName:%{public}s",
230 r.physical, fd, preHandlerTime, r.time, r.deviceType,
231 r.eventType, r.deviceName);
232
233 PrintEventJoyStickAxisInfo(std::string("abs_throttle"), r.abs_throttle);
234 PrintEventJoyStickAxisInfo(std::string("abs_hat0x"), r.abs_hat0x);
235 PrintEventJoyStickAxisInfo(std::string("abs_hat0y"), r.abs_hat0y);
236 PrintEventJoyStickAxisInfo(std::string("abs_x"), r.abs_x);
237 PrintEventJoyStickAxisInfo(std::string("abs_y"), r.abs_y);
238 PrintEventJoyStickAxisInfo(std::string("abs_z"), r.abs_z);
239 PrintEventJoyStickAxisInfo(std::string("abs_rx"), r.abs_rx);
240 PrintEventJoyStickAxisInfo(std::string("abs_ry"), r.abs_ry);
241 PrintEventJoyStickAxisInfo(std::string("abs_rz"), r.abs_rz);
242 }
243
PrintWMSInfo(const std::string & str,const int32_t fd,const int32_t abilityId,const int32_t focusId)244 void PrintWMSInfo(const std::string& str, const int32_t fd, const int32_t abilityId, const int32_t focusId)
245 {
246 MMI_LOGD("MMIWMS:windowId:%{public}s", str.c_str());
247 if (focusId == -1) {
248 MMI_LOGD("WMS:windowId = ''");
249 } else {
250 MMI_LOGD("WMS:windowId:%{public}d", focusId);
251 }
252 MMI_LOGD("CALL_AMS, fd:%{public}d,abilityID:%{public}d", fd, abilityId);
253 }
254
GetPid()255 int32_t GetPid()
256 {
257 return static_cast<int32_t>(getpid());
258 }
259
GetFileName(const std::string & strPath)260 std::string GetFileName(const std::string& strPath)
261 {
262 size_t nPos = strPath.find_last_of('/');
263 if (strPath.npos == nPos)
264 nPos = strPath.find_last_of('\\');
265 if (strPath.npos == nPos)
266 return strPath;
267 return strPath.substr(nPos + 1, strPath.npos);
268 }
269
GetProgramName()270 const char* GetProgramName()
271 {
272 constexpr size_t programNameSize = 256;
273 static char programName[programNameSize] = {};
274 if (programName[0] != '\0') {
275 return programName;
276 }
277
278 constexpr size_t bufSize = 512;
279 char buf[bufSize] = { 0 };
280 if (sprintf_s(buf, bufSize, "/proc/%d/cmdline", static_cast<int32_t>(getpid())) == -1) {
281 KMSG_LOGE("GetProcessInfo sprintf_s /proc/.../cmdline error");
282 return "";
283 }
284 FILE *fp = fopen(buf, "rb");
285 if (fp == nullptr) {
286 KMSG_LOGE("fp is nullptr, filename = %s.", buf);
287 return "";
288 }
289 constexpr size_t bufLineSize = 512;
290 char bufLine[bufLineSize] = { 0 };
291 if ((fgets(bufLine, bufLineSize, fp) == nullptr)) {
292 KMSG_LOGE("fgets fail.");
293 (void)fclose(fp);
294 fp = nullptr;
295 return "";
296 }
297 (void)fclose(fp);
298 fp = nullptr;
299
300 std::string tempName(bufLine);
301 tempName = GetFileName(tempName);
302 if (tempName.empty()) {
303 KMSG_LOGE("tempName is empty.");
304 return "";
305 }
306 const size_t copySize = (std::min)(tempName.size(), programNameSize - 1);
307 if (copySize == 0) {
308 KMSG_LOGE("copySize is 0.");
309 return "";
310 }
311 int32_t ret = memcpy_s(programName, programNameSize, tempName.c_str(), copySize);
312 if (RET_OK != ret) {
313 return "";
314 }
315 KMSG_LOGI("GetProgramName success. programName = %s", programName);
316
317 return programName;
318 }
319
MmiBasename(char * path)320 char* MmiBasename(char* path)
321 {
322 if (path == nullptr) {
323 return nullptr;
324 }
325
326 char* rightSlash = strrchr(path, '/');
327 char* pBasename = nullptr;
328 if (rightSlash != nullptr) {
329 pBasename = (rightSlash + 1);
330 } else {
331 pBasename = path;
332 }
333
334 return pBasename;
335 }
336
SetThreadName(const std::string & name)337 void SetThreadName(const std::string& name)
338 {
339 prctl(PR_SET_NAME, name.c_str());
340 }
341
342 namespace {
343 thread_local std::string g_threadName;
344 }
GetThreadName()345 const std::string& GetThreadName()
346 {
347 if (!g_threadName.empty()) {
348 return g_threadName;
349 }
350 constexpr size_t MAX_THREAD_NAME_SIZE = 16;
351 char thisThreadName[MAX_THREAD_NAME_SIZE + 1];
352 int32_t ret = prctl(PR_GET_NAME, thisThreadName);
353 if (ret == 0) {
354 thisThreadName[MAX_THREAD_NAME_SIZE] = '\0';
355 g_threadName = thisThreadName;
356 } else {
357 printf("in GetThreadName, call prctl get name fail, errno: %d.\n", errno);
358 }
359 return g_threadName;
360 }
361
AddId(std::vector<int32_t> & list,int32_t id)362 void AddId(std::vector<int32_t> &list, int32_t id)
363 {
364 if (id <= 0) {
365 return;
366 }
367 auto it = std::find(list.begin(), list.end(), id);
368 if (it != list.end()) {
369 return;
370 }
371 list.push_back(id);
372 }
373
CalculateDifference(const std::vector<int32_t> & list1,std::vector<int32_t> & list2,std::vector<int32_t> & difList)374 size_t CalculateDifference(const std::vector<int32_t> &list1, std::vector<int32_t> &list2,
375 std::vector<int32_t> &difList)
376 {
377 if (list1.empty()) {
378 difList = list2;
379 return difList.size();
380 }
381 if (list2.empty()) {
382 difList = list1;
383 return difList.size();
384 }
385 std::vector<int32_t> l1 = list1;
386 std::sort(l1.begin(), l1.end());
387 std::vector<int32_t> l2 = list2;
388 std::sort(l2.begin(), l2.end());
389 std::set_difference(l1.begin(), l1.end(), l2.begin(), l2.end(), std::back_inserter(difList));
390 return difList.size();
391 }
392
StringFmt(const char * str,...)393 std::string StringFmt(const char* str, ...)
394 {
395 CHKR(str != nullptr, PARAM_INPUT_INVALID, "");
396 va_list args;
397 va_start(args, str);
398 char buf[MAX_PACKET_BUF_SIZE] = {};
399 if (vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, str, args) == -1) {
400 MMI_LOGE("vsnprintf_s error");
401 va_end(args);
402 return "";
403 }
404 va_end(args);
405 return buf;
406 }
407
408 } // namespace MMI
409 } // namespace OHOS
410