• 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 <thread>
16 #include <iostream>
17 #include <fstream>
18 #include <string>
19 #include <vector>
20 #include <cstdio>
21 #include <sstream>
22 #include <iomanip>
23 #include "include/parse_trace.h"
24 #include "include/sp_log.h"
25 
26 namespace OHOS {
27 namespace SmartPerf {
ParseTraceNoh(const std::string & fileNamePath,const std::string & appPid)28 double ParseTrace::ParseTraceNoh(const std::string &fileNamePath, const std::string &appPid)
29 {
30     int conversion = 1000;
31     double code = -1;
32     char realPath[PATH_MAX] = {0x00};
33     if (realpath(fileNamePath.c_str(), realPath) == nullptr) {
34         std::cout << "" << std::endl;
35     }
36     infile.open(realPath);
37     if (infile.fail()) {
38         std::cout << "File "
39                   << "open fail" << std::endl;
40         LOGE("ParseTrace open file(%s) failed ", fileNamePath.c_str());
41         infile.close();
42         return code;
43     } else {
44         code = SmartPerf::ParseTrace::ParseNohTrace(fileNamePath, appPid);
45     }
46     infile.close();
47     return code * conversion;
48 }
ParseNohTrace(const std::string & fileNamePath,const std::string & appPid)49 double ParseTrace::ParseNohTrace(const std::string &fileNamePath, const std::string &appPid)
50 {
51     std::string line;
52     std::string::size_type positionPid;
53     double codeTime = -1;
54     while (getline(infile, line)) {
55         startTime = SmartPerf::ParseTrace::GetStartTime(line, startTime);
56         frameId = SmartPerf::ParseTrace::GetFrameId(line, appPid, frameId);
57 
58         positionPid = line.find("[" + appPid + "," + frameId + "]");
59         if (positionPid != std::string::npos) {
60             size_t position1 = line.find("....");
61             size_t position2 = line.find(":");
62             size_t flagTimeSize = 5;
63             flagTime = line.substr(position1 + flagTimeSize, position2 - position1 - flagTimeSize);
64             if (std::stof(endTime) == 0) {
65                 endTime = flagTime;
66                 continue;
67             }
68             float dataThreshold = 0.3;
69             if ((std::stof(flagTime) - std::stof(endTime)) > dataThreshold) {
70                 break;
71             } else {
72                 endTime = flagTime;
73             }
74         }
75     }
76     codeTime = SmartPerf::ParseTrace::GetTime(startTime, endTime);
77     return codeTime;
78 }
GetFrameId(std::string line,const std::string & appPid,const std::string & fid)79 std::string ParseTrace::GetFrameId(std::string line, const std::string &appPid, const std::string &fid)
80 {
81     std::string::size_type positionTransactionFlag = line.find("transactionFlag:[" + appPid);
82     if (positionTransactionFlag != std::string::npos) {
83         size_t positionFrame1 = line.rfind("[" + appPid + ",");
84         size_t positionFrame2 = line.rfind("]");
85         size_t subNum = 2;
86         size_t off = positionFrame1 + subNum + appPid.length();
87         size_t count = positionFrame2 - positionFrame1 - subNum - appPid.length();
88         frameId = line.substr(off, count);
89     } else {
90         frameId = fid;
91     }
92     return frameId;
93 }
GetWindowTime(std::string line,const std::string & wt)94 std::string ParseTrace::GetWindowTime(std::string line, const std::string &wt)
95 {
96     size_t positionWindow = line.find("H:RSUniRender::Process:[leashWindow");
97     if (positionWindow != std::string::npos) {
98         size_t positionWindow1 = line.rfind(")");
99         size_t subNumSize = 4;
100         std::string windowSizeFlag = line.substr(positionWindow1 - subNumSize, subNumSize);
101         std::string windowSize = "";
102         if (std::stof(windowSize) == 0) {
103             const int windowSizeNum = 1344;
104             if (std::stof(windowSizeFlag) == windowSizeNum) {
105                 windowSize = "";
106             } else {
107                 windowSize = windowSizeFlag;
108             }
109         } else {
110             if (std::stof(windowSize) != std::stof(windowSizeFlag)) {
111                 size_t subNum = 5;
112                 size_t position1 = line.find("....");
113                 size_t position2 = line.find(":");
114                 windowTime = line.substr(position1 + subNum, position2 - position1 - subNum);
115                 windowSize = windowSizeFlag;
116             } else {
117                 windowTime = wt;
118             }
119         }
120     }
121     return windowTime;
122 }
ParseTraceCold(const std::string & fileNamePath,const std::string & appPid)123 double ParseTrace::ParseTraceCold(const std::string &fileNamePath, const std::string &appPid)
124 {
125     int conversion = 1000;
126     double code = -1;
127     char realPath[PATH_MAX] = {0x00};
128     if (realpath(fileNamePath.c_str(), realPath) == nullptr) {
129         std::cout << "" << std::endl;
130     }
131     infile.open(realPath);
132     if (infile.fail()) {
133         std::cout << "File "
134                   << "open fail" << std::endl;
135         LOGE("ParseTrace::ParseTraceCold open file(%s) failed ", fileNamePath.c_str());
136         return 0;
137     } else {
138         code = SmartPerf::ParseTrace::ParseCodeTrace(fileNamePath, appPid);
139     }
140     infile.close();
141     LOGI("ParseTrace::ParseTraceCold OK");
142     return code * conversion;
143 }
ParseTraceHot(const std::string & fileNamePath)144 double ParseTrace::ParseTraceHot(const std::string &fileNamePath)
145 {
146     int conversion = 1000;
147     double code = -1;
148     char realPath[PATH_MAX] = {0x00};
149     if (realpath(fileNamePath.c_str(), realPath) == nullptr) {
150         std::cout << "" << std::endl;
151     }
152     infile.open(realPath);
153     if (infile.fail()) {
154         std::cout << "File "
155                   << "open fail" << std::endl;
156         LOGE("ParseTrace::ParseTraceHot open file(%s) failed ", fileNamePath.c_str());
157         return 0;
158     } else {
159         code = SmartPerf::ParseTrace::ParseHotTrace(fileNamePath);
160     }
161     infile.close();
162     LOGI("ParseTrace::ParseTraceHot OK");
163     return code * conversion;
164 }
ParseCodeTrace(const std::string & fileNamePath,const std::string & appPid)165 double ParseTrace::ParseCodeTrace(const std::string &fileNamePath, const std::string &appPid)
166 {
167     std::string line;
168     std::string::size_type tracingMarkWrite;
169     std::string::size_type fourPoint;
170     double codeTime = -1;
171     while (getline(infile, line)) {
172         startTime = SmartPerf::ParseTrace::GetStartTime(line, startTime);
173         tracingMarkWrite = line.find("tracing_mark_write: B|" + appPid + "|H:RSRenderThread DrawFrame:");
174         fourPoint = line.find("....");
175         if (tracingMarkWrite != std::string::npos && fourPoint != std::string::npos) {
176             size_t p1 = line.find("....");
177             size_t p2 = line.find(":");
178             size_t subNum = 5;
179             endTime = line.substr(p1 + subNum, p2 - p1 - subNum);
180             int endNum = std::stof(endTime);
181             int endFlagNum = std::stof(endTimeFlag);
182             int startNum = std::stof(startTime);
183             int timeNum = endNum - endFlagNum;
184             double interval = 0.3;
185             if (timeNum < interval) {
186                 endTimeFlag = endTime;
187                 continue;
188             }
189             if (std::stof(endTimeFlag) == 0) {
190                 endTimeFlag = endTime;
191             } else if (endFlagNum != 0 && startNum != 0 && timeNum > interval) {
192                 break;
193             } else {
194                 endTimeFlag = endTime;
195             }
196         }
197     }
198     codeTime = SmartPerf::ParseTrace::GetTime(startTime, endTime);
199     return codeTime;
200 }
ParseHotTrace(const std::string & fileNamePath)201 double ParseTrace::ParseHotTrace(const std::string &fileNamePath)
202 {
203     std::string line;
204     std::string::size_type doComposition;
205     double codeTime = -1;
206     while (getline(infile, line)) {
207         startTime = SmartPerf::ParseTrace::GetStartTime(line, startTime);
208         doComposition = line.find("H:RSMainThread::DoComposition");
209         if (doComposition != std::string::npos) {
210             size_t position1 = line.find("....");
211             size_t position2 = line.find(":");
212             int subNum = 5;
213             endTime = line.substr(position1 + subNum, position2 - position1 - subNum);
214             int endNum = std::stof(endTime);
215             int endFlagNum = std::stof(endTimeFlag);
216             int startNum = std::stof(startTime);
217             int timeNum = endNum - endFlagNum;
218             double interval = 0.3;
219             if (timeNum < interval) {
220                 endTimeFlag = endTime;
221                 continue;
222             }
223             if (std::stof(endTimeFlag) == 0) {
224                 endTimeFlag = endTime;
225             } else if (endFlagNum != 0 && startNum != 0 && timeNum > interval) {
226                 break;
227             } else {
228                 endTimeFlag = endTime;
229             }
230         }
231     }
232     codeTime = SmartPerf::ParseTrace::GetTime(startTime, endTime);
233     return codeTime;
234 }
GetTime(std::string start,std::string end)235 double ParseTrace::GetTime(std::string start, std::string end)
236 {
237     double codeTime = -1;
238     if (std::stof(end) == 0 || std::stof(start) == 0) {
239         return codeTime;
240     } else {
241         double displayTime = 0.040;
242         codeTime = std::stof(end) - std::stof(start) + displayTime;
243     }
244     return codeTime;
245 }
GetStartTime(std::string line,const std::string & startTimeBefore)246 std::string ParseTrace::GetStartTime(std::string line, const std::string &startTimeBefore)
247 {
248     std::string::size_type te = line.find("H:touchEventDispatch");
249     std::string::size_type td = line.find("H:TouchEventDispatch");
250     std::string::size_type pd = line.find("H:PointerEventDispatch");
251     std::string::size_type kd = line.find("H:KeyEventDispatch");
252     std::string::size_type nop = std::string::npos;
253     if (te != nop || td != nop || pd != nop || kd != nop) {
254         size_t touchNum = 3;
255         if (flagTouch <= touchNum) {
256             size_t position1 = line.find("....");
257             size_t position2 = line.find(":");
258             size_t subNum = 5;
259             startTime = line.substr(position1 + subNum, position2 - position1 - subNum);
260             flagTime = "0";
261             flagTouch++;
262         } else {
263             startTime = startTimeBefore;
264         }
265     } else {
266         startTime = startTimeBefore;
267     }
268     return startTime;
269 }
270 }
271 }