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 #ifndef OHOS_ROSEN_RESSCHED_REPORT_H
17 #define OHOS_ROSEN_RESSCHED_REPORT_H
18 
19 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
20 #include "event_handler.h"
21 #include "res_sched_client.h"
22 #endif
23 #include "window_helper.h"
24 #include "wm_common.h"
25 #include "wm_single_instance.h"
26 
27 namespace OHOS {
28 namespace Rosen {
29 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
30 namespace {
31 constexpr int64_t PERF_TIME_OUT = 200;
32 constexpr int64_t SLIDE_PERF_TIME_OUT = 1000;
33 constexpr int32_t PERF_CLICK_NORMAL_CODE = 9;
34 constexpr int32_t PERF_DRAG_CODE = 31;
35 constexpr int32_t PERF_MOVE_CODE = 32;
36 constexpr int32_t PERF_ANIMATION_BOOST_CODE = 33;
37 constexpr int32_t PERF_SLIDE_CODE = 11;
38 constexpr int32_t PERF_STATUS_BAR_DRAG_CODE = 37;
39 const std::string TASK_NAME = "SlideOff";
40 }
41 
42 /**
43  * @brief Slide event status
44  */
45 enum SlideEventStatus : int64_t {
46     SLIDE_EVENT_OFF = 0,
47     SLIDE_EVENT_ON = 1,
48     SLIDE_NORMAL_BEGIN = 3,
49     SLIDE_NORMAL_END = 4,
50 };
51 #endif
52 
53 class ResSchedReport {
54     WM_DECLARE_SINGLE_INSTANCE(ResSchedReport);
55     public:
StopPerfIfNeed()56     void StopPerfIfNeed()
57     {
58 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
59         if (windowDragBoost_) {
60             ClosePerf(PERF_DRAG_CODE);
61             windowDragBoost_ = false;
62         }
63         if (windowMovingBoost_) {
64             ClosePerf(PERF_MOVE_CODE);
65             windowMovingBoost_ = false;
66         }
67 #endif
68     }
69 
TrigClick()70     void TrigClick()
71     {
72 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
73         std::unordered_map<std::string, std::string> mapPayload;
74         // 2 means click event.
75         OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(PERF_CLICK_NORMAL_CODE, 2, mapPayload);
76 #endif
77     }
78 
AnimationBoost()79     void AnimationBoost()
80     {
81 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
82         std::unordered_map<std::string, std::string> mapPayload;
83         OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(PERF_ANIMATION_BOOST_CODE, 0, mapPayload);
84 #endif
85     }
86 
RequestPerfIfNeed(WindowSizeChangeReason reason,WindowType type,WindowMode mode)87     void RequestPerfIfNeed(WindowSizeChangeReason reason, WindowType type, WindowMode mode)
88     {
89 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
90         if (WindowHelper::IsMainFloatingWindow(type, mode) || WindowHelper::IsSplitWindowMode(mode)) {
91             switch (reason) {
92                 case WindowSizeChangeReason::DRAG_END: {
93                     if (windowDragBoost_) {
94                         ClosePerf(PERF_DRAG_CODE);
95                         windowDragBoost_ = false;
96                     }
97                     break;
98                 }
99                 case WindowSizeChangeReason::DRAG_START:
100                     [[fallthrough]];
101                 case WindowSizeChangeReason::DRAG: {
102                     RequestPerf(PERF_DRAG_CODE, PERF_TIME_OUT);
103                     windowDragBoost_ = true;
104                     break;
105                 }
106                 case WindowSizeChangeReason::DRAG_MOVE:
107                 case WindowSizeChangeReason::MOVE: {
108                     RequestPerf(PERF_MOVE_CODE, PERF_TIME_OUT);
109                     windowMovingBoost_ = true;
110                     break;
111                 }
112                 default: {
113                     // doing nothing
114                 }
115             }
116         }
117 #endif
118     }
119 
TrigSlide(WindowType type,bool isOn)120     void TrigSlide(WindowType type, bool isOn)
121     {
122 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
123         if (type == WindowType::WINDOW_TYPE_STATUS_BAR || type == WindowType::WINDOW_TYPE_PANEL) {
124             StatusBarDrag(isOn);
125         }
126         if (type == WindowType::WINDOW_TYPE_DESKTOP || type == WindowType::WINDOW_TYPE_KEYGUARD) {
127             Slide(isOn);
128         }
129 #endif
130     }
131 private:
132 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
StatusBarDrag(bool isOn)133     void StatusBarDrag(bool isOn)
134     {
135         static auto lastRequestPerfTime = std::chrono::steady_clock::now();
136         static auto eventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
137         static auto handler = std::make_shared<AppExecFwk::EventHandler>(eventRunner);
138         static auto task = []() {
139             std::unordered_map<std::string, std::string> mapPayload;
140             OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(PERF_STATUS_BAR_DRAG_CODE,
141                 1, mapPayload);
142         };
143         auto current = std::chrono::steady_clock::now();
144         bool isTimeOut = std::chrono::duration_cast<std::chrono::milliseconds>(current - lastRequestPerfTime).
145             count() > SLIDE_PERF_TIME_OUT;
146         if (isTimeOut && isOn) {
147             handler->RemoveTask(TASK_NAME);
148             lastRequestPerfTime = current;
149             std::unordered_map<std::string, std::string> mapPayload;
150             OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(PERF_STATUS_BAR_DRAG_CODE,
151                 0, mapPayload);
152         }
153         if (!isOn) {
154             std::unordered_map<std::string, std::string> mapPayload;
155             OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(PERF_STATUS_BAR_DRAG_CODE,
156                 0, mapPayload);
157             // 990 is the animation duration.
158             handler->PostTask(task, TASK_NAME, 990, AppExecFwk::EventQueue::Priority::HIGH);
159         }
160     }
161 
Slide(bool isOn)162     void Slide(bool isOn)
163     {
164         static auto lastRequestPerfTime = std::chrono::steady_clock::now();
165         auto current = std::chrono::steady_clock::now();
166         bool isTimeOut = std::chrono::duration_cast<std::chrono::milliseconds>(current - lastRequestPerfTime).
167             count() > SLIDE_PERF_TIME_OUT;
168         if (isTimeOut && isOn) {
169             lastRequestPerfTime = current;
170             std::unordered_map<std::string, std::string> mapPayload;
171             OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(PERF_SLIDE_CODE,
172                 SlideEventStatus::SLIDE_EVENT_ON, mapPayload);
173         }
174         if (!isOn) {
175             std::unordered_map<std::string, std::string> mapPayload;
176             OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(PERF_SLIDE_CODE,
177                 SlideEventStatus::SLIDE_EVENT_OFF, mapPayload);
178         }
179     }
180 
RequestPerf(int32_t code,int64_t timeOut)181     void RequestPerf(int32_t code, int64_t timeOut)
182     {
183         auto currentTime = std::chrono::steady_clock::now();
184         bool isTimeOut = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastRequestPerfTime_).
185             count() > timeOut;
186         if (isTimeOut) {
187             std::unordered_map<std::string, std::string> mapPayload;
188             // 0 means doing action.
189             OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(code, 0, mapPayload);
190             lastRequestPerfTime_ = currentTime;
191         }
192     }
193 
ClosePerf(int32_t code)194     void ClosePerf(int32_t code)
195     {
196         std::unordered_map<std::string, std::string> mapPayload;
197         // 1 means stop action.
198         OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(code, 1, mapPayload);
199     }
200 
201     std::chrono::steady_clock::time_point lastRequestPerfTime_ = std::chrono::steady_clock::now();
202     bool windowMovingBoost_ = false;
203     bool windowDragBoost_ = false;
204 #endif
205 };
206 } // namespace Rosen
207 } // namespace OHOS
208 #endif // OHOS_ROSEN_RESSCHED_REPORT_H
209