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