1f857971dSopenharmony_ci/*
2f857971dSopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3f857971dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4f857971dSopenharmony_ci * you may not use this file except in compliance with the License.
5f857971dSopenharmony_ci * You may obtain a copy of the License at
6f857971dSopenharmony_ci *
7f857971dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8f857971dSopenharmony_ci *
9f857971dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10f857971dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11f857971dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f857971dSopenharmony_ci * See the License for the specific language governing permissions and
13f857971dSopenharmony_ci * limitations under the License.
14f857971dSopenharmony_ci */
15f857971dSopenharmony_ci
16f857971dSopenharmony_ci#include "include/util.h"
17f857971dSopenharmony_ci
18f857971dSopenharmony_ci#include <string>
19f857971dSopenharmony_ci
20f857971dSopenharmony_ci#ifndef OHOS_BUILD_ENABLE_ARKUI_X
21f857971dSopenharmony_ci#include <sys/prctl.h>
22f857971dSopenharmony_ci#endif // OHOS_BUILD_ENABLE_ARKUI_X
23f857971dSopenharmony_ci#include <sys/stat.h>
24f857971dSopenharmony_ci#include <sys/syscall.h>
25f857971dSopenharmony_ci#include <unistd.h>
26f857971dSopenharmony_ci
27f857971dSopenharmony_ci#ifndef OHOS_BUILD_ENABLE_ARKUI_X
28f857971dSopenharmony_ci#include "parameters.h"
29f857971dSopenharmony_ci#endif // OHOS_BUILD_ENABLE_ARKUI_X
30f857971dSopenharmony_ci#include "securec.h"
31f857971dSopenharmony_ci
32f857971dSopenharmony_ci#include "devicestatus_define.h"
33f857971dSopenharmony_ci#include "utility.h"
34f857971dSopenharmony_ci
35f857971dSopenharmony_ci#undef LOG_TAG
36f857971dSopenharmony_ci#define LOG_TAG "Util"
37f857971dSopenharmony_ci
38f857971dSopenharmony_cinamespace OHOS {
39f857971dSopenharmony_cinamespace Msdp {
40f857971dSopenharmony_cinamespace DeviceStatus {
41f857971dSopenharmony_cinamespace {
42f857971dSopenharmony_ciconstexpr size_t BUF_TID_SIZE { 10 };
43f857971dSopenharmony_ciconstexpr size_t PROGRAM_NAME_SIZE { 256 };
44f857971dSopenharmony_ciconstexpr size_t BUF_CMD_SIZE { 512 };
45f857971dSopenharmony_ciconstexpr uint32_t BASE_YEAR { 1900 };
46f857971dSopenharmony_ciconstexpr uint32_t BASE_MON { 1 };
47f857971dSopenharmony_ciconstexpr uint32_t MS_NS { 1000000 };
48f857971dSopenharmony_ciconstexpr int32_t FILE_SIZE_MAX { 0x5000 };
49f857971dSopenharmony_ciconstexpr size_t SHORT_KEY_LENGTH { 20 };
50f857971dSopenharmony_ciconstexpr size_t PLAINTEXT_LENGTH { 4 };
51f857971dSopenharmony_ciconstexpr int32_t ROTATE_POLICY_WINDOW_ROTATE { 0 };
52f857971dSopenharmony_ciconstexpr int32_t ROTATE_POLICY_SCREEN_ROTATE { 1 };
53f857971dSopenharmony_ciconstexpr int32_t ROTATE_POLICY_FOLD_MODE { 2 };
54f857971dSopenharmony_ci#ifndef OHOS_BUILD_ENABLE_ARKUI_X
55f857971dSopenharmony_ciconst int32_t ROTATE_POLICY = OHOS::system::GetIntParameter("const.window.device.rotate_policy", 0);
56f857971dSopenharmony_ciconst std::string FOLD_ROTATE_POLICY = OHOS::system::GetParameter("const.window.foldabledevice.rotate_policy", "0,0");
57f857971dSopenharmony_ci#endif // OHOS_BUILD_ENABLE_ARKUI_X
58f857971dSopenharmony_ciconst std::string SVG_PATH { "/system/etc/device_status/drag_icon/" };
59f857971dSopenharmony_ci} // namespace
60f857971dSopenharmony_ci
61f857971dSopenharmony_ciint32_t GetPid()
62f857971dSopenharmony_ci{
63f857971dSopenharmony_ci    return static_cast<int32_t>(getpid());
64f857971dSopenharmony_ci}
65f857971dSopenharmony_ci
66f857971dSopenharmony_cistatic std::string GetThisThreadIdOfString()
67f857971dSopenharmony_ci{
68f857971dSopenharmony_ci    thread_local std::string threadLocalId;
69f857971dSopenharmony_ci    if (threadLocalId.empty()) {
70f857971dSopenharmony_ci        long tid = syscall(SYS_gettid);
71f857971dSopenharmony_ci        char buf[BUF_TID_SIZE] = { 0 };
72f857971dSopenharmony_ci        const int32_t ret = sprintf_s(buf, BUF_TID_SIZE, "%06d", tid);
73f857971dSopenharmony_ci        if (ret < 0) {
74f857971dSopenharmony_ci            FI_HILOGE("Call sprintf_s failed, ret:%{public}d", ret);
75f857971dSopenharmony_ci            return threadLocalId;
76f857971dSopenharmony_ci        }
77f857971dSopenharmony_ci        buf[BUF_TID_SIZE - 1] = '\0';
78f857971dSopenharmony_ci        threadLocalId = buf;
79f857971dSopenharmony_ci    }
80f857971dSopenharmony_ci    return threadLocalId;
81f857971dSopenharmony_ci}
82f857971dSopenharmony_ci
83f857971dSopenharmony_ciuint64_t GetThisThreadId()
84f857971dSopenharmony_ci{
85f857971dSopenharmony_ci    std::string threadId = GetThisThreadIdOfString();
86f857971dSopenharmony_ci    uint64_t tid = std::stoull(threadId);
87f857971dSopenharmony_ci    return tid;
88f857971dSopenharmony_ci}
89f857971dSopenharmony_ci
90f857971dSopenharmony_ciint64_t GetMillisTime()
91f857971dSopenharmony_ci{
92f857971dSopenharmony_ci    auto timeNow = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now());
93f857971dSopenharmony_ci    auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(timeNow.time_since_epoch());
94f857971dSopenharmony_ci    return tmp.count();
95f857971dSopenharmony_ci}
96f857971dSopenharmony_ci
97f857971dSopenharmony_civoid GetTimeStamp(std::string &startTime)
98f857971dSopenharmony_ci{
99f857971dSopenharmony_ci    timespec curTime;
100f857971dSopenharmony_ci    clock_gettime(CLOCK_REALTIME, &curTime);
101f857971dSopenharmony_ci    struct tm *timeinfo = localtime(&(curTime.tv_sec));
102f857971dSopenharmony_ci    CHKPV(timeinfo);
103f857971dSopenharmony_ci    startTime.append(std::to_string(timeinfo->tm_year + BASE_YEAR)).append("-")
104f857971dSopenharmony_ci        .append(std::to_string(timeinfo->tm_mon + BASE_MON)).append("-").append(std::to_string(timeinfo->tm_mday))
105f857971dSopenharmony_ci        .append(" ").append(std::to_string(timeinfo->tm_hour)).append(":").append(std::to_string(timeinfo->tm_min))
106f857971dSopenharmony_ci        .append(":").append(std::to_string(timeinfo->tm_sec)).append(".")
107f857971dSopenharmony_ci        .append(std::to_string(curTime.tv_nsec / MS_NS));
108f857971dSopenharmony_ci}
109f857971dSopenharmony_ci
110f857971dSopenharmony_civoid SetThreadName(const std::string &name)
111f857971dSopenharmony_ci{
112f857971dSopenharmony_ci#ifndef OHOS_BUILD_ENABLE_ARKUI_X
113f857971dSopenharmony_ci    prctl(PR_SET_NAME, name.c_str());
114f857971dSopenharmony_ci#endif // OHOS_BUILD_ENABLE_ARKUI_X
115f857971dSopenharmony_ci}
116f857971dSopenharmony_ci
117f857971dSopenharmony_cistatic size_t StringToken(std::string &strs, const std::string &sep, std::string &token)
118f857971dSopenharmony_ci{
119f857971dSopenharmony_ci    token = "";
120f857971dSopenharmony_ci    if (strs.empty()) {
121f857971dSopenharmony_ci        return strs.npos;
122f857971dSopenharmony_ci    }
123f857971dSopenharmony_ci    size_t seat = strs.npos;
124f857971dSopenharmony_ci    size_t temp = 0;
125f857971dSopenharmony_ci    for (auto &item : sep) {
126f857971dSopenharmony_ci        temp = strs.find(item);
127f857971dSopenharmony_ci        if (strs.npos != temp) {
128f857971dSopenharmony_ci            seat = (std::min)(seat, temp);
129f857971dSopenharmony_ci        }
130f857971dSopenharmony_ci    }
131f857971dSopenharmony_ci    if (strs.npos != seat) {
132f857971dSopenharmony_ci        token = strs.substr(0, seat);
133f857971dSopenharmony_ci        if (strs.npos != seat + 1) {
134f857971dSopenharmony_ci            strs = strs.substr(seat + 1, strs.npos);
135f857971dSopenharmony_ci        }
136f857971dSopenharmony_ci        if (seat == 0) {
137f857971dSopenharmony_ci            return StringToken(strs, sep, token);
138f857971dSopenharmony_ci        }
139f857971dSopenharmony_ci    } else {
140f857971dSopenharmony_ci        token = strs;
141f857971dSopenharmony_ci        strs = "";
142f857971dSopenharmony_ci    }
143f857971dSopenharmony_ci    return token.size();
144f857971dSopenharmony_ci}
145f857971dSopenharmony_ci
146f857971dSopenharmony_cisize_t StringSplit(const std::string &str, const std::string &sep, std::vector<std::string> &vecList)
147f857971dSopenharmony_ci{
148f857971dSopenharmony_ci    size_t size = 0;
149f857971dSopenharmony_ci    auto strs = str;
150f857971dSopenharmony_ci    std::string token;
151f857971dSopenharmony_ci    while (str.npos != (size = StringToken(strs, sep, token))) {
152f857971dSopenharmony_ci        vecList.push_back(token);
153f857971dSopenharmony_ci    }
154f857971dSopenharmony_ci    return vecList.size();
155f857971dSopenharmony_ci}
156f857971dSopenharmony_ci
157f857971dSopenharmony_cistd::string StringPrintf(const char *format, ...)
158f857971dSopenharmony_ci{
159f857971dSopenharmony_ci    char space[1024] { 0 };
160f857971dSopenharmony_ci
161f857971dSopenharmony_ci    va_list ap;
162f857971dSopenharmony_ci    va_start(ap, format);
163f857971dSopenharmony_ci    std::string result;
164f857971dSopenharmony_ci    int32_t ret = vsnprintf_s(space, sizeof(space), sizeof(space) - 1, format, ap);
165f857971dSopenharmony_ci    if (ret >= RET_OK && static_cast<size_t>(ret) < sizeof(space)) {
166f857971dSopenharmony_ci        result = space;
167f857971dSopenharmony_ci    } else {
168f857971dSopenharmony_ci        FI_HILOGE("The buffer is overflow");
169f857971dSopenharmony_ci    }
170f857971dSopenharmony_ci    va_end(ap);
171f857971dSopenharmony_ci    return result;
172f857971dSopenharmony_ci}
173f857971dSopenharmony_ci
174f857971dSopenharmony_cistd::string GetAnonyString(const std::string &value)
175f857971dSopenharmony_ci{
176f857971dSopenharmony_ci    if (value.empty()) {
177f857971dSopenharmony_ci        return "empty";
178f857971dSopenharmony_ci    }
179f857971dSopenharmony_ci    std::string anonyStr = "******";
180f857971dSopenharmony_ci    std::string str;
181f857971dSopenharmony_ci    size_t strLen = value.length();
182f857971dSopenharmony_ci    if (strLen == 0) {
183f857971dSopenharmony_ci        FI_HILOGE("strLen is 0, value will overflow");
184f857971dSopenharmony_ci        return "empty";
185f857971dSopenharmony_ci    } else if (strLen <= SHORT_KEY_LENGTH) {
186f857971dSopenharmony_ci        str += value[0];
187f857971dSopenharmony_ci        str += anonyStr;
188f857971dSopenharmony_ci        str += value[strLen - 1];
189f857971dSopenharmony_ci    } else {
190f857971dSopenharmony_ci        str.append(value, 0, PLAINTEXT_LENGTH);
191f857971dSopenharmony_ci        str += anonyStr;
192f857971dSopenharmony_ci        str.append(value, strLen - PLAINTEXT_LENGTH, PLAINTEXT_LENGTH);
193f857971dSopenharmony_ci    }
194f857971dSopenharmony_ci    return str;
195f857971dSopenharmony_ci}
196f857971dSopenharmony_ci
197f857971dSopenharmony_cistatic std::string GetFileName(const std::string &path)
198f857971dSopenharmony_ci{
199f857971dSopenharmony_ci    size_t nPos = path.find_last_of('/');
200f857971dSopenharmony_ci    if (path.npos == nPos) {
201f857971dSopenharmony_ci        nPos = path.find_last_of('\\');
202f857971dSopenharmony_ci    }
203f857971dSopenharmony_ci    if (path.npos == nPos) {
204f857971dSopenharmony_ci        return path;
205f857971dSopenharmony_ci    }
206f857971dSopenharmony_ci    return path.substr(nPos + 1, path.npos);
207f857971dSopenharmony_ci}
208f857971dSopenharmony_ci
209f857971dSopenharmony_ciconst char* GetProgramName()
210f857971dSopenharmony_ci{
211f857971dSopenharmony_ci    static char programName[PROGRAM_NAME_SIZE] = { 0 };
212f857971dSopenharmony_ci    if (programName[0] != '\0') {
213f857971dSopenharmony_ci        return programName;
214f857971dSopenharmony_ci    }
215f857971dSopenharmony_ci
216f857971dSopenharmony_ci    char buf[BUF_CMD_SIZE] = { 0 };
217f857971dSopenharmony_ci    int32_t ret = sprintf_s(buf, BUF_CMD_SIZE, "/proc/%d/cmdline", static_cast<int32_t>(getpid()));
218f857971dSopenharmony_ci    if (ret == -1) {
219f857971dSopenharmony_ci        FI_HILOGE("GetProcessInfo sprintf_s cmdline error");
220f857971dSopenharmony_ci        return "";
221f857971dSopenharmony_ci    }
222f857971dSopenharmony_ci    FILE *fp = fopen(buf, "rb");
223f857971dSopenharmony_ci    if (fp == nullptr) {
224f857971dSopenharmony_ci        FI_HILOGE("The fp is nullptr, filename:%{public}s", buf);
225f857971dSopenharmony_ci        return "";
226f857971dSopenharmony_ci    }
227f857971dSopenharmony_ci    static constexpr size_t bufLineSize = 512;
228f857971dSopenharmony_ci    char bufLine[bufLineSize] = { 0 };
229f857971dSopenharmony_ci    if ((fgets(bufLine, bufLineSize, fp) == nullptr)) {
230f857971dSopenharmony_ci        FI_HILOGE("fgets failed");
231f857971dSopenharmony_ci        if (fclose(fp) != 0) {
232f857971dSopenharmony_ci            FI_HILOGW("Close file failed");
233f857971dSopenharmony_ci        }
234f857971dSopenharmony_ci        fp = nullptr;
235f857971dSopenharmony_ci        return "";
236f857971dSopenharmony_ci    }
237f857971dSopenharmony_ci    if (fclose(fp) != 0) {
238f857971dSopenharmony_ci        FI_HILOGW("Close file:%{public}s failed", buf);
239f857971dSopenharmony_ci    }
240f857971dSopenharmony_ci    fp = nullptr;
241f857971dSopenharmony_ci
242f857971dSopenharmony_ci    std::string tempName(bufLine);
243f857971dSopenharmony_ci    tempName = GetFileName(tempName);
244f857971dSopenharmony_ci    if (tempName.empty()) {
245f857971dSopenharmony_ci        FI_HILOGE("tempName is empty");
246f857971dSopenharmony_ci        return "";
247f857971dSopenharmony_ci    }
248f857971dSopenharmony_ci    size_t copySize = std::min(tempName.size(), PROGRAM_NAME_SIZE - 1);
249f857971dSopenharmony_ci    if (copySize == 0) {
250f857971dSopenharmony_ci        FI_HILOGE("The copySize is 0");
251f857971dSopenharmony_ci        return "";
252f857971dSopenharmony_ci    }
253f857971dSopenharmony_ci    errno_t result = memcpy_s(programName, PROGRAM_NAME_SIZE, tempName.c_str(), copySize);
254f857971dSopenharmony_ci    if (result != EOK) {
255f857971dSopenharmony_ci        FI_HILOGE("memcpy_s failed");
256f857971dSopenharmony_ci        return "";
257f857971dSopenharmony_ci    }
258f857971dSopenharmony_ci    FI_HILOGI("Get program name success, programName:%{public}s", programName);
259f857971dSopenharmony_ci
260f857971dSopenharmony_ci    return programName;
261f857971dSopenharmony_ci}
262f857971dSopenharmony_ci
263f857971dSopenharmony_cibool CheckFileExtendName(const std::string &filePath, const std::string &checkExtension)
264f857971dSopenharmony_ci{
265f857971dSopenharmony_ci    std::string::size_type pos = filePath.find_last_of('.');
266f857971dSopenharmony_ci    if (pos == std::string::npos) {
267f857971dSopenharmony_ci        FI_HILOGE("File is not found extension");
268f857971dSopenharmony_ci        return false;
269f857971dSopenharmony_ci    }
270f857971dSopenharmony_ci    return (filePath.substr(pos + 1, filePath.npos) == checkExtension);
271f857971dSopenharmony_ci}
272f857971dSopenharmony_ci
273f857971dSopenharmony_cibool IsValidPath(const std::string &rootDir, const std::string &filePath)
274f857971dSopenharmony_ci{
275f857971dSopenharmony_ci    return (filePath.compare(0, rootDir.size(), rootDir) == 0);
276f857971dSopenharmony_ci}
277f857971dSopenharmony_ci
278f857971dSopenharmony_cibool IsValidSvgPath(const std::string &filePath)
279f857971dSopenharmony_ci{
280f857971dSopenharmony_ci    return IsValidPath(SVG_PATH, filePath);
281f857971dSopenharmony_ci}
282f857971dSopenharmony_ci
283f857971dSopenharmony_cibool IsValidSvgFile(const std::string &filePath)
284f857971dSopenharmony_ci{
285f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
286f857971dSopenharmony_ci    if (filePath.empty()) {
287f857971dSopenharmony_ci        FI_HILOGE("FilePath is empty");
288f857971dSopenharmony_ci        return false;
289f857971dSopenharmony_ci    }
290f857971dSopenharmony_ci    char realPath[PATH_MAX] = { 0 };
291f857971dSopenharmony_ci    if (realpath(filePath.c_str(), realPath) == nullptr) {
292f857971dSopenharmony_ci        FI_HILOGE("Realpath return nullptr, realPath:%{private}s", realPath);
293f857971dSopenharmony_ci        return false;
294f857971dSopenharmony_ci    }
295f857971dSopenharmony_ci#ifndef OHOS_BUILD_ENABLE_ARKUI_X
296f857971dSopenharmony_ci    if (!IsValidSvgPath(realPath)) {
297f857971dSopenharmony_ci        FI_HILOGE("File path invalid");
298f857971dSopenharmony_ci        return false;
299f857971dSopenharmony_ci    }
300f857971dSopenharmony_ci#endif // OHOS_BUILD_ENABLE_ARKUI_X
301f857971dSopenharmony_ci    if (!Utility::DoesFileExist(realPath)) {
302f857971dSopenharmony_ci        FI_HILOGE("File not exist");
303f857971dSopenharmony_ci        return false;
304f857971dSopenharmony_ci    }
305f857971dSopenharmony_ci    if (!CheckFileExtendName(realPath, "svg")) {
306f857971dSopenharmony_ci        FI_HILOGE("Unable to parse files other than svg format");
307f857971dSopenharmony_ci        return false;
308f857971dSopenharmony_ci    }
309f857971dSopenharmony_ci    int32_t fileSize = Utility::GetFileSize(realPath);
310f857971dSopenharmony_ci    if ((fileSize <= 0) || (fileSize > FILE_SIZE_MAX)) {
311f857971dSopenharmony_ci        FI_HILOGE("File size out of read range");
312f857971dSopenharmony_ci        return false;
313f857971dSopenharmony_ci    }
314f857971dSopenharmony_ci    return true;
315f857971dSopenharmony_ci}
316f857971dSopenharmony_ci
317f857971dSopenharmony_cibool IsNum(const std::string &str)
318f857971dSopenharmony_ci{
319f857971dSopenharmony_ci    std::istringstream sin(str);
320f857971dSopenharmony_ci    double num = 0.0;
321f857971dSopenharmony_ci    return (sin >> num) && sin.eof();
322f857971dSopenharmony_ci}
323f857971dSopenharmony_ci
324f857971dSopenharmony_civoid GetRotatePolicy(bool &isScreenRotation, std::vector<std::string> &foldRotatePolicys)
325f857971dSopenharmony_ci{
326f857971dSopenharmony_ci#ifndef OHOS_BUILD_ENABLE_ARKUI_X
327f857971dSopenharmony_ci    if (ROTATE_POLICY == ROTATE_POLICY_WINDOW_ROTATE) {
328f857971dSopenharmony_ci        isScreenRotation = false;
329f857971dSopenharmony_ci        return;
330f857971dSopenharmony_ci    }
331f857971dSopenharmony_ci    if (ROTATE_POLICY == ROTATE_POLICY_SCREEN_ROTATE) {
332f857971dSopenharmony_ci        isScreenRotation = true;
333f857971dSopenharmony_ci        return;
334f857971dSopenharmony_ci    }
335f857971dSopenharmony_ci    if (ROTATE_POLICY == ROTATE_POLICY_FOLD_MODE) {
336f857971dSopenharmony_ci        isScreenRotation = false;
337f857971dSopenharmony_ci        StringSplit(FOLD_ROTATE_POLICY, ",", foldRotatePolicys);
338f857971dSopenharmony_ci        return;
339f857971dSopenharmony_ci    }
340f857971dSopenharmony_ci#endif // OHOS_BUILD_ENABLE_ARKUI_X
341f857971dSopenharmony_ci}
342f857971dSopenharmony_ci} // namespace DeviceStatus
343f857971dSopenharmony_ci} // namespace Msdp
344f857971dSopenharmony_ci} // namespace OHOS