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