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