1 /*
2  * Copyright (c) 2023 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 #ifndef ARKUI_PERF_MONITOR_H
17 #define ARKUI_PERF_MONITOR_H
18 
19 #include <mutex>
20 #include <string>
21 #include <map>
22 #include <vector>
23 #include <algorithm>
24 #include <memory>
25 
26 #include "base/utils/macros.h"
27 #include "base/utils/aps_monitor.h"
28 
29 namespace OHOS::Ace {
30 constexpr int32_t US_TO_MS = 1000;
31 constexpr int32_t NS_TO_MS = 1000000;
32 constexpr int32_t NS_TO_S = 1000000000;
33 constexpr char DEFAULT_SCENE_ID[] = "NONE_ANIMATION";
34 
35 enum PerfActionType {
36     UNKNOWN_ACTION = -1,
37     LAST_DOWN = 0,
38     LAST_UP = 1,
39     FIRST_MOVE = 2
40 };
41 
42 enum PerfSourceType {
43     UNKNOWN_SOURCE = -1,
44     PERF_TOUCH_EVENT = 0,
45     PERF_MOUSE_EVENT = 1,
46     PERF_TOUCH_PAD = 2,
47     PERF_JOY_STICK = 3,
48     PERF_KEY_EVENT = 4
49 };
50 
51 enum PerfEventType {
52     UNKNOWN_EVENT = -1,
53     EVENT_RESPONSE = 0,
54     EVENT_COMPLETE = 1,
55     EVENT_JANK_FRAME = 2
56 };
57 
58 struct BaseInfo {
59     int32_t pid {-1};
60     int32_t versionCode {0};
61     std::string versionName {""};
62     std::string bundleName {""};
63     std::string processName {""};
64     std::string abilityName {""};
65     std::string pageUrl {""};
66     std::string pageName {""};
67     std::string note {""};
68 };
69 
70 struct DataBase {
71     std::string sceneId {""};
72     int32_t maxSuccessiveFrames {0};
73     int32_t totalMissed {0};
74     int32_t totalFrames {0};
75     int64_t inputTime {0};
76     int64_t beginVsyncTime {0};
77     int64_t endVsyncTime {0};
78     int64_t maxFrameTime {0};
79     int64_t maxFrameTimeSinceStart {0};
80     int64_t maxHitchTime {0};
81     int64_t maxHitchTimeSinceStart {0};
82     bool needReportRs {false};
83     bool isDisplayAnimator {false};
84     PerfSourceType sourceType {UNKNOWN_SOURCE};
85     PerfActionType actionType {UNKNOWN_ACTION};
86     PerfEventType eventType {UNKNOWN_EVENT};
87     BaseInfo baseInfo;
88 };
89 
90 struct JankInfo {
91     int64_t skippedFrameTime {0};
92     std::string windowName {""};
93     std::string sceneId {""};
94     int32_t filterType {0};
95     BaseInfo baseInfo;
96 };
97 
98 void ConvertRealtimeToSystime(int64_t realTime, int64_t& sysTime);
99 std::string GetSourceTypeName(PerfSourceType sourceType);
100 std::string ParsePageUrl(const std::string& pagePath);
101 
102 class SceneRecord {
103 public:
104     void InitRecord(const std::string& sId, PerfActionType aType, PerfSourceType sType, const std::string& nt,
105         int64_t time);
106     void RecordFrame(int64_t vsyncTime, int64_t duration, int32_t skippedFrames);
107     void Report(const std::string& sceneId, int64_t vsyncTime, bool isRsRender);
108     bool IsTimeOut(int64_t nowTime);
109     bool IsFirstFrame();
110     bool IsDisplayAnimator(const std::string& sceneId);
111     void Reset();
112 public:
113     int64_t inputTime {0};
114     int64_t beginVsyncTime {0};
115     int64_t endVsyncTime {0};
116     int64_t  maxFrameTime {0};
117     int64_t maxFrameTimeSinceStart {0};
118     int64_t maxHitchTime {0};
119     int64_t maxHitchTimeSinceStart {0};
120     int32_t maxSuccessiveFrames {0};
121     int32_t totalMissed {0};
122     int32_t totalFrames {0};
123     int32_t seqMissFrames {0};
124     bool isSuccessive {false};
125     bool isFirstFrame {false};
126     bool needReportRs {false};
127     bool isDisplayAnimator {false};
128     std::string sceneId {""};
129     PerfActionType actionType {UNKNOWN_ACTION};
130     PerfSourceType sourceType {UNKNOWN_SOURCE};
131     std::string note {""};
132 };
133 
134 class ACE_FORCE_EXPORT PerfMonitor {
135 public:
136     void Start(const std::string& sceneId, PerfActionType type, const std::string& note);
137     void End(const std::string& sceneId, bool isRsRender);
138     void RecordInputEvent(PerfActionType type, PerfSourceType sourceType, int64_t time);
139     int64_t GetInputTime(const std::string& sceneId, PerfActionType type, const std::string& note);
140     void SetFrameTime(int64_t vsyncTime, int64_t duration, double jank, const std::string& windowName);
141     void ReportJankFrameApp(double jank);
142     void SetPageUrl(const std::string& pageUrl);
143     std::string GetPageUrl();
144     void SetPageName(const std::string& pageName);
145     std::string GetPageName();
146     void SetAppForeground(bool isShow);
147     void SetAppStartStatus();
148     static PerfMonitor* GetPerfMonitor();
149     static PerfMonitor* pMonitor;
150     void SetApsMonitor(const std::shared_ptr<ApsMonitor>& apsMonitor);
151     void ReportPageShowMsg(const std::string& pageUrl, const std::string& bundleName,
152                            const std::string& pageName);
153 
154 private:
155     SceneRecord* GetRecord(const std::string& sceneId);
156     void RemoveRecord(const std::string& sceneId);
157     void ReportAnimateStart(const std::string& sceneId, SceneRecord* record);
158     void ReportAnimateEnd(const std::string& sceneId, SceneRecord* record);
159     void FlushDataBase(SceneRecord* record, DataBase& data);
160     void ReportPerfEvent(PerfEventType type, DataBase& data);
161     void RecordBaseInfo(SceneRecord* record);
162     bool IsExceptResponseTime(int64_t time, const std::string& sceneId);
163     int32_t GetFilterType() const;
164 private:
165     std::shared_ptr<ApsMonitor> apsMonitor_ = nullptr;
166     std::map<PerfActionType, int64_t> mInputTime;
167     int64_t mVsyncTime {0};
168     PerfSourceType mSourceType {UNKNOWN_SOURCE};
169     BaseInfo baseInfo;
170     mutable std::mutex mMutex;
171     std::map<std::string, SceneRecord*> mRecords;
172 
173     // for jank frame app
174     bool isResponseExclusion {false};
175     bool isStartAppFrame {false};
176     bool isBackgroundApp {false};
177     bool isExclusionWindow {false};
178     int64_t startAppTime {0};
179     std::string currentSceneId {""};
180     // filter common discarded frames in white list
181     bool isExceptAnimator {false};
182     bool IsSceneIdInSceneWhiteList(const std::string& sceneId);
183     void CheckTimeOutOfExceptAnimatorStatus(const std::string& sceneId);
184     bool IsExclusionFrame();
185     void CheckInStartAppStatus();
186     void CheckExclusionWindow(const std::string& windowName);
187     void CheckResponseStatus();
188     void ProcessJank(double jank, const std::string& windowName);
189     void ReportJankFrame(double jank, const std::string& windowName);
190 };
191 } // namespace OHOS::Ace
192 #endif // ARKUI_PERF_MONITOR_H
193