• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <cstdio>
16 #include <algorithm>
17 #include <iostream>
18 #include <sstream>
19 #include <queue>
20 #include <string>
21 #include <thread>
22 #include <unistd.h>
23 #include <ctime>
24 #include <sys/time.h>
25 #include "include/sp_utils.h"
26 #include "include/ByTrace.h"
27 #include "include/Capture.h"
28 #include "include/FPS.h"
29 #include "include/startup_delay.h"
30 #include "include/sp_log.h"
31 namespace OHOS {
32 namespace SmartPerf {
ItemData()33 std::map<std::string, std::string> FPS::ItemData()
34 {
35     std::map<std::string, std::string> result;
36     FpsInfo fpsInfoResult;
37     if (surfaceViewName.length() > 0) {
38         fpsInfoResult = GetDiffLayersFpsInfo(surfaceViewName);
39         prevResultFpsInfo = fpsInfoResult;
40     } else {
41         fpsInfoResult = GetFpsInfo();
42         prevResultFpsInfo = fpsInfoResult;
43     }
44     result["refreshrate"] = GetScreenInfo();
45     result["fps"] = std::to_string(fpsInfoResult.fps);
46     LOGI("result.fps====: %s", std::to_string(fpsInfoResult.fps).c_str());
47     LOGI("result.curTime====: %s", std::to_string(fpsInfoResult.curTime).c_str());
48     std::string jitterStr = "";
49     std::string split = "";
50     for (size_t i = 0; i < fpsInfoResult.jitters.size(); i++) {
51         if (i > 0) {
52             split = ";;";
53         }
54         jitterStr += split + std::to_string(fpsInfoResult.jitters[i]);
55     }
56     result["fpsJitters"] = jitterStr;
57     LOGI("result.jitters====: %s", jitterStr.c_str());
58     if (pkgName.length() > 0) {
59         std::string processId = "";
60         OHOS::SmartPerf::StartUpDelay sp;
61         processId = sp.GetPidByPkg(pkgName);
62         LOGI("FPS::processId -- %s", processId.c_str());
63         if (processId.empty()) {
64             result["fps"] = "NA";
65             result["fpsJitters"] = "NA";
66         }
67     }
68 
69     SetFpsCurrentFpsTime(fpsInfoResult);
70 
71     LOGI("FPS::ItemData map size(%u)", result.size());
72     return result;
73 }
74 
GetScreenInfo() const75 std::string FPS::GetScreenInfo() const
76 {
77     std::string resultScreen = SPUtils::GetScreen();
78     unsigned int pos = resultScreen.find("=");
79     std::string numStr = resultScreen.substr(pos + 1);
80     LOGI("numStr====: %s", numStr.c_str());
81     return numStr;
82 }
83 
SetFpsCurrentFpsTime(FpsInfo fpsInfoResult)84 void FPS::SetFpsCurrentFpsTime(FpsInfo fpsInfoResult)
85 {
86     ffTime.fps = fpsInfoResult.fps;
87     if (!fpsInfoResult.jitters.empty()) {
88         auto maxElement = std::max_element(fpsInfoResult.jitters.begin(), fpsInfoResult.jitters.end());
89         ffTime.currentFpsTime = *maxElement;
90     }
91 }
92 
GetFpsCurrentFpsTime()93 FpsCurrentFpsTime FPS::GetFpsCurrentFpsTime()
94 {
95     return ffTime;
96 }
97 
SetPackageName(std::string pName)98 void FPS::SetPackageName(std::string pName)
99 {
100     pkgName = std::move(pName);
101 }
SetLayerName(std::string sName)102 void FPS::SetLayerName(std::string sName)
103 {
104     surfaceViewName = std::move(sName);
105 }
GetDiffLayersFpsInfo(const std::string & sName)106 FpsInfo FPS::GetDiffLayersFpsInfo(const std::string &sName)
107 {
108     GetCurrentTime();
109     fpsInfoMax = GetSurfaceFrame(sName);
110     return fpsInfoMax;
111 }
112 
GetCurrentTime()113 void FPS::GetCurrentTime()
114 {
115     for (int i = 0; i < fifty; i++) {
116         struct timespec time1 = { 0 };
117         clock_gettime(CLOCK_MONOTONIC, &time1);
118         int curTimeNow = static_cast<int>(time1.tv_sec - 1);
119         if (curTimeNow == prevResultFpsInfo.curTime) {
120             usleep(sleepNowTime);
121         } else {
122             break;
123         }
124     }
125 }
126 
GetFpsInfo()127 FpsInfo FPS::GetFpsInfo()
128 {
129     fpsInfoMax.fps = 0;
130     if (pkgName.empty()) {
131         return fpsInfoMax;
132     }
133     bool onTop = IsForeGround();
134     if (onTop) {
135         LOGI("onTop===========");
136         std::string uniteLayer = "UniRender";
137         GetCurrentTime();
138         fpsInfoMax = GetSurfaceFrame(uniteLayer);
139     } else {
140         fpsInfoMax.Clear();
141     }
142     return fpsInfoMax;
143 }
144 
GetSurfaceFrame(std::string name)145 FpsInfo FPS::GetSurfaceFrame(std::string name)
146 {
147     if (name == "") {
148         return FpsInfo();
149     }
150     static std::map<std::string, FpsInfo> fpsMap;
151     if (fpsMap.count(name) == 0) {
152         FpsInfo tmp;
153         tmp.fps = 0;
154         fpsMap[name] = tmp;
155     }
156     fpsInfo = fpsMap[name];
157     fpsInfo.fps = 0;
158     FILE *fp;
159     static char tmp[1024];
160     std::string cmd = "hidumper -s 10 -a \"fps " + name + "\"";
161     fp = popen(cmd.c_str(), "r");
162     if (fp == nullptr) {
163         return fpsInfo;
164     }
165     fpsNum = 0;
166     refresh = true;
167     lastTime = -1;
168     LOGI("dump time: start!");
169     struct timespec time1 = { 0 };
170     clock_gettime(CLOCK_MONOTONIC, &time1);
171     fpsInfo.curTime = static_cast<int>(time1.tv_sec - 1);
172     fpsInfo.currTimeDump = (time1.tv_sec - 1) * mod + time1.tv_nsec;
173     LOGI("Time-------time1.tv_sec: %s", std::to_string(time1.tv_sec).c_str());
174     LOGI("Time-------time1.tv_nsec: %s", std::to_string(time1.tv_nsec).c_str());
175     LOGI("Time-------fpsInfo.curTime: %s", std::to_string(fpsInfo.curTime).c_str());
176     LOGI("Time-------fpsInfo.currTimeDump: %s", std::to_string(fpsInfo.currTimeDump).c_str());
177     while (fgets(tmp, sizeof(tmp), fp) != nullptr) {
178         std::string str(tmp);
179         LOGD("dump time: %s", str.c_str());
180         frameReadyTime = 0;
181         std::stringstream sstream;
182         sstream << tmp;
183         sstream >> frameReadyTime;
184         if (frameReadyTime == 0) {
185             continue;
186         }
187         if (lastReadyTime >= frameReadyTime) {
188             lastReadyTime = -1;
189             continue;
190         }
191         GetSameTimeNums();
192     }
193     pclose(fp);
194     LOGI("Time-------fpsNum: %s", std::to_string(fpsNum).c_str());
195     return fpsInfo;
196 }
197 
GetSameTimeNums()198 void FPS::GetSameTimeNums()
199 {
200     std::string onScreenTime = std::to_string(frameReadyTime / mod);
201     std::string fpsCurTime = std::to_string(fpsInfo.curTime);
202     if (onScreenTime.find(fpsCurTime) != std::string::npos) {
203         fpsNum++;
204         fpsInfo.currTimeStamps.push_back(frameReadyTime);
205     }
206     fpsInfo.fps = fpsNum;
207     if (onScreenTime == fpsCurTime) {
208         long long jitter;
209         if (lastTime != -1) {
210             jitter = frameReadyTime - lastTime;
211             fpsInfo.jitters.push_back(jitter);
212         } else {
213             if (lastFrameReadyTime != 0) {
214                 jitter = frameReadyTime - lastFrameReadyTime;
215                 fpsInfo.jitters.push_back(jitter);
216             }
217         }
218         lastTime = frameReadyTime;
219         lastFrameReadyTime = frameReadyTime;
220     }
221 }
222 
IsForeGround()223 bool FPS::IsForeGround()
224 {
225     const std::string cmd = "hidumper -s WindowManagerService -a -a";
226     char buf[1024] = {'\0'};
227     std::string appLine = "app name [" + pkgName;
228     std::string bundleLine = "bundle name [" + pkgName;
229     isFoundAppName = false;
230     isFoundBundleName = false;
231     FILE *fd = popen(cmd.c_str(), "r");
232     if (fd == nullptr) {
233         return false;
234     }
235     while (fgets(buf, sizeof(buf), fd) != nullptr) {
236         std::string line = buf;
237         if (line.find(appLine) != std::string::npos) {
238             isFoundAppName = true;
239         }
240         if (line.find(bundleLine) != std::string::npos) {
241             isFoundBundleName = true;
242         }
243         if (isFoundAppName || isFoundBundleName) {
244             if (line.find("app state") != std::string::npos) {
245                 bool tag = IsFindForeGround(line);
246                 pclose(fd);
247                 return tag;
248             }
249         }
250     }
251     pclose(fd);
252     return false;
253 }
254 
IsFindForeGround(std::string line) const255 bool FPS::IsFindForeGround(std::string line) const
256 {
257     std::string foreGroundTag = line.substr(line.find("#") + 1);
258     if (foreGroundTag.find("FOREGROUND") != std::string::npos) {
259         return true;
260     } else {
261         return false;
262     }
263 }
264 }
265 }
266