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 #include "slide_recognizer.h"
16
17 #include <mutex>
18
19 #include "event_listener_mgr.h"
20 #include "ffrt_inner.h"
21 #include "plugin_mgr.h"
22 #include "res_common_util.h"
23 #include "res_sched_log.h"
24 #include "res_sched_mgr.h"
25 #include "res_type.h"
26
27 namespace OHOS {
28 namespace ResourceSchedule {
29 namespace {
30 static const std::string UP_SPEED_KEY = "up_speed";
31 static uint32_t g_slideState = SlideRecognizeStat::IDLE;
32 static ffrt::recursive_mutex stateMutex;
__anon9c329c500202(const nlohmann::json payload) 33 static auto g_reportListFlingLockedEnd = [](const nlohmann::json payload) {
34 std::lock_guard<ffrt::recursive_mutex> lock(stateMutex);
35 if (g_slideState != SlideRecognizeStat::LIST_FLING) {
36 return;
37 }
38 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_SLIDE_RECOGNIZE,
39 ResType::SlideEventStatus::SLIDE_EVENT_OFF, payload);
40 nlohmann::json extInfo;
41 EventListenerMgr::GetInstance().SendEvent(ResType::EventType::EVENT_DRAW_FRAME_REPORT,
42 ResType::EventValue::EVENT_VALUE_DRAW_FRAME_REPORT_STOP, extInfo);
43 g_slideState = SlideRecognizeStat::IDLE;
44 };
45 }
46
~SlideRecognizer()47 SlideRecognizer::~SlideRecognizer()
48 {
49 RESSCHED_LOGI("~UpdatingSceneRecognizer");
50 }
51
OnDispatchResource(uint32_t resType,int64_t value,const nlohmann::json & payload)52 void SlideRecognizer::OnDispatchResource(uint32_t resType, int64_t value, const nlohmann::json& payload)
53 {
54 switch (resType) {
55 case ResType::RES_TYPE_SLIDE_RECOGNIZE:
56 HandleSlideEvent(value, payload);
57 break;
58 case ResType::RES_TYPE_SEND_FRAME_EVENT:
59 HandleSendFrameEvent(FillRealPid(payload));
60 break;
61 case ResType::RES_TYPE_CLICK_RECOGNIZE:
62 HandleClickEvent(value, payload);
63 break;
64 default:
65 RESSCHED_LOGD("unkonw resType");
66 break;
67 }
68 }
69
HandleSlideEvent(int64_t value,const nlohmann::json & payload)70 void SlideRecognizer::HandleSlideEvent(int64_t value, const nlohmann::json& payload)
71 {
72 if (value == ResType::SlideEventStatus::SLIDE_EVENT_DETECTING) {
73 HandleSlideDetecting(payload);
74 } else if (value == ResType::SlideEventStatus::SLIDE_EVENT_ON) {
75 HandleListFlingStart(payload);
76 } else if (value == ResType::SlideEventStatus::SLIDE_EVENT_OFF) {
77 HandleSlideOFFEvent();
78 }
79 }
80
HandleSlideOFFEvent()81 void SlideRecognizer::HandleSlideOFFEvent()
82 {
83 std::lock_guard<ffrt::recursive_mutex> lock(stateMutex);
84 if (g_slideState == SlideRecognizeStat::SLIDE_NORMAL_DETECTING) {
85 return;
86 }
87 if (listFlingEndTask_) {
88 ffrt::skip(listFlingEndTask_);
89 }
90 if (listFlingTimeOutTask_) {
91 ffrt::skip(listFlingTimeOutTask_);
92 }
93 nlohmann::json extInfo;
94 EventListenerMgr::GetInstance().SendEvent(ResType::EventType::EVENT_DRAW_FRAME_REPORT,
95 ResType::EventValue::EVENT_VALUE_DRAW_FRAME_REPORT_STOP, extInfo);
96 g_slideState = SlideRecognizeStat::IDLE;
97 }
98
HandleSlideDetecting(const nlohmann::json & payload)99 void SlideRecognizer::HandleSlideDetecting(const nlohmann::json& payload)
100 {
101 if (g_slideState == SlideRecognizeStat::LIST_FLING) {
102 if (listFlingEndTask_) {
103 ffrt::skip(listFlingEndTask_);
104 }
105 if (listFlingTimeOutTask_) {
106 ffrt::skip(listFlingTimeOutTask_);
107 }
108 listFlingEndTask_ = nullptr;
109 listFlingTimeOutTask_ = nullptr;
110 g_reportListFlingLockedEnd(FillRealPid(payload));
111 }
112 nlohmann::json extInfo;
113 EventListenerMgr::GetInstance().SendEvent(ResType::EventType::EVENT_DRAW_FRAME_REPORT,
114 ResType::EventValue::EVENT_VALUE_DRAW_FRAME_REPORT_START, extInfo);
115 slideDetectingTime_ = ResCommonUtil::GetNowMillTime();
116 g_slideState = SlideRecognizeStat::SLIDE_NORMAL_DETECTING;
117 if (!payload.contains("clientPid") || !payload["clientPid"].is_string()) {
118 RESSCHED_LOGE("payload with no clientPid");
119 return;
120 }
121 slidePid_ = payload["clientPid"];
122 }
123
HandleListFlingStart(const nlohmann::json & payload)124 void SlideRecognizer::HandleListFlingStart(const nlohmann::json& payload)
125 {
126 std::lock_guard<ffrt::recursive_mutex> lock(stateMutex);
127 if (g_slideState == SlideRecognizeStat::LIST_FLING) {
128 return;
129 }
130 nlohmann::json extInfo;
131 EventListenerMgr::GetInstance().SendEvent(ResType::EventType::EVENT_DRAW_FRAME_REPORT,
132 ResType::EventValue::EVENT_VALUE_DRAW_FRAME_REPORT_START, extInfo);
133 g_slideState = SlideRecognizeStat::LIST_FLING;
134 if (listFlingEndTask_) {
135 ffrt::skip(listFlingEndTask_);
136 }
137 listFlingEndTask_ = ffrt::submit_h([payload]() {
138 g_reportListFlingLockedEnd(payload);
139 }, {}, {}, ffrt::task_attr().delay(listFlingEndTime_));
140 if (listFlingTimeOutTask_) {
141 ffrt::skip(listFlingTimeOutTask_);
142 }
143 listFlingTimeOutTask_ = ffrt::submit_h([payload]() {
144 g_reportListFlingLockedEnd(payload);
145 }, {}, {}, ffrt::task_attr().delay(listFlingTimeOutTime_));
146 }
147
HandleSendFrameEvent(const nlohmann::json & payload)148 void SlideRecognizer::HandleSendFrameEvent(const nlohmann::json& payload)
149 {
150 std::lock_guard<ffrt::recursive_mutex> lock(stateMutex);
151 if (g_slideState == SlideRecognizeStat::SLIDE_NORMAL_DETECTING) {
152 int64_t nowTime = ResCommonUtil::GetNowMillTime();
153 if (nowTime - slideDetectingTime_ < slideNormalDecectingTime_) {
154 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_SLIDE_RECOGNIZE,
155 ResType::SlideEventStatus::SLIDE_NORMAL_BEGIN, payload);
156 g_slideState = SlideRecognizeStat::SLIDE_NORMAL;
157 } else {
158 g_slideState = SlideRecognizeStat::IDLE;
159 }
160 nlohmann::json extInfo;
161 EventListenerMgr::GetInstance().SendEvent(ResType::EventType::EVENT_DRAW_FRAME_REPORT,
162 ResType::EventValue::EVENT_VALUE_DRAW_FRAME_REPORT_STOP, extInfo);
163 } else if (g_slideState == SlideRecognizeStat::LIST_FLING) {
164 if (listFlingEndTask_) {
165 ffrt::skip(listFlingEndTask_);
166 }
167 listFlingEndTask_ = ffrt::submit_h([payload]() {
168 g_reportListFlingLockedEnd(payload);
169 }, {}, {}, ffrt::task_attr().delay(listFlingEndTime_));
170 }
171 }
172
HandleClickEvent(int64_t value,const nlohmann::json & payload)173 void SlideRecognizer::HandleClickEvent(int64_t value, const nlohmann::json& payload)
174 {
175 std::lock_guard<ffrt::recursive_mutex> lock(stateMutex);
176 //not in slide stat
177 if (g_slideState != SlideRecognizeStat::SLIDE_NORMAL) {
178 return;
179 }
180 // receive up event, silde normal end
181 if (value == ResType::ClickEventType::TOUCH_EVENT_UP ||
182 value == ResType::ClickEventType::TOUCH_EVENT_PULL_UP) {
183 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_SLIDE_RECOGNIZE,
184 ResType::SlideEventStatus::SLIDE_NORMAL_END, payload);
185 float upSpeed = 0.0;
186 if (!payload.contains("clientPid") || !payload["clientPid"].is_string()) {
187 RESSCHED_LOGE("payload with no clientPid");
188 return;
189 }
190 slidePid_ = payload["clientPid"];
191 if (!payload.contains(UP_SPEED_KEY) || !payload[UP_SPEED_KEY].is_string()) {
192 return;
193 }
194 // if up speed large than LIST_FLING_SPEED_LIMIT,start recognize list fling.
195 if (ResCommonUtil::StrToFloat(payload[UP_SPEED_KEY], upSpeed) && upSpeed > listFlingSpeedLimit_) {
196 nlohmann::json extInfo;
197 EventListenerMgr::GetInstance().SendEvent(ResType::EventType::EVENT_DRAW_FRAME_REPORT,
198 ResType::EventValue::EVENT_VALUE_DRAW_FRAME_REPORT_START, extInfo);
199 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_SLIDE_RECOGNIZE,
200 ResType::SlideEventStatus::SLIDE_EVENT_ON, payload);
201 }
202 }
203 }
204
FillRealPid(const nlohmann::json & payload)205 nlohmann::json SlideRecognizer::FillRealPid(const nlohmann::json& payload)
206 {
207 if (slidePid_.empty()) {
208 return payload;
209 }
210 nlohmann::json payloadM = payload;
211 payloadM["clientPid"] = slidePid_;
212 return payloadM;
213 }
214
SetListFlingTimeoutTime(int64_t value)215 void SlideRecognizer::SetListFlingTimeoutTime(int64_t value)
216 {
217 listFlingTimeOutTime_ = value;
218 }
219
SetListFlingEndTime(int64_t value)220 void SlideRecognizer::SetListFlingEndTime(int64_t value)
221 {
222 listFlingEndTime_ = value;
223 }
224
SetListFlingSpeedLimit(float value)225 void SlideRecognizer::SetListFlingSpeedLimit(float value)
226 {
227 listFlingSpeedLimit_ = value;
228 }
229
SetSlideNormalDetectingTime(int64_t value)230 void SlideRecognizer::SetSlideNormalDetectingTime(int64_t value)
231 {
232 slideNormalDecectingTime_ = value;
233 }
234 } // namespace ResourceSchedule
235 } // namespace OHOS