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_adapter.h"
17
18 #include "input_event_handler.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 "TouchGestureAdapter"
24
25 namespace OHOS {
26 namespace MMI {
TouchGestureAdapter(TouchGestureType type,std::shared_ptr<TouchGestureAdapter> next)27 TouchGestureAdapter::TouchGestureAdapter(TouchGestureType type, std::shared_ptr<TouchGestureAdapter> next)
28 : gestureType_(type), nextAdapter_(next)
29 {}
30
SetGestureCondition(bool flag,TouchGestureType type,int32_t fingers)31 void TouchGestureAdapter::SetGestureCondition(bool flag, TouchGestureType type, int32_t fingers)
32 {
33 if ((gestureDetector_ != nullptr) && ((type & gestureType_) == gestureType_)) {
34 if (flag) {
35 gestureDetector_->AddGestureFingers(fingers);
36 } else {
37 gestureDetector_->RemoveGestureFingers(fingers);
38 }
39 }
40 if (nextAdapter_ != nullptr) {
41 nextAdapter_->SetGestureCondition(flag, type, fingers);
42 }
43 }
44
process(std::shared_ptr<PointerEvent> event)45 void TouchGestureAdapter::process(std::shared_ptr<PointerEvent> event)
46 {
47 LogTouchEvent(event);
48 OnTouchEvent(event);
49 if (ShouldDeliverToNext() && nextAdapter_ != nullptr) {
50 nextAdapter_->process(event);
51 }
52 }
53
HandleGestureWindowEmerged(int32_t windowId,std::shared_ptr<PointerEvent> lastTouchEvent)54 void TouchGestureAdapter::HandleGestureWindowEmerged(int32_t windowId, std::shared_ptr<PointerEvent> lastTouchEvent)
55 {
56 if (gestureDetector_ != nullptr) {
57 gestureDetector_->HandleGestureWindowEmerged(windowId, lastTouchEvent);
58 }
59 if (nextAdapter_ != nullptr) {
60 nextAdapter_->HandleGestureWindowEmerged(windowId, lastTouchEvent);
61 }
62 }
63
Init()64 void TouchGestureAdapter::Init()
65 {
66 if (gestureDetector_ == nullptr) {
67 gestureDetector_ = std::make_shared<TouchGestureDetector>(gestureType_, shared_from_this());
68 }
69 if (nextAdapter_ != nullptr) {
70 nextAdapter_->Init();
71 }
72 }
73
LogTouchEvent(std::shared_ptr<PointerEvent> event) const74 void TouchGestureAdapter::LogTouchEvent(std::shared_ptr<PointerEvent> event) const
75 {
76 CHKPV(event);
77 if (event->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
78 return;
79 }
80 switch (event->GetPointerAction()) {
81 case PointerEvent::POINTER_ACTION_DOWN:
82 case PointerEvent::POINTER_ACTION_UP:
83 case PointerEvent::POINTER_ACTION_CANCEL:
84 case PointerEvent::POINTER_ACTION_PULL_UP: {
85 break;
86 }
87 default: {
88 return;
89 }
90 }
91 auto pointers = event->GetPointerIds();
92 std::ostringstream sTouches;
93 sTouches << "(";
94
95 if (auto iter = pointers.cbegin(); iter != pointers.cend()) {
96 sTouches << *iter;
97 for (++iter; iter != pointers.cend(); ++iter) {
98 sTouches << "," << *iter;
99 }
100 }
101 sTouches << ")";
102 MMI_HILOGI("GestureType:%{public}u,No:%{public}d,PA:%{public}s,PI:%{public}d,Touches:%{public}s",
103 gestureType_, event->GetId(), event->DumpPointerAction(), event->GetPointerId(),
104 std::move(sTouches).str().c_str());
105 }
106
GetGestureFactory()107 std::shared_ptr<TouchGestureAdapter> TouchGestureAdapter::GetGestureFactory()
108 {
109 std::shared_ptr<TouchGestureAdapter> pinch =
110 std::make_shared<TouchGestureAdapter>(TOUCH_GESTURE_TYPE_PINCH, nullptr);
111 std::shared_ptr<TouchGestureAdapter> swipe =
112 std::make_shared<TouchGestureAdapter>(TOUCH_GESTURE_TYPE_SWIPE, pinch);
113 swipe->Init();
114 return swipe;
115 }
116
OnTouchEvent(std::shared_ptr<PointerEvent> event)117 void TouchGestureAdapter::OnTouchEvent(std::shared_ptr<PointerEvent> event)
118 {
119 CHKPV(event);
120 CHKPV(gestureDetector_);
121 if (event->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
122 return;
123 }
124 shouldDeliverToNext_ = true;
125
126 if (gestureType_ == TOUCH_GESTURE_TYPE_SWIPE) {
127 OnSwipeGesture(event);
128 } else if (gestureType_ == TOUCH_GESTURE_TYPE_PINCH) {
129 OnPinchGesture(event);
130 }
131 if (gestureStarted_ && (event->GetPointerAction() == PointerEvent::POINTER_ACTION_MOVE)) {
132 shouldDeliverToNext_ = false;
133 }
134 }
135
OnSwipeGesture(std::shared_ptr<PointerEvent> event)136 void TouchGestureAdapter::OnSwipeGesture(std::shared_ptr<PointerEvent> event)
137 {
138 CHKPV(gestureDetector_);
139 if ((state_ == GestureState::PINCH) && (event->GetPointerAction() == PointerEvent::POINTER_ACTION_MOVE)) {
140 return;
141 }
142 gestureStarted_ = gestureDetector_->OnTouchEvent(event);
143 state_ = gestureStarted_ ? GestureState::SWIPE : GestureState::IDLE;
144 }
145
OnPinchGesture(std::shared_ptr<PointerEvent> event)146 void TouchGestureAdapter::OnPinchGesture(std::shared_ptr<PointerEvent> event)
147 {
148 CHKPV(gestureDetector_);
149 if ((state_ == GestureState::SWIPE) && (event->GetPointerAction() == PointerEvent::POINTER_ACTION_MOVE)) {
150 return;
151 }
152 gestureStarted_ = gestureDetector_->OnTouchEvent(event);
153 state_ = gestureStarted_ ? GestureState::PINCH : GestureState::IDLE;
154 }
155
OnGestureEvent(std::shared_ptr<PointerEvent> event,GestureMode mode)156 bool TouchGestureAdapter::OnGestureEvent(std::shared_ptr<PointerEvent> event, GestureMode mode)
157 {
158 #ifdef OHOS_BUILD_ENABLE_MONITOR
159 auto pointEvent = std::make_shared<PointerEvent>(*event);
160 pointEvent->UpdateId();
161 pointEvent->SetHandlerEventType(HANDLE_EVENT_TYPE_TOUCH_GESTURE);
162 switch (mode) {
163 case GestureMode::ACTION_SWIPE_DOWN:
164 pointEvent->SetPointerAction(PointerEvent::TOUCH_ACTION_SWIPE_DOWN);
165 break;
166 case GestureMode::ACTION_SWIPE_UP:
167 pointEvent->SetPointerAction(PointerEvent::TOUCH_ACTION_SWIPE_UP);
168 break;
169 case GestureMode::ACTION_SWIPE_LEFT:
170 pointEvent->SetPointerAction(PointerEvent::TOUCH_ACTION_SWIPE_LEFT);
171 break;
172 case GestureMode::ACTION_SWIPE_RIGHT:
173 pointEvent->SetPointerAction(PointerEvent::TOUCH_ACTION_SWIPE_RIGHT);
174 break;
175 case GestureMode::ACTION_PINCH_CLOSED:
176 pointEvent->SetPointerAction(PointerEvent::TOUCH_ACTION_PINCH_CLOSEED);
177 break;
178 case GestureMode::ACTION_PINCH_OPENED:
179 pointEvent->SetPointerAction(PointerEvent::TOUCH_ACTION_PINCH_OPENED);
180 break;
181 case GestureMode::ACTION_GESTURE_END:
182 pointEvent->SetPointerAction(PointerEvent::TOUCH_ACTION_GESTURE_END);
183 break;
184 default:
185 MMI_HILOGW("unknow mode:%{public}d", mode);
186 return false;
187 }
188 auto monitor = InputHandler->GetMonitorHandler();
189 CHKPF(monitor);
190 monitor->HandlePointerEvent(pointEvent);
191 #endif // OHOS_BUILD_ENABLE_MONITOR
192 return true;
193 }
194
OnGestureTrend(std::shared_ptr<PointerEvent> event)195 void TouchGestureAdapter::OnGestureTrend(std::shared_ptr<PointerEvent> event)
196 {
197 WIN_MGR->CancelAllTouches(event);
198 }
199 } // namespace MMI
200 } // namespace OHOS