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 }