• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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