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