• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }