• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "perform_reporter.h"
17 
18 #include <hisysevent.h>
19 
20 #include "window_manager_hilog.h"
21 
22 namespace OHOS {
23 namespace Rosen {
24 namespace {
25     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "PerformReporter"};
26 }
WM_IMPLEMENT_SINGLE_INSTANCE(WindowInfoReporter)27 WM_IMPLEMENT_SINGLE_INSTANCE(WindowInfoReporter)
28 
29 /**
30  * @brief Construct a new Perform Reporter:: Perform Reporter object
31  *
32  * @param tag A tag that in report string
33  * @param timeSpiltsMs The time-interval that data statistic, details look up the comments in function body
34  * @param reportInterval Report data after reportInterval round start-end
35  */
36 PerformReporter::PerformReporter(const std::string& tag,
37     const std::vector<int64_t>& timeSpiltsMs, uint32_t reportInterval)
38     : tag_(tag), reportInterval_(reportInterval)
39 {
40     // re-organ data struct
41     // a, b, c, d -->
42     // (0, a] : cnt=0, (a, b] : cnt=0, (b, c] : cnt=0, (c, d] : cnt=0
43     for (auto split : timeSpiltsMs) {
44         timeSplitCount_[split] = 0;
45     }
46     // (d, +limit] : cnt=0
47     timeSplitCount_[BARRIER] = 0;
48     totalCount_ = 0;
49 }
50 
start()51 void PerformReporter::start()
52 {
53     startTime_ = std::chrono::steady_clock::now();
54 }
55 
end()56 void PerformReporter::end()
57 {
58     auto currentTime = std::chrono::steady_clock::now();
59     int64_t costTime = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - startTime_).count();
60 
61     count(costTime);
62 
63     bool repSucc = report();
64     if (repSucc) {
65         clear();
66     }
67 }
68 
report()69 bool PerformReporter::report()
70 {
71     if (totalCount_ < reportInterval_) {
72         return false;
73     }
74 
75     std::ostringstream oss;
76     oss << tag_ << ": ";
77     auto maxSplit = 0;
78     for (const auto& iter: timeSplitCount_) {
79         if (iter.first != BARRIER) {
80             oss << "BELLOW" << iter.first << "(ms): " << iter.second << ", ";
81             maxSplit = iter.first;
82         }
83     }
84     oss << "ABOVE" << maxSplit << "(ms): " << timeSplitCount_[BARRIER];
85 
86     int32_t ret = HiSysEventWrite(
87         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER, tag_,
88         OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "MSG", oss.str());
89     WLOGI("Write HiSysEvent ret:%{public}d", ret);
90     return ret == 0;
91 }
92 
count(int64_t costTime)93 void PerformReporter::count(int64_t costTime)
94 {
95     totalCount_++;
96     for (auto& iter: timeSplitCount_) {
97         if (costTime <= iter.first) {
98             iter.second++;
99             break;
100         }
101     }
102 
103     std::ostringstream oss;
104     oss << tag_ << " cost " << costTime << "ms, total count " << totalCount_;
105     WLOGI("%{public}s", oss.str().c_str());
106 }
107 
clear()108 void PerformReporter::clear()
109 {
110     totalCount_ = 0;
111     for (auto& iter: timeSplitCount_) {
112         iter.second = 0;
113     }
114 }
115 
GetMsgString(const FullInfoMap & infoMap)116 std::string WindowInfoReporter::GetMsgString(const FullInfoMap& infoMap)
117 {
118     if (infoMap.empty()) {
119         return "";
120     }
121     std::ostringstream oss;
122     oss << "{";
123     for (auto& bundleInfos : infoMap) {
124         if (bundleInfos.second.empty()) {
125             continue;
126         }
127         oss << "{";
128         for (auto& packageInfo : bundleInfos.second) {
129             oss << "BUNDLE_NAME:" << bundleInfos.first << ",";
130             oss << "ABILITY_NAME:" << packageInfo.first << ",";
131             oss << "COUNT:" << packageInfo.second;
132         }
133         oss << "},";
134     }
135     oss << "};";
136     return oss.str();
137 }
138 
GetMsgString(const BundleNameMap & infoMap)139 std::string WindowInfoReporter::GetMsgString(const BundleNameMap& infoMap)
140 {
141     if (infoMap.empty()) {
142         return "";
143     }
144     std::ostringstream oss;
145     oss << "{";
146     for (auto& bundleInfo : infoMap) {
147         oss << "{";
148         oss << "BUNDLE_NAME:" << bundleInfo.first << ",";
149         oss << "COUNT:" << bundleInfo.second;
150         oss << "},";
151     }
152     oss << "};";
153     return oss.str();
154 }
155 
InsertCreateReportInfo(const std::string & bundleName)156 void WindowInfoReporter::InsertCreateReportInfo(const std::string& bundleName)
157 {
158     UpdateReportInfo(windowCreateReportInfos_, bundleName);
159 }
160 
InsertShowReportInfo(const std::string & bundleName)161 void WindowInfoReporter::InsertShowReportInfo(const std::string& bundleName)
162 {
163     UpdateReportInfo(windowShowReportInfos_, bundleName);
164 }
165 
InsertHideReportInfo(const std::string & bundleName)166 void WindowInfoReporter::InsertHideReportInfo(const std::string& bundleName)
167 {
168     UpdateReportInfo(windowHideReportInfos_, bundleName);
169 }
170 
InsertDestroyReportInfo(const std::string & bundleName)171 void WindowInfoReporter::InsertDestroyReportInfo(const std::string& bundleName)
172 {
173     UpdateReportInfo(windowDestoryReportInfos_, bundleName);
174 }
175 
InsertNavigationBarReportInfo(const std::string & bundleName,const std::string & packageName)176 void WindowInfoReporter::InsertNavigationBarReportInfo(const std::string& bundleName, const std::string& packageName)
177 {
178     UpdateReportInfo(windowNavigationBarReportInfos_, bundleName, packageName);
179 }
180 
UpdateReportInfo(FullInfoMap & infoMap,const std::string & bundleName,const std::string & packageName)181 void WindowInfoReporter::UpdateReportInfo(FullInfoMap& infoMap,
182     const std::string& bundleName, const std::string& packageName)
183 {
184     if (bundleName.empty() || packageName.empty()) {
185         return;
186     }
187     std::lock_guard<std::mutex> lock(mtx_);
188     auto iter = infoMap.find(bundleName);
189     if (iter == infoMap.end()) {
190         std::map<std::string, uint32_t> infos;
191         infos.insert(std::make_pair(packageName, 1));
192         infoMap.insert(std::make_pair(bundleName, infos));
193         return;
194     }
195 
196     auto countPairIter = iter->second.find(packageName);
197     if (countPairIter == iter->second.end()) {
198         iter->second.insert(std::make_pair(packageName, 1));
199         return;
200     }
201     infoMap[bundleName][packageName]++;
202 }
203 
UpdateReportInfo(BundleNameMap & infoMap,const std::string & bundleName)204 void WindowInfoReporter::UpdateReportInfo(BundleNameMap& infoMap, const std::string& bundleName)
205 {
206     if (bundleName.empty()) {
207         return;
208     }
209     std::lock_guard<std::mutex> lock(mtx_);
210     auto iter = infoMap.find(bundleName);
211     if (iter == infoMap.end()) {
212         infoMap.insert(std::make_pair(bundleName, 1));
213         return;
214     }
215     infoMap[bundleName]++;
216 }
217 
ReportBackButtonInfoImmediately()218 void WindowInfoReporter::ReportBackButtonInfoImmediately()
219 {
220     Report("WM_REPORT_BACK_KEYEVENT", "Click Back Button");
221 }
222 
ReportZeroOpacityInfoImmediately(const std::string & bundleName,const std::string & packageName)223 void WindowInfoReporter::ReportZeroOpacityInfoImmediately(const std::string& bundleName, const std::string& packageName)
224 {
225     if (bundleName.empty()) {
226         return;
227     }
228     std::ostringstream oss;
229     oss << "{ PROCESS_NAME:" << bundleName.c_str() << ", PACKAGE_NAME:" << "" << packageName.c_str() << " }";
230     Report("WM_REPORT_WINDOW_OPACITY_ZERO", oss.str());
231 }
232 
ReportRecordedInfos()233 void WindowInfoReporter::ReportRecordedInfos()
234 {
235     std::lock_guard<std::mutex> lock(mtx_);
236     WLOGFD("----Report HiSysEvent write all-----");
237     Report("WM_REPORT_WINDOW_CREATE", GetMsgString(windowCreateReportInfos_));
238     Report("WM_REPORT_WINDOW_SHOW", GetMsgString(windowShowReportInfos_));
239     Report("WM_REPORT_WINDOW_HIDE", GetMsgString(windowHideReportInfos_));
240     Report("WM_REPORT_WINDOW_DESTORY", GetMsgString(windowDestoryReportInfos_));
241     Report("WM_REPORT_HIDE_NAVIGATIONBAR", GetMsgString(windowNavigationBarReportInfos_));
242     ClearRecordedInfos();
243 }
244 
Report(const std::string & reportTag,const std::string & msg)245 void WindowInfoReporter::Report(const std::string& reportTag, const std::string& msg)
246 {
247     if (msg.empty()) {
248         return;
249     }
250     WLOGFD("Report Tag : [%{public}s], Msg: %{public}s", reportTag.c_str(), msg.c_str());
251     int32_t ret = HiSysEventWrite(
252         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER, reportTag,
253         OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "MSG", msg);
254     if (ret != 0) {
255         WLOGFE("Write HiSysEvent error, ret:%{public}d", ret);
256     }
257 }
258 
ClearRecordedInfos()259 void WindowInfoReporter::ClearRecordedInfos()
260 {
261     WLOGFD("Clear all hiSysEvent write information");
262     windowCreateReportInfos_.clear();
263     windowShowReportInfos_.clear();
264     windowHideReportInfos_.clear();
265     windowDestoryReportInfos_.clear();
266     windowNavigationBarReportInfos_.clear();
267 }
268 }
269 }