• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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_handler_manager.h"
17 
18 #include <cinttypes>
19 
20 #include "bytrace_adapter.h"
21 #include "input_handler_type.h"
22 #include "anr_handler.h"
23 #include "multimodal_event_handler.h"
24 #include "multimodal_input_connect_manager.h"
25 #include "mmi_log.h"
26 #include "napi_constants.h"
27 #include "net_packet.h"
28 #include "proto.h"
29 
30 namespace OHOS {
31 namespace MMI {
32 namespace {
33 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "InputHandlerManager" };
34 } // namespace
35 
InputHandlerManager()36 InputHandlerManager::InputHandlerManager()
37 {
38     monitorCallback_ =
39         std::bind(&InputHandlerManager::OnDispatchEventProcessed, this, std::placeholders::_1, std::placeholders::_2);
40 }
41 
AddHandler(InputHandlerType handlerType,std::shared_ptr<IInputEventConsumer> consumer,HandleEventType eventType,int32_t priority,uint32_t deviceTags)42 int32_t InputHandlerManager::AddHandler(InputHandlerType handlerType, std::shared_ptr<IInputEventConsumer> consumer,
43     HandleEventType eventType, int32_t priority, uint32_t deviceTags)
44 {
45     CALL_INFO_TRACE;
46     CHKPR(consumer, INVALID_HANDLER_ID);
47     eventType = HANDLE_EVENT_TYPE_NONE;
48     if ((deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD)) != 0) {
49         eventType |= HANDLE_EVENT_TYPE_KEY;
50     }
51     if ((deviceTags & (CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_MAX) -
52         CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD))) != 0) {
53         eventType |= HANDLE_EVENT_TYPE_POINTER;
54     }
55     std::lock_guard<std::mutex> guard(mtxHandlers_);
56     if ((monitorHandlers_.size() + interHandlers_.size()) >= MAX_N_INPUT_HANDLERS) {
57         MMI_HILOGE("The number of handlers exceeds the maximum");
58         return ERROR_EXCEED_MAX_COUNT;
59     }
60     int32_t handlerId = GetNextId();
61     if (handlerId == INVALID_HANDLER_ID) {
62         MMI_HILOGE("Exceeded limit of 32-bit maximum number of integers");
63         return INVALID_HANDLER_ID;
64     }
65     if (eventType == HANDLE_EVENT_TYPE_NONE) {
66         MMI_HILOGE("Invalid event type");
67         return INVALID_HANDLER_ID;
68     }
69     const HandleEventType currentType = GetEventType();
70     MMI_HILOGD("Register new handler:%{public}d, currentType:%{public}d, deviceTags:%{public}d", handlerId, currentType,
71         deviceTags);
72     uint32_t currentTags = GetDeviceTags();
73     if (RET_OK == AddLocal(handlerId, handlerType, eventType, priority, deviceTags, consumer)) {
74         MMI_HILOGD("New handler successfully registered, report to server");
75         const HandleEventType newType = GetEventType();
76         if (currentType != newType || ((currentTags & deviceTags) != deviceTags)) {
77             deviceTags = GetDeviceTags();
78             MMI_HILOGD("handlerType:%{public}d, newType:%{public}d, deviceTags:%{public}d, priority:%{public}d",
79                 handlerType, newType, deviceTags, priority);
80             int32_t ret = AddToServer(handlerType, newType, priority, deviceTags);
81             if (ret != RET_OK) {
82                 MMI_HILOGD("Handler:%{public}d permissions failed, remove the monitor", handlerId);
83                 RemoveLocal(handlerId, handlerType, deviceTags);
84                 return ret;
85             }
86         }
87     } else {
88         handlerId = INVALID_HANDLER_ID;
89     }
90     return handlerId;
91 }
92 
RemoveHandler(int32_t handlerId,InputHandlerType handlerType)93 void InputHandlerManager::RemoveHandler(int32_t handlerId, InputHandlerType handlerType)
94 {
95     CALL_INFO_TRACE;
96     MMI_HILOGD("Unregister handler:%{public}d,type:%{public}d", handlerId, handlerType);
97     std::lock_guard<std::mutex> guard(mtxHandlers_);
98     const HandleEventType currentType = GetEventType();
99     uint32_t currentTags = GetDeviceTags();
100     uint32_t deviceTags = 0;
101     if (RET_OK == RemoveLocal(handlerId, handlerType, deviceTags)) {
102         MMI_HILOGD("Handler:%{public}d deviceTags:%{public}d unregistered, report to server", handlerId, deviceTags);
103         const HandleEventType newType = GetEventType();
104         const int32_t newLevel = GetPriority();
105         const uint64_t newTags = GetDeviceTags();
106         if (currentType != newType || ((currentTags & deviceTags) != 0)) {
107             RemoveFromServer(handlerType, newType, newLevel, newTags);
108         }
109     }
110 }
111 
AddLocal(int32_t handlerId,InputHandlerType handlerType,HandleEventType eventType,int32_t priority,uint32_t deviceTags,std::shared_ptr<IInputEventConsumer> monitor)112 int32_t InputHandlerManager::AddLocal(int32_t handlerId, InputHandlerType handlerType, HandleEventType eventType,
113     int32_t priority, uint32_t deviceTags, std::shared_ptr<IInputEventConsumer> monitor)
114 {
115     InputHandlerManager::Handler handler{
116         .handlerId_ = handlerId,
117         .handlerType_ = handlerType,
118         .eventType_ = eventType,
119         .priority_ = priority,
120         .deviceTags_ = deviceTags,
121         .consumer_ = monitor,
122     };
123     if (handlerType == InputHandlerType::MONITOR) {
124         auto ret = monitorHandlers_.emplace(handler.handlerId_, handler);
125         if (!ret.second) {
126             MMI_HILOGE("Duplicate handler:%{public}d", handler.handlerId_);
127             return RET_ERR;
128         }
129     }
130     if (handlerType == InputHandlerType::INTERCEPTOR) {
131         auto iterIndex = interHandlers_.begin();
132         for (; iterIndex != interHandlers_.end(); ++iterIndex) {
133             if (handler.priority_ < iterIndex->priority_) {
134                 break;
135             }
136         }
137         auto iter = interHandlers_.emplace(iterIndex, handler);
138         if (iter == interHandlers_.end()) {
139             MMI_HILOGE("Add new handler failed");
140             return RET_ERR;
141         }
142     }
143     return RET_OK;
144 }
145 
AddToServer(InputHandlerType handlerType,HandleEventType eventType,int32_t priority,uint32_t deviceTags)146 int32_t InputHandlerManager::AddToServer(InputHandlerType handlerType, HandleEventType eventType, int32_t priority,
147     uint32_t deviceTags)
148 {
149     int32_t ret = MultimodalInputConnMgr->AddInputHandler(handlerType, eventType, priority, deviceTags);
150     if (ret != RET_OK) {
151         MMI_HILOGE("Send to server failed, ret:%{public}d", ret);
152     }
153     return ret;
154 }
155 
RemoveLocal(int32_t handlerId,InputHandlerType handlerType,uint32_t & deviceTags)156 int32_t InputHandlerManager::RemoveLocal(int32_t handlerId, InputHandlerType handlerType, uint32_t &deviceTags)
157 {
158     if (handlerType == InputHandlerType::MONITOR) {
159         auto iter = monitorHandlers_.find(handlerId);
160         if (iter == monitorHandlers_.end()) {
161             MMI_HILOGE("No handler with specified");
162             return RET_ERR;
163         }
164         if (handlerType != iter->second.handlerType_) {
165             MMI_HILOGE("Unmatched handler type, InputHandlerType:%{public}d,FindHandlerType:%{public}d", handlerType,
166                 iter->second.handlerType_);
167             return RET_ERR;
168         }
169         monitorHandlers_.erase(iter);
170     }
171 
172     if (handlerType == InputHandlerType::INTERCEPTOR) {
173         for (auto it = interHandlers_.begin(); it != interHandlers_.end(); ++it) {
174             if (handlerId == it->handlerId_) {
175                 deviceTags = it->deviceTags_;
176                 interHandlers_.erase(it);
177                 break;
178             }
179         }
180     }
181     return RET_OK;
182 }
183 
RemoveFromServer(InputHandlerType handlerType,HandleEventType eventType,int32_t priority,uint32_t deviceTags)184 void InputHandlerManager::RemoveFromServer(InputHandlerType handlerType, HandleEventType eventType, int32_t priority,
185     uint32_t deviceTags)
186 {
187     int32_t ret = MultimodalInputConnMgr->RemoveInputHandler(handlerType, eventType, priority, deviceTags);
188     if (ret != 0) {
189         MMI_HILOGE("Send to server failed, ret:%{public}d", ret);
190     }
191 }
192 
GetNextId()193 int32_t InputHandlerManager::GetNextId()
194 {
195     if (nextId_ == std::numeric_limits<int32_t>::max()) {
196         MMI_HILOGE("Exceeded limit of 32-bit maximum number of integers");
197         return INVALID_HANDLER_ID;
198     }
199     return nextId_++;
200 }
201 
FindHandler(int32_t handlerId)202 std::shared_ptr<IInputEventConsumer> InputHandlerManager::FindHandler(int32_t handlerId)
203 {
204     if (GetHandlerType() == InputHandlerType::MONITOR) {
205         auto iter = monitorHandlers_.find(handlerId);
206         if (iter != monitorHandlers_.end()) {
207             return iter->second.consumer_;
208         }
209     }
210     if (GetHandlerType() == InputHandlerType::INTERCEPTOR) {
211         for (const auto &item : interHandlers_) {
212             if (item.handlerId_ == handlerId) {
213                 return item.consumer_;
214             }
215         }
216     }
217     return nullptr;
218 }
219 
220 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
OnInputEvent(std::shared_ptr<KeyEvent> keyEvent,uint32_t deviceTags)221 void InputHandlerManager::OnInputEvent(std::shared_ptr<KeyEvent> keyEvent, uint32_t deviceTags)
222 {
223     CHK_PID_AND_TID();
224     CHKPV(keyEvent);
225     std::lock_guard<std::mutex> guard(mtxHandlers_);
226     BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::TRACE_STOP, BytraceAdapter::KEY_INTERCEPT_EVENT);
227     if (GetHandlerType() == InputHandlerType::MONITOR) {
228         for (const auto &item : monitorHandlers_) {
229             if ((item.second.eventType_ & HANDLE_EVENT_TYPE_KEY) != HANDLE_EVENT_TYPE_KEY) {
230                 continue;
231             }
232             int32_t handlerId = item.first;
233             std::shared_ptr<IInputEventConsumer> consumer = item.second.consumer_;
234             CHKPV(consumer);
235             consumer->OnInputEvent(keyEvent);
236             MMI_HILOGD("Key event id:%{public}d keyCode:%{public}d", handlerId, keyEvent->GetKeyCode());
237         }
238     }
239     if (GetHandlerType() == InputHandlerType::INTERCEPTOR) {
240         for (const auto &item : interHandlers_) {
241             if ((item.eventType_ & HANDLE_EVENT_TYPE_KEY) != HANDLE_EVENT_TYPE_KEY) {
242                 continue;
243             }
244             int32_t handlerId = item.handlerId_;
245             std::shared_ptr<IInputEventConsumer> consumer = item.consumer_;
246             CHKPV(consumer);
247             consumer->OnInputEvent(keyEvent);
248             MMI_HILOGD("Key event id:%{public}d keyCode:%{public}d", handlerId, keyEvent->GetKeyCode());
249             break;
250         }
251     }
252 }
253 #endif // OHOS_BUILD_ENABLE_KEYBOARD
254 
255 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
CheckInputDeviceSource(const std::shared_ptr<PointerEvent> pointerEvent,uint32_t deviceTags) const256 bool InputHandlerManager::CheckInputDeviceSource(
257     const std::shared_ptr<PointerEvent> pointerEvent, uint32_t deviceTags) const
258 {
259     if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN) &&
260         ((deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_TOUCH)) ||
261         (deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_TABLET_TOOL)))) {
262         return true;
263     } else if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE) &&
264         (deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_POINTER))) {
265         return true;
266     } else if ((pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHPAD) &&
267         (deviceTags & CapabilityToTags(InputDeviceCapability::INPUT_DEV_CAP_POINTER))) {
268         return true;
269     }
270     return false;
271 }
272 
GetConsumerInfos(std::shared_ptr<PointerEvent> pointerEvent,uint32_t deviceTags,std::map<int32_t,std::shared_ptr<IInputEventConsumer>> & consumerInfos)273 void InputHandlerManager::GetConsumerInfos(std::shared_ptr<PointerEvent> pointerEvent, uint32_t deviceTags,
274     std::map<int32_t, std::shared_ptr<IInputEventConsumer>> &consumerInfos)
275 {
276     std::lock_guard<std::mutex> guard(mtxHandlers_);
277     int32_t consumerCount = 0;
278     if (GetHandlerType() == InputHandlerType::MONITOR) {
279         consumerCount = GetMonitorConsumerInfos(pointerEvent, consumerInfos);
280     }
281     if (GetHandlerType() == InputHandlerType::INTERCEPTOR) {
282         for (const auto &item : interHandlers_) {
283             if ((item.eventType_ & HANDLE_EVENT_TYPE_POINTER) != HANDLE_EVENT_TYPE_POINTER) {
284                 continue;
285             }
286             if (((deviceTags & item.deviceTags_) == item.deviceTags_) &&
287                 !CheckInputDeviceSource(pointerEvent, item.deviceTags_)) {
288                 continue;
289             }
290             int32_t handlerId = item.handlerId_;
291             std::shared_ptr<IInputEventConsumer> consumer = item.consumer_;
292             CHKPV(consumer);
293             auto ret = consumerInfos.emplace(handlerId, consumer);
294             if (!ret.second) {
295                 MMI_HILOGI("Duplicate handler:%{public}d", handlerId);
296                 continue;
297             }
298             consumerCount++;
299             break;
300         }
301     }
302 
303     if (consumerCount == 0) {
304         MMI_HILOGE("All task post failed");
305         return;
306     }
307     int32_t tokenType = MultimodalInputConnMgr->GetTokenType();
308     if (tokenType != TokenType::TOKEN_HAP) {
309         return;
310     }
311     AddMouseEventId(pointerEvent);
312     AddProcessedEventId(pointerEvent, consumerCount);
313 }
314 
AddMouseEventId(std::shared_ptr<PointerEvent> pointerEvent)315 void InputHandlerManager::AddMouseEventId(std::shared_ptr<PointerEvent> pointerEvent)
316 {
317     if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE) {
318         mouseEventIds_.emplace(pointerEvent->GetId());
319     }
320 }
321 
AddProcessedEventId(std::shared_ptr<PointerEvent> pointerEvent,int32_t consumerCount)322 void InputHandlerManager::AddProcessedEventId(std::shared_ptr<PointerEvent> pointerEvent, int32_t consumerCount)
323 {
324     if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN ||
325         pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHPAD) {
326         processedEvents_.emplace(pointerEvent->GetId(), consumerCount);
327     }
328 }
329 
GetMonitorConsumerInfos(std::shared_ptr<PointerEvent> pointerEvent,std::map<int32_t,std::shared_ptr<IInputEventConsumer>> & consumerInfos)330 int32_t InputHandlerManager::GetMonitorConsumerInfos(std::shared_ptr<PointerEvent> pointerEvent,
331     std::map<int32_t, std::shared_ptr<IInputEventConsumer>> &consumerInfos)
332 {
333     int32_t consumerCount = 0;
334     for (const auto &item : monitorHandlers_) {
335         if ((item.second.eventType_ & HANDLE_EVENT_TYPE_POINTER) != HANDLE_EVENT_TYPE_POINTER) {
336             continue;
337         }
338         int32_t handlerId = item.first;
339         std::shared_ptr<IInputEventConsumer> consumer = item.second.consumer_;
340         CHKPR(consumer, INVALID_HANDLER_ID);
341         auto ret = consumerInfos.emplace(handlerId, consumer);
342         if (!ret.second) {
343             MMI_HILOGI("Duplicate handler:%{public}d", handlerId);
344             continue;
345         }
346         consumerCount++;
347     }
348     return consumerCount;
349 }
350 
OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent,uint32_t deviceTags)351 void InputHandlerManager::OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent, uint32_t deviceTags)
352 {
353     CHK_PID_AND_TID();
354     CHKPV(pointerEvent);
355     BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_STOP, BytraceAdapter::POINT_INTERCEPT_EVENT);
356     std::map<int32_t, std::shared_ptr<IInputEventConsumer>> consumerInfos;
357     GetConsumerInfos(pointerEvent, deviceTags, consumerInfos);
358     for (const auto &iter : consumerInfos) {
359         auto tempEvent = std::make_shared<PointerEvent>(*pointerEvent);
360         tempEvent->SetProcessedCallback(monitorCallback_);
361         CHKPV(iter.second);
362         auto consumer = iter.second;
363         consumer->OnInputEvent(tempEvent);
364         MMI_HILOGD("Pointer event id:%{public}d pointerId:%{public}d", iter.first, pointerEvent->GetPointerId());
365     }
366 }
367 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
368 
369 #if defined(OHOS_BUILD_ENABLE_INTERCEPTOR) || defined(OHOS_BUILD_ENABLE_MONITOR)
OnConnected()370 void InputHandlerManager::OnConnected()
371 {
372     CALL_DEBUG_ENTER;
373     HandleEventType eventType = GetEventType();
374     int32_t priority = GetPriority();
375     uint32_t deviceTags = GetDeviceTags();
376     if (eventType != HANDLE_EVENT_TYPE_NONE) {
377         AddToServer(GetHandlerType(), eventType, priority, deviceTags);
378     }
379 }
380 #endif // OHOS_BUILD_ENABLE_INTERCEPTOR || OHOS_BUILD_ENABLE_MONITOR
381 
HasHandler(int32_t handlerId)382 bool InputHandlerManager::HasHandler(int32_t handlerId)
383 {
384     std::lock_guard<std::mutex> guard(mtxHandlers_);
385     if (GetHandlerType() == InputHandlerType::MONITOR) {
386         auto iter = monitorHandlers_.find(handlerId);
387         return (iter != monitorHandlers_.end());
388     }
389     if (GetHandlerType() == InputHandlerType::INTERCEPTOR) {
390         for (const auto &item : interHandlers_) {
391             if (item.handlerId_ == handlerId) {
392                 return true;
393             }
394         }
395     }
396     return false;
397 }
398 
GetEventType() const399 HandleEventType InputHandlerManager::GetEventType() const
400 {
401     uint32_t eventType{ HANDLE_EVENT_TYPE_NONE };
402     if (GetHandlerType() == InputHandlerType::MONITOR) {
403         if (monitorHandlers_.empty()) {
404             MMI_HILOGD("monitorHandlers_ is empty");
405             return HANDLE_EVENT_TYPE_NONE;
406         }
407         for (const auto &inputHandler : monitorHandlers_) {
408             eventType |= inputHandler.second.eventType_;
409         }
410     }
411 
412     if (GetHandlerType() == InputHandlerType::INTERCEPTOR) {
413         if (interHandlers_.empty()) {
414             MMI_HILOGD("interHandlers_ is empty");
415             return HANDLE_EVENT_TYPE_NONE;
416         }
417         for (const auto &interHandler : interHandlers_) {
418             eventType |= interHandler.eventType_;
419         }
420     }
421     return eventType;
422 }
423 
GetPriority() const424 int32_t InputHandlerManager::GetPriority() const
425 {
426     int32_t priority{ DEFUALT_INTERCEPTOR_PRIORITY };
427     if (GetHandlerType() == InputHandlerType::INTERCEPTOR) {
428         if (!interHandlers_.empty()) {
429             priority = interHandlers_.front().priority_;
430         }
431     }
432     return priority;
433 }
434 
GetDeviceTags() const435 uint32_t InputHandlerManager::GetDeviceTags() const
436 {
437     uint32_t deviceTags = 0;
438     if (GetHandlerType() == InputHandlerType::INTERCEPTOR) {
439         for (const auto &item : interHandlers_) {
440             deviceTags |= item.deviceTags_;
441         }
442     }
443     if (GetHandlerType() == InputHandlerType::MONITOR) {
444         for (const auto &item : monitorHandlers_) {
445             deviceTags |= item.second.deviceTags_;
446         }
447     }
448     return deviceTags;
449 }
450 
OnDispatchEventProcessed(int32_t eventId,int64_t actionTime)451 void InputHandlerManager::OnDispatchEventProcessed(int32_t eventId, int64_t actionTime)
452 {
453     std::lock_guard<std::mutex> guard(mtxHandlers_);
454     CALL_DEBUG_ENTER;
455     MMIClientPtr client = MMIEventHdl.GetMMIClient();
456     CHKPV(client);
457     if (mouseEventIds_.find(eventId) != mouseEventIds_.end()) {
458         mouseEventIds_.erase(eventId);
459         return;
460     }
461     auto iter = processedEvents_.find(eventId);
462     if (iter == processedEvents_.end()) {
463         MMI_HILOGE("EventId not in processedEvents_");
464         return;
465     }
466     int32_t count = iter->second;
467     processedEvents_.erase(iter);
468     count--;
469     if (count > 0) {
470         processedEvents_.emplace(eventId, count);
471         return;
472     }
473     ANRHDL->SetLastProcessedEventId(ANR_MONITOR, eventId, actionTime);
474 }
475 } // namespace MMI
476 } // namespace OHOS
477