1 /*
2 * Copyright (c) 2025 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
16 #include "perf_constants.h"
17 #include "perf_model.h"
18 #include "perf_utils.h"
19 #include "hiview_logger.h"
20
21 namespace OHOS {
22 namespace HiviewDFX {
23 constexpr int64_t SCENE_TIMEOUT = 10000000000;
24
InitRecord(const std::string & sId,PerfActionType aType,PerfSourceType sType,const std::string & nt,int64_t time)25 void AnimatorRecord::InitRecord(const std::string& sId, PerfActionType aType, PerfSourceType sType,
26 const std::string& nt, int64_t time)
27 {
28 sceneId = sId;
29 actionType = aType;
30 sourceType = sType;
31 note = nt;
32 inputTime = time;
33 beginVsyncTime = GetCurrentRealTimeNs();
34 isDisplayAnimator = IsDisplayAnimator(sceneId);
35 }
36
IsTimeOut(int64_t nowTime)37 bool AnimatorRecord::IsTimeOut(int64_t nowTime)
38 {
39 if (nowTime - beginVsyncTime > SCENE_TIMEOUT) {
40 return true;
41 }
42 return false;
43 }
44
RecordFrame(int64_t vsyncTime,int64_t duration,int32_t skippedFrames)45 void AnimatorRecord::RecordFrame(int64_t vsyncTime, int64_t duration, int32_t skippedFrames)
46 {
47 int64_t currentTimeNs = GetCurrentRealTimeNs();
48 if (totalFrames == 0) {
49 beginVsyncTime = currentTimeNs;
50 isFirstFrame = true;
51 } else {
52 isFirstFrame = false;
53 }
54 skippedFrames = static_cast<int32_t>(duration / SINGLE_FRAME_TIME);
55 if (!isFirstFrame && skippedFrames >= 1) {
56 if (isSuccessive) {
57 seqMissFrames = seqMissFrames + skippedFrames;
58 } else {
59 seqMissFrames = skippedFrames;
60 isSuccessive = true;
61 }
62 if (maxSuccessiveFrames < seqMissFrames) {
63 maxSuccessiveFrames = seqMissFrames;
64 }
65 totalMissed += skippedFrames;
66 } else {
67 isSuccessive = false;
68 seqMissFrames = 0;
69 }
70 if (!isFirstFrame && duration > maxFrameTime) {
71 maxFrameTime = duration;
72 maxFrameTimeSinceStart = (currentTimeNs - beginVsyncTime) / NS_TO_MS;
73 }
74 totalFrames++;
75 }
76
Report(const std::string & sceneId,int64_t vsyncTime,bool isRsRender)77 void AnimatorRecord::Report(const std::string& sceneId, int64_t vsyncTime, bool isRsRender)
78 {
79 if (isRsRender || vsyncTime <= beginVsyncTime) {
80 endVsyncTime = GetCurrentRealTimeNs();
81 } else {
82 endVsyncTime = vsyncTime;
83 }
84 needReportRs = !isRsRender;
85 }
86
IsFirstFrame()87 bool AnimatorRecord::IsFirstFrame()
88 {
89 return isFirstFrame;
90 }
91
IsDisplayAnimator(const std::string & sceneId)92 bool AnimatorRecord::IsDisplayAnimator(const std::string& sceneId)
93 {
94 if (sceneId == PerfConstants::APP_LIST_FLING || sceneId == PerfConstants::APP_SWIPER_SCROLL
95 || sceneId == PerfConstants::SNAP_RECENT_ANI
96 || sceneId == PerfConstants::WINDOW_RECT_RESIZE
97 || sceneId == PerfConstants::WINDOW_RECT_MOVE
98 || sceneId == PerfConstants::META_BALLS_TURBO_CHARGING_ANIMATION
99 || sceneId == PerfConstants::ABILITY_OR_PAGE_SWITCH_INTERACTIVE
100 || sceneId == PerfConstants::SCROLLER_ANIMATION
101 || sceneId == PerfConstants::LAUNCHER_SPRINGBACK_SCROLL) {
102 return true;
103 }
104 return false;
105 }
106
Reset()107 void AnimatorRecord::Reset()
108 {
109 beginVsyncTime = 0;
110 endVsyncTime = 0;
111 maxFrameTime = 0;
112 maxFrameTimeSinceStart = 0;
113 maxHitchTime = 0;
114 maxHitchTimeSinceStart = 0;
115 maxSuccessiveFrames = 0;
116 seqMissFrames = 0;
117 totalMissed = 0;
118 totalFrames = 0;
119 isSuccessive = false;
120 isFirstFrame = false;
121 sceneId = "";
122 actionType = UNKNOWN_ACTION;
123 sourceType = UNKNOWN_SOURCE;
124 note = "";
125 }
126
StartRecord(const SceneType & sType)127 void SceneRecord::StartRecord(const SceneType& sType)
128 {
129 type = sType;
130 status = true;
131 }
132
StopRecord(const SceneType & sType)133 void SceneRecord::StopRecord(const SceneType& sType)
134 {
135 if (type != sType) {
136 return;
137 }
138 status = false;
139 }
140
StartRecord(const SceneType & sType,const std::string & sId)141 void SceneRecord::StartRecord(const SceneType& sType, const std::string& sId)
142 {
143 StartRecord(sType);
144 sceneId = sId;
145 }
146
StopRecord(const SceneType & sType,const std::string & sId)147 void SceneRecord::StopRecord(const SceneType& sType, const std::string& sId)
148 {
149 if (type != sType || sceneId != sId) {
150 return;
151 }
152 status = false;
153 }
154
StartRecord(const SceneType & sType,const std::string & sId)155 void NonExperienceAnimator::StartRecord(const SceneType& sType, const std::string& sId)
156 {
157 type = sType;
158 sceneId = sId;
159 status = IsNonExperienceWhiteList(sId);
160 }
161
StopRecord(const SceneType & sType,const std::string & sId)162 void NonExperienceAnimator::StopRecord(const SceneType& sType, const std::string& sId)
163 {
164 if (type != sType || sceneId != sId) {
165 return;
166 }
167 if (IsNonExperienceWhiteList(sId)) {
168 status = false;
169 }
170 }
171
IsNonExperienceWhiteList(const std::string & sceneId)172 bool NonExperienceAnimator::IsNonExperienceWhiteList(const std::string& sceneId)
173 {
174 if (sceneId == PerfConstants::LAUNCHER_APP_LAUNCH_FROM_ICON ||
175 sceneId == PerfConstants::LAUNCHER_APP_LAUNCH_FROM_DOCK ||
176 sceneId == PerfConstants::LAUNCHER_APP_LAUNCH_FROM_MISSON ||
177 sceneId == PerfConstants::LAUNCHER_APP_SWIPE_TO_HOME ||
178 sceneId == PerfConstants::LAUNCHER_APP_BACK_TO_HOME ||
179 sceneId == PerfConstants::EXIT_RECENT_2_HOME_ANI ||
180 sceneId == PerfConstants::APP_SWIPER_FLING ||
181 sceneId == PerfConstants::ABILITY_OR_PAGE_SWITCH ||
182 sceneId == PerfConstants::SCREENLOCK_SCREEN_INTO_PIN ||
183 sceneId == PerfConstants::SCREENLOCK_SCREEN_OFF_ANIM) {
184 return true;
185 }
186 return false;
187 }
188
StartRecord(const SceneType & sType,const std::string & sId)189 void NonExperienceWindow::StartRecord(const SceneType& sType, const std::string& sId)
190 {
191 type = sType;
192 sceneId = sId;
193 status = IsNonExperienceWhiteList(sId);
194 }
195
StopRecord(const SceneType & sType,const std::string & sId)196 void NonExperienceWindow::StopRecord(const SceneType& sType, const std::string& sId)
197 {
198 if (type != sType || sceneId != sId) {
199 return;
200 }
201 status = false;
202 }
203
IsNonExperienceWhiteList(const std::string & windowName)204 bool NonExperienceWindow::IsNonExperienceWhiteList(const std::string& windowName)
205 {
206 if (windowName == "softKeyboard1" ||
207 windowName == "SCBWallpaper1" ||
208 windowName == "SCBStatusBar15") {
209 return true;
210 }
211 return false;
212 }
213
StartRecord(const SceneType & sType,const std::string & sId)214 void NonExperiencePageLoading::StartRecord(const SceneType& sType, const std::string& sId)
215 {
216 type = sType;
217 sceneId = sId;
218 if (!status) {
219 status = IsNonExperienceWhiteList(sId);
220 }
221 }
222
StopRecord(const SceneType & sType)223 void NonExperiencePageLoading::StopRecord(const SceneType& sType)
224 {
225 if (type != sType) {
226 return;
227 }
228 status = false;
229 }
230
IsNonExperienceWhiteList(const std::string & sceneId)231 bool NonExperiencePageLoading::IsNonExperienceWhiteList(const std::string& sceneId)
232 {
233 // 上滑退出和转场动效后第一帧标记为加载帧,实际体验为加载慢,非丢帧卡顿
234 if (sceneId == PerfConstants::LAUNCHER_APP_SWIPE_TO_HOME ||
235 sceneId == PerfConstants::ABILITY_OR_PAGE_SWITCH) {
236 return true;
237 }
238 return false;
239 }
240
StartRecord(const SceneType & sType)241 void NonExperienceAppStart::StartRecord(const SceneType& sType)
242 {
243 type = sType;
244 status = true;
245 startTime = GetCurrentRealTimeNs();
246 duration = 0;
247 }
248
StopRecord(const SceneType & sType)249 void NonExperienceAppStart::StopRecord(const SceneType& sType)
250 {
251 if (type != sType) {
252 return;
253 }
254 status = IsInStartAppStatus();
255 }
256
IsInStartAppStatus()257 bool NonExperienceAppStart::IsInStartAppStatus()
258 {
259 int64_t curTime = GetCurrentRealTimeNs();
260 duration = curTime - startTime;
261 if (duration >= STARTAPP_FRAME_TIMEOUT) {
262 return false;
263 } else {
264 return true;
265 }
266 }
267
268 }
269 }