106f6ba60Sopenharmony_ci/*
206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License.
506f6ba60Sopenharmony_ci * You may obtain a copy of the License at
606f6ba60Sopenharmony_ci *
706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
806f6ba60Sopenharmony_ci *
906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and
1306f6ba60Sopenharmony_ci * limitations under the License.
1406f6ba60Sopenharmony_ci */
1506f6ba60Sopenharmony_ci#include <cstdio>
1606f6ba60Sopenharmony_ci#include <algorithm>
1706f6ba60Sopenharmony_ci#include <iostream>
1806f6ba60Sopenharmony_ci#include <sstream>
1906f6ba60Sopenharmony_ci#include <queue>
2006f6ba60Sopenharmony_ci#include <vector>
2106f6ba60Sopenharmony_ci#include <map>
2206f6ba60Sopenharmony_ci#include <string>
2306f6ba60Sopenharmony_ci#include <ctime>
2406f6ba60Sopenharmony_ci#include <thread>
2506f6ba60Sopenharmony_ci#include <unistd.h>
2606f6ba60Sopenharmony_ci#include <sys/time.h>
2706f6ba60Sopenharmony_ci#include "include/profiler_fps.h"
2806f6ba60Sopenharmony_ci#include "include/sp_log.h"
2906f6ba60Sopenharmony_ci#include "include/sp_utils.h"
3006f6ba60Sopenharmony_ci#include "include/ByTrace.h"
3106f6ba60Sopenharmony_ci#include "include/startup_delay.h"
3206f6ba60Sopenharmony_ci#include "include/common.h"
3306f6ba60Sopenharmony_ci
3406f6ba60Sopenharmony_cinamespace OHOS {
3506f6ba60Sopenharmony_cinamespace SmartPerf {
3606f6ba60Sopenharmony_cistd::map<std::string, std::string> ProfilerFPS::ItemData()
3706f6ba60Sopenharmony_ci{
3806f6ba60Sopenharmony_ci    std::map<std::string, std::string> result;
3906f6ba60Sopenharmony_ci    FpsInfoProfiler finalResult;
4006f6ba60Sopenharmony_ci    if (isGameLayer == "1") {
4106f6ba60Sopenharmony_ci        std::string gameLayerName = GetGameLayer();
4206f6ba60Sopenharmony_ci        LOGI("ProfilerFPS::gameLayerName: (%s)", gameLayerName.c_str());
4306f6ba60Sopenharmony_ci        if (!gameLayerName.empty()) {
4406f6ba60Sopenharmony_ci            finalResult = selfRerderLayers(gameLayerName);
4506f6ba60Sopenharmony_ci        }
4606f6ba60Sopenharmony_ci    } else {
4706f6ba60Sopenharmony_ci        finalResult = GetFpsInfo();
4806f6ba60Sopenharmony_ci    }
4906f6ba60Sopenharmony_ci    lastFpsInfoResult = finalResult;
5006f6ba60Sopenharmony_ci    if (processFlag) {
5106f6ba60Sopenharmony_ci        result["fps"] = "NA";
5206f6ba60Sopenharmony_ci        result["fpsJitters"] = "NA";
5306f6ba60Sopenharmony_ci    } else {
5406f6ba60Sopenharmony_ci        int fullFrame = 120;
5506f6ba60Sopenharmony_ci        if (finalResult.fps > fullFrame) {
5606f6ba60Sopenharmony_ci            finalResult.fps = fullFrame;
5706f6ba60Sopenharmony_ci        }
5806f6ba60Sopenharmony_ci        result["fps"] = std::to_string(finalResult.fps);
5906f6ba60Sopenharmony_ci        LOGI("ProfilerFPS.result.fps: %s", std::to_string(finalResult.fps).c_str());
6006f6ba60Sopenharmony_ci        LOGI("ProfilerFPS.result.curTime: %s", std::to_string(finalResult.curTime).c_str());
6106f6ba60Sopenharmony_ci        std::string jitterStr = "";
6206f6ba60Sopenharmony_ci        std::string split = "";
6306f6ba60Sopenharmony_ci        for (size_t i = 0; i < finalResult.jitters.size(); i++) {
6406f6ba60Sopenharmony_ci            if (i > 0) {
6506f6ba60Sopenharmony_ci                split = ";;";
6606f6ba60Sopenharmony_ci            }
6706f6ba60Sopenharmony_ci            jitterStr += split + std::to_string(finalResult.jitters[i]);
6806f6ba60Sopenharmony_ci        }
6906f6ba60Sopenharmony_ci        result["fpsJitters"] = jitterStr;
7006f6ba60Sopenharmony_ci        LOGI("ProfilerFPS.result.jitters: %s", jitterStr.c_str());
7106f6ba60Sopenharmony_ci        if (isCatchTrace > 0) {
7206f6ba60Sopenharmony_ci            ByTrace::GetInstance().CheckFpsJitters(finalResult.jitters, finalResult.fps);
7306f6ba60Sopenharmony_ci        }
7406f6ba60Sopenharmony_ci    }
7506f6ba60Sopenharmony_ci    return result;
7606f6ba60Sopenharmony_ci}
7706f6ba60Sopenharmony_ci
7806f6ba60Sopenharmony_civoid ProfilerFPS::SetTraceCatch()
7906f6ba60Sopenharmony_ci{
8006f6ba60Sopenharmony_ci    isCatchTrace = 1;
8106f6ba60Sopenharmony_ci}
8206f6ba60Sopenharmony_ci
8306f6ba60Sopenharmony_civoid ProfilerFPS::SetPackageName(std::string pName)
8406f6ba60Sopenharmony_ci{
8506f6ba60Sopenharmony_ci    pkgName = std::move(pName);
8606f6ba60Sopenharmony_ci}
8706f6ba60Sopenharmony_ci
8806f6ba60Sopenharmony_civoid ProfilerFPS::SetProcessId(const std::string &pid)
8906f6ba60Sopenharmony_ci{
9006f6ba60Sopenharmony_ci    processId = pid;
9106f6ba60Sopenharmony_ci}
9206f6ba60Sopenharmony_ci
9306f6ba60Sopenharmony_civoid ProfilerFPS::GetResultFPS(int sectionsNum)
9406f6ba60Sopenharmony_ci{
9506f6ba60Sopenharmony_ci    struct timeval start;
9606f6ba60Sopenharmony_ci    struct timeval end;
9706f6ba60Sopenharmony_ci    gettimeofday(&start, nullptr);
9806f6ba60Sopenharmony_ci    FpsInfoProfiler fpsInfoResult;
9906f6ba60Sopenharmony_ci    unsigned long runTime;
10006f6ba60Sopenharmony_ci    fpsInfoResult = GetFpsInfo();
10106f6ba60Sopenharmony_ci    if (fpsInfoResult.fps == 0) {
10206f6ba60Sopenharmony_ci        if (lastCurrTime == 0) {
10306f6ba60Sopenharmony_ci            long long currTime = (fpsInfoResult.currTimeDump / msClear) * msClear + fpsInfoResult.currTimeDiff;
10406f6ba60Sopenharmony_ci            lastCurrTime = currTime / oneSec;
10506f6ba60Sopenharmony_ci            printf("fps:%d|%lld\n", fpsInfoResult.fps, currTime / oneSec);
10606f6ba60Sopenharmony_ci        } else {
10706f6ba60Sopenharmony_ci            printf("fps:%d|%lld\n", fpsInfoResult.fps, lastCurrTime + oneThousand);
10806f6ba60Sopenharmony_ci            lastCurrTime = lastCurrTime + oneThousand;
10906f6ba60Sopenharmony_ci        }
11006f6ba60Sopenharmony_ci    } else {
11106f6ba60Sopenharmony_ci        long long currTime = (fpsInfoResult.currTimeStamps[0] / msClear) * msClear + fpsInfoResult.currTimeDiff;
11206f6ba60Sopenharmony_ci        lastCurrTime = currTime / oneSec;
11306f6ba60Sopenharmony_ci        printf("fps:%d|%lld\n", fpsInfoResult.fps, lastCurrTime);
11406f6ba60Sopenharmony_ci    }
11506f6ba60Sopenharmony_ci    lastFpsInfoResult = fpsInfoResult;
11606f6ba60Sopenharmony_ci    if (sectionsNum != 0 && fpsInfoResult.fps != 0) {
11706f6ba60Sopenharmony_ci        GetSectionsFps(fpsInfoResult, sectionsNum);
11806f6ba60Sopenharmony_ci    }
11906f6ba60Sopenharmony_ci    time_t now = time(nullptr);
12006f6ba60Sopenharmony_ci    if (now == -1) {
12106f6ba60Sopenharmony_ci        LOGI("Failed to get current time.");
12206f6ba60Sopenharmony_ci        return;
12306f6ba60Sopenharmony_ci    }
12406f6ba60Sopenharmony_ci    char *dt = ctime(&now);
12506f6ba60Sopenharmony_ci    LOGI("printf time is: %s", dt);
12606f6ba60Sopenharmony_ci    fflush(stdout);
12706f6ba60Sopenharmony_ci    gettimeofday(&end, nullptr);
12806f6ba60Sopenharmony_ci    runTime = end.tv_sec * 1e6 - start.tv_sec * 1e6 + end.tv_usec - start.tv_usec;
12906f6ba60Sopenharmony_ci    LOGI("printf time is runTime: %s", std::to_string(runTime).c_str());
13006f6ba60Sopenharmony_ci    if (runTime < sleepTime) {
13106f6ba60Sopenharmony_ci        usleep(sleepTime - runTime);
13206f6ba60Sopenharmony_ci    }
13306f6ba60Sopenharmony_ci    OHOS::SmartPerf::SPUtils::GetCurrentTime(ten, lastFpsInfoResult.curTime);
13406f6ba60Sopenharmony_ci}
13506f6ba60Sopenharmony_ci
13606f6ba60Sopenharmony_civoid ProfilerFPS::GetTimeDiff()
13706f6ba60Sopenharmony_ci{
13806f6ba60Sopenharmony_ci    long long clockRealTime = 0;
13906f6ba60Sopenharmony_ci    long long clockMonotonicRaw = 0;
14006f6ba60Sopenharmony_ci    int two = 2;
14106f6ba60Sopenharmony_ci    std::string strRealTime;
14206f6ba60Sopenharmony_ci    const std::string cmd = CMD_COMMAND_MAP.at(CmdCommand::TIMESTAMPS);
14306f6ba60Sopenharmony_ci    FILE *fd = popen(cmd.c_str(), "r");
14406f6ba60Sopenharmony_ci    if (fd == nullptr) {
14506f6ba60Sopenharmony_ci        return;
14606f6ba60Sopenharmony_ci    }
14706f6ba60Sopenharmony_ci    char buf[1024] = {'\0'};
14806f6ba60Sopenharmony_ci    while ((fgets(buf, sizeof(buf), fd)) != nullptr) {
14906f6ba60Sopenharmony_ci        std::string line = buf;
15006f6ba60Sopenharmony_ci        std::vector<std::string> params;
15106f6ba60Sopenharmony_ci        SPUtils::StrSplit(line, " ", params);
15206f6ba60Sopenharmony_ci        if (params[0].find("CLOCK_REALTIME") != std::string::npos && clockRealTime == 0) {
15306f6ba60Sopenharmony_ci            strRealTime = params[two];
15406f6ba60Sopenharmony_ci            strRealTime.erase(strRealTime.find('.'), 1);
15506f6ba60Sopenharmony_ci            clockRealTime = std::stoll(strRealTime);
15606f6ba60Sopenharmony_ci            currRealTime = clockRealTime;
15706f6ba60Sopenharmony_ci        } else if (params[0].find("CLOCK_MONOTONIC_RAW") != std::string::npos && clockMonotonicRaw == 0) {
15806f6ba60Sopenharmony_ci            strRealTime = params[two];
15906f6ba60Sopenharmony_ci            strRealTime.erase(strRealTime.find('.'), 1);
16006f6ba60Sopenharmony_ci            clockMonotonicRaw = std::stoll(strRealTime);
16106f6ba60Sopenharmony_ci        }
16206f6ba60Sopenharmony_ci    }
16306f6ba60Sopenharmony_ci    pclose(fd);
16406f6ba60Sopenharmony_ci    fpsInfo.currTimeDiff = clockRealTime - clockMonotonicRaw;
16506f6ba60Sopenharmony_ci}
16606f6ba60Sopenharmony_ci
16706f6ba60Sopenharmony_civoid ProfilerFPS::GetSectionsPrint(int printCount, long long msStartTime, int numb, long long harTime) const
16806f6ba60Sopenharmony_ci{
16906f6ba60Sopenharmony_ci    if (printCount < numb) {
17006f6ba60Sopenharmony_ci        for (int i = 0; i < numb - printCount; i++) {
17106f6ba60Sopenharmony_ci            msStartTime += harTime;
17206f6ba60Sopenharmony_ci            printf("sectionsFps:%d|%lld\n", 0, msStartTime);
17306f6ba60Sopenharmony_ci        }
17406f6ba60Sopenharmony_ci    }
17506f6ba60Sopenharmony_ci}
17606f6ba60Sopenharmony_ci
17706f6ba60Sopenharmony_civoid ProfilerFPS::PrintSections(int msCount, long long currTimeLast,
17806f6ba60Sopenharmony_ci                                long long currTimeStart, long long currLastTime) const
17906f6ba60Sopenharmony_ci{
18006f6ba60Sopenharmony_ci    int conversionFps = 1000000;
18106f6ba60Sopenharmony_ci    int conversionTime = 1000;
18206f6ba60Sopenharmony_ci    long long times = 120;
18306f6ba60Sopenharmony_ci    int fpsNums = 0;
18406f6ba60Sopenharmony_ci    if (msCount == 0) {
18506f6ba60Sopenharmony_ci        fpsNums = 0;
18606f6ba60Sopenharmony_ci    } else {
18706f6ba60Sopenharmony_ci        fpsNums = msCount - 1;
18806f6ba60Sopenharmony_ci    }
18906f6ba60Sopenharmony_ci    double timeN = (currTimeLast - currTimeStart) * 1.0 / conversionTime;
19006f6ba60Sopenharmony_ci    if (timeN == 0) {
19106f6ba60Sopenharmony_ci        printf("sectionsFps:%d|%lld\n", 0, currLastTime);
19206f6ba60Sopenharmony_ci        return;
19306f6ba60Sopenharmony_ci    }
19406f6ba60Sopenharmony_ci    double fpsSections = (fpsNums * conversionFps) / timeN;
19506f6ba60Sopenharmony_ci    int fpsSectionsInt = round(fpsSections);
19606f6ba60Sopenharmony_ci    if (fpsSectionsInt > static_cast<int>(times)) {
19706f6ba60Sopenharmony_ci        fpsSectionsInt = static_cast<int>(times);
19806f6ba60Sopenharmony_ci    }
19906f6ba60Sopenharmony_ci    printf("sectionsFps:%d|%lld\n", fpsSectionsInt, currLastTime);
20006f6ba60Sopenharmony_ci}
20106f6ba60Sopenharmony_ci
20206f6ba60Sopenharmony_civoid ProfilerFPS::GetSectionsFps(FpsInfoProfiler &fpsInfoResult, int nums) const
20306f6ba60Sopenharmony_ci{
20406f6ba60Sopenharmony_ci    int msCount = 0;
20506f6ba60Sopenharmony_ci    long long msJiange = 0;
20606f6ba60Sopenharmony_ci    if (nums != 0) {
20706f6ba60Sopenharmony_ci        msJiange = msClear / nums;
20806f6ba60Sopenharmony_ci    }
20906f6ba60Sopenharmony_ci    long long msStartTime = (fpsInfoResult.currTimeStamps[0] / msClear) * msClear + msJiange;
21006f6ba60Sopenharmony_ci    long long currLastTime = lastCurrTime;
21106f6ba60Sopenharmony_ci    long long harTime = msJiange / 1000000;
21206f6ba60Sopenharmony_ci    int printCount = 0;
21306f6ba60Sopenharmony_ci    long long currTimeStart = 0;
21406f6ba60Sopenharmony_ci    long long currTimeLast = 0;
21506f6ba60Sopenharmony_ci    for (size_t i = 0; i < fpsInfoResult.currTimeStamps.size(); i++) {
21606f6ba60Sopenharmony_ci        long long currTime = fpsInfoResult.currTimeStamps[i];
21706f6ba60Sopenharmony_ci        if (currTime <= msStartTime) {
21806f6ba60Sopenharmony_ci            if (msCount == 0) {
21906f6ba60Sopenharmony_ci                currTimeStart = currTime;
22006f6ba60Sopenharmony_ci            }
22106f6ba60Sopenharmony_ci            currTimeLast = currTime;
22206f6ba60Sopenharmony_ci            msCount++;
22306f6ba60Sopenharmony_ci        } else {
22406f6ba60Sopenharmony_ci            while (currTime > msStartTime) {
22506f6ba60Sopenharmony_ci                PrintSections(msCount, currTimeLast, currTimeStart, currLastTime);
22606f6ba60Sopenharmony_ci                printCount++;
22706f6ba60Sopenharmony_ci                msCount = 1;
22806f6ba60Sopenharmony_ci                msStartTime += msJiange;
22906f6ba60Sopenharmony_ci                currLastTime += harTime;
23006f6ba60Sopenharmony_ci                currTimeLast = currTime;
23106f6ba60Sopenharmony_ci                currTimeStart = currTime;
23206f6ba60Sopenharmony_ci            }
23306f6ba60Sopenharmony_ci        }
23406f6ba60Sopenharmony_ci        if (i == (static_cast<size_t>(fpsInfoResult.currTimeStamps.size()) - 1)) {
23506f6ba60Sopenharmony_ci            PrintSections(msCount, currTimeLast, currTimeStart, currLastTime);
23606f6ba60Sopenharmony_ci            currTimeLast = currTime;
23706f6ba60Sopenharmony_ci            printCount++;
23806f6ba60Sopenharmony_ci            GetSectionsPrint(printCount, currLastTime, nums, harTime);
23906f6ba60Sopenharmony_ci        }
24006f6ba60Sopenharmony_ci    }
24106f6ba60Sopenharmony_ci}
24206f6ba60Sopenharmony_ci
24306f6ba60Sopenharmony_civoid ProfilerFPS::GetFPS(std::vector<std::string> v)
24406f6ba60Sopenharmony_ci{
24506f6ba60Sopenharmony_ci    if (v[number] == "") {
24606f6ba60Sopenharmony_ci        printf("the args of num must be not-null!\n");
24706f6ba60Sopenharmony_ci    } else {
24806f6ba60Sopenharmony_ci        this->num = atoi(v[number].c_str());
24906f6ba60Sopenharmony_ci        if (this->num < 0) {
25006f6ba60Sopenharmony_ci            printf("set num:%d not valid arg\n", this->num);
25106f6ba60Sopenharmony_ci        }
25206f6ba60Sopenharmony_ci        printf("set num:%d success\n", this->num);
25306f6ba60Sopenharmony_ci        int sectionsNum = (static_cast<int>(v.size()) >= four) ? atoi(v[four].c_str()) : 0;
25406f6ba60Sopenharmony_ci        if (sectionsNum > ten) {
25506f6ba60Sopenharmony_ci            printf("set sectionsNum:%d not valid arg \n", sectionsNum);
25606f6ba60Sopenharmony_ci        } else {
25706f6ba60Sopenharmony_ci            for (int i = 0; i < this->num; i++) {
25806f6ba60Sopenharmony_ci                GetResultFPS(sectionsNum);
25906f6ba60Sopenharmony_ci            }
26006f6ba60Sopenharmony_ci        }
26106f6ba60Sopenharmony_ci    }
26206f6ba60Sopenharmony_ci    printf("SP_daemon exec finished!\n");
26306f6ba60Sopenharmony_ci}
26406f6ba60Sopenharmony_ci
26506f6ba60Sopenharmony_cistd::string ProfilerFPS::GetSurface()
26606f6ba60Sopenharmony_ci{
26706f6ba60Sopenharmony_ci    std::string cmdResult;
26806f6ba60Sopenharmony_ci    std::string dumperSurface = HIDUMPER_CMD_MAP.at(HidumperCmd::DUMPER_SURFACE);
26906f6ba60Sopenharmony_ci    SPUtils::LoadCmd(dumperSurface, cmdResult);
27006f6ba60Sopenharmony_ci    size_t positionLeft = cmdResult.find("[");
27106f6ba60Sopenharmony_ci    size_t positionRight = cmdResult.find("]");
27206f6ba60Sopenharmony_ci    size_t positionNum = 1;
27306f6ba60Sopenharmony_ci    return cmdResult.substr(positionLeft + positionNum, positionRight - positionLeft - positionNum);
27406f6ba60Sopenharmony_ci}
27506f6ba60Sopenharmony_ci
27606f6ba60Sopenharmony_ciFpsInfoProfiler ProfilerFPS::GetFpsInfo()
27706f6ba60Sopenharmony_ci{
27806f6ba60Sopenharmony_ci    processFlag = false;
27906f6ba60Sopenharmony_ci    fpsInfoMax.fps = 0;
28006f6ba60Sopenharmony_ci    std::string uniteLayer;
28106f6ba60Sopenharmony_ci    if (!rkFlag) {
28206f6ba60Sopenharmony_ci        uniteLayer = "UniRender";
28306f6ba60Sopenharmony_ci    } else {
28406f6ba60Sopenharmony_ci        ProfilerFPS &profilerFps = ProfilerFPS::GetInstance();
28506f6ba60Sopenharmony_ci        uniteLayer = profilerFps.GetSurface();
28606f6ba60Sopenharmony_ci    }
28706f6ba60Sopenharmony_ci    if (ohFlag) {
28806f6ba60Sopenharmony_ci        uniteLayer = GetSurface();
28906f6ba60Sopenharmony_ci    }
29006f6ba60Sopenharmony_ci    if (pkgName.empty() || pkgName.find("sceneboard") != std::string::npos) {
29106f6ba60Sopenharmony_ci        LOGI("ProfilerFPS.pkgName: %s", pkgName.c_str());
29206f6ba60Sopenharmony_ci        OHOS::SmartPerf::SPUtils::GetCurrentTime(fifty, lastFpsInfoResult.curTime);
29306f6ba60Sopenharmony_ci        fpsInfoMax = GetSurfaceFrame(uniteLayer);
29406f6ba60Sopenharmony_ci    } else {
29506f6ba60Sopenharmony_ci        bool onTop = OHOS::SmartPerf::SPUtils::IsForeGround(pkgName);
29606f6ba60Sopenharmony_ci        if (onTop) {
29706f6ba60Sopenharmony_ci            OHOS::SmartPerf::SPUtils::GetCurrentTime(fifty, lastFpsInfoResult.curTime);
29806f6ba60Sopenharmony_ci            fpsInfoMax = GetSurfaceFrame(uniteLayer);
29906f6ba60Sopenharmony_ci        } else {
30006f6ba60Sopenharmony_ci            LOGI("ProfilerFPS::app is in the background");
30106f6ba60Sopenharmony_ci            if (processId.empty()) {
30206f6ba60Sopenharmony_ci                processFlag = true;
30306f6ba60Sopenharmony_ci                fpsInfoMax.Clear();
30406f6ba60Sopenharmony_ci            } else {
30506f6ba60Sopenharmony_ci                fpsInfoMax.Clear();
30606f6ba60Sopenharmony_ci            }
30706f6ba60Sopenharmony_ci        }
30806f6ba60Sopenharmony_ci    }
30906f6ba60Sopenharmony_ci    return fpsInfoMax;
31006f6ba60Sopenharmony_ci}
31106f6ba60Sopenharmony_ci
31206f6ba60Sopenharmony_ciFpsInfoProfiler ProfilerFPS::GetSurfaceFrame(std::string name)
31306f6ba60Sopenharmony_ci{
31406f6ba60Sopenharmony_ci    if (name == "") {
31506f6ba60Sopenharmony_ci        return FpsInfoProfiler();
31606f6ba60Sopenharmony_ci    }
31706f6ba60Sopenharmony_ci    static std::map<std::string, FpsInfoProfiler> fpsMap;
31806f6ba60Sopenharmony_ci    if (fpsMap.count(name) == 0) {
31906f6ba60Sopenharmony_ci        FpsInfoProfiler tmp;
32006f6ba60Sopenharmony_ci        tmp.fps = 0;
32106f6ba60Sopenharmony_ci        fpsMap[name] = tmp;
32206f6ba60Sopenharmony_ci    }
32306f6ba60Sopenharmony_ci    fpsInfo = fpsMap[name];
32406f6ba60Sopenharmony_ci    fpsInfo.fps = 0;
32506f6ba60Sopenharmony_ci    FILE *fp;
32606f6ba60Sopenharmony_ci    static char tmp[1024];
32706f6ba60Sopenharmony_ci    GetTimeDiff();
32806f6ba60Sopenharmony_ci    std::string cmd = "hidumper -s 10 -a \"fps " + name + "\"";
32906f6ba60Sopenharmony_ci    if (cmd.empty()) {
33006f6ba60Sopenharmony_ci        LOGE("cmd is null");
33106f6ba60Sopenharmony_ci        return fpsInfo;
33206f6ba60Sopenharmony_ci    }
33306f6ba60Sopenharmony_ci    fp = popen(cmd.c_str(), "r");
33406f6ba60Sopenharmony_ci    if (fp == nullptr) {
33506f6ba60Sopenharmony_ci        LOGE("Failed to open hidumper file");
33606f6ba60Sopenharmony_ci        return fpsInfo;
33706f6ba60Sopenharmony_ci    }
33806f6ba60Sopenharmony_ci    fpsNum = 0;
33906f6ba60Sopenharmony_ci    prevScreenTimestamp = -1;
34006f6ba60Sopenharmony_ci    LOGI("ProfilerFPS dump time: start!");
34106f6ba60Sopenharmony_ci    struct timespec time1 = { 0 };
34206f6ba60Sopenharmony_ci    clock_gettime(CLOCK_MONOTONIC, &time1);
34306f6ba60Sopenharmony_ci    fpsInfo.curTime = static_cast<int>(time1.tv_sec - 1);
34406f6ba60Sopenharmony_ci    fpsInfo.currTimeDump = (time1.tv_sec - 1) * mod + time1.tv_nsec;
34506f6ba60Sopenharmony_ci    LOGI("ProfilerFPS fpsInfo.curTime: %d", fpsInfo.curTime);
34606f6ba60Sopenharmony_ci    while (fgets(tmp, sizeof(tmp), fp) != nullptr) {
34706f6ba60Sopenharmony_ci        std::string str(tmp);
34806f6ba60Sopenharmony_ci        LOGD("ProfilerFPS dump time: %s", str.c_str());
34906f6ba60Sopenharmony_ci        curScreenTimestamp = 0;
35006f6ba60Sopenharmony_ci        std::stringstream sstream;
35106f6ba60Sopenharmony_ci        sstream << tmp;
35206f6ba60Sopenharmony_ci        sstream >> curScreenTimestamp;
35306f6ba60Sopenharmony_ci        if (curScreenTimestamp == 0) {
35406f6ba60Sopenharmony_ci            continue;
35506f6ba60Sopenharmony_ci        }
35606f6ba60Sopenharmony_ci        CalcFpsAndJitters();
35706f6ba60Sopenharmony_ci    }
35806f6ba60Sopenharmony_ci    pclose(fp);
35906f6ba60Sopenharmony_ci    LOGI("ProfilerFPS fpsNum: %d", fpsNum);
36006f6ba60Sopenharmony_ci    return fpsInfo;
36106f6ba60Sopenharmony_ci}
36206f6ba60Sopenharmony_ci
36306f6ba60Sopenharmony_civoid ProfilerFPS::CalcFpsAndJitters()
36406f6ba60Sopenharmony_ci{
36506f6ba60Sopenharmony_ci    std::string onScreenTime = std::to_string(curScreenTimestamp / mod);
36606f6ba60Sopenharmony_ci    std::string fpsCurTime = std::to_string(fpsInfo.curTime);
36706f6ba60Sopenharmony_ci    if (onScreenTime.find(fpsCurTime) != std::string::npos) {
36806f6ba60Sopenharmony_ci        fpsNum++;
36906f6ba60Sopenharmony_ci        fpsInfo.currTimeStamps.push_back(curScreenTimestamp);
37006f6ba60Sopenharmony_ci    }
37106f6ba60Sopenharmony_ci    fpsInfo.fps = fpsNum;
37206f6ba60Sopenharmony_ci    if (onScreenTime == fpsCurTime) {
37306f6ba60Sopenharmony_ci        long long jitter;
37406f6ba60Sopenharmony_ci        if (prevScreenTimestamp != -1) {
37506f6ba60Sopenharmony_ci            jitter = curScreenTimestamp - prevScreenTimestamp;
37606f6ba60Sopenharmony_ci            fpsInfo.jitters.push_back(jitter);
37706f6ba60Sopenharmony_ci        } else {
37806f6ba60Sopenharmony_ci            if (prevlastScreenTimestamp != 0 && (curScreenTimestamp - prevlastScreenTimestamp) < mod) {
37906f6ba60Sopenharmony_ci                jitter = curScreenTimestamp - prevlastScreenTimestamp;
38006f6ba60Sopenharmony_ci                fpsInfo.jitters.push_back(jitter);
38106f6ba60Sopenharmony_ci            } else {
38206f6ba60Sopenharmony_ci                jitter = curScreenTimestamp - curScreenTimestamp / mod * mod;
38306f6ba60Sopenharmony_ci                fpsInfo.jitters.push_back(jitter);
38406f6ba60Sopenharmony_ci            }
38506f6ba60Sopenharmony_ci        }
38606f6ba60Sopenharmony_ci        prevScreenTimestamp = curScreenTimestamp;
38706f6ba60Sopenharmony_ci        prevlastScreenTimestamp = curScreenTimestamp;
38806f6ba60Sopenharmony_ci    }
38906f6ba60Sopenharmony_ci}
39006f6ba60Sopenharmony_ci
39106f6ba60Sopenharmony_civoid ProfilerFPS::GetOhFps(std::vector<std::string> v)
39206f6ba60Sopenharmony_ci{
39306f6ba60Sopenharmony_ci    if (v[number] == "") {
39406f6ba60Sopenharmony_ci        printf("the args of num must be not-null!\n");
39506f6ba60Sopenharmony_ci    } else {
39606f6ba60Sopenharmony_ci        this->num = atoi(v[number].c_str());
39706f6ba60Sopenharmony_ci        if (this->num < 0) {
39806f6ba60Sopenharmony_ci            printf("set num:%d not vaild arg\n", this->num);
39906f6ba60Sopenharmony_ci        }
40006f6ba60Sopenharmony_ci        printf("set num:%d success\n", this->num);
40106f6ba60Sopenharmony_ci        ohFlag = true;
40206f6ba60Sopenharmony_ci        int sectionsNum;
40306f6ba60Sopenharmony_ci        if (static_cast<int>(v.size()) < four) {
40406f6ba60Sopenharmony_ci            sectionsNum = 0;
40506f6ba60Sopenharmony_ci        } else {
40606f6ba60Sopenharmony_ci            sectionsNum = atoi(v[four].c_str());
40706f6ba60Sopenharmony_ci        }
40806f6ba60Sopenharmony_ci        for (int i = 0; i < this->num; i++) {
40906f6ba60Sopenharmony_ci            GetResultFPS(sectionsNum);
41006f6ba60Sopenharmony_ci        }
41106f6ba60Sopenharmony_ci    }
41206f6ba60Sopenharmony_ci    printf("SP_daemon exec finished!\n");
41306f6ba60Sopenharmony_ci}
41406f6ba60Sopenharmony_ci
41506f6ba60Sopenharmony_civoid ProfilerFPS::SetGameLayer(std::string isGameView)
41606f6ba60Sopenharmony_ci{
41706f6ba60Sopenharmony_ci    isGameLayer = std::move(isGameView);
41806f6ba60Sopenharmony_ci}
41906f6ba60Sopenharmony_ci
42006f6ba60Sopenharmony_ciFpsInfoProfiler ProfilerFPS::selfRerderLayers(const std::string &gameLayer)
42106f6ba60Sopenharmony_ci{
42206f6ba60Sopenharmony_ci    OHOS::SmartPerf::SPUtils::GetCurrentTime(fifty, lastFpsInfoResult.curTime);
42306f6ba60Sopenharmony_ci    fpsInfoMax = GetSurfaceFrame(gameLayer);
42406f6ba60Sopenharmony_ci    return fpsInfoMax;
42506f6ba60Sopenharmony_ci}
42606f6ba60Sopenharmony_ci
42706f6ba60Sopenharmony_cistd::string ProfilerFPS::GetGameLayer()
42806f6ba60Sopenharmony_ci{
42906f6ba60Sopenharmony_ci    std::string gameLayer = "";
43006f6ba60Sopenharmony_ci    if (processId.empty()) {
43106f6ba60Sopenharmony_ci        return gameLayer;
43206f6ba60Sopenharmony_ci    }
43306f6ba60Sopenharmony_ci    std::string cmdResult;
43406f6ba60Sopenharmony_ci    std::string dumperSurface = HIDUMPER_CMD_MAP.at(HidumperCmd::DUMPER_SURFACE);
43506f6ba60Sopenharmony_ci    SPUtils::LoadCmd(dumperSurface, cmdResult);
43606f6ba60Sopenharmony_ci    LOGI("ProfilerFPS::cmdResult: (%s)", cmdResult.c_str());
43706f6ba60Sopenharmony_ci    std::string start = "NodeId[";
43806f6ba60Sopenharmony_ci    std::string end = "]";
43906f6ba60Sopenharmony_ci    size_t startPos = cmdResult.find(start) + start.length();
44006f6ba60Sopenharmony_ci    size_t endPos = cmdResult.find(end, startPos);
44106f6ba60Sopenharmony_ci    std::string nodeIdStr = cmdResult.substr(startPos, endPos - startPos);
44206f6ba60Sopenharmony_ci    LOGI("ProfilerFPS::nodeIdStr: (%s)", nodeIdStr.c_str());
44306f6ba60Sopenharmony_ci    uint64_t nodeId;
44406f6ba60Sopenharmony_ci    const int kShiftAmount = 32;
44506f6ba60Sopenharmony_ci    if (!nodeIdStr.empty()) {
44606f6ba60Sopenharmony_ci        std::stringstream ss(nodeIdStr);
44706f6ba60Sopenharmony_ci        ss >> nodeId;
44806f6ba60Sopenharmony_ci        if (ss.fail() || !ss.eof()) {
44906f6ba60Sopenharmony_ci            return gameLayer;
45006f6ba60Sopenharmony_ci        }
45106f6ba60Sopenharmony_ci        nodeId = nodeId >> kShiftAmount;
45206f6ba60Sopenharmony_ci        LOGI("ProfilerFPS::nodeId: (%d)", nodeId);
45306f6ba60Sopenharmony_ci        if (std::to_string(nodeId) == processId) {
45406f6ba60Sopenharmony_ci            size_t layerStartPos = cmdResult.find("[");
45506f6ba60Sopenharmony_ci            size_t layerEndPos = cmdResult.find("]");
45606f6ba60Sopenharmony_ci            if (layerEndPos - layerStartPos <= 1 && layerEndPos > endPos) {
45706f6ba60Sopenharmony_ci                return gameLayer;
45806f6ba60Sopenharmony_ci            }
45906f6ba60Sopenharmony_ci            layerStartPos += 1;
46006f6ba60Sopenharmony_ci            gameLayer = cmdResult.substr(layerStartPos, layerEndPos - layerStartPos);
46106f6ba60Sopenharmony_ci        }
46206f6ba60Sopenharmony_ci    }
46306f6ba60Sopenharmony_ci    LOGI("ProfilerFPS::gameLayer: (%s)", gameLayer.c_str());
46406f6ba60Sopenharmony_ci    return gameLayer;
46506f6ba60Sopenharmony_ci}
46606f6ba60Sopenharmony_civoid ProfilerFPS::SetRkFlag()
46706f6ba60Sopenharmony_ci{
46806f6ba60Sopenharmony_ci    rkFlag = true;
46906f6ba60Sopenharmony_ci}
47006f6ba60Sopenharmony_ci}
47106f6ba60Sopenharmony_ci}