148f512ceSopenharmony_ci/*
248f512ceSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
348f512ceSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
448f512ceSopenharmony_ci * you may not use this file except in compliance with the License.
548f512ceSopenharmony_ci * You may obtain a copy of the License at
648f512ceSopenharmony_ci *
748f512ceSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
848f512ceSopenharmony_ci *
948f512ceSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1048f512ceSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1148f512ceSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1248f512ceSopenharmony_ci * See the License for the specific language governing permissions and
1348f512ceSopenharmony_ci * limitations under the License.
1448f512ceSopenharmony_ci */
1548f512ceSopenharmony_ci
1648f512ceSopenharmony_ci#include "utilities.h"
1748f512ceSopenharmony_ci
1848f512ceSopenharmony_ci#include <zlib.h>
1948f512ceSopenharmony_ci#include <thread>
2048f512ceSopenharmony_ci#if defined(CONFIG_HAS_SYSPARA) && defined(is_ohos) && is_ohos
2148f512ceSopenharmony_ci#include <parameters.h>
2248f512ceSopenharmony_ci#endif
2348f512ceSopenharmony_ci#if defined(is_mingw) && is_mingw
2448f512ceSopenharmony_ci#include <io.h>
2548f512ceSopenharmony_ci#endif
2648f512ceSopenharmony_ci
2748f512ceSopenharmony_ci#include "hiperf_hilog.h"
2848f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos && defined(BUNDLE_FRAMEWORK_ENABLE)
2948f512ceSopenharmony_ci#include "application_info.h"
3048f512ceSopenharmony_ci#include "bundle_mgr_proxy.h"
3148f512ceSopenharmony_ci#endif
3248f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos
3348f512ceSopenharmony_ci#include "iservice_registry.h"
3448f512ceSopenharmony_ci#include "system_ability_definition.h"
3548f512ceSopenharmony_ciusing namespace OHOS;
3648f512ceSopenharmony_ciusing namespace OHOS::AppExecFwk;
3748f512ceSopenharmony_ci#endif
3848f512ceSopenharmony_ci
3948f512ceSopenharmony_ciusing namespace std::chrono;
4048f512ceSopenharmony_cinamespace OHOS {
4148f512ceSopenharmony_cinamespace Developtools {
4248f512ceSopenharmony_cinamespace HiPerf {
4348f512ceSopenharmony_ci
4448f512ceSopenharmony_cistatic const std::string USER_DOMESTIC_BETA = "beta";
4548f512ceSopenharmony_cistatic const std::string USER_TYPE_PARAM = "const.logsystem.versiontype";
4648f512ceSopenharmony_cistatic const std::string USER_TYPE_PARAM_GET = "";
4748f512ceSopenharmony_cistatic const std::string HIVIEW_CMDLINE = "/system/bin/hiview";
4848f512ceSopenharmony_ci
4948f512ceSopenharmony_cistd::string CanonicalizeSpecPath(const char* src)
5048f512ceSopenharmony_ci{
5148f512ceSopenharmony_ci    if (src == nullptr) {
5248f512ceSopenharmony_ci        HLOGE("Error: CanonicalizeSpecPath failed");
5348f512ceSopenharmony_ci        return "";
5448f512ceSopenharmony_ci    } else if (strlen(src) >= PATH_MAX) {
5548f512ceSopenharmony_ci        HLOGE("Error: CanonicalizeSpecPath %s failed", src);
5648f512ceSopenharmony_ci        return "";
5748f512ceSopenharmony_ci    }
5848f512ceSopenharmony_ci    char resolvedPath[PATH_MAX] = { 0 };
5948f512ceSopenharmony_ci#if defined(_WIN32)
6048f512ceSopenharmony_ci    if (!_fullpath(resolvedPath, src, PATH_MAX)) {
6148f512ceSopenharmony_ci        HLOGE("Error: _fullpath %s failed", src);
6248f512ceSopenharmony_ci        return "";
6348f512ceSopenharmony_ci    }
6448f512ceSopenharmony_ci#else
6548f512ceSopenharmony_ci    if (access(src, F_OK) == 0) {
6648f512ceSopenharmony_ci        if (strstr(src, "/proc/") == src && strstr(src, "/data/storage") != nullptr) { // for sandbox
6748f512ceSopenharmony_ci            if (strncpy_s(resolvedPath, sizeof(resolvedPath), src, strlen(src)) == -1) {
6848f512ceSopenharmony_ci                HLOGE("Error: strncpy_s %s failed", src);
6948f512ceSopenharmony_ci                return "";
7048f512ceSopenharmony_ci            }
7148f512ceSopenharmony_ci        } else if (realpath(src, resolvedPath) == nullptr) {
7248f512ceSopenharmony_ci            HLOGE("Error: realpath %s failed", src);
7348f512ceSopenharmony_ci            return "";
7448f512ceSopenharmony_ci        }
7548f512ceSopenharmony_ci    } else {
7648f512ceSopenharmony_ci        std::string fileName(src);
7748f512ceSopenharmony_ci        if (fileName.find("..") == std::string::npos) {
7848f512ceSopenharmony_ci            if (sprintf_s(resolvedPath, PATH_MAX, "%s", src) == -1) {
7948f512ceSopenharmony_ci                HLOGE("Error: sprintf_s %s failed", src);
8048f512ceSopenharmony_ci                return "";
8148f512ceSopenharmony_ci            }
8248f512ceSopenharmony_ci        } else {
8348f512ceSopenharmony_ci            HLOGE("Error: find .. %s failed", src);
8448f512ceSopenharmony_ci            return "";
8548f512ceSopenharmony_ci        }
8648f512ceSopenharmony_ci    }
8748f512ceSopenharmony_ci#endif
8848f512ceSopenharmony_ci    std::string res(resolvedPath);
8948f512ceSopenharmony_ci    return res;
9048f512ceSopenharmony_ci}
9148f512ceSopenharmony_ci
9248f512ceSopenharmony_ciuint32_t RoundUp(uint32_t x, const int align)
9348f512ceSopenharmony_ci{
9448f512ceSopenharmony_ci    return (((x) + (align) >= 1 ? (x) + (align) - 1 : 0) / (align)) * (align);
9548f512ceSopenharmony_ci}
9648f512ceSopenharmony_ci
9748f512ceSopenharmony_cistd::string StringReplace(std::string source, const std::string &from, const std::string &to)
9848f512ceSopenharmony_ci{
9948f512ceSopenharmony_ci    size_t pos = 0;
10048f512ceSopenharmony_ci    std::string result;
10148f512ceSopenharmony_ci    // find
10248f512ceSopenharmony_ci    while ((pos = source.find(from)) != std::string::npos) {
10348f512ceSopenharmony_ci        // replace
10448f512ceSopenharmony_ci        result.append(source.substr(0, pos) + to);
10548f512ceSopenharmony_ci        source.erase(0, pos + from.length());
10648f512ceSopenharmony_ci    }
10748f512ceSopenharmony_ci    // add last token
10848f512ceSopenharmony_ci    result.append(source);
10948f512ceSopenharmony_ci    return result;
11048f512ceSopenharmony_ci}
11148f512ceSopenharmony_ci
11248f512ceSopenharmony_cisize_t SubStringCount(const std::string &source, const std::string &sub)
11348f512ceSopenharmony_ci{
11448f512ceSopenharmony_ci    size_t count(0);
11548f512ceSopenharmony_ci    size_t pos(0);
11648f512ceSopenharmony_ci    if (sub.empty()) {
11748f512ceSopenharmony_ci        return source.size();
11848f512ceSopenharmony_ci    }
11948f512ceSopenharmony_ci    while ((pos = source.find(sub, pos)) != std::string::npos) {
12048f512ceSopenharmony_ci        pos += sub.size();
12148f512ceSopenharmony_ci        count++;
12248f512ceSopenharmony_ci    }
12348f512ceSopenharmony_ci    return count;
12448f512ceSopenharmony_ci}
12548f512ceSopenharmony_ci
12648f512ceSopenharmony_cistd::vector<std::string> StringSplit(std::string source, const std::string &split)
12748f512ceSopenharmony_ci{
12848f512ceSopenharmony_ci    std::vector<std::string> result;
12948f512ceSopenharmony_ci
13048f512ceSopenharmony_ci    // find
13148f512ceSopenharmony_ci    if (!split.empty()) {
13248f512ceSopenharmony_ci        size_t pos = 0;
13348f512ceSopenharmony_ci        while ((pos = source.find(split)) != std::string::npos) {
13448f512ceSopenharmony_ci            // split
13548f512ceSopenharmony_ci            std::string token = source.substr(0, pos);
13648f512ceSopenharmony_ci            if (!token.empty()) {
13748f512ceSopenharmony_ci                result.push_back(token);
13848f512ceSopenharmony_ci            }
13948f512ceSopenharmony_ci            source.erase(0, pos + split.length());
14048f512ceSopenharmony_ci        }
14148f512ceSopenharmony_ci    }
14248f512ceSopenharmony_ci    // add last token
14348f512ceSopenharmony_ci    if (!source.empty()) {
14448f512ceSopenharmony_ci        result.push_back(source);
14548f512ceSopenharmony_ci    }
14648f512ceSopenharmony_ci    return result;
14748f512ceSopenharmony_ci}
14848f512ceSopenharmony_ciStdoutRecord::StdoutRecord(const std::string &tempFile, const std::string &mode)
14948f512ceSopenharmony_ci{
15048f512ceSopenharmony_ci    if (!tempFile.empty()) {
15148f512ceSopenharmony_ci        std::string resolvedPath = CanonicalizeSpecPath(tempFile.c_str());
15248f512ceSopenharmony_ci        recordFile_ = fopen(resolvedPath.c_str(), mode.c_str());
15348f512ceSopenharmony_ci        if (recordFile_ == nullptr) {
15448f512ceSopenharmony_ci            HLOGE("tmpfile create failed '%s' with mode '%s'", tempFile.c_str(), mode.c_str());
15548f512ceSopenharmony_ci        } else {
15648f512ceSopenharmony_ci            // auto start it
15748f512ceSopenharmony_ci            Start();
15848f512ceSopenharmony_ci        }
15948f512ceSopenharmony_ci    }
16048f512ceSopenharmony_ci}
16148f512ceSopenharmony_cibool StdoutRecord::Start()
16248f512ceSopenharmony_ci{
16348f512ceSopenharmony_ci    content_ = EMPTY_STRING;
16448f512ceSopenharmony_ci    fflush(stdout);
16548f512ceSopenharmony_ci
16648f512ceSopenharmony_ci    // we will save output here
16748f512ceSopenharmony_ci    if (recordFile_ == nullptr) {
16848f512ceSopenharmony_ci        recordFile_ = std::tmpfile();
16948f512ceSopenharmony_ci    }
17048f512ceSopenharmony_ci    if (recordFile_ == nullptr) {
17148f512ceSopenharmony_ci        // try second way
17248f512ceSopenharmony_ci        std::string fileName = "/data/local/tmp/temp.stdout";
17348f512ceSopenharmony_ci        std::string resolvedPath = CanonicalizeSpecPath(fileName.c_str());
17448f512ceSopenharmony_ci        recordFile_ = fopen(resolvedPath.c_str(), "w+");
17548f512ceSopenharmony_ci        if (recordFile_ == nullptr) {
17648f512ceSopenharmony_ci            HLOGF("tmpfile create failed '%s'", fileName.c_str());
17748f512ceSopenharmony_ci            return false;
17848f512ceSopenharmony_ci        }
17948f512ceSopenharmony_ci    }
18048f512ceSopenharmony_ci
18148f512ceSopenharmony_ci    // we save the stdout
18248f512ceSopenharmony_ci    stdoutFile_ = OHOS::UniqueFd(dup(STDOUT_FILENO));
18348f512ceSopenharmony_ci    CHECK_TRUE(stdoutFile_ == -1, false, 1, "std dup failed");
18448f512ceSopenharmony_ci
18548f512ceSopenharmony_ci    // setup temp file as stdout
18648f512ceSopenharmony_ci    if (dup2(fileno(recordFile_), STDOUT_FILENO) != -1) {
18748f512ceSopenharmony_ci        stop_ = false;
18848f512ceSopenharmony_ci        return true;
18948f512ceSopenharmony_ci    } else {
19048f512ceSopenharmony_ci        HLOGF("std dup2 failed");
19148f512ceSopenharmony_ci        return false;
19248f512ceSopenharmony_ci    }
19348f512ceSopenharmony_ci}
19448f512ceSopenharmony_ci
19548f512ceSopenharmony_cistd::string StdoutRecord::Stop()
19648f512ceSopenharmony_ci{
19748f512ceSopenharmony_ci    if (stop_) {
19848f512ceSopenharmony_ci        return content_;
19948f512ceSopenharmony_ci    }
20048f512ceSopenharmony_ci    fflush(stdout);
20148f512ceSopenharmony_ci    // restore fd
20248f512ceSopenharmony_ci    dup2(stdoutFile_, STDOUT_FILENO);
20348f512ceSopenharmony_ci
20448f512ceSopenharmony_ci    // return file content
20548f512ceSopenharmony_ci    if (recordFile_ != nullptr) {
20648f512ceSopenharmony_ci        const long fileLength = lseek(fileno(recordFile_), 0, SEEK_END);
20748f512ceSopenharmony_ci        content_.resize(fileLength);
20848f512ceSopenharmony_ci        lseek(fileno(recordFile_), 0, SEEK_SET);
20948f512ceSopenharmony_ci        const long len = read(fileno(recordFile_), content_.data(), fileLength);
21048f512ceSopenharmony_ci        std::fclose(recordFile_);
21148f512ceSopenharmony_ci        recordFile_ = nullptr;
21248f512ceSopenharmony_ci        if (len < 0) {
21348f512ceSopenharmony_ci            HLOGE("tmp file read failed (try read %ld)", fileLength);
21448f512ceSopenharmony_ci        } else if (len < fileLength) {
21548f512ceSopenharmony_ci            HLOGE("not all the data is read, lost %ld/%ld bytes", fileLength - len, fileLength);
21648f512ceSopenharmony_ci        }
21748f512ceSopenharmony_ci    } else {
21848f512ceSopenharmony_ci        HLOGE("recordFile_ is nullptr");
21948f512ceSopenharmony_ci    }
22048f512ceSopenharmony_ci    stop_ = true;
22148f512ceSopenharmony_ci    return content_;
22248f512ceSopenharmony_ci}
22348f512ceSopenharmony_ci
22448f512ceSopenharmony_cibool IsDigits(const std::string &str)
22548f512ceSopenharmony_ci{
22648f512ceSopenharmony_ci    if (str.empty()) {
22748f512ceSopenharmony_ci        return false;
22848f512ceSopenharmony_ci    } else {
22948f512ceSopenharmony_ci        return std::all_of(str.begin(), str.end(), ::isdigit);
23048f512ceSopenharmony_ci    }
23148f512ceSopenharmony_ci}
23248f512ceSopenharmony_ci
23348f512ceSopenharmony_cibool IsHexDigits(const std::string &str)
23448f512ceSopenharmony_ci{
23548f512ceSopenharmony_ci    if (str.empty()) {
23648f512ceSopenharmony_ci        return false;
23748f512ceSopenharmony_ci    }
23848f512ceSopenharmony_ci    const std::string prefix {"0x"};
23948f512ceSopenharmony_ci    std::string effectStr {str};
24048f512ceSopenharmony_ci    if (prefix.compare(0, prefix.size(), effectStr.substr(0, prefix.size())) == 0) {
24148f512ceSopenharmony_ci        effectStr = effectStr.substr(prefix.size(), effectStr.size() - prefix.size());
24248f512ceSopenharmony_ci    }
24348f512ceSopenharmony_ci    CHECK_TRUE(effectStr.empty(), false, 0, "");
24448f512ceSopenharmony_ci    std::size_t start {0};
24548f512ceSopenharmony_ci    for (; start < effectStr.size(); ++start) {
24648f512ceSopenharmony_ci        if (effectStr[start] == '0') {
24748f512ceSopenharmony_ci            continue;
24848f512ceSopenharmony_ci        }
24948f512ceSopenharmony_ci        break;
25048f512ceSopenharmony_ci    }
25148f512ceSopenharmony_ci    if (start == effectStr.size()) {
25248f512ceSopenharmony_ci        effectStr = "0";
25348f512ceSopenharmony_ci    }
25448f512ceSopenharmony_ci    return std::all_of(effectStr.begin(), effectStr.end(), ::isxdigit);
25548f512ceSopenharmony_ci}
25648f512ceSopenharmony_ci
25748f512ceSopenharmony_cibool IsDir(const std::string &path)
25848f512ceSopenharmony_ci{
25948f512ceSopenharmony_ci    struct stat st;
26048f512ceSopenharmony_ci    if (stat(path.c_str(), &st) == 0) {
26148f512ceSopenharmony_ci        return S_ISDIR(st.st_mode);
26248f512ceSopenharmony_ci    }
26348f512ceSopenharmony_ci    return false;
26448f512ceSopenharmony_ci}
26548f512ceSopenharmony_ci
26648f512ceSopenharmony_cibool IsPath(const std::string &fileName)
26748f512ceSopenharmony_ci{
26848f512ceSopenharmony_ci    HLOG_ASSERT(!fileName.empty());
26948f512ceSopenharmony_ci    if (fileName[0] == PATH_SEPARATOR) {
27048f512ceSopenharmony_ci        return true;
27148f512ceSopenharmony_ci    }
27248f512ceSopenharmony_ci    const int prefixPathLen = 2;
27348f512ceSopenharmony_ci    if (fileName.substr(0, prefixPathLen) == "./") {
27448f512ceSopenharmony_ci        return true;
27548f512ceSopenharmony_ci    }
27648f512ceSopenharmony_ci    return false;
27748f512ceSopenharmony_ci}
27848f512ceSopenharmony_ci
27948f512ceSopenharmony_cistd::string PlatformPathConvert(const std::string &path)
28048f512ceSopenharmony_ci{
28148f512ceSopenharmony_ci#if defined(is_mingw) && is_mingw
28248f512ceSopenharmony_ci    return StringReplace(path, "/", "\\");
28348f512ceSopenharmony_ci#else
28448f512ceSopenharmony_ci    return path;
28548f512ceSopenharmony_ci#endif
28648f512ceSopenharmony_ci}
28748f512ceSopenharmony_ci
28848f512ceSopenharmony_cistd::string ReadFileToString(const std::string &fileName)
28948f512ceSopenharmony_ci{
29048f512ceSopenharmony_ci    std::string resolvedPath = CanonicalizeSpecPath(fileName.c_str());
29148f512ceSopenharmony_ci    std::ifstream inputString(resolvedPath, std::ios::in);
29248f512ceSopenharmony_ci    if (!inputString or !inputString.is_open()) {
29348f512ceSopenharmony_ci        return EMPTY_STRING;
29448f512ceSopenharmony_ci    }
29548f512ceSopenharmony_ci    std::istreambuf_iterator<char> firstIt = {inputString};
29648f512ceSopenharmony_ci    std::istreambuf_iterator<char> lastIt = {};
29748f512ceSopenharmony_ci
29848f512ceSopenharmony_ci    std::string content(firstIt, lastIt);
29948f512ceSopenharmony_ci    return content;
30048f512ceSopenharmony_ci}
30148f512ceSopenharmony_ci
30248f512ceSopenharmony_cibool ReadFileToString(const std::string &fileName, std::string &fileData, size_t fileSize)
30348f512ceSopenharmony_ci{
30448f512ceSopenharmony_ci    fileData.clear();
30548f512ceSopenharmony_ci    std::string resolvedPath = CanonicalizeSpecPath(fileName.c_str());
30648f512ceSopenharmony_ci    OHOS::UniqueFd fd(open(resolvedPath.c_str(), O_RDONLY | O_BINARY));
30748f512ceSopenharmony_ci    if (fileSize == 0) {
30848f512ceSopenharmony_ci        struct stat fileStat;
30948f512ceSopenharmony_ci        if (fstat(fd.Get(), &fileStat) != -1 && fileStat.st_size > 0) {
31048f512ceSopenharmony_ci            fileData.reserve(fileStat.st_size);
31148f512ceSopenharmony_ci        }
31248f512ceSopenharmony_ci    } else {
31348f512ceSopenharmony_ci        fileData.reserve(fileSize);
31448f512ceSopenharmony_ci    }
31548f512ceSopenharmony_ci
31648f512ceSopenharmony_ci    char buf[BUFSIZ] __attribute__((__uninitialized__));
31748f512ceSopenharmony_ci    ssize_t readSize;
31848f512ceSopenharmony_ci    while ((readSize = read(fd.Get(), &buf[0], sizeof(buf))) > 0) {
31948f512ceSopenharmony_ci        fileData.append(buf, readSize);
32048f512ceSopenharmony_ci    }
32148f512ceSopenharmony_ci    return (readSize == 0) ? true : false;
32248f512ceSopenharmony_ci}
32348f512ceSopenharmony_ci
32448f512ceSopenharmony_cibool WriteStringToFile(const std::string &fileName, const std::string &value)
32548f512ceSopenharmony_ci{
32648f512ceSopenharmony_ci    std::string resolvedPath = CanonicalizeSpecPath(fileName.c_str());
32748f512ceSopenharmony_ci    std::ofstream output(resolvedPath, std::ios::out);
32848f512ceSopenharmony_ci    if (!output) {
32948f512ceSopenharmony_ci        return false;
33048f512ceSopenharmony_ci    }
33148f512ceSopenharmony_ci    output << value;
33248f512ceSopenharmony_ci
33348f512ceSopenharmony_ci    return output.good();
33448f512ceSopenharmony_ci}
33548f512ceSopenharmony_ci
33648f512ceSopenharmony_cibool IsRoot()
33748f512ceSopenharmony_ci{
33848f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos
33948f512ceSopenharmony_ci    std::string debugMode = "0";
34048f512ceSopenharmony_ci    debugMode = OHOS::system::GetParameter("const.debuggable", debugMode);
34148f512ceSopenharmony_ci    return debugMode == "1";
34248f512ceSopenharmony_ci#else
34348f512ceSopenharmony_ci    return true;
34448f512ceSopenharmony_ci#endif
34548f512ceSopenharmony_ci}
34648f512ceSopenharmony_ci
34748f512ceSopenharmony_cibool PowerOfTwo(uint64_t n)
34848f512ceSopenharmony_ci{
34948f512ceSopenharmony_ci    return n && (!(n & (n - 1)));
35048f512ceSopenharmony_ci}
35148f512ceSopenharmony_ci
35248f512ceSopenharmony_cibool ReadIntFromProcFile(const std::string &path, int &value)
35348f512ceSopenharmony_ci{
35448f512ceSopenharmony_ci    std::string s = ReadFileToString(path);
35548f512ceSopenharmony_ci    CHECK_TRUE(s.empty(), false, 0, "");
35648f512ceSopenharmony_ci    value = std::stoi(s);
35748f512ceSopenharmony_ci    return true;
35848f512ceSopenharmony_ci}
35948f512ceSopenharmony_ci
36048f512ceSopenharmony_cibool WriteIntToProcFile(const std::string &path, int value)
36148f512ceSopenharmony_ci{
36248f512ceSopenharmony_ci    std::string s = std::to_string(value);
36348f512ceSopenharmony_ci
36448f512ceSopenharmony_ci    return WriteStringToFile(path, s);
36548f512ceSopenharmony_ci}
36648f512ceSopenharmony_ci
36748f512ceSopenharmony_ci// compress specified dataFile into gzip file
36848f512ceSopenharmony_cibool CompressFile(const std::string &dataFile, const std::string &destFile)
36948f512ceSopenharmony_ci{
37048f512ceSopenharmony_ci    std::string resolvedPath = CanonicalizeSpecPath(dataFile.c_str());
37148f512ceSopenharmony_ci    FILE *fp = fopen(resolvedPath.c_str(), "rb");
37248f512ceSopenharmony_ci    if (fp == nullptr) {
37348f512ceSopenharmony_ci        HLOGE("Fail to open data file %s", dataFile.c_str());
37448f512ceSopenharmony_ci        perror("Fail to fopen(rb)");
37548f512ceSopenharmony_ci        return false;
37648f512ceSopenharmony_ci    }
37748f512ceSopenharmony_ci
37848f512ceSopenharmony_ci    std::unique_ptr<gzFile_s, decltype(&gzclose)> fgz(gzopen(destFile.c_str(), "wb"), gzclose);
37948f512ceSopenharmony_ci    if (fgz == nullptr) {
38048f512ceSopenharmony_ci        HLOGE("Fail to call gzopen(%s)", destFile.c_str());
38148f512ceSopenharmony_ci        fclose(fp);
38248f512ceSopenharmony_ci        return false;
38348f512ceSopenharmony_ci    }
38448f512ceSopenharmony_ci
38548f512ceSopenharmony_ci    std::vector<char> buf(COMPRESS_READ_BUF_SIZE);
38648f512ceSopenharmony_ci    size_t len = 0;
38748f512ceSopenharmony_ci    while ((len = fread(buf.data(), sizeof(uint8_t), buf.size(), fp))) {
38848f512ceSopenharmony_ci        if (gzwrite(fgz.get(), buf.data(), len) == 0) {
38948f512ceSopenharmony_ci            HLOGE("Fail to call gzwrite for %zu bytes", len);
39048f512ceSopenharmony_ci            fclose(fp);
39148f512ceSopenharmony_ci            return false;
39248f512ceSopenharmony_ci        }
39348f512ceSopenharmony_ci    }
39448f512ceSopenharmony_ci    if (!feof(fp)) {
39548f512ceSopenharmony_ci        if (ferror(fp) != 0) {
39648f512ceSopenharmony_ci            HLOGE("ferror return err");
39748f512ceSopenharmony_ci            fclose(fp);
39848f512ceSopenharmony_ci            return false;
39948f512ceSopenharmony_ci        }
40048f512ceSopenharmony_ci    }
40148f512ceSopenharmony_ci    if (fclose(fp) < 0) {
40248f512ceSopenharmony_ci        return false;
40348f512ceSopenharmony_ci    }
40448f512ceSopenharmony_ci    return true;
40548f512ceSopenharmony_ci}
40648f512ceSopenharmony_ci
40748f512ceSopenharmony_ci// uncompress specified gzip file into dataFile
40848f512ceSopenharmony_cibool UncompressFile(const std::string &gzipFile, const std::string &dataFile)
40948f512ceSopenharmony_ci{
41048f512ceSopenharmony_ci    std::string resolvedPath = CanonicalizeSpecPath(dataFile.c_str());
41148f512ceSopenharmony_ci    FILE *fp = fopen(resolvedPath.c_str(), "wb");
41248f512ceSopenharmony_ci    if (fp == nullptr) {
41348f512ceSopenharmony_ci        HLOGE("Fail to open data file %s", dataFile.c_str());
41448f512ceSopenharmony_ci        perror("Fail to fopen(rb)");
41548f512ceSopenharmony_ci        return false;
41648f512ceSopenharmony_ci    }
41748f512ceSopenharmony_ci    std::unique_ptr<gzFile_s, decltype(&gzclose)> fgz(gzopen(gzipFile.c_str(), "rb"), gzclose);
41848f512ceSopenharmony_ci    if (fgz == nullptr) {
41948f512ceSopenharmony_ci        HLOGE("Fail to call gzopen(%s)", gzipFile.c_str());
42048f512ceSopenharmony_ci        fclose(fp);
42148f512ceSopenharmony_ci        return false;
42248f512ceSopenharmony_ci    }
42348f512ceSopenharmony_ci
42448f512ceSopenharmony_ci    std::vector<char> buf(COMPRESS_READ_BUF_SIZE);
42548f512ceSopenharmony_ci    z_size_t len = 0;
42648f512ceSopenharmony_ci    while ((len = gzfread(buf.data(), sizeof(uint8_t), buf.size(), fgz.get()))) {
42748f512ceSopenharmony_ci        if (len != fwrite(buf.data(), sizeof(uint8_t), len, fp)) {
42848f512ceSopenharmony_ci            HLOGE("Fail to call fwrite for %zu bytes", len);
42948f512ceSopenharmony_ci            fclose(fp);
43048f512ceSopenharmony_ci            return false;
43148f512ceSopenharmony_ci        }
43248f512ceSopenharmony_ci    }
43348f512ceSopenharmony_ci    if (!gzeof(fgz.get())) {
43448f512ceSopenharmony_ci        int rc = 0;
43548f512ceSopenharmony_ci        const char *err = gzerror(fgz.get(), &rc);
43648f512ceSopenharmony_ci        if (rc != Z_OK) {
43748f512ceSopenharmony_ci            HLOGE("gzfread return %d:%s", rc, err);
43848f512ceSopenharmony_ci            fclose(fp);
43948f512ceSopenharmony_ci            return false;
44048f512ceSopenharmony_ci        }
44148f512ceSopenharmony_ci    }
44248f512ceSopenharmony_ci    if (fclose(fp) < 0) {
44348f512ceSopenharmony_ci        return false;
44448f512ceSopenharmony_ci    }
44548f512ceSopenharmony_ci    return true;
44648f512ceSopenharmony_ci}
44748f512ceSopenharmony_ci
44848f512ceSopenharmony_cistd::string &StringTrim(std::string &string)
44948f512ceSopenharmony_ci{
45048f512ceSopenharmony_ci    if (!string.empty()) {
45148f512ceSopenharmony_ci        string.erase(0, string.find_first_not_of(" "));
45248f512ceSopenharmony_ci        string.erase(string.find_last_not_of(" ") + 1);
45348f512ceSopenharmony_ci    }
45448f512ceSopenharmony_ci    return string;
45548f512ceSopenharmony_ci}
45648f512ceSopenharmony_ci
45748f512ceSopenharmony_cistd::vector<std::string> GetEntriesInDir(const std::string &basePath)
45848f512ceSopenharmony_ci{
45948f512ceSopenharmony_ci    std::vector<std::string> result;
46048f512ceSopenharmony_ci    std::string resolvedPath = CanonicalizeSpecPath(basePath.c_str());
46148f512ceSopenharmony_ci    CHECK_TRUE(resolvedPath.empty(), result, 0, "");
46248f512ceSopenharmony_ci    DIR *dir = opendir(resolvedPath.c_str());
46348f512ceSopenharmony_ci    CHECK_TRUE(dir == nullptr, result, 0, "");
46448f512ceSopenharmony_ci    dirent *entry;
46548f512ceSopenharmony_ci    while ((entry = readdir(dir)) != nullptr) {
46648f512ceSopenharmony_ci        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
46748f512ceSopenharmony_ci            continue;
46848f512ceSopenharmony_ci        }
46948f512ceSopenharmony_ci        result.push_back(entry->d_name);
47048f512ceSopenharmony_ci    }
47148f512ceSopenharmony_ci    closedir(dir);
47248f512ceSopenharmony_ci    return result;
47348f512ceSopenharmony_ci}
47448f512ceSopenharmony_ci
47548f512ceSopenharmony_cistd::vector<std::string> GetSubDirs(const std::string &basePath)
47648f512ceSopenharmony_ci{
47748f512ceSopenharmony_ci    std::vector<std::string> entries = GetEntriesInDir(basePath);
47848f512ceSopenharmony_ci    std::vector<std::string> result = {};
47948f512ceSopenharmony_ci    for (std::size_t index = 0; index < entries.size(); ++index) {
48048f512ceSopenharmony_ci        if (IsDir(basePath + "/" + entries[index])) {
48148f512ceSopenharmony_ci            result.push_back(std::move(entries[index]));
48248f512ceSopenharmony_ci        }
48348f512ceSopenharmony_ci    }
48448f512ceSopenharmony_ci    return result;
48548f512ceSopenharmony_ci}
48648f512ceSopenharmony_ci
48748f512ceSopenharmony_cibool IsSameCommand(const std::string &cmdLine, const std::string &cmdName)
48848f512ceSopenharmony_ci{
48948f512ceSopenharmony_ci    std::vector<std::string> cmdpaths = StringSplit(cmdLine, "/");
49048f512ceSopenharmony_ci    if (!cmdpaths.empty()) {
49148f512ceSopenharmony_ci        if (strcmp(cmdpaths.back().c_str(), cmdName.c_str()) == 0) {
49248f512ceSopenharmony_ci            return true;
49348f512ceSopenharmony_ci        }
49448f512ceSopenharmony_ci    }
49548f512ceSopenharmony_ci    return false;
49648f512ceSopenharmony_ci}
49748f512ceSopenharmony_ci
49848f512ceSopenharmony_cistd::vector<pid_t> GetSubthreadIDs(const pid_t pid)
49948f512ceSopenharmony_ci{
50048f512ceSopenharmony_ci    std::string path {"/proc/"};
50148f512ceSopenharmony_ci    path += std::to_string(pid);
50248f512ceSopenharmony_ci    path += "/task/";
50348f512ceSopenharmony_ci    auto tids = GetSubDirs(path);
50448f512ceSopenharmony_ci    std::vector<pid_t> res {};
50548f512ceSopenharmony_ci    for (auto tidStr : tids) {
50648f512ceSopenharmony_ci        pid_t tid = static_cast<pid_t>(std::stoul(tidStr, nullptr));
50748f512ceSopenharmony_ci        if (tid == pid) {
50848f512ceSopenharmony_ci            continue;
50948f512ceSopenharmony_ci        }
51048f512ceSopenharmony_ci        res.push_back(tid);
51148f512ceSopenharmony_ci    }
51248f512ceSopenharmony_ci    return res;
51348f512ceSopenharmony_ci}
51448f512ceSopenharmony_ci
51548f512ceSopenharmony_cistd::vector<pid_t> GetSubthreadIDs(const pid_t pid, std::map<pid_t, ThreadInfos> &thread_map)
51648f512ceSopenharmony_ci{
51748f512ceSopenharmony_ci    std::string path {"/proc/"};
51848f512ceSopenharmony_ci    path += std::to_string(pid);
51948f512ceSopenharmony_ci    path += "/task/";
52048f512ceSopenharmony_ci    auto tids = GetSubDirs(path);
52148f512ceSopenharmony_ci    std::vector<pid_t> res{};
52248f512ceSopenharmony_ci    for (auto tidStr : tids) {
52348f512ceSopenharmony_ci        ThreadInfos info;
52448f512ceSopenharmony_ci        pid_t tid = static_cast<pid_t>(std::stoul(tidStr, nullptr));
52548f512ceSopenharmony_ci        info.tid = tid;
52648f512ceSopenharmony_ci        info.pid = pid;
52748f512ceSopenharmony_ci        thread_map[tid] = info;
52848f512ceSopenharmony_ci        res.push_back(tid);
52948f512ceSopenharmony_ci    }
53048f512ceSopenharmony_ci    return res;
53148f512ceSopenharmony_ci}
53248f512ceSopenharmony_ci
53348f512ceSopenharmony_cibool StringStartsWith(const std::string &string, const std::string &with)
53448f512ceSopenharmony_ci{
53548f512ceSopenharmony_ci    return string.find(with) == 0;
53648f512ceSopenharmony_ci}
53748f512ceSopenharmony_ci
53848f512ceSopenharmony_cibool StringEndsWith(const std::string &string, const std::string &with)
53948f512ceSopenharmony_ci{
54048f512ceSopenharmony_ci    if (string.empty()) {
54148f512ceSopenharmony_ci        // empty string only end with empty string
54248f512ceSopenharmony_ci        if (with.empty()) {
54348f512ceSopenharmony_ci            return true;
54448f512ceSopenharmony_ci        } else {
54548f512ceSopenharmony_ci            return false;
54648f512ceSopenharmony_ci        }
54748f512ceSopenharmony_ci    }
54848f512ceSopenharmony_ci    return string.rfind(with) == (string.length() - with.length());
54948f512ceSopenharmony_ci}
55048f512ceSopenharmony_ci
55148f512ceSopenharmony_civoid HexDump(const void *buf, size_t size, size_t maxSize)
55248f512ceSopenharmony_ci{
55348f512ceSopenharmony_ci    const unsigned char *byteBuf = static_cast<const unsigned char *>(buf);
55448f512ceSopenharmony_ci    const size_t dumpByteEachLine = 8;
55548f512ceSopenharmony_ci    size_t outputBytes = 0;
55648f512ceSopenharmony_ci    if (!maxSize) {
55748f512ceSopenharmony_ci        outputBytes = size;
55848f512ceSopenharmony_ci    } else {
55948f512ceSopenharmony_ci        outputBytes = std::min(size, maxSize);
56048f512ceSopenharmony_ci    }
56148f512ceSopenharmony_ci
56248f512ceSopenharmony_ci    for (size_t i = 0; i <= outputBytes; i += dumpByteEachLine) {
56348f512ceSopenharmony_ci        HLOGM(" %02zu: %s ", i, BufferToHexString(byteBuf, dumpByteEachLine).c_str());
56448f512ceSopenharmony_ci        byteBuf += dumpByteEachLine;
56548f512ceSopenharmony_ci    }
56648f512ceSopenharmony_ci}
56748f512ceSopenharmony_ci
56848f512ceSopenharmony_cistd::string BufferToHexString(const std::vector<unsigned char> &vec)
56948f512ceSopenharmony_ci{
57048f512ceSopenharmony_ci    return BufferToHexString(vec.data(), vec.size());
57148f512ceSopenharmony_ci}
57248f512ceSopenharmony_ci
57348f512ceSopenharmony_cistd::string BufferToHexString(const unsigned char buf[], size_t size)
57448f512ceSopenharmony_ci{
57548f512ceSopenharmony_ci    std::stringstream ss;
57648f512ceSopenharmony_ci    ss << size << ":";
57748f512ceSopenharmony_ci    for (size_t i = 0; i < size; i++) {
57848f512ceSopenharmony_ci        ss << " 0x" << std::setfill('0') << std::setw(BYTE_PRINT_WIDTH) << std::hex
57948f512ceSopenharmony_ci           << (unsigned short)buf[i];
58048f512ceSopenharmony_ci    }
58148f512ceSopenharmony_ci    return ss.str();
58248f512ceSopenharmony_ci}
58348f512ceSopenharmony_ci
58448f512ceSopenharmony_civoid CollectPidsByAppname(std::set<pid_t> &pids, const std::string &appPackage)
58548f512ceSopenharmony_ci{
58648f512ceSopenharmony_ci    const std::string basePath {"/proc/"};
58748f512ceSopenharmony_ci    const std::string cmdline {"/cmdline"};
58848f512ceSopenharmony_ci    std::vector<std::string> subDirs = GetSubDirs(basePath);
58948f512ceSopenharmony_ci    for (const auto &subDir : subDirs) {
59048f512ceSopenharmony_ci        if (!IsDigits(subDir)) {
59148f512ceSopenharmony_ci            continue;
59248f512ceSopenharmony_ci        }
59348f512ceSopenharmony_ci        std::string fileName {basePath + subDir + cmdline};
59448f512ceSopenharmony_ci        if (IsSameCommand(ReadFileToString(fileName), appPackage)) {
59548f512ceSopenharmony_ci            pids.emplace(std::stoul(subDir, nullptr));
59648f512ceSopenharmony_ci        }
59748f512ceSopenharmony_ci    }
59848f512ceSopenharmony_ci}
59948f512ceSopenharmony_ci
60048f512ceSopenharmony_cibool IsRestarted(const std::string &appPackage)
60148f512ceSopenharmony_ci{
60248f512ceSopenharmony_ci    printf("please restart %s for profiling within 30 seconds\n", appPackage.c_str());
60348f512ceSopenharmony_ci    std::set<pid_t> oldPids {};
60448f512ceSopenharmony_ci    std::set<pid_t> newPids {};
60548f512ceSopenharmony_ci    std::vector<pid_t> intersection;
60648f512ceSopenharmony_ci    const auto startTime = steady_clock::now();
60748f512ceSopenharmony_ci    const auto endTime = startTime + std::chrono::seconds(CHECK_TIMEOUT);
60848f512ceSopenharmony_ci    CollectPidsByAppname(oldPids, appPackage);
60948f512ceSopenharmony_ci    do {
61048f512ceSopenharmony_ci        CollectPidsByAppname(newPids, appPackage);
61148f512ceSopenharmony_ci        std::set_intersection(oldPids.begin(), oldPids.end(),
61248f512ceSopenharmony_ci            newPids.begin(), newPids.end(), std::back_insert_iterator(intersection));
61348f512ceSopenharmony_ci        // app names are same, no intersection, means app restarted
61448f512ceSopenharmony_ci        CHECK_TRUE(intersection.empty(), true, 0, "");
61548f512ceSopenharmony_ci        intersection.clear();
61648f512ceSopenharmony_ci        newPids.clear();
61748f512ceSopenharmony_ci        std::this_thread::sleep_for(milliseconds(CHECK_FREQUENCY));
61848f512ceSopenharmony_ci    } while (steady_clock::now() < endTime);
61948f512ceSopenharmony_ci    printf("app %s was not stopped within 30 seconds\n", appPackage.c_str());
62048f512ceSopenharmony_ci    return false;
62148f512ceSopenharmony_ci}
62248f512ceSopenharmony_ci
62348f512ceSopenharmony_cipid_t GetAppPackagePid(const std::string &appPackage, const pid_t oldPid, const int checkAppMs,
62448f512ceSopenharmony_ci                       const uint64_t waitAppTimeOut)
62548f512ceSopenharmony_ci{
62648f512ceSopenharmony_ci    pid_t res {-1};
62748f512ceSopenharmony_ci    const std::string basePath {"/proc/"};
62848f512ceSopenharmony_ci    const std::string cmdline {"/cmdline"};
62948f512ceSopenharmony_ci    const auto startTime = steady_clock::now();
63048f512ceSopenharmony_ci    const auto endTime = startTime + std::chrono::seconds(waitAppTimeOut);
63148f512ceSopenharmony_ci    do {
63248f512ceSopenharmony_ci        std::vector<std::string> subDirs = GetSubDirs(basePath);
63348f512ceSopenharmony_ci        for (const auto &subDir : subDirs) {
63448f512ceSopenharmony_ci            if (!IsDigits(subDir)) {
63548f512ceSopenharmony_ci                continue;
63648f512ceSopenharmony_ci            }
63748f512ceSopenharmony_ci            std::string fileName {basePath + subDir + cmdline};
63848f512ceSopenharmony_ci            if (IsSameCommand(ReadFileToString(fileName), appPackage)) {
63948f512ceSopenharmony_ci                res = std::stoul(subDir, nullptr);
64048f512ceSopenharmony_ci                HLOGD("[GetAppPackagePid]: get appid for %s is %d", appPackage.c_str(), res);
64148f512ceSopenharmony_ci                return res;
64248f512ceSopenharmony_ci            }
64348f512ceSopenharmony_ci        }
64448f512ceSopenharmony_ci        std::this_thread::sleep_for(milliseconds(checkAppMs));
64548f512ceSopenharmony_ci    } while (steady_clock::now() < endTime);
64648f512ceSopenharmony_ci
64748f512ceSopenharmony_ci    return res;
64848f512ceSopenharmony_ci}
64948f512ceSopenharmony_ci
65048f512ceSopenharmony_cibool CheckAppIsRunning (std::vector<pid_t> &selectPids, const std::string &appPackage, int checkAppMs)
65148f512ceSopenharmony_ci{
65248f512ceSopenharmony_ci    if (!appPackage.empty()) {
65348f512ceSopenharmony_ci        pid_t appPid = GetAppPackagePid(appPackage, -1, checkAppMs, waitAppRunCheckTimeOut);
65448f512ceSopenharmony_ci        if (appPid <= 0) {
65548f512ceSopenharmony_ci            printf("app %s not running\n", appPackage.c_str());
65648f512ceSopenharmony_ci            return false;
65748f512ceSopenharmony_ci        }
65848f512ceSopenharmony_ci        HLOGD("[CheckAppIsRunning] get appPid %d for app %s\n", appPid, appPackage.c_str());
65948f512ceSopenharmony_ci        selectPids.push_back(appPid);
66048f512ceSopenharmony_ci    }
66148f512ceSopenharmony_ci    return true;
66248f512ceSopenharmony_ci}
66348f512ceSopenharmony_ci
66448f512ceSopenharmony_cibool IsExistDebugByApp(const std::string& bundleName)
66548f512ceSopenharmony_ci{
66648f512ceSopenharmony_ci    std::string bundleNameTmp = bundleName;
66748f512ceSopenharmony_ci    auto pos = bundleNameTmp.find(":");
66848f512ceSopenharmony_ci    if (pos != std::string::npos) {
66948f512ceSopenharmony_ci        bundleNameTmp = bundleNameTmp.substr(0, pos);
67048f512ceSopenharmony_ci    }
67148f512ceSopenharmony_ci    if (!IsSupportNonDebuggableApp() && !bundleNameTmp.empty() && !IsDebugableApp(bundleNameTmp)) {
67248f512ceSopenharmony_ci        HLOGE("--app option only support debug application.");
67348f512ceSopenharmony_ci        printf("--app option only support debug application\n");
67448f512ceSopenharmony_ci        return false;
67548f512ceSopenharmony_ci    }
67648f512ceSopenharmony_ci    return true;
67748f512ceSopenharmony_ci}
67848f512ceSopenharmony_ci
67948f512ceSopenharmony_cibool IsExistDebugByPid(const std::vector<pid_t> &pids)
68048f512ceSopenharmony_ci{
68148f512ceSopenharmony_ci    CHECK_TRUE(pids.empty(), true, 1, "IsExistDebugByPid: pids is empty.");
68248f512ceSopenharmony_ci    for (auto pid : pids) {
68348f512ceSopenharmony_ci        CHECK_TRUE(pid <= 0, false, LOG_TYPE_PRINTF, "Invalid -p value '%d', the pid should be larger than 0\n", pid);
68448f512ceSopenharmony_ci        std::string bundleName = GetProcessName(pid);
68548f512ceSopenharmony_ci        auto pos = bundleName.find(":");
68648f512ceSopenharmony_ci        if (pos != std::string::npos) {
68748f512ceSopenharmony_ci            bundleName = bundleName.substr(0, pos);
68848f512ceSopenharmony_ci        }
68948f512ceSopenharmony_ci        if (!IsSupportNonDebuggableApp() && !IsDebugableApp(bundleName)) {
69048f512ceSopenharmony_ci            HLOGE("-p option only support debug application for %s", bundleName.c_str());
69148f512ceSopenharmony_ci            printf("-p option only support debug application\n");
69248f512ceSopenharmony_ci            return false;
69348f512ceSopenharmony_ci        }
69448f512ceSopenharmony_ci    }
69548f512ceSopenharmony_ci    return true;
69648f512ceSopenharmony_ci}
69748f512ceSopenharmony_ci
69848f512ceSopenharmony_cibool IsDebugableApp(const std::string& bundleName)
69948f512ceSopenharmony_ci{
70048f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos && defined(BUNDLE_FRAMEWORK_ENABLE)
70148f512ceSopenharmony_ci    CHECK_TRUE(bundleName.empty(), false, LOG_TYPE_PRINTF, "bundleName is empty!\n");
70248f512ceSopenharmony_ci    sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
70348f512ceSopenharmony_ci    CHECK_TRUE(sam == nullptr, false, LOG_TYPE_PRINTF, "GetSystemAbilityManager failed!\n");
70448f512ceSopenharmony_ci    sptr<IRemoteObject> remoteObject = sam->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
70548f512ceSopenharmony_ci    CHECK_TRUE(remoteObject == nullptr, false, LOG_TYPE_PRINTF, "Get BundleMgr SA failed!\n");
70648f512ceSopenharmony_ci    sptr<BundleMgrProxy> proxy = iface_cast<BundleMgrProxy>(remoteObject);
70748f512ceSopenharmony_ci    CHECK_TRUE(proxy == nullptr, false, LOG_TYPE_PRINTF, "iface_cast failed!\n");
70848f512ceSopenharmony_ci    AppExecFwk::ApplicationInfo appInfo;
70948f512ceSopenharmony_ci    bool ret = proxy->GetApplicationInfo(bundleName, AppExecFwk::GET_APPLICATION_INFO_WITH_DISABLE,
71048f512ceSopenharmony_ci                                         AppExecFwk::Constants::ANY_USERID, appInfo);
71148f512ceSopenharmony_ci    CHECK_TRUE(!ret, false, 1, "%s GetApplicationInfo failed!", bundleName.c_str());
71248f512ceSopenharmony_ci    HLOGD("bundleName is %s,appProvisionType: %s", bundleName.c_str(), appInfo.appProvisionType.c_str());
71348f512ceSopenharmony_ci    return appInfo.appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG;
71448f512ceSopenharmony_ci#else
71548f512ceSopenharmony_ci    return false;
71648f512ceSopenharmony_ci#endif
71748f512ceSopenharmony_ci}
71848f512ceSopenharmony_ci
71948f512ceSopenharmony_cibool IsSupportNonDebuggableApp()
72048f512ceSopenharmony_ci{
72148f512ceSopenharmony_ci    // root first
72248f512ceSopenharmony_ci    if (IsRoot()) {
72348f512ceSopenharmony_ci        return true;
72448f512ceSopenharmony_ci    }
72548f512ceSopenharmony_ci    // user mode
72648f512ceSopenharmony_ci    CHECK_TRUE(!IsBeta(), false, 0, "");
72748f512ceSopenharmony_ci    // restricted aplication for beta
72848f512ceSopenharmony_ci    CHECK_TRUE(!IsAllowProfilingUid(), false, 0, "");
72948f512ceSopenharmony_ci    return true;
73048f512ceSopenharmony_ci}
73148f512ceSopenharmony_ci
73248f512ceSopenharmony_ciconst std::string GetUserType()
73348f512ceSopenharmony_ci{
73448f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos
73548f512ceSopenharmony_ci    std::string userType = OHOS::system::GetParameter(USER_TYPE_PARAM, USER_TYPE_PARAM_GET);
73648f512ceSopenharmony_ci    HLOGD("GetUserType: userType is %s", userType.c_str());
73748f512ceSopenharmony_ci    return userType;
73848f512ceSopenharmony_ci#else
73948f512ceSopenharmony_ci    return "";
74048f512ceSopenharmony_ci#endif
74148f512ceSopenharmony_ci}
74248f512ceSopenharmony_ci
74348f512ceSopenharmony_cibool GetDeveloperMode()
74448f512ceSopenharmony_ci{
74548f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos
74648f512ceSopenharmony_ci    bool developerMode = OHOS::system::GetBoolParameter("const.security.developermode.state", false);
74748f512ceSopenharmony_ci    HLOGD("GetDeveloperMode: developerMode is %d", developerMode);
74848f512ceSopenharmony_ci    return developerMode;
74948f512ceSopenharmony_ci#else
75048f512ceSopenharmony_ci    return true;
75148f512ceSopenharmony_ci#endif
75248f512ceSopenharmony_ci}
75348f512ceSopenharmony_ci
75448f512ceSopenharmony_cibool LittleMemory()
75548f512ceSopenharmony_ci{
75648f512ceSopenharmony_ci    std::ifstream file("/proc/meminfo");
75748f512ceSopenharmony_ci    std::string line;
75848f512ceSopenharmony_ci    while (getline(file, line)) {
75948f512ceSopenharmony_ci        if (line.find("MemTotal:") != std::string::npos) {
76048f512ceSopenharmony_ci            int memSize = stoi(line.substr(line.find(":") + 1));
76148f512ceSopenharmony_ci            CHECK_TRUE(memSize < (LITTLE_MEMORY_SIZE * MULTIPLE_SIZE * MULTIPLE_SIZE), true, 0, "");
76248f512ceSopenharmony_ci        }
76348f512ceSopenharmony_ci    }
76448f512ceSopenharmony_ci    return false;
76548f512ceSopenharmony_ci}
76648f512ceSopenharmony_ci
76748f512ceSopenharmony_ci// only for domestic beta
76848f512ceSopenharmony_cibool IsBeta()
76948f512ceSopenharmony_ci{
77048f512ceSopenharmony_ci    std::string userTypeRsp = GetUserType();
77148f512ceSopenharmony_ci    if (userTypeRsp == USER_DOMESTIC_BETA) {
77248f512ceSopenharmony_ci        return true;
77348f512ceSopenharmony_ci    }
77448f512ceSopenharmony_ci    // default release when usertype param is invalid
77548f512ceSopenharmony_ci    CHECK_TRUE(userTypeRsp.empty(), true, 1, "GetUserType is empty [%s]", userTypeRsp.c_str());
77648f512ceSopenharmony_ci    return false;
77748f512ceSopenharmony_ci}
77848f512ceSopenharmony_ci
77948f512ceSopenharmony_cibool IsAllowProfilingUid()
78048f512ceSopenharmony_ci{
78148f512ceSopenharmony_ci#if (defined(is_linux) && is_linux) || (defined(is_ohos) && is_ohos)
78248f512ceSopenharmony_ci    static unsigned int curUid = getuid();
78348f512ceSopenharmony_ci    HLOGD("curUid is %d\n", curUid);
78448f512ceSopenharmony_ci    CHECK_TRUE(ALLOW_UIDS.find(curUid) != ALLOW_UIDS.end(), true, 0, "");
78548f512ceSopenharmony_ci    return false;
78648f512ceSopenharmony_ci#else
78748f512ceSopenharmony_ci    return false;
78848f512ceSopenharmony_ci#endif
78948f512ceSopenharmony_ci}
79048f512ceSopenharmony_ci
79148f512ceSopenharmony_cistd::string GetProcessName(int pid)
79248f512ceSopenharmony_ci{
79348f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos
79448f512ceSopenharmony_ci    std::string filePath = "/proc/" + std::to_string(pid) + "/cmdline";
79548f512ceSopenharmony_ci    std::string bundleName = ReadFileToString(filePath);
79648f512ceSopenharmony_ci    return bundleName.substr(0, strlen(bundleName.c_str()));
79748f512ceSopenharmony_ci#else
79848f512ceSopenharmony_ci    return "";
79948f512ceSopenharmony_ci#endif
80048f512ceSopenharmony_ci}
80148f512ceSopenharmony_ci
80248f512ceSopenharmony_cibool NeedAdaptSandboxPath(char *filename, int pid, u16 &headerSize)
80348f512ceSopenharmony_ci{
80448f512ceSopenharmony_ci    std::string oldFilename = filename;
80548f512ceSopenharmony_ci    if (oldFilename.find("/data/storage") == 0 && access(oldFilename.c_str(), F_OK) != 0) {
80648f512ceSopenharmony_ci        std::string newFilename = "/proc/" + std::to_string(pid) + "/root" + oldFilename;
80748f512ceSopenharmony_ci        (void)memset_s(filename, KILO, '\0', KILO);
80848f512ceSopenharmony_ci        if (strncpy_s(filename, KILO, newFilename.c_str(), newFilename.size()) != 0) {
80948f512ceSopenharmony_ci            HLOGD("strncpy_s recordMmap2 failed!");
81048f512ceSopenharmony_ci        }
81148f512ceSopenharmony_ci        headerSize += newFilename.size() - oldFilename.size();
81248f512ceSopenharmony_ci        return true;
81348f512ceSopenharmony_ci    }
81448f512ceSopenharmony_ci    return false;
81548f512ceSopenharmony_ci}
81648f512ceSopenharmony_ci
81748f512ceSopenharmony_cibool NeedAdaptHMBundlePath(std::string& filename, const std::string& threadname)
81848f512ceSopenharmony_ci{
81948f512ceSopenharmony_ci    static bool needCheck = true;
82048f512ceSopenharmony_ci    if (!needCheck) {
82148f512ceSopenharmony_ci        return false;
82248f512ceSopenharmony_ci    }
82348f512ceSopenharmony_ci    const std::string path = "/data/storage/el1/bundle";
82448f512ceSopenharmony_ci    std::string newFileName = filename;
82548f512ceSopenharmony_ci    size_t pos = newFileName.find(path);
82648f512ceSopenharmony_ci    if (pos != std::string::npos) {
82748f512ceSopenharmony_ci        if (access(filename.c_str(), F_OK) != 0) {
82848f512ceSopenharmony_ci            const std::string newpath = "/data/app/el1/bundle/public/";
82948f512ceSopenharmony_ci            // /data/storage/el1/bundle/libs/arm64/libentry.so
83048f512ceSopenharmony_ci            newFileName.replace(pos, path.length(), newpath + threadname);
83148f512ceSopenharmony_ci            if (access(newFileName.c_str(), F_OK) != 0) {
83248f512ceSopenharmony_ci                return false;
83348f512ceSopenharmony_ci            }
83448f512ceSopenharmony_ci            // /data/app/el1/bundle/public/<procname>/libs/arm64/libentry.so
83548f512ceSopenharmony_ci            filename = newFileName;
83648f512ceSopenharmony_ci            HLOGD("Fix hm bundle path to %s", filename.c_str());
83748f512ceSopenharmony_ci            return true;
83848f512ceSopenharmony_ci        } else {
83948f512ceSopenharmony_ci            needCheck = false;
84048f512ceSopenharmony_ci        }
84148f512ceSopenharmony_ci    }
84248f512ceSopenharmony_ci    return false;
84348f512ceSopenharmony_ci}
84448f512ceSopenharmony_ci
84548f512ceSopenharmony_cibool IsArkJsFile(const std::string& filepath)
84648f512ceSopenharmony_ci{
84748f512ceSopenharmony_ci    return (StringEndsWith(filepath, ".hap") ||
84848f512ceSopenharmony_ci            StringStartsWith(filepath, "[anon:ArkTS Code") ||
84948f512ceSopenharmony_ci            StringEndsWith(filepath, ".hsp") ||
85048f512ceSopenharmony_ci            StringEndsWith(filepath, ".abc") ||
85148f512ceSopenharmony_ci            StringEndsWith(filepath, ".hqf"));
85248f512ceSopenharmony_ci}
85348f512ceSopenharmony_ci
85448f512ceSopenharmony_cibool IsHiviewCall()
85548f512ceSopenharmony_ci{
85648f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos
85748f512ceSopenharmony_ci    pid_t ppid = syscall(SYS_getppid);
85848f512ceSopenharmony_ci    std::string cmdline = GetProcessName(ppid);
85948f512ceSopenharmony_ci    HLOGD("getppid is %d, cmdline is %s", ppid, cmdline.c_str());
86048f512ceSopenharmony_ci    if (cmdline == HIVIEW_CMDLINE) {
86148f512ceSopenharmony_ci        HLOGD("hiview call");
86248f512ceSopenharmony_ci        return true;
86348f512ceSopenharmony_ci    }
86448f512ceSopenharmony_ci    return false;
86548f512ceSopenharmony_ci#else
86648f512ceSopenharmony_ci    return false;
86748f512ceSopenharmony_ci#endif
86848f512ceSopenharmony_ci}
86948f512ceSopenharmony_ci
87048f512ceSopenharmony_cibool IsApplicationEncryped(const int pid)
87148f512ceSopenharmony_ci{
87248f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos && defined(BUNDLE_FRAMEWORK_ENABLE)
87348f512ceSopenharmony_ci    CHECK_TRUE(pid <= 0, false, LOG_TYPE_PRINTF, "Invalid -p value '%d', the pid should be larger than 0\n", pid);
87448f512ceSopenharmony_ci    std::string bundleName = GetProcessName(pid);
87548f512ceSopenharmony_ci    CHECK_TRUE(bundleName.empty(), false, 1, "bundleName is empty,pid is %d", pid);
87648f512ceSopenharmony_ci    sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
87748f512ceSopenharmony_ci    CHECK_TRUE(sam == nullptr, false, LOG_TYPE_PRINTF, "GetSystemAbilityManager failed!\n");
87848f512ceSopenharmony_ci    sptr<IRemoteObject> remoteObject = sam->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
87948f512ceSopenharmony_ci    CHECK_TRUE(remoteObject == nullptr, false, LOG_TYPE_PRINTF, "Get BundleMgr SA failed!\n");
88048f512ceSopenharmony_ci    sptr<BundleMgrProxy> proxy = iface_cast<BundleMgrProxy>(remoteObject);
88148f512ceSopenharmony_ci    CHECK_TRUE(proxy == nullptr, false, LOG_TYPE_PRINTF, "iface_cast failed!\n");
88248f512ceSopenharmony_ci
88348f512ceSopenharmony_ci    AppExecFwk::ApplicationInfo appInfo;
88448f512ceSopenharmony_ci    bool ret = proxy->GetApplicationInfo(bundleName, AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO,
88548f512ceSopenharmony_ci                                         AppExecFwk::Constants::ANY_USERID, appInfo);
88648f512ceSopenharmony_ci    CHECK_TRUE(!ret, false, 1, "%s:%s GetApplicationInfo failed!", __func__, bundleName.c_str());
88748f512ceSopenharmony_ci    bool isEncrypted = (appInfo.applicationReservedFlag &
88848f512ceSopenharmony_ci                        static_cast<uint32_t>(AppExecFwk::ApplicationReservedFlag::ENCRYPTED_APPLICATION)) != 0;
88948f512ceSopenharmony_ci    HLOGD("check application encryped.%d : %s, pid:%d", isEncrypted, bundleName.c_str(), pid);
89048f512ceSopenharmony_ci    return isEncrypted;
89148f512ceSopenharmony_ci#else
89248f512ceSopenharmony_ci    return false;
89348f512ceSopenharmony_ci#endif
89448f512ceSopenharmony_ci}
89548f512ceSopenharmony_ci} // namespace HiPerf
89648f512ceSopenharmony_ci} // namespace Developtools
89748f512ceSopenharmony_ci} // namespace OHOS
898