1 /*
2  * Copyright (c) 2021-2022 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 "input_event_handler.h"
17 
18 #include <cinttypes>
19 #include <cstdio>
20 #include <cstring>
21 #include <functional>
22 #include <vector>
23 
24 #include <sys/stat.h>
25 #include <unistd.h>
26 
27 #include "libinput.h"
28 #include "key_command_handler.h"
29 #include "timer_manager.h"
30 #include "util.h"
31 
32 #undef MMI_LOG_DOMAIN
33 #define MMI_LOG_DOMAIN MMI_LOG_HANDLER
34 #undef MMI_LOG_TAG
35 #define MMI_LOG_TAG "InputEventHandler"
36 
37 namespace OHOS {
38 namespace MMI {
39 namespace {
40 constexpr int32_t MT_TOOL_PALM { 2 };
41 } // namespace
42 
InputEventHandler()43 InputEventHandler::InputEventHandler()
44 {
45     lastEventBeginTime_ = GetSysClockTime();
46     udsServer_ = nullptr;
47 }
48 
~InputEventHandler()49 InputEventHandler::~InputEventHandler() {}
50 
Init(UDSServer & udsServer)51 void InputEventHandler::Init(UDSServer& udsServer)
52 {
53     udsServer_ = &udsServer;
54     BuildInputHandlerChain();
55 }
56 
OnEvent(void * event,int64_t frameTime)57 void InputEventHandler::OnEvent(void *event, int64_t frameTime)
58 {
59     CHKPV(eventNormalizeHandler_);
60     if (event == nullptr) {
61         eventNormalizeHandler_->HandleEvent(nullptr, frameTime);
62         return;
63     }
64 
65     idSeed_ += 1;
66     const uint64_t maxUInt64 = (std::numeric_limits<uint64_t>::max)() - 1;
67     if (idSeed_ >= maxUInt64) {
68         MMI_HILOGE("The value is flipped. id:%{public}" PRId64, idSeed_);
69         idSeed_ = 1;
70     }
71 
72     auto *lpEvent = static_cast<libinput_event *>(event);
73     CHKPV(lpEvent);
74     int32_t eventType = libinput_event_get_type(lpEvent);
75     int64_t beginTime = GetSysClockTime();
76     lastEventBeginTime_ = beginTime;
77     MMI_HILOGD("Event reporting. id:%{public}" PRId64 ",tid:%{public}" PRId64 ",eventType:%{public}d,"
78                "beginTime:%{public}" PRId64, idSeed_, GetThisThreadId(), eventType, beginTime);
79     if (IsTouchpadMistouch(lpEvent)) {
80         return;
81     }
82     ResetLogTrace();
83     eventNormalizeHandler_->HandleEvent(lpEvent, frameTime);
84     int64_t endTime = GetSysClockTime();
85     int64_t lostTime = endTime - beginTime;
86     MMI_HILOGD("Event handling completed. id:%{public}" PRId64 ",endTime:%{public}" PRId64
87                ",lostTime:%{public}" PRId64, idSeed_, endTime, lostTime);
88 }
89 
IsTouchpadMistouch(libinput_event * event)90 bool InputEventHandler::IsTouchpadMistouch(libinput_event* event)
91 {
92     CHKPF(event);
93     auto touchpad = libinput_event_get_touchpad_event(event);
94     if (touchpad != nullptr) {
95         int32_t toolType = libinput_event_touchpad_get_tool_type(touchpad);
96         if (toolType == MT_TOOL_PALM) {
97             MMI_HILOGD("Touchpad event is palm");
98             return false;
99         }
100     }
101 
102     auto type = libinput_event_get_type(event);
103     if (type == LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
104         MMI_HILOGD("Touchpad event is button");
105         return false;
106     }
107 
108     if (type == LIBINPUT_EVENT_POINTER_TAP) {
109         auto isTapMistouch = IsTouchpadTapMistouch(event);
110         return isTapMistouch;
111     }
112 
113     if (type == LIBINPUT_EVENT_KEYBOARD_KEY) {
114         isTyping_ = true;
115         if (TimerMgr->IsExist(timerId_)) {
116             TimerMgr->ResetTimer(timerId_);
117         } else {
118             static constexpr int32_t timeout = 400;
119             std::weak_ptr<InputEventHandler> weakPtr = shared_from_this();
120             timerId_ = TimerMgr->AddTimer(timeout, 1, [weakPtr]() {
121                 CALL_DEBUG_ENTER;
122                 auto sharedPtr = weakPtr.lock();
123                 CHKPV(sharedPtr);
124                 MMI_HILOGD("Mistouch timer:%{public}d", sharedPtr->timerId_);
125                 sharedPtr->timerId_ = -1;
126                 sharedPtr->isTyping_ = false;
127             });
128         }
129     }
130     if (isTyping_ && (type == LIBINPUT_EVENT_POINTER_MOTION_TOUCHPAD || type == LIBINPUT_EVENT_TOUCHPAD_MOTION)) {
131         MMI_HILOGD("The touchpad event is mistouch");
132         return true;
133     }
134     return false;
135 }
136 
IsTouchpadTapMistouch(libinput_event * event)137 bool InputEventHandler::IsTouchpadTapMistouch(libinput_event* event)
138 {
139     CHKPF(event);
140     auto data = libinput_event_get_pointer_event(event);
141     CHKPF(data);
142     auto state = libinput_event_pointer_get_button_state(data);
143     if (state == LIBINPUT_BUTTON_STATE_PRESSED) {
144         if (isTyping_) {
145             isTapMistouch_ = true;
146             MMI_HILOGD("The tapPressed event is mistouch");
147             return true;
148         }
149     }
150     if (state == LIBINPUT_BUTTON_STATE_RELEASED) {
151         if (isTapMistouch_) {
152             isTapMistouch_ = false;
153             MMI_HILOGD("The tapReleased event is mistouch");
154             return true;
155         }
156     }
157     return false;
158 }
159 
BuildInputHandlerChain()160 int32_t InputEventHandler::BuildInputHandlerChain()
161 {
162     eventNormalizeHandler_ = std::make_shared<EventNormalizeHandler>();
163 #if !defined(OHOS_BUILD_ENABLE_KEYBOARD) && !defined(OHOS_BUILD_ENABLE_POINTER) && !defined(OHOS_BUILD_ENABLE_TOUCH)
164     return RET_OK;
165 #endif // !OHOS_BUILD_ENABLE_KEYBOARD && !OHOS_BUILD_ENABLE_POINTER && !OHOS_BUILD_ENABLE_TOUCH
166 
167     std::shared_ptr<IInputEventHandler> handler = eventNormalizeHandler_;
168 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
169     eventFilterHandler_ = std::make_shared<EventFilterHandler>();
170     handler->SetNext(eventFilterHandler_);
171     handler = eventFilterHandler_;
172 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
173 
174 #ifdef OHOS_BUILD_ENABLE_INTERCEPTOR
175     eventInterceptorHandler_ = std::make_shared<EventInterceptorHandler>();
176     handler->SetNext(eventInterceptorHandler_);
177     handler = eventInterceptorHandler_;
178 #endif // OHOS_BUILD_ENABLE_INTERCEPTOR
179 
180 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
181 #ifdef OHOS_BUILD_ENABLE_COMBINATION_KEY
182     eventKeyCommandHandler_ = std::make_shared<KeyCommandHandler>();
183     handler->SetNext(eventKeyCommandHandler_);
184     handler = eventKeyCommandHandler_;
185 #endif // OHOS_BUILD_ENABLE_COMBINATION_KEY
186     eventSubscriberHandler_ = std::make_shared<KeySubscriberHandler>();
187     handler->SetNext(eventSubscriberHandler_);
188     handler = eventSubscriberHandler_;
189 #endif // OHOS_BUILD_ENABLE_KEYBOARD
190 #ifdef OHOS_BUILD_ENABLE_SWITCH
191     switchEventSubscriberHandler_ = std::make_shared<SwitchSubscriberHandler>();
192     handler->SetNext(switchEventSubscriberHandler_);
193     handler = switchEventSubscriberHandler_;
194 #endif // OHOS_BUILD_ENABLE_SWITCH
195 #ifdef OHOS_BUILD_ENABLE_MONITOR
196     eventMonitorHandler_ = std::make_shared<EventMonitorHandler>();
197     handler->SetNext(eventMonitorHandler_);
198     handler = eventMonitorHandler_;
199 #endif // OHOS_BUILD_ENABLE_MONITOR
200     eventDispatchHandler_ = std::make_shared<EventDispatchHandler>();
201     handler->SetNext(eventDispatchHandler_);
202     return RET_OK;
203 }
204 
GetIntervalSinceLastInput(int64_t & timeInterval)205 int32_t InputEventHandler::GetIntervalSinceLastInput(int64_t &timeInterval)
206 {
207     int64_t currentSystemTime = GetSysClockTime();
208     timeInterval = currentSystemTime - lastEventBeginTime_;
209     return RET_OK;
210 }
211 
GetUDSServer() const212 UDSServer* InputEventHandler::GetUDSServer() const
213 {
214     return udsServer_;
215 }
216 
GetEventNormalizeHandler() const217 std::shared_ptr<EventNormalizeHandler> InputEventHandler::GetEventNormalizeHandler() const
218 {
219     return eventNormalizeHandler_;
220 }
221 
GetInterceptorHandler() const222 std::shared_ptr<EventInterceptorHandler> InputEventHandler::GetInterceptorHandler() const
223 {
224     return eventInterceptorHandler_;
225 }
226 
GetSubscriberHandler() const227 std::shared_ptr<KeySubscriberHandler> InputEventHandler::GetSubscriberHandler() const
228 {
229     return eventSubscriberHandler_;
230 }
231 
GetSwitchSubscriberHandler() const232 std::shared_ptr<SwitchSubscriberHandler> InputEventHandler::GetSwitchSubscriberHandler() const
233 {
234     return switchEventSubscriberHandler_;
235 }
236 
GetKeyCommandHandler() const237 std::shared_ptr<KeyCommandHandler> InputEventHandler::GetKeyCommandHandler() const
238 {
239     return eventKeyCommandHandler_;
240 }
241 
GetMonitorHandler() const242 std::shared_ptr<EventMonitorHandler> InputEventHandler::GetMonitorHandler() const
243 {
244     return eventMonitorHandler_;
245 }
246 
GetFilterHandler() const247 std::shared_ptr<EventFilterHandler> InputEventHandler::GetFilterHandler() const
248 {
249     return eventFilterHandler_;
250 }
251 
GetEventDispatchHandler() const252 std::shared_ptr<EventDispatchHandler> InputEventHandler::GetEventDispatchHandler() const
253 {
254     return eventDispatchHandler_;
255 }
256 } // namespace MMI
257 } // namespace OHOS