• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "AnimatorSceneDataProcessor.h"
17 #include "JlogId.h"
18 #include "hiview_logger.h"
19 
20 namespace OHOS {
21 namespace HiviewDFX {
22 DEFINE_LOG_LABEL(0xD002D66, "Hiview-XPerformance");
23 
24 namespace {
25 const int32_t S_TO_MS = 1000;
26 const int64_t S_TO_US = 10000000;
27 // process animator point when timeout
28 const int32_t TIME_OUT = 5000;
29 
30 // define animator process point
31 enum ANIMATOR_POINT {
32     SUP_START_POINT = -1,
33     START_POINT = 0,
34     END_POINT = 1
35 };
36 }
GetCurrentRealtimeMs()37 static int64_t GetCurrentRealtimeMs()
38 {
39     struct timespec t;
40     t.tv_sec = t.tv_nsec = 0;
41     clock_gettime(CLOCK_REALTIME, &t);
42     return (t.tv_sec * S_TO_MS + t.tv_nsec / S_TO_US);
43 }
44 
SetCb(IAnimatorSceneDataProcessor::MetricReporter * cb)45 void AnimatorSceneDataProcessor::SetCb(IAnimatorSceneDataProcessor::MetricReporter* cb)
46 {
47     this->cb = cb;
48 }
49 
CacheFocusWindowPid(std::shared_ptr<XperfEvt> evt)50 void AnimatorSceneDataProcessor::CacheFocusWindowPid(std::shared_ptr<XperfEvt> evt)
51 {
52     if (evt == nullptr) {
53         return;
54     }
55     focusWindowPid = evt->pid;
56     focusBundleName = evt->bundleName;
57 }
58 
ProcessSceneData(std::shared_ptr<XperfEvt> evt)59 void AnimatorSceneDataProcessor::ProcessSceneData(std::shared_ptr<XperfEvt> evt)
60 {
61     HIVIEW_LOGD("[AnimatorSceneDataProcessor::ProcessSceneData]");
62     if (evt == nullptr) {
63         HIVIEW_LOGD("[AnimatorSceneDataProcessor::ProcessSceneData] evt == nullptr");
64         return;
65     }
66     switch (evt->logId) {
67         case JLID_ACE_INTERACTION_APP_JANK:
68             HIVIEW_LOGD("[AnimatorSceneDataProcessor::ProcessSceneData] JLID_ACE_INTERACTION_APP_JANK");
69             CreateRecord(evt, START_POINT);
70             break;
71         case JLID_GRAPHIC_INTERACTION_RENDER_JANK:
72             HIVIEW_LOGD("[AnimatorSceneDataProcessor::ProcessSceneData] JLID_GRAPHIC_INTERACTION_RENDER_JANK");
73             if (!HasStartPoint(evt)) {
74                 CreateRecord(evt, SUP_START_POINT);
75             }
76             SaveAnimatorPoint(evt, END_POINT);
77             break;
78         case JLID_WINDOWMANAGER_FOCUS_WINDOW:
79             HIVIEW_LOGD("[AnimatorSceneDataProcessor::ProcessSceneData] JLID_WINDOWMANAGER_FOCUS_WINDOW");
80             CacheFocusWindowPid(evt);
81             break;
82         default:
83             return;
84     }
85     if (AllPointsReceived(evt)) {
86         HIVIEW_LOGD("[AnimatorSceneDataProcessor::ProcessSceneData] AllPointsReceived");
87         AnimatorRecord* record = GetRecord(evt->animatorInfo.basicInfo.uniqueId);
88         if (record == nullptr) {
89             HIVIEW_LOGD("[AnimatorSceneDataProcessor::ProcessSceneData] record == nullptr");
90             return;
91         }
92         AnimatorMetrics metrics = CalcMetrics(*record);
93         Report(metrics);
94         DeleteRecord(evt->animatorInfo.basicInfo.uniqueId);
95     }
96     HandleTimeOutPoints();
97 }
98 
CreateRecord(std::shared_ptr<XperfEvt> evt,int32_t indexPoint)99 void AnimatorSceneDataProcessor::CreateRecord(std::shared_ptr<XperfEvt> evt, int32_t indexPoint)
100 {
101     HIVIEW_LOGD("[AnimatorSceneDataProcessor::CreateRecord]");
102     if (evt == nullptr) {
103         return;
104     }
105     AnimatorRecord* animatorRecord = new AnimatorRecord();
106     db.insert(std::map<int32_t, AnimatorRecord*>::value_type(evt->animatorInfo.basicInfo.uniqueId, animatorRecord));
107     SaveAnimatorPoint(evt, indexPoint);
108 }
109 
HasStartPoint(std::shared_ptr<XperfEvt> evt)110 bool AnimatorSceneDataProcessor::HasStartPoint(std::shared_ptr<XperfEvt> evt)
111 {
112     if (evt == nullptr) {
113         return false;
114     }
115     AnimatorRecord* record = GetRecord(evt->animatorInfo.basicInfo.uniqueId);
116     if (record != nullptr && record->hasStartPoint) {
117         return true;
118     }
119     return false;
120 }
121 
AllPointsReceived(std::shared_ptr<XperfEvt> evt)122 bool AnimatorSceneDataProcessor::AllPointsReceived(std::shared_ptr<XperfEvt> evt)
123 {
124     if (evt == nullptr) {
125         return false;
126     }
127     AnimatorRecord* record = GetRecord(evt->animatorInfo.basicInfo.uniqueId);
128     if (record != nullptr) {
129         if (record->hasStartPoint &&
130             record->receviedPoint >= record->allReceviedPoint) {
131             return true;
132         }
133     }
134     return false;
135 }
136 
SaveAnimatorPoint(std::shared_ptr<XperfEvt> evt,int32_t indexPoint)137 void AnimatorSceneDataProcessor::SaveAnimatorPoint(std::shared_ptr<XperfEvt> evt, int32_t indexPoint)
138 {
139     HIVIEW_LOGD("[AnimatorSceneDataProcessor::SaveAnimatorPoint]");
140     if (evt == nullptr) {
141         return;
142     }
143     AnimatorRecord* record = GetRecord(evt->animatorInfo.basicInfo.uniqueId);
144     if (record == nullptr) {
145         return;
146     }
147     if (indexPoint == START_POINT || indexPoint == SUP_START_POINT) {
148         record->hasStartPoint = true;
149         record->startTime = GetCurrentRealtimeMs();
150     }
151     record->receviedPoint++;
152     if (indexPoint == SUP_START_POINT) {
153         record->animatorPoints[START_POINT].basicInfo = evt->animatorInfo.basicInfo;
154         return;
155     }
156     record->animatorPoints[indexPoint].basicInfo = evt->animatorInfo.basicInfo;
157     record->animatorPoints[indexPoint].commonInfo = evt->animatorInfo.commonInfo;
158 }
159 
CalcMetrics(const AnimatorRecord & record)160 AnimatorMetrics AnimatorSceneDataProcessor::CalcMetrics(const AnimatorRecord& record)
161 {
162     AnimatorMetrics animatorMetrics;
163     animatorMetrics.basicInfo = record.animatorPoints[START_POINT].basicInfo;
164     animatorMetrics.appInfo = record.animatorPoints[START_POINT].commonInfo;
165     animatorMetrics.rsInfo = record.animatorPoints[END_POINT].commonInfo;
166     if (animatorMetrics.basicInfo.bundleNameEx.empty()) {
167         animatorMetrics.basicInfo.bundleNameEx = animatorMetrics.basicInfo.moduleName;
168     }
169     if (animatorMetrics.basicInfo.bundleNameEx == focusBundleName ||
170         (animatorMetrics.basicInfo.bundleNameEx.empty() && animatorMetrics.basicInfo.moduleName == focusBundleName)) {
171         animatorMetrics.focus = true;
172     } else {
173         animatorMetrics.focus = false;
174     }
175     return animatorMetrics;
176 }
177 
Report(const AnimatorMetrics & metrics)178 void AnimatorSceneDataProcessor::Report(const AnimatorMetrics& metrics)
179 {
180     HIVIEW_LOGD("[AnimatorSceneDataProcessor::Report]");
181     cb->ReportMetrics(metrics);
182 }
183 
GetRecord(const int32_t uniqueId)184 AnimatorRecord* AnimatorSceneDataProcessor::GetRecord(const int32_t uniqueId)
185 {
186     AnimatorRecord* record = nullptr;
187     if (db.find(uniqueId) != db.end()) {
188         record = db[uniqueId];
189     }
190     return record;
191 }
192 
DeleteRecord(const int32_t uniqueId)193 void AnimatorSceneDataProcessor::DeleteRecord(const int32_t uniqueId)
194 {
195     auto iter = db.find(uniqueId);
196     if (iter != db.end()) {
197         delete iter->second;
198         db.erase(iter);
199     }
200 }
201 
HandleTimeOutPoints()202 void AnimatorSceneDataProcessor::HandleTimeOutPoints()
203 {
204     HIVIEW_LOGD("[AnimatorSceneDataProcessor::HandleTimeOutPoints] begin");
205     for (auto it = db.begin(); it != db.end();) {
206         if (it->second != nullptr && (GetCurrentRealtimeMs() - (it->second)->startTime) >= TIME_OUT) {
207             HIVIEW_LOGD("[AnimatorSceneDataProcessor::HandleTimeOutPoints] match if");
208             Report(CalcMetrics(*(it->second)));
209             delete it->second;
210             it = db.erase(it);
211             continue;
212         }
213         it++;
214     }
215     HIVIEW_LOGD("[AnimatorSceneDataProcessor::HandleTimeOutPoints] end");
216 }
217 } // HiviewDFX
218 } // OHOS