• 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 #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