1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
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 "common.h"
17 #include <fcntl.h>
18 #include <array>
19 #include <cinttypes>
20 #include <csignal>
21 #include <dirent.h>
22 #include <fstream>
23 #include <iostream>
24 #include <parameter.h>
25 #include <parameters.h>
26 #include <sstream>
27 #include <sys/file.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <unistd.h>
31 #include <sys/stat.h>
32
33 #include "application_info.h"
34 #include "bundle_mgr_proxy.h"
35 #include "file_ex.h"
36 #include "iservice_registry.h"
37 #include "logging.h"
38 #include "system_ability_definition.h"
39 #include "os_account_info.h"
40 #include "os_account_manager.h"
41
42 using namespace OHOS;
43 using namespace OHOS::AppExecFwk;
44 namespace COMMON {
45 namespace {
46 const std::map<std::string, clockid_t> clockIdMap = {
47 {"realtime", CLOCK_REALTIME},
48 {"mono", CLOCK_MONOTONIC},
49 {"process_cputime_id", CLOCK_PROCESS_CPUTIME_ID},
50 {"thread_cputime_id", CLOCK_THREAD_CPUTIME_ID},
51 {"mono_raw", CLOCK_MONOTONIC_RAW},
52 {"realtime_coarse", CLOCK_REALTIME_COARSE},
53 {"mono_coarse", CLOCK_MONOTONIC_COARSE},
54 {"boot", CLOCK_BOOTTIME},
55 {"realtime_alarm", CLOCK_REALTIME_ALARM},
56 {"boot_alarm", CLOCK_BOOTTIME_ALARM},
57 {"sgi_cycle", CLOCK_SGI_CYCLE},
58 {"tai", CLOCK_TAI},
59 };
60 constexpr int EXECVP_ERRNO = 2;
61 const int SHELL_UID = 2000;
62 const std::string DEFAULT_PATH = "/data/local/tmp/";
63 constexpr int READ = 0;
64 constexpr int WRITE = 1;
65 const int FILE_PATH_SIZE = 512;
66 const int BUFFER_SIZE = 1024;
67 const int INVALID_PID = -1;
68 constexpr int32_t EC_INVALID_VALUE = -2;
69 const std::string KEY_HIVIEW_USER_TYPE = "const.logsystem.versiontype";
70 }
71
IsProcessRunning(int & lockFileFd)72 bool IsProcessRunning(int& lockFileFd)
73 {
74 setgid(SHELL_UID);
75 char buffer[PATH_MAX + 1] = {0};
76 readlink("/proc/self/exe", buffer, PATH_MAX);
77 std::string processName = buffer;
78 int pos = static_cast<int>(processName.find_last_of('/'));
79 if (pos != 0) {
80 processName = processName.substr(pos + 1, processName.size());
81 }
82
83 std::string fileName = DEFAULT_PATH + processName + ".pid";
84 umask(S_IWOTH);
85 int fd = open(fileName.c_str(), O_WRONLY | O_CREAT, static_cast<mode_t>(0664)); // 0664: rw-rw-r--
86 if (fd < 0) {
87 const int bufSize = 256;
88 char buf[bufSize] = {0};
89 strerror_r(errno, buf, bufSize);
90 PROFILER_LOG_ERROR(LOG_CORE, "%s:failed to open(%s), errno(%d:%s)", __func__, fileName.c_str(), errno, buf);
91 return false;
92 }
93 int flags = fcntl(fd, F_GETFD);
94 if (flags == -1) {
95 close(fd);
96 PROFILER_LOG_ERROR(LOG_CORE, "%s: get fd flags failed!", __func__);
97 return false;
98 }
99 flags |= FD_CLOEXEC;
100 if (fcntl(fd, F_SETFD, flags) == -1) {
101 close(fd);
102 PROFILER_LOG_ERROR(LOG_CORE, "%s: set fd_cloexec failed!", __func__);
103 return false;
104 }
105 if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
106 // 进程正在运行,加锁失败
107 close(fd);
108 printf("%s is running, please don't start it again.\n", processName.c_str());
109 PROFILER_LOG_ERROR(LOG_CORE, "%s is running, please don't start it again.", processName.c_str());
110 return true;
111 }
112 std::string pidStr = std::to_string(getpid());
113 auto nbytes = write(fd, pidStr.data(), pidStr.size());
114 lockFileFd = fd;
115 CHECK_TRUE(static_cast<size_t>(nbytes) == pidStr.size(), false, "write pid FAILED!");
116 return false;
117 }
118
IsProcessExist(const std::string & processName,int & pid)119 bool IsProcessExist(const std::string& processName, int& pid)
120 {
121 DIR* dir = opendir("/proc");
122 CHECK_NOTNULL(dir, false, "open /proc dir failed");
123 struct dirent* ptr;
124 int pidValue = INVALID_PID;
125 while ((ptr = readdir(dir)) != nullptr) {
126 if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
127 continue;
128 }
129 if ((!isdigit(*ptr->d_name)) || ptr->d_type != DT_DIR) {
130 continue;
131 }
132 char filePath[FILE_PATH_SIZE] = {0};
133 int len = snprintf_s(filePath, FILE_PATH_SIZE, FILE_PATH_SIZE - 1, "/proc/%s/cmdline", ptr->d_name);
134 if (len < 0) {
135 PROFILER_LOG_WARN(LOG_CORE, "maybe, the contents of cmdline had be cut off");
136 continue;
137 }
138 FILE* fp = fopen(filePath, "r");
139 if (fp == nullptr) {
140 PROFILER_LOG_DEBUG(LOG_CORE, "open file failed! %s", filePath);
141 continue;
142 }
143 char buf[BUFFER_SIZE] = {0};
144 if (fgets(buf, sizeof(buf) - 1, fp) == nullptr) {
145 fclose(fp);
146 continue;
147 }
148 std::string str(buf);
149 size_t found = str.rfind("/");
150 std::string fullProcess;
151 if (found != std::string::npos) {
152 fullProcess = str.substr(found + 1);
153 } else {
154 fullProcess = str;
155 }
156 if (fullProcess == processName) {
157 pidValue = atoi(ptr->d_name);
158 fclose(fp);
159 break;
160 }
161 fclose(fp);
162 }
163 closedir(dir);
164 if (pidValue != INVALID_PID) {
165 pid = pidValue;
166 }
167 return pidValue != INVALID_PID;
168 }
169
CloseStdio()170 static void CloseStdio()
171 {
172 close(STDIN_FILENO);
173 close(STDOUT_FILENO);
174 close(STDERR_FILENO);
175 }
176
StartProcess(const std::string & processBin,std::vector<char * > & argv)177 int StartProcess(const std::string& processBin, std::vector<char*>& argv)
178 {
179 int pid = fork();
180 if (pid == 0) {
181 CloseStdio();
182 argv.push_back(nullptr); // last item in argv must be NULL
183 int retval = execvp(processBin.c_str(), argv.data());
184 if (retval == -1 && errno == EXECVP_ERRNO) {
185 printf("warning: %s does not exist!\n", processBin.c_str());
186 PROFILER_LOG_WARN(LOG_CORE, "warning: %s does not exist!", processBin.c_str());
187 }
188 _exit(EXIT_FAILURE);
189 }
190
191 return pid;
192 }
193
KillProcess(int pid)194 int KillProcess(int pid)
195 {
196 if (pid == -1) {
197 return -1;
198 }
199 int stat;
200 kill(pid, SIGTERM);
201 if (waitpid(pid, &stat, 0) == -1) {
202 if (errno != EINTR) {
203 stat = -1;
204 }
205 }
206 return stat;
207 }
208
PrintMallinfoLog(const std::string & mallInfoPrefix,const struct mallinfo2 & mi)209 void PrintMallinfoLog(const std::string& mallInfoPrefix, const struct mallinfo2& mi)
210 {
211 #ifdef HOOK_ENABLE
212 std::string mallinfoLog = mallInfoPrefix;
213 mallinfoLog += "arena = " + std::to_string(mi.arena) + ", ordblks = " + std::to_string(mi.ordblks);
214 mallinfoLog += ", smblks = " + std::to_string(mi.smblks) + ", hblks = " + std::to_string(mi.hblks);
215 mallinfoLog += ", hblkhd = " + std::to_string(mi.hblkhd) + ", usmblks = " + std::to_string(mi.usmblks);
216 mallinfoLog +=
217 ", fsmblks = " + std::to_string(mi.fsmblks) + ", uordblks = " + std::to_string(mi.uordblks);
218 mallinfoLog +=
219 ", fordblks = " + std::to_string(mi.fordblks) + ", keepcost = " + std::to_string(mi.keepcost);
220 PROFILER_LOG_INFO(LOG_CORE, "%s", mallinfoLog.c_str());
221 #endif // HOOK_ENABLE
222 }
223
IsUserMode()224 bool IsUserMode()
225 {
226 std::string debugMode = "0";
227 debugMode = OHOS::system::GetParameter("const.debuggable", debugMode);
228 if (debugMode != "0") {
229 PROFILER_LOG_ERROR(LOG_CORE, "It is not user mode!");
230 }
231 return debugMode == "0";
232 }
233
GetDeveloperMode()234 bool GetDeveloperMode()
235 {
236 bool developerMode = OHOS::system::GetBoolParameter("const.security.developermode.state", true);
237 if (!developerMode) {
238 PROFILER_LOG_INFO(LOG_CORE, "It is not developer mode!");
239 }
240 return developerMode;
241 }
242
CustomFdClose(int & fd)243 inline int CustomFdClose(int& fd)
244 {
245 int ret = close(fd);
246 if (ret == 0) {
247 fd = -1;
248 }
249 return ret;
250 }
251
CustomFdFclose(FILE ** fp)252 inline int CustomFdFclose(FILE** fp)
253 {
254 int ret = fclose(*fp);
255 if (ret == 0) {
256 *fp = nullptr;
257 }
258 return ret;
259 }
260
CustomPopen(const std::vector<std::string> & command,const char * type,int fds[],volatile pid_t & childPid,bool needUnblock)261 FILE* CustomPopen(const std::vector<std::string>& command, const char* type, int fds[],
262 volatile pid_t& childPid, bool needUnblock)
263 {
264 PROFILER_LOG_DEBUG(LOG_CORE, "BEGN %s: ready!", __func__);
265 if (command.empty() || type == nullptr) {
266 PROFILER_LOG_ERROR(LOG_CORE, "%s: param invalid", __func__);
267 return nullptr;
268 }
269
270 // only allow "r" or "w"
271 if ((type[0] != 'r' && type[0] != 'w') || type[1] != 0) {
272 errno = EINVAL;
273 return nullptr;
274 }
275
276 CHECK_TRUE(pipe(fds) == 0, nullptr, "Pipe open failed!");
277
278 pid_t pid = fork();
279 if (pid == -1) {
280 perror("fork");
281 exit(1);
282 }
283
284 if (pid == 0) {
285 char* const envp[] = {nullptr};
286 // execve : the last argv must be nullptr.
287 std::vector<char*> argv(command.size() + 1, nullptr);
288 for (size_t i = 0, cmdSize = command.size(); i < cmdSize; i++) {
289 argv[i] = const_cast<char*>(command[i].data());
290 }
291
292 if (strncmp(type, "r", strlen(type)) == 0) {
293 CHECK_TRUE(CustomFdClose(fds[READ]) == 0, nullptr, "CustomFdClose failed!");
294 dup2(fds[WRITE], STDOUT_FILENO); // Redirect stdout to pipe
295 CHECK_TRUE(CustomFdClose(fds[WRITE]) == 0, nullptr, "CustomFdClose failed!");
296 } else {
297 CHECK_TRUE(CustomFdClose(fds[WRITE]) == 0, nullptr, "CustomFdClose failed!");
298 dup2(fds[READ], STDIN_FILENO); // Redirect stdin to pipe
299 CHECK_TRUE(CustomFdClose(fds[READ]) == 0, nullptr, "CustomFdClose failed!");
300 }
301
302 setpgid(pid, pid);
303 // exe path = argv[0]; exe name = argv[1]
304 if (execve(argv[0], &argv[1], envp) == -1) {
305 PROFILER_LOG_ERROR(LOG_CORE, "execve failed {%s:%s}", __func__, strerror(errno));
306 exit(EXIT_FAILURE);
307 }
308 }
309
310 if (!needUnblock) {
311 if (strncmp(type, "r", strlen(type)) == 0) {
312 // Close the WRITE end of the pipe since parent's fd is read-only
313 CHECK_TRUE(CustomFdClose(fds[WRITE]) == 0, nullptr, "%s %d CustomFdClose failed! errno(%s)\n",
314 __func__, __LINE__, strerror(errno));
315 } else {
316 // Close the READ end of the pipe since parent's fd is write-only
317 CHECK_TRUE(CustomFdClose(fds[READ]) == 0, nullptr, "%s %d CustomFdClose failed! errno(%s)\n",
318 __func__, __LINE__, strerror(errno));
319 }
320 }
321
322 // Make sure the parent pipe reads and writes exist;CustomPUnblock will use.
323 childPid = pid;
324 if (strncmp(type, "r", strlen(type)) == 0) {
325 PROFILER_LOG_DEBUG(LOG_CORE, "END %s fds[READ]: success!", __func__);
326 return fdopen(fds[READ], "r");
327 }
328
329 PROFILER_LOG_DEBUG(LOG_CORE, "END %s fds[WRITE]: success!", __func__);
330 return fdopen(fds[WRITE], "w");
331 }
332
CustomPclose(FILE * fp,int fds[],volatile pid_t & childPid,bool needUnblock)333 int CustomPclose(FILE* fp, int fds[], volatile pid_t& childPid, bool needUnblock)
334 {
335 PROFILER_LOG_DEBUG(LOG_CORE, "BEGN %s: ready!", __func__);
336 CHECK_NOTNULL(fp, -1, "NOTE %s: fp is null", __func__);
337
338 int stat = 0;
339
340 if (needUnblock) {
341 PROFILER_LOG_DEBUG(LOG_CORE, "NOTE Kill Endless Loop Child %d.", childPid);
342 kill(childPid, SIGKILL);
343 }
344
345 while (waitpid(childPid, &stat, 0) == -1) {
346 PROFILER_LOG_ERROR(LOG_CORE, "%s: %s.", __func__, strerror(errno));
347 if (errno == EINTR) {
348 continue;
349 }
350 break;
351 }
352
353 if (needUnblock) {
354 if (fileno(fp) == fds[READ]) {
355 fds[READ] = -1;
356 CHECK_TRUE(CustomFdClose(fds[WRITE]) == 0, -1, "CustomFdClose failed!");
357 } else if (fileno(fp) == fds[WRITE]) {
358 fds[WRITE] = -1;
359 CHECK_TRUE(CustomFdClose(fds[READ]) == 0, -1, "CustomFdClose failed!");
360 } else {
361 PROFILER_LOG_INFO(LOG_CORE, "%s: Can't find fp in fds[READ/WRITE].", __func__);
362 }
363 }
364
365 CHECK_TRUE(CustomFdFclose(&fp) == 0, -1, "CustomFdFclose failed!");
366
367 PROFILER_LOG_DEBUG(LOG_CORE, "END %s: success!", __func__);
368 return stat;
369 }
370
371 // IF pipe fds is block, before release other threads, you need call CustomPUnblock
CustomPUnblock(int fds[])372 int CustomPUnblock(int fds[])
373 {
374 PROFILER_LOG_DEBUG(LOG_CORE, "BEGN %s: ready!", __func__);
375
376 CHECK_TRUE(fds[READ] != -1 && fds[WRITE] != -1, -1, "END fds[READ/WRITE]=-1");
377
378 int stat = fcntl(fds[READ], F_GETFL);
379 CHECK_TRUE(stat != -1, -1, "END fcntl(F_GETFL) failed!");
380
381 if (!(stat & O_NONBLOCK)) {
382 PROFILER_LOG_DEBUG(LOG_CORE, "NOTE %s: ready!Unblock r_fd and close all", __func__);
383 const char* eof = "\n\0";
384 write(fds[WRITE], eof, strlen(eof) + 1);
385 fcntl(fds[READ], F_SETFL, O_NONBLOCK);
386 }
387 PROFILER_LOG_DEBUG(LOG_CORE, "END %s: success!", __func__);
388 return 0;
389 }
390
GetServicePort()391 int GetServicePort()
392 {
393 const std::string portRangePath = "/proc/sys/net/ipv4/ip_local_port_range";
394 std::ifstream file(portRangePath.c_str());
395 CHECK_TRUE(file.is_open(), -1, "Open file failed! filePath:%s", portRangePath.c_str());
396
397 std::string rangeStr;
398 copy(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), std::back_inserter(rangeStr));
399
400 int minPort;
401 int maxPort;
402 std::istringstream istr(rangeStr);
403 istr >> minPort >> maxPort;
404 const int offset = 3168; // To be compatible with previously used port 50051;
405 int port = (minPort + maxPort) / 2 + offset;
406 PROFILER_LOG_DEBUG(LOG_CORE, "Service port is: %d", port);
407 return port;
408 }
409
SplitString(const std::string & str,const std::string & sep,std::vector<std::string> & ret)410 void SplitString(const std::string& str, const std::string &sep, std::vector<std::string>& ret)
411 {
412 if (str.empty()) {
413 PROFILER_LOG_ERROR(LOG_CORE, "The string splited is empty!");
414 return;
415 }
416 std::string::size_type beginPos = str.find_first_not_of(sep);
417 std::string::size_type findPos = 0;
418 while (beginPos != std::string::npos) {
419 findPos = str.find(sep, beginPos);
420 std::string tmp;
421 if (findPos != std::string::npos) {
422 tmp = str.substr(beginPos, findPos - beginPos);
423 beginPos = findPos + sep.length();
424 } else {
425 tmp = str.substr(beginPos);
426 beginPos = findPos;
427 }
428 if (!tmp.empty()) {
429 ret.push_back(tmp);
430 tmp.clear();
431 }
432 }
433 }
434
CheckApplicationPermission(int pid,const std::string & processName)435 bool CheckApplicationPermission(int pid, const std::string& processName)
436 {
437 std::string bundleName;
438 if (pid > 0) {
439 std::string filePath = "/proc/" + std::to_string(pid) + "/cmdline";
440 if (!LoadStringFromFile(filePath, bundleName)) {
441 PROFILER_LOG_ERROR(LOG_CORE, "Get process name by pid failed!");
442 return false;
443 }
444 bundleName.resize(strlen(bundleName.c_str()));
445 } else {
446 bundleName = processName;
447 }
448 auto pos = bundleName.find(":");
449 if (pos != std::string::npos) {
450 bundleName = bundleName.substr(0, pos);
451 }
452 CHECK_TRUE(!bundleName.empty(), false, "Pid or process name is illegal!");
453
454 sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
455 CHECK_NOTNULL(sam, false, "GetSystemAbilityManager failed!");
456 sptr<IRemoteObject> remoteObject = sam->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
457 CHECK_NOTNULL(remoteObject, false, "Get BundleMgr SA failed!");
458 sptr<BundleMgrProxy> proxy = iface_cast<BundleMgrProxy>(remoteObject);
459 AppExecFwk::ApplicationInfo appInfo;
460 bool ret = proxy->GetApplicationInfo(bundleName, AppExecFwk::GET_APPLICATION_INFO_WITH_DISABLE,
461 AppExecFwk::Constants::ANY_USERID, appInfo);
462 if (!ret) {
463 PROFILER_LOG_ERROR(LOG_CORE, "GetApplicationInfo failed!");
464 return false;
465 }
466 return appInfo.appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG;
467 }
CheckApplicationEncryped(int pid,const std::string & processName)468 bool CheckApplicationEncryped(int pid, const std::string& processName)
469 {
470 std::string bundleName;
471 if (pid > 0) {
472 std::string filePath = "/proc/" + std::to_string(pid) + "/cmdline";
473 if (!LoadStringFromFile(filePath, bundleName)) {
474 PROFILER_LOG_ERROR(LOG_CORE, "Get process name by pid failed!");
475 return false;
476 }
477 bundleName.resize(strlen(bundleName.c_str()));
478 } else {
479 bundleName = processName;
480 }
481 auto pos = bundleName.find(":");
482 if (pos != std::string::npos) {
483 bundleName = bundleName.substr(0, pos);
484 }
485 CHECK_TRUE(!bundleName.empty(), false, "Pid or process name is illegal!");
486 sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
487 CHECK_NOTNULL(sam, false, "GetSystemAbilityManager failed!");
488 sptr<IRemoteObject> remoteObject = sam->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
489 CHECK_NOTNULL(remoteObject, false, "Get BundleMgr SA failed!");
490 sptr<BundleMgrProxy> proxy = iface_cast<BundleMgrProxy>(remoteObject);
491 AppExecFwk::ApplicationInfo appInfo;
492 bool ret = proxy->GetApplicationInfo(bundleName, AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO,
493 AppExecFwk::Constants::ANY_USERID, appInfo);
494 CHECK_TRUE(ret, false, "%s:%s GetApplicationInfo failed!", __func__, bundleName.c_str());
495 bool isEncrypted = (appInfo.applicationReservedFlag &
496 static_cast<uint32_t>(AppExecFwk::ApplicationReservedFlag::ENCRYPTED_APPLICATION)) != 0;
497 PROFILER_LOG_INFO(LOG_CORE, "%s: check application encryped.%d : %s", __func__, isEncrypted, bundleName.c_str());
498 return isEncrypted;
499 }
500
VerifyPath(const std::string & filePath,const std::vector<std::string> & validPaths)501 bool VerifyPath(const std::string& filePath, const std::vector<std::string>& validPaths)
502 {
503 if (validPaths.size() == 0) {
504 return true;
505 }
506
507 for (const std::string& path : validPaths) {
508 if (filePath.rfind(path, 0) == 0) {
509 return true;
510 }
511 }
512 return false;
513 }
514
RealPath(std::string & filePath)515 const char* RealPath(std::string &filePath)
516 {
517 if (filePath.size() > 0 && (filePath.back() == '/' || filePath.back() == '.')) {
518 return nullptr;
519 }
520 if (filePath.find('.') == std::string::npos) {
521 return filePath.c_str();
522 }
523 std::vector<std::string> paths;
524 SplitString(filePath, "/", paths);
525 std::vector<std::string> validPaths;
526 for (std::string& pathName: paths) {
527 if (pathName == "..") {
528 if (validPaths.size() == 0) {
529 return nullptr;
530 } else {
531 validPaths.pop_back();
532 }
533 } else {
534 validPaths.emplace_back(pathName);
535 }
536 }
537 filePath = "/";
538 for (std::string &pathName : validPaths) {
539 filePath += pathName;
540 filePath += "/";
541 }
542 filePath.pop_back();
543 return filePath.c_str();
544 }
545
ReadFile(const std::string & filePath,const std::vector<std::string> & validPaths,std::string & fileContent)546 bool ReadFile(const std::string &filePath, const std::vector<std::string>& validPaths, std::string& fileContent)
547 {
548 std::string pathName = filePath;
549 const char* realFilePath = RealPath(pathName);
550 CHECK_NOTNULL(realFilePath, false, "Fail to realPath: %s", filePath.c_str());
551
552 std::string realFilePathStr(realFilePath);
553 CHECK_TRUE(VerifyPath(realFilePathStr, validPaths), false, "Fail to VerifyPath: %s", realFilePathStr.c_str());
554
555 std::ifstream fileStream(realFilePathStr, std::ios::in);
556 CHECK_TRUE(fileStream.is_open(), false, "Fail to open file %s", realFilePathStr.c_str());
557
558 std::istreambuf_iterator<char> firstIt = { fileStream };
559 std::string content(firstIt, {});
560 fileContent = content;
561 return true;
562 }
563
GetErrorMsg()564 std::string GetErrorMsg()
565 {
566 const int bufSize = 256;
567 char buffer[bufSize] = { 0 };
568 strerror_r(errno, buffer, bufSize);
569 std::string errorMsg(buffer);
570 return errorMsg;
571 }
572
GetTimeStr()573 std::string GetTimeStr()
574 {
575 time_t now = time(nullptr);
576 struct tm tmTime;
577 localtime_r(&now, &tmTime);
578
579 char buffer[32] = {0};
580 // 1900: count of years
581 (void)sprintf_s(buffer, sizeof(buffer), "%04d%02d%02d_%02d%02d%02d", tmTime.tm_year + 1900, tmTime.tm_mon + 1,
582 tmTime.tm_mday, tmTime.tm_hour, tmTime.tm_min, tmTime.tm_sec);
583 std::string timeStr(buffer);
584 return timeStr;
585 }
586
587 // get clockid by str, return CLOCK_REALTIME as default
GetClockId(const std::string & clockIdStr)588 clockid_t GetClockId(const std::string& clockIdStr)
589 {
590 clockid_t clockId = CLOCK_REALTIME;
591 auto iter = clockIdMap.find(clockIdStr);
592 if (iter != clockIdMap.end()) {
593 clockId = iter->second;
594 }
595 return clockId;
596 }
597
GetClockStr(const int32_t clockId)598 std::string GetClockStr(const int32_t clockId)
599 {
600 std::string ret = "realtime";
601 for (const auto& [str, id] : clockIdMap) {
602 if (id == clockId) {
603 ret = str;
604 break;
605 }
606 }
607 return ret;
608 }
609
AdaptSandboxPath(std::string & filePath,int pid)610 void AdaptSandboxPath(std::string& filePath, int pid)
611 {
612 if (filePath.find("/data/storage") == 0 && access(filePath.c_str(), F_OK) != 0) {
613 filePath = "/proc/" + std::to_string(pid) + "/root" + filePath;
614 }
615 }
616
GetCurrentUserId(int32_t & userId)617 bool GetCurrentUserId(int32_t& userId)
618 {
619 std::vector<int32_t> activeIds;
620 int32_t ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeIds);
621 if (ret != 0) {
622 PROFILER_LOG_ERROR(LOG_CORE, "QueryActiveOsAccountIds failed ret:%d", ret);
623 return false;
624 }
625
626 if (activeIds.empty()) {
627 PROFILER_LOG_ERROR(LOG_CORE, "QueryActiveOsAccountIds activeIds empty");
628 return false;
629 }
630 userId = activeIds[0];
631 PROFILER_LOG_INFO(LOG_CORE, "QueryActiveOsAccountIds userId[0]:%d", userId);
632 return true;
633 }
634
GetPackageUid(const std::string & name)635 int32_t GetPackageUid(const std::string& name)
636 {
637 int32_t userId = 0;
638 if (!GetCurrentUserId(userId)) {
639 PROFILER_LOG_ERROR(LOG_CORE, "Failed to get current user id");
640 return EC_INVALID_VALUE;
641 }
642 auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
643 if (manager == nullptr) {
644 PROFILER_LOG_ERROR(LOG_CORE, "systemAbilityManager is nullptr");
645 return EC_INVALID_VALUE;
646 }
647 sptr<IRemoteObject> remoteObject = manager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
648 if (remoteObject == nullptr) {
649 PROFILER_LOG_ERROR(LOG_CORE, "failed to get service id");
650 return EC_INVALID_VALUE;
651 }
652 sptr<AppExecFwk::IBundleMgr> mgr = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
653 if (mgr == nullptr) {
654 PROFILER_LOG_ERROR(LOG_CORE, "mgr is nullptr");
655 return EC_INVALID_VALUE;
656 }
657 int32_t uid = mgr->GetUidByBundleName(name, userId);
658 PROFILER_LOG_INFO(LOG_CORE, "pkgname is: %s, uid is : %d", name.c_str(), uid);
659 return uid;
660 }
661
IsBetaVersion()662 bool IsBetaVersion()
663 {
664 int ret = static_cast<int>(FindParameter(KEY_HIVIEW_USER_TYPE.c_str()));
665 if (ret == -1) {
666 PROFILER_LOG_INFO(LOG_CORE, "user type is not exist");
667 return true;
668 }
669 std::string userType = OHOS::system::GetParameter(KEY_HIVIEW_USER_TYPE, "");
670 PROFILER_LOG_INFO(LOG_CORE, "user type is:%s", userType.c_str());
671 return userType == "beta";
672 }
673 } // namespace COMMON
674