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 "touch_gesture_manager.h"
17
18 #include "key_command_handler_util.h"
19
20 #undef MMI_LOG_DOMAIN
21 #define MMI_LOG_DOMAIN MMI_LOG_HANDLER
22 #undef MMI_LOG_TAG
23 #define MMI_LOG_TAG "TouchGestureManager"
24
25 namespace OHOS {
26 namespace MMI {
27 namespace {
28 const char* TOUCH_GESTURE_RECOGNIZER_NAME { "touchGesture" };
29 }
30
TouchGestureManager(std::shared_ptr<DelegateInterface> delegate)31 TouchGestureManager::TouchGestureManager(std::shared_ptr<DelegateInterface> delegate)
32 : delegate_(delegate)
33 {
34 touchGesture_ = TouchGestureAdapter::GetGestureFactory();
35 SetupSessionObserver();
36 }
37
~TouchGestureManager()38 TouchGestureManager::~TouchGestureManager()
39 {
40 RemoveAllHandlers();
41 }
42
AddHandler(int32_t session,TouchGestureType gestureType,int32_t nFingers)43 void TouchGestureManager::AddHandler(int32_t session, TouchGestureType gestureType, int32_t nFingers)
44 {
45 if (!GestureMonitorHandler::CheckMonitorValid(gestureType, nFingers)) {
46 MMI_HILOGE("Unsupported touch gesture (GestureType:%{public}d, FingerNo:%{public}d)",
47 static_cast<int32_t>(gestureType), nFingers);
48 return;
49 }
50 Handler handler {
51 .session_ = session,
52 .gesture_ = gestureType,
53 .nFingers_ = nFingers,
54 };
55 if (handlers_.find(handler) != handlers_.cend()) {
56 return;
57 }
58 MMI_HILOGI("Start monitoring touch gesture(Session:%{public}d, Gesture:%{public}u, nFingers:%{public}d)",
59 session, gestureType, nFingers);
60 StartRecognization(gestureType, nFingers);
61 handlers_.emplace(handler);
62 }
63
RemoveHandler(int32_t session,TouchGestureType gestureType,int32_t nFingers)64 void TouchGestureManager::RemoveHandler(int32_t session, TouchGestureType gestureType, int32_t nFingers)
65 {
66 Handler handler {
67 .session_ = session,
68 .gesture_ = gestureType,
69 .nFingers_ = nFingers,
70 };
71 auto iter = handlers_.find(handler);
72 if (iter == handlers_.cend()) {
73 return;
74 }
75 handlers_.erase(iter);
76 MMI_HILOGI("Stop monitoring touch gesture(Session:%{public}d, Gesture:%{public}u, nFingers:%{public}d)",
77 session, gestureType, nFingers);
78 StopRecognization(gestureType, nFingers);
79 }
80
HandleGestureWindowEmerged(int32_t windowId,std::shared_ptr<PointerEvent> lastTouchEvent)81 void TouchGestureManager::HandleGestureWindowEmerged(int32_t windowId, std::shared_ptr<PointerEvent> lastTouchEvent)
82 {
83 CHKPV(touchGesture_);
84 touchGesture_->HandleGestureWindowEmerged(windowId, lastTouchEvent);
85 }
86
StartRecognization(TouchGestureType gestureType,int32_t nFingers)87 void TouchGestureManager::StartRecognization(TouchGestureType gestureType, int32_t nFingers)
88 {
89 auto iter = std::find_if(handlers_.cbegin(), handlers_.cend(),
90 [gestureType, nFingers](const auto &handler) {
91 return ((handler.gesture_ == gestureType) && (handler.nFingers_ == nFingers));
92 });
93 if (iter != handlers_.cend()) {
94 return;
95 }
96 MMI_HILOGI("Start recognizing touch gesture(Gesture:%{public}u, nFingers:%{public}d)", gestureType, nFingers);
97 CHKPV(touchGesture_);
98 touchGesture_->SetGestureCondition(true, gestureType, nFingers);
99
100 auto delegate = delegate_.lock();
101 CHKPV(delegate);
102 if (delegate->HasHandler(TOUCH_GESTURE_RECOGNIZER_NAME)) {
103 return;
104 }
105 MMI_HILOGI("Start touch gesture recognization");
106 auto callback = [touchGesture = touchGesture_](std::shared_ptr<PointerEvent> event) -> int32_t {
107 CHKPR(touchGesture, ERROR_NULL_POINTER);
108 touchGesture->process(event);
109 return RET_OK;
110 };
111 auto ret = delegate->AddHandler(
112 InputHandlerType::MONITOR,
113 DelegateInterface::HandlerSummary {
114 .handlerName = TOUCH_GESTURE_RECOGNIZER_NAME,
115 .eventType = HANDLE_EVENT_TYPE_POINTER,
116 .mode = HandlerMode::SYNC,
117 .cb = callback,
118 });
119 if (ret != RET_OK) {
120 MMI_HILOGE("Failed to add gesture recognizer, ret:%{public}d", ret);
121 }
122 }
123
StopRecognization(TouchGestureType gestureType,int32_t nFingers)124 void TouchGestureManager::StopRecognization(TouchGestureType gestureType, int32_t nFingers)
125 {
126 auto iter = std::find_if(handlers_.cbegin(), handlers_.cend(),
127 [gestureType, nFingers](const auto &handler) {
128 return ((handler.gesture_ == gestureType) && (handler.nFingers_ == nFingers));
129 });
130 if (iter != handlers_.cend()) {
131 return;
132 }
133 MMI_HILOGI("Stop recognizing touch gesture(Gesture:%{public}u, nFingers:%{public}d)", gestureType, nFingers);
134 CHKPV(touchGesture_);
135 touchGesture_->SetGestureCondition(false, gestureType, nFingers);
136
137 if (!handlers_.empty()) {
138 return;
139 }
140 MMI_HILOGI("Stop touch gesture recognization");
141 auto delegate = delegate_.lock();
142 CHKPV(delegate);
143 delegate->RemoveHandler(InputHandlerType::MONITOR, TOUCH_GESTURE_RECOGNIZER_NAME);
144 }
145
RemoveAllHandlers()146 void TouchGestureManager::RemoveAllHandlers()
147 {
148 for (auto iter = handlers_.cbegin(); iter != handlers_.cend(); iter = handlers_.cbegin()) {
149 RemoveHandler(iter->session_, iter->gesture_, iter->nFingers_);
150 }
151 }
152
SetupSessionObserver()153 void TouchGestureManager::SetupSessionObserver()
154 {
155 auto udsServerPtr = InputHandler->GetUDSServer();
156 CHKPV(udsServerPtr);
157 udsServerPtr->AddSessionDeletedCallback([this](SessionPtr session) {
158 CHKPV(session);
159 OnSessionLost(session->GetPid());
160 });
161 }
162
OnSessionLost(int32_t session)163 void TouchGestureManager::OnSessionLost(int32_t session)
164 {
165 MMI_HILOGI("Clear handlers related to lost session(%{public}d)", session);
166 std::set<Handler> handlers;
167
168 std::for_each(handlers_.cbegin(), handlers_.cend(),
169 [session, &handlers](const auto &handler) {
170 if (handler.session_ == session) {
171 handlers.emplace(handler);
172 }
173 });
174 std::for_each(handlers.cbegin(), handlers.cend(),
175 [this](const auto &handler) {
176 MMI_HILOGI("Remove handler(%{public}u, %{public}d) related to lost session(%{public}d)",
177 handler.gesture_, handler.nFingers_, handler.session_);
178 RemoveHandler(handler.session_, handler.gesture_, handler.nFingers_);
179 });
180 }
181 } // namespace MMI
182 } // namespace OHOS