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 #include "util.h"
20
21 #undef MMI_LOG_DOMAIN
22 #define MMI_LOG_DOMAIN MMI_LOG_HANDLER
23 #undef MMI_LOG_TAG
24 #define MMI_LOG_TAG "TouchGestureAdapter"
25
26 namespace OHOS {
27 namespace MMI {
TouchGestureAdapter(TouchGestureType type, std::shared_ptr<TouchGestureAdapter> next)28 TouchGestureAdapter::TouchGestureAdapter(TouchGestureType type, std::shared_ptr<TouchGestureAdapter> next)
29 : gestureType_(type), nextAdapter_(next)
30 {}
31
SetGestureCondition(bool flag, TouchGestureType type, int32_t fingers)32 void TouchGestureAdapter::SetGestureCondition(bool flag, TouchGestureType type, int32_t fingers)
33 {
34 static bool isAll = false;
35 if (gestureDetector_ != nullptr &&
36 (type == gestureType_ || type == TOUCH_GESTURE_TYPE_ALL)) {
37 if (type == TOUCH_GESTURE_TYPE_ALL) {
38 isAll = flag;
39 }
40 if (flag) {
41 gestureDetector_->AddGestureFingers(fingers);
42 }
43 if (!flag && !isAll) {
44 gestureDetector_->RemoveGestureFingers(fingers);
45 }
46 }
47 if (nextAdapter_ != nullptr) {
48 nextAdapter_->SetGestureCondition(flag, type, fingers);
49 }
50 }
51
process(std::shared_ptr<PointerEvent> event)52 void TouchGestureAdapter::process(std::shared_ptr<PointerEvent> event)
53 {
54 OnTouchEvent(event);
55 if (ShouldDeliverToNext() && nextAdapter_ != nullptr) {
56 nextAdapter_->process(event);
57 }
58 }
59
Init()60 void TouchGestureAdapter::Init()
61 {
62 if (gestureDetector_ == nullptr) {
63 gestureDetector_ = std::make_shared<TouchGestureDetector>(gestureType_, shared_from_this());
64 }
65 if (nextAdapter_ != nullptr) {
66 nextAdapter_->Init();
67 }
68 }
69
GetGestureFactory()70 std::shared_ptr<TouchGestureAdapter> TouchGestureAdapter::GetGestureFactory()
71 {
72 std::shared_ptr<TouchGestureAdapter> pinch =
73 std::make_shared<TouchGestureAdapter>(TOUCH_GESTURE_TYPE_PINCH, nullptr);
74 std::shared_ptr<TouchGestureAdapter> swipe =
75 std::make_shared<TouchGestureAdapter>(TOUCH_GESTURE_TYPE_SWIPE, pinch);
76 swipe->Init();
77 return swipe;
78 }
79
OnTouchEvent(std::shared_ptr<PointerEvent> event)80 void TouchGestureAdapter::OnTouchEvent(std::shared_ptr<PointerEvent> event)
81 {
82 CHKPV(event);
83 CHKPV(gestureDetector_);
84 if (event->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
85 return;
86 }
87 int32_t action = event->GetPointerAction();
88 if (!gestureStarted_ && action == PointerEvent::POINTER_ACTION_DOWN) {
89 hasCancel_ = false;
90 }
91 shouldDeliverToNext_ = true;
92 if (!gestureStarted_ && action == PointerEvent::POINTER_ACTION_UP) {
93 gestureDetector_->OnTouchEvent(event);
94 return;
95 }
96 if (gestureType_ == TOUCH_GESTURE_TYPE_SWIPE) {
97 OnSwipeGesture(event);
98 } else if (gestureType_ == TOUCH_GESTURE_TYPE_PINCH) {
99 OnPinchGesture(event);
100 }
101 if (gestureStarted_ && !hasCancel_ && state_ != GestureState::IDLE) {
102 hasCancel_ = true;
103 OnGestureSuccessful(event);
104 }
105 if (gestureStarted_ && action == PointerEvent::POINTER_ACTION_MOVE) {
106 shouldDeliverToNext_ = false;
107 }
108 }
109
OnGestureSuccessful(std::shared_ptr<PointerEvent> event)110 void TouchGestureAdapter::OnGestureSuccessful(std::shared_ptr<PointerEvent> event)
111 {
112 CHKPV(event);
113 MMI_HILOGI("type:%{public}d,state:%{public}d", gestureType_, state_);
114 auto items = event->GetAllPointerItems();
115 for (const auto &item : items) {
116 if (!item.IsPressed()) {
117 continue;
118 }
119 int32_t pointerId = item.GetPointerId();
120 auto pointerEvent = std::make_shared<PointerEvent>(*event);
121 pointerEvent->SetPointerId(pointerId);
122 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_CANCEL);
123 pointerEvent->SetActionTime(GetSysClockTime());
124 pointerEvent->UpdateId();
125 pointerEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT | InputEvent::EVENT_FLAG_NO_MONITOR);
126 auto eventDispatchHandler = InputHandler->GetEventDispatchHandler();
127 CHKPV(eventDispatchHandler);
128 eventDispatchHandler->HandlePointerEvent(pointerEvent);
129 }
130 }
131
OnSwipeGesture(std::shared_ptr<PointerEvent> event)132 void TouchGestureAdapter::OnSwipeGesture(std::shared_ptr<PointerEvent> event)
133 {
134 CHKPV(gestureDetector_);
135 if (state_ == GestureState::PINCH) {
136 return;
137 }
138 gestureStarted_ = gestureDetector_->OnTouchEvent(event);
139 state_ = gestureStarted_ ? GestureState::SWIPE : GestureState::IDLE;
140 }
141
OnPinchGesture(std::shared_ptr<PointerEvent> event)142 void TouchGestureAdapter::OnPinchGesture(std::shared_ptr<PointerEvent> event)
143 {
144 CHKPV(gestureDetector_);
145 if (state_ == GestureState::SWIPE) {
146 return;
147 }
148 gestureStarted_ = gestureDetector_->OnTouchEvent(event);
149 state_ = gestureStarted_ ? GestureState::PINCH : GestureState::IDLE;
150 }
151
OnGestureEvent(std::shared_ptr<PointerEvent> event, GestureMode mode)152 bool TouchGestureAdapter::OnGestureEvent(std::shared_ptr<PointerEvent> event, GestureMode mode)
153 {
154 #ifdef OHOS_BUILD_ENABLE_MONITOR
155 auto pointEvent = std::make_shared<PointerEvent>(*event);
156 pointEvent->SetHandlerEventType(HANDLE_EVENT_TYPE_TOUCH_GESTURE);
157 switch (mode) {
158 case GestureMode::ACTION_SWIPE_DOWN:
159 pointEvent->SetPointerAction(PointerEvent::TOUCH_ACTION_SWIPE_DOWN);
160 break;
161 case GestureMode::ACTION_SWIPE_UP:
162 pointEvent->SetPointerAction(PointerEvent::TOUCH_ACTION_SWIPE_UP);
163 break;
164 case GestureMode::ACTION_SWIPE_LEFT:
165 pointEvent->SetPointerAction(PointerEvent::TOUCH_ACTION_SWIPE_LEFT);
166 break;
167 case GestureMode::ACTION_SWIPE_RIGHT:
168 pointEvent->SetPointerAction(PointerEvent::TOUCH_ACTION_SWIPE_RIGHT);
169 break;
170 case GestureMode::ACTION_PINCH_CLOSED:
171 pointEvent->SetPointerAction(PointerEvent::TOUCH_ACTION_PINCH_CLOSEED);
172 break;
173 case GestureMode::ACTION_PINCH_OPENED:
174 pointEvent->SetPointerAction(PointerEvent::TOUCH_ACTION_PINCH_OPENED);
175 break;
176 case GestureMode::ACTION_GESTURE_END:
177 pointEvent->SetPointerAction(PointerEvent::TOUCH_ACTION_GESTURE_END);
178 break;
179 default:
180 MMI_HILOGW("unknow mode:%{public}d", mode);
181 return false;
182 }
183 auto monitor = InputHandler->GetMonitorHandler();
184 CHKPF(monitor);
185 monitor->HandlePointerEvent(pointEvent);
186 #endif // OHOS_BUILD_ENABLE_MONITOR
187 return true;
188 }
189 } // namespace MMI
190 } // namespace OHOS