• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_handler_manager.h"
17 
18 #include <cinttypes>
19 
20 #include "bytrace_adapter.h"
21 #include "input_handler_type.h"
22 #include "multimodal_event_handler.h"
23 #include "multimodal_input_connect_manager.h"
24 #include "mmi_log.h"
25 #include "napi_constants.h"
26 #include "net_packet.h"
27 #include "proto.h"
28 
29 namespace OHOS {
30 namespace MMI {
31 namespace {
32 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "InputHandlerManager" };
33 } // namespace
34 
InputHandlerManager()35 InputHandlerManager::InputHandlerManager()
36 {
37     monitorCallback_ = std::bind(&InputHandlerManager::OnDispatchEventProcessed, this, std::placeholders::_1);
38 }
39 
AddHandler(InputHandlerType handlerType,std::shared_ptr<IInputEventConsumer> consumer,HandleEventType eventType)40 int32_t InputHandlerManager::AddHandler(InputHandlerType handlerType,
41     std::shared_ptr<IInputEventConsumer> consumer, HandleEventType eventType)
42 {
43     CALL_INFO_TRACE;
44     CHKPR(consumer, INVALID_HANDLER_ID);
45     std::lock_guard<std::mutex> guard(mtxHandlers_);
46     if (inputHandlers_.size() >= MAX_N_INPUT_HANDLERS) {
47         MMI_HILOGE("The number of handlers exceeds the maximum");
48         return ERROR_EXCEED_MAX_COUNT;
49     }
50     int32_t handlerId = GetNextId();
51     if (handlerId == INVALID_HANDLER_ID) {
52         MMI_HILOGE("Exceeded limit of 32-bit maximum number of integers");
53         return INVALID_HANDLER_ID;
54     }
55 
56     if (eventType == HANDLE_EVENT_TYPE_NONE) {
57         MMI_HILOGE("Invalid event type");
58         return INVALID_HANDLER_ID;
59     }
60     const HandleEventType currentType = GetEventType();
61     MMI_HILOGD("Register new handler:%{public}d", handlerId);
62     if (RET_OK == AddLocal(handlerId, handlerType, eventType, consumer)) {
63         MMI_HILOGD("New handler successfully registered, report to server");
64         const HandleEventType newType = GetEventType();
65         if (currentType != newType) {
66             int32_t ret = AddToServer(handlerType, newType);
67             if (ret != RET_OK) {
68                 MMI_HILOGD("Handler:%{public}d permissions failed, remove the monitor", handlerId);
69                 RemoveLocal(handlerId, handlerType);
70                 return ret;
71             }
72         }
73     } else {
74         handlerId = INVALID_HANDLER_ID;
75     }
76     return handlerId;
77 }
78 
RemoveHandler(int32_t handlerId,InputHandlerType handlerType)79 void InputHandlerManager::RemoveHandler(int32_t handlerId, InputHandlerType handlerType)
80 {
81     CALL_INFO_TRACE;
82     MMI_HILOGD("Unregister handler:%{public}d,type:%{public}d", handlerId, handlerType);
83     std::lock_guard<std::mutex> guard(mtxHandlers_);
84     const HandleEventType currentType = GetEventType();
85     if (RET_OK == RemoveLocal(handlerId, handlerType)) {
86         MMI_HILOGD("Handler:%{public}d unregistered, report to server", handlerId);
87         const HandleEventType newType = GetEventType();
88         if (currentType != newType) {
89             RemoveFromServer(handlerType, newType);
90         }
91     }
92 }
93 
AddLocal(int32_t handlerId,InputHandlerType handlerType,HandleEventType eventType,std::shared_ptr<IInputEventConsumer> monitor)94 int32_t InputHandlerManager::AddLocal(int32_t handlerId, InputHandlerType handlerType,
95     HandleEventType eventType, std::shared_ptr<IInputEventConsumer> monitor)
96 {
97     InputHandlerManager::Handler handler {
98         .handlerId_ = handlerId,
99         .handlerType_ = handlerType,
100         .eventType_ = eventType,
101         .consumer_ = monitor,
102     };
103     auto ret = inputHandlers_.emplace(handler.handlerId_, handler);
104     if (!ret.second) {
105         MMI_HILOGE("Duplicate handler:%{public}d", handler.handlerId_);
106         return RET_ERR;
107     }
108     return RET_OK;
109 }
110 
AddToServer(InputHandlerType handlerType,HandleEventType eventType)111 int32_t InputHandlerManager::AddToServer(InputHandlerType handlerType, HandleEventType eventType)
112 {
113     int32_t ret = MultimodalInputConnMgr->AddInputHandler(handlerType, eventType);
114     if (ret != RET_OK) {
115         MMI_HILOGE("Send to server failed, ret:%{public}d", ret);
116     }
117     return ret;
118 }
119 
RemoveLocal(int32_t handlerId,InputHandlerType handlerType)120 int32_t InputHandlerManager::RemoveLocal(int32_t handlerId, InputHandlerType handlerType)
121 {
122     auto tItr = inputHandlers_.find(handlerId);
123     if (tItr == inputHandlers_.end()) {
124         MMI_HILOGE("No handler with specified");
125         return RET_ERR;
126     }
127     if (handlerType != tItr->second.handlerType_) {
128         MMI_HILOGE("Unmatched handler type, InputHandlerType:%{public}d,FindHandlerType:%{public}d",
129                    handlerType, tItr->second.handlerType_);
130         return RET_ERR;
131     }
132     inputHandlers_.erase(tItr);
133     return RET_OK;
134 }
135 
RemoveFromServer(InputHandlerType handlerType,HandleEventType eventType)136 void InputHandlerManager::RemoveFromServer(InputHandlerType handlerType, HandleEventType eventType)
137 {
138     int32_t ret = MultimodalInputConnMgr->RemoveInputHandler(handlerType, eventType);
139     if (ret != 0) {
140         MMI_HILOGE("Send to server failed, ret:%{public}d", ret);
141     }
142 }
143 
GetNextId()144 int32_t InputHandlerManager::GetNextId()
145 {
146     if (nextId_ == std::numeric_limits<int32_t>::max()) {
147         MMI_HILOGE("Exceeded limit of 32-bit maximum number of integers");
148         return INVALID_HANDLER_ID;
149     }
150     return nextId_++;
151 }
152 
FindHandler(int32_t handlerId)153 std::shared_ptr<IInputEventConsumer> InputHandlerManager::FindHandler(int32_t handlerId)
154 {
155     auto tItr = inputHandlers_.find(handlerId);
156     if (tItr != inputHandlers_.end()) {
157         return tItr->second.consumer_;
158     }
159     return nullptr;
160 }
161 
162 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
OnInputEvent(std::shared_ptr<KeyEvent> keyEvent)163 void InputHandlerManager::OnInputEvent(std::shared_ptr<KeyEvent> keyEvent)
164 {
165     CHK_PID_AND_TID();
166     CHKPV(keyEvent);
167     std::lock_guard<std::mutex> guard(mtxHandlers_);
168     BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::TRACE_STOP, BytraceAdapter::KEY_INTERCEPT_EVENT);
169     for (const auto &handler : inputHandlers_) {
170         if ((handler.second.eventType_ & HANDLE_EVENT_TYPE_KEY) != HANDLE_EVENT_TYPE_KEY) {
171             continue;
172         }
173         int32_t handlerId = handler.first;
174         auto consumer = handler.second.consumer_;
175         CHKPV(consumer);
176         consumer->OnInputEvent(keyEvent);
177         MMI_HILOGD("Key event id:%{public}d keyCode:%{public}d", handlerId, keyEvent->GetKeyCode());
178     }
179 }
180 #endif // OHOS_BUILD_ENABLE_KEYBOARD
181 
182 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
GetConsumerInfos(std::shared_ptr<PointerEvent> pointerEvent,std::map<int32_t,std::shared_ptr<IInputEventConsumer>> & consumerInfos)183 void InputHandlerManager::GetConsumerInfos(std::shared_ptr<PointerEvent> pointerEvent,
184     std::map<int32_t, std::shared_ptr<IInputEventConsumer>> &consumerInfos)
185 {
186     std::lock_guard<std::mutex> guard(mtxHandlers_);
187     int32_t consumerCount = 0;
188     for (const auto &iter : inputHandlers_) {
189         if ((iter.second.eventType_ & HANDLE_EVENT_TYPE_POINTER) != HANDLE_EVENT_TYPE_POINTER) {
190             continue;
191         }
192         int32_t handlerId = iter.first;
193         auto consumer = iter.second.consumer_;
194         CHKPV(consumer);
195         auto ret = consumerInfos.emplace(handlerId, consumer);
196         if (!ret.second) {
197             MMI_HILOGI("Duplicate handler:%{public}d", handlerId);
198             continue;
199         }
200         consumerCount++;
201     }
202     if (consumerCount == 0) {
203         MMI_HILOGE("All task post failed");
204         return;
205     }
206     int32_t tokenType = MultimodalInputConnMgr->GetTokenType();
207     if (tokenType != TokenType::TOKEN_HAP) {
208         return;
209     }
210     if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE) {
211         mouseEventIds_.emplace(pointerEvent->GetId());
212     }
213     if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
214         processedEvents_.emplace(pointerEvent->GetId(), consumerCount);
215     }
216 }
217 
OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent)218 void InputHandlerManager::OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent)
219 {
220     CHK_PID_AND_TID();
221     CHKPV(pointerEvent);
222     BytraceAdapter::StartBytrace(pointerEvent, BytraceAdapter::TRACE_STOP, BytraceAdapter::POINT_INTERCEPT_EVENT);
223     std::map<int32_t, std::shared_ptr<IInputEventConsumer>> consumerInfos;
224     GetConsumerInfos(pointerEvent, consumerInfos);
225     for (const auto &iter : consumerInfos) {
226         auto tempEvent = std::make_shared<PointerEvent>(*pointerEvent);
227         tempEvent->SetProcessedCallback(monitorCallback_);
228         CHKPV(iter.second);
229         auto consumer = iter.second;
230         consumer->OnInputEvent(tempEvent);
231         MMI_HILOGD("Pointer event id:%{public}d pointerId:%{public}d", iter.first, pointerEvent->GetPointerId());
232     }
233 }
234 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
235 
236 #if defined(OHOS_BUILD_ENABLE_INTERCEPTOR) || defined(OHOS_BUILD_ENABLE_MONITOR)
OnConnected()237 void InputHandlerManager::OnConnected()
238 {
239     CALL_DEBUG_ENTER;
240     HandleEventType eventType = GetEventType();
241     if (eventType != HANDLE_EVENT_TYPE_NONE) {
242         AddToServer(GetHandlerType(), eventType);
243     }
244 }
245 #endif // OHOS_BUILD_ENABLE_INTERCEPTOR || OHOS_BUILD_ENABLE_MONITOR
246 
HasHandler(int32_t handlerId)247 bool InputHandlerManager::HasHandler(int32_t handlerId)
248 {
249     std::lock_guard<std::mutex> guard(mtxHandlers_);
250     auto iter = inputHandlers_.find(handlerId);
251     return (iter != inputHandlers_.end());
252 }
253 
GetEventType() const254 HandleEventType InputHandlerManager::GetEventType() const
255 {
256     if (inputHandlers_.empty()) {
257         MMI_HILOGD("InputHandlers is empty");
258         return HANDLE_EVENT_TYPE_NONE;
259     }
260     HandleEventType eventType { HANDLE_EVENT_TYPE_NONE };
261     for (const auto &inputHandler : inputHandlers_) {
262         eventType |= inputHandler.second.eventType_;
263     }
264     return eventType;
265 }
266 
OnDispatchEventProcessed(int32_t eventId)267 void InputHandlerManager::OnDispatchEventProcessed(int32_t eventId)
268 {
269     CALL_DEBUG_ENTER;
270     std::lock_guard<std::mutex> guard(mtxHandlers_);
271     MMIClientPtr client = MMIEventHdl.GetMMIClient();
272     CHKPV(client);
273     if (mouseEventIds_.find(eventId) != mouseEventIds_.end()) {
274         mouseEventIds_.erase(eventId);
275         return;
276     }
277     auto iter = processedEvents_.find(eventId);
278     if (iter == processedEvents_.end()) {
279         MMI_HILOGE("EventId not in processedEvents_");
280         return;
281     }
282     int32_t count = iter->second;
283     processedEvents_.erase(iter);
284     count--;
285     if (count > 0) {
286         processedEvents_.emplace(eventId, count);
287         return;
288     }
289     NetPacket pkt(MmiMessageId::MARK_PROCESS);
290     pkt << eventId << ANR_MONITOR;
291     if (pkt.ChkRWError()) {
292         MMI_HILOGE("Packet write event failed");
293         return;
294     }
295     if (!client->SendMessage(pkt)) {
296         MMI_HILOGE("Send message failed, errCode:%{public}d", MSG_SEND_FAIL);
297         return;
298     }
299 }
300 } // namespace MMI
301 } // namespace OHOS
302