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 #include "input_handler_manager_global.h"
16 #include "input_event_handler.h"
17 #include "define_multimodal.h"
18 #include "event_dispatch.h"
19 #include "input_event_data_transformation.h"
20 #include "mmi_log.h"
21 #include "net_packet.h"
22 #include "proto.h"
23
24 namespace OHOS {
25 namespace MMI {
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "InputHandlerManagerGlobal" };
28 }
29
AddInputHandler(int32_t handlerId,InputHandlerType handlerType,SessionPtr session)30 int32_t InputHandlerManagerGlobal::AddInputHandler(int32_t handlerId,
31 InputHandlerType handlerType, SessionPtr session)
32 {
33 InitSessionLostCallback();
34 CHKR(IsValidHandlerId(handlerId), PARAM_INPUT_INVALID, RET_ERR);
35 CHKPR(session, RET_ERR);
36 if (handlerType == InputHandlerType::MONITOR) {
37 if (!session->HasPermission()) {
38 MMI_LOGE("no permission, can not add monitor");
39 return RET_ERR;
40 }
41 MMI_LOGD("Register monitor:%{public}d", handlerId);
42 SessionHandler mon { handlerId, handlerType, session };
43 return monitors_.AddMonitor(mon);
44 }
45 if (handlerType == InputHandlerType::INTERCEPTOR) {
46 MMI_LOGD("Register interceptor:%{public}d", handlerId);
47 SessionHandler interceptor { handlerId, handlerType, session };
48 return interceptors_.AddInterceptor(interceptor);
49 }
50 MMI_LOGW("Invalid handler type");
51 return RET_ERR;
52 }
53
RemoveInputHandler(int32_t handlerId,InputHandlerType handlerType,SessionPtr session)54 void InputHandlerManagerGlobal::RemoveInputHandler(int32_t handlerId,
55 InputHandlerType handlerType, SessionPtr session)
56 {
57 if (handlerType == InputHandlerType::MONITOR) {
58 if (!session->HasPermission()) {
59 MMI_LOGE("no permission, can not remove monitor");
60 return;
61 }
62 MMI_LOGD("Unregister monitor:%{public}d", handlerId);
63 SessionHandler monitor { handlerId, handlerType, session };
64 monitors_.RemoveMonitor(monitor);
65 } else if (handlerType == InputHandlerType::INTERCEPTOR) {
66 MMI_LOGD("Unregister interceptor:%{public}d", handlerId);
67 SessionHandler interceptor { handlerId, handlerType, session };
68 interceptors_.RemoveInterceptor(interceptor);
69 }
70 }
71
MarkConsumed(int32_t handlerId,int32_t eventId,SessionPtr session)72 void InputHandlerManagerGlobal::MarkConsumed(int32_t handlerId, int32_t eventId, SessionPtr session)
73 {
74 MMI_LOGD("Mark consumed state, monitor:%{public}d", handlerId);
75 monitors_.MarkConsumed(handlerId, eventId, session);
76 }
77
HandleEvent(std::shared_ptr<KeyEvent> keyEvent)78 bool InputHandlerManagerGlobal::HandleEvent(std::shared_ptr<KeyEvent> keyEvent)
79 {
80 MMI_LOGD("Handle KeyEvent");
81 CHKPF(keyEvent);
82 if (keyEvent->HasFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT)) {
83 MMI_LOGD("This event has been tagged as not to be intercepted");
84 } else {
85 if (interceptors_.HandleEvent(keyEvent)) {
86 MMI_LOGD("Key event was intercepted");
87 return true;
88 }
89 }
90 if (keyEvent->HasFlag(InputEvent::EVENT_FLAG_NO_MONITOR)) {
91 MMI_LOGD("This event has been tagged as not to be monitored");
92 } else {
93 if (monitors_.HandleEvent(keyEvent)) {
94 MMI_LOGD("Key event was consumed");
95 return true;
96 }
97 }
98 return false;
99 }
100
HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)101 bool InputHandlerManagerGlobal::HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)
102 {
103 CHKPF(pointerEvent);
104 if (pointerEvent->HasFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT)) {
105 MMI_LOGD("This event has been tagged as not to be intercepted");
106 } else {
107 if (interceptors_.HandleEvent(pointerEvent)) {
108 MMI_LOGD("Pointer event was intercepted");
109 return true;
110 }
111 }
112 if (pointerEvent->HasFlag(InputEvent::EVENT_FLAG_NO_MONITOR)) {
113 MMI_LOGD("This event has been tagged as not to be monitored");
114 } else {
115 if (monitors_.HandleEvent(pointerEvent)) {
116 MMI_LOGD("Pointer event was consumed");
117 return true;
118 }
119 }
120 return false;
121 }
122
InitSessionLostCallback()123 void InputHandlerManagerGlobal::InitSessionLostCallback()
124 {
125 if (sessionLostCallbackInitialized_) {
126 return;
127 }
128 auto udsServerPtr = InputHandler->GetUDSServer();
129 CHKPV(udsServerPtr);
130 udsServerPtr->AddSessionDeletedCallback(std::bind(
131 &InputHandlerManagerGlobal::OnSessionLost, this, std::placeholders::_1));
132 sessionLostCallbackInitialized_ = true;
133 MMI_LOGD("The callback on session deleted is registered successfully");
134 }
135
OnSessionLost(SessionPtr session)136 void InputHandlerManagerGlobal::OnSessionLost(SessionPtr session)
137 {
138 monitors_.OnSessionLost(session);
139 interceptors_.OnSessionLost(session);
140 }
141
SendToClient(std::shared_ptr<KeyEvent> keyEvent) const142 void InputHandlerManagerGlobal::SessionHandler::SendToClient(std::shared_ptr<KeyEvent> keyEvent) const
143 {
144 CHKPV(keyEvent);
145 NetPacket pkt(MmiMessageId::REPORT_KEY_EVENT);
146 CHK(pkt.Write(id_), STREAM_BUF_WRITE_FAIL);
147 CHK((InputEventDataTransformation::KeyEventToNetPacket(keyEvent, pkt) == RET_OK),
148 STREAM_BUF_WRITE_FAIL);
149 CHK(session_->SendMsg(pkt), MSG_SEND_FAIL);
150 }
151
SendToClient(std::shared_ptr<PointerEvent> pointerEvent) const152 void InputHandlerManagerGlobal::SessionHandler::SendToClient(std::shared_ptr<PointerEvent> pointerEvent) const
153 {
154 CHKPV(pointerEvent);
155 NetPacket pkt(MmiMessageId::REPORT_POINTER_EVENT);
156 MMI_LOGD("Service SendToClient id:%{public}d,InputHandlerType:%{public}d", id_, handlerType_);
157 CHK(pkt.Write(id_), STREAM_BUF_WRITE_FAIL);
158 CHK(pkt.Write(handlerType_), STREAM_BUF_WRITE_FAIL);
159 CHK((OHOS::MMI::InputEventDataTransformation::Marshalling(pointerEvent, pkt) == RET_OK),
160 STREAM_BUF_WRITE_FAIL);
161 CHK(session_->SendMsg(pkt), MSG_SEND_FAIL);
162 }
163
AddMonitor(const SessionHandler & monitor)164 int32_t InputHandlerManagerGlobal::MonitorCollection::AddMonitor(const SessionHandler& monitor)
165 {
166 std::lock_guard<std::mutex> guard(lockMonitors_);
167 if (monitors_.size() >= MAX_N_INPUT_MONITORS) {
168 MMI_LOGE("The number of monitors exceeds the maximum:%{public}zu,monitors,errCode:%{public}d",
169 monitors_.size(), INVALID_MONITOR_MON);
170 return RET_ERR;
171 }
172 auto ret = monitors_.insert(monitor);
173 if (ret.second) {
174 MMI_LOGD("Service AddMonitor Success");
175 } else {
176 MMI_LOGW("Duplicate monitors");
177 }
178 return RET_OK;
179 }
180
RemoveMonitor(const SessionHandler & monitor)181 void InputHandlerManagerGlobal::MonitorCollection::RemoveMonitor(const SessionHandler& monitor)
182 {
183 std::lock_guard<std::mutex> guard(lockMonitors_);
184 std::set<SessionHandler>::const_iterator tItr = monitors_.find(monitor);
185 if (tItr != monitors_.end()) {
186 monitors_.erase(tItr);
187 MMI_LOGD("Service RemoveMonitor Success");
188 }
189 }
190
MarkConsumed(int32_t monitorId,int32_t eventId,SessionPtr session)191 void InputHandlerManagerGlobal::MonitorCollection::MarkConsumed(int32_t monitorId, int32_t eventId, SessionPtr session)
192 {
193 if (!HasMonitor(monitorId, session)) {
194 MMI_LOGW("Specified monitor does not exist, monitor:%{public}d", monitorId);
195 return;
196 }
197 if (monitorConsumed_) {
198 MMI_LOGW("Event consumed");
199 return;
200 }
201 if ((downEventId_ < 0) || (lastPointerEvent_ == nullptr)) {
202 MMI_LOGI("No touch event or press event without a previous finger is not handled");
203 return;
204 }
205 if (downEventId_ > eventId) {
206 MMI_LOGW("A new process has began %{public}d,%{public}d", downEventId_, eventId);
207 return;
208 }
209 monitorConsumed_ = true;
210 MMI_LOGD("Cancel operation");
211 std::shared_ptr<PointerEvent> pointerEvent = std::make_shared<PointerEvent>(*lastPointerEvent_);
212 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_CANCEL);
213 pointerEvent->SetActionTime(GetSysClockTime());
214 pointerEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT | InputEvent::EVENT_FLAG_NO_MONITOR);
215 EventDispatch eDispatch;
216 eDispatch.HandlePointerEvent(pointerEvent);
217 }
218
GetPriority() const219 int32_t InputHandlerManagerGlobal::MonitorCollection::GetPriority() const
220 {
221 return IInputEventHandler::DEFAULT_MONITOR;
222 }
223
HandleEvent(std::shared_ptr<KeyEvent> keyEvent)224 bool InputHandlerManagerGlobal::MonitorCollection::HandleEvent(std::shared_ptr<KeyEvent> keyEvent)
225 {
226 CHKPF(keyEvent);
227 std::lock_guard<std::mutex> guard(lockMonitors_);
228 MMI_LOGD("There are currently %{public}zu monitors", monitors_.size());
229 for (const auto &mon : monitors_) {
230 mon.SendToClient(keyEvent);
231 }
232 return false;
233 }
234
HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)235 bool InputHandlerManagerGlobal::MonitorCollection::HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)
236 {
237 CHKPF(pointerEvent);
238 UpdateConsumptionState(pointerEvent);
239 Monitor(pointerEvent);
240 return monitorConsumed_;
241 }
242
HasMonitor(int32_t monitorId,SessionPtr session)243 bool InputHandlerManagerGlobal::MonitorCollection::HasMonitor(int32_t monitorId, SessionPtr session)
244 {
245 std::lock_guard<std::mutex> guard(lockMonitors_);
246 SessionHandler monitor { monitorId, InputHandlerType::MONITOR, session };
247 return (monitors_.find(monitor) != monitors_.end());
248 }
249
UpdateConsumptionState(std::shared_ptr<PointerEvent> pointerEvent)250 void InputHandlerManagerGlobal::MonitorCollection::UpdateConsumptionState(std::shared_ptr<PointerEvent> pointerEvent)
251 {
252 CHKPV(pointerEvent);
253 if (pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
254 MMI_LOGE("This is not a touch-screen event");
255 return;
256 }
257 lastPointerEvent_ = pointerEvent;
258 constexpr size_t nPtrsIndNewProc = 1;
259
260 if (pointerEvent->GetPointersIdList().size() != nPtrsIndNewProc) {
261 MMI_LOGD("First press and last lift intermediate process");
262 return;
263 }
264 if (pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_DOWN) {
265 MMI_LOGD("Press for the first time");
266 downEventId_ = pointerEvent->GetId();
267 monitorConsumed_ = false;
268 } else if (pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_UP) {
269 MMI_LOGD("The last time lift");
270 downEventId_ = -1;
271 lastPointerEvent_.reset();
272 }
273 }
274
Monitor(std::shared_ptr<PointerEvent> pointerEvent)275 void InputHandlerManagerGlobal::MonitorCollection::Monitor(std::shared_ptr<PointerEvent> pointerEvent)
276 {
277 CHKPV(pointerEvent);
278 std::lock_guard<std::mutex> guard(lockMonitors_);
279 MMI_LOGD("There are currently %{public}zu monitors", monitors_.size());
280 for (const auto &monitor : monitors_) {
281 monitor.SendToClient(pointerEvent);
282 }
283 }
284
OnSessionLost(SessionPtr session)285 void InputHandlerManagerGlobal::MonitorCollection::OnSessionLost(SessionPtr session)
286 {
287 std::lock_guard<std::mutex> guard(lockMonitors_);
288 std::set<SessionHandler>::const_iterator cItr = monitors_.cbegin();
289 while (cItr != monitors_.cend()) {
290 if (cItr->session_ != session) {
291 ++cItr;
292 } else {
293 cItr = monitors_.erase(cItr);
294 }
295 }
296 }
297
GetPriority() const298 int32_t InputHandlerManagerGlobal::InterceptorCollection::GetPriority() const
299 {
300 return IInputEventHandler::DEFAULT_INTERCEPTOR;
301 }
302
HandleEvent(std::shared_ptr<KeyEvent> keyEvent)303 bool InputHandlerManagerGlobal::InterceptorCollection::HandleEvent(std::shared_ptr<KeyEvent> keyEvent)
304 {
305 CHKPF(keyEvent);
306 std::lock_guard<std::mutex> guard(lockInterceptors_);
307 if (interceptors_.empty()) {
308 return false;
309 }
310 MMI_LOGD("There are currently:%{public}zu interceptors", interceptors_.size());
311 for (const auto &interceptor : interceptors_) {
312 interceptor.SendToClient(keyEvent);
313 }
314 return true;
315 }
316
HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)317 bool InputHandlerManagerGlobal::InterceptorCollection::HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)
318 {
319 CHKPF(pointerEvent);
320 std::lock_guard<std::mutex> guard(lockInterceptors_);
321 if (interceptors_.empty()) {
322 return false;
323 }
324 MMI_LOGD("There are currently:%{public}zu interceptors", interceptors_.size());
325 for (const auto &interceptor : interceptors_) {
326 interceptor.SendToClient(pointerEvent);
327 }
328 return true;
329 }
330
AddInterceptor(const SessionHandler & interceptor)331 int32_t InputHandlerManagerGlobal::InterceptorCollection::AddInterceptor(const SessionHandler& interceptor)
332 {
333 std::lock_guard<std::mutex> guard(lockInterceptors_);
334 if (interceptors_.size() >= MAX_N_INPUT_INTERCEPTORS) {
335 MMI_LOGE("The number of interceptors exceeds limit");
336 return RET_ERR;
337 }
338 auto ret = interceptors_.insert(interceptor);
339 if (ret.second) {
340 MMI_LOGD("Register interceptor successfully");
341 } else {
342 MMI_LOGW("Duplicate interceptors");
343 }
344 return RET_OK;
345 }
346
RemoveInterceptor(const SessionHandler & interceptor)347 void InputHandlerManagerGlobal::InterceptorCollection::RemoveInterceptor(const SessionHandler& interceptor)
348 {
349 std::lock_guard<std::mutex> guard(lockInterceptors_);
350 std::set<SessionHandler>::const_iterator tItr = interceptors_.find(interceptor);
351 if (tItr != interceptors_.cend()) {
352 interceptors_.erase(tItr);
353 MMI_LOGD("Unregister interceptor successfully");
354 }
355 }
356
OnSessionLost(SessionPtr session)357 void InputHandlerManagerGlobal::InterceptorCollection::OnSessionLost(SessionPtr session)
358 {
359 std::lock_guard<std::mutex> guard(lockInterceptors_);
360 std::set<SessionHandler>::const_iterator cItr = interceptors_.cbegin();
361 while (cItr != interceptors_.cend()) {
362 if (cItr->session_ != session) {
363 ++cItr;
364 } else {
365 cItr = interceptors_.erase(cItr);
366 }
367 }
368 }
369 } // namespace MMI
370 } // namespace OHOS
371
372