1 /*
2 * Copyright (c) 2025 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 "event_pre_monitor_handler.h"
17
18 #include "input_event_data_transformation.h"
19 #include "input_event_handler.h"
20 #include "util_ex.h"
21 #include "multimodal_input_plugin_manager.h"
22
23 #undef MMI_LOG_DOMAIN
24 #define MMI_LOG_DOMAIN MMI_LOG_HANDLER
25 #undef MMI_LOG_TAG
26 #define MMI_LOG_TAG "EventPreMonitorHandler"
27
28 namespace OHOS {
29 namespace MMI {
30 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)31 void EventPreMonitorHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
32 {
33 CHKPV(keyEvent);
34 OnHandleEvent(keyEvent);
35 CHKPV(nextHandler_);
36 auto callback = [this](std::shared_ptr<KeyEvent> keyEvent) {
37 this->nextHandler_->HandleKeyEvent(keyEvent);
38 };
39 auto manager = InputPluginManager::GetInstance();
40 if (manager != nullptr) {
41 manager->PluginAssignmentCallBack(callback, InputPluginStage::INPUT_BEFORE_KEYCOMMAND);
42 int32_t result = manager->HandleEvent(keyEvent, InputPluginStage::INPUT_BEFORE_KEYCOMMAND);
43 if (result != 0) {
44 return;
45 }
46 }
47 callback(keyEvent);
48 }
49 #endif // OHOS_BUILD_ENABLE_KEYBOARD
50
51 #ifdef OHOS_BUILD_ENABLE_POINTER
HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)52 void EventPreMonitorHandler::HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)
53 {
54 CHKPV(pointerEvent);
55 CHKPV(nextHandler_);
56 nextHandler_->HandlePointerEvent(pointerEvent);
57 }
58 #endif // OHOS_BUILD_ENABLE_POINTER
59
60 #ifdef OHOS_BUILD_ENABLE_TOUCH
HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)61 void EventPreMonitorHandler::HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)
62 {
63 CHKPV(pointerEvent);
64 CHKPV(nextHandler_);
65 nextHandler_->HandleTouchEvent(pointerEvent);
66 }
67 #endif // OHOS_BUILD_ENABLE_TOUCH
68
AddInputHandler(SessionPtr session,int32_t handlerId,HandleEventType eventType,std::vector<int32_t> keys)69 int32_t EventPreMonitorHandler::AddInputHandler(
70 SessionPtr session, int32_t handlerId, HandleEventType eventType, std::vector<int32_t> keys)
71 {
72 CALL_INFO_TRACE;
73 CHKPR(session, RET_ERR);
74 if ((eventType & HANDLE_EVENT_TYPE_ALL) == HANDLE_EVENT_TYPE_NONE) {
75 MMI_HILOGE("Invalid event type");
76 return RET_ERR;
77 }
78 InitSessionLostCallback();
79 auto mon = std::make_shared<SessionHandler>(session, handlerId, eventType, keys);
80 return monitors_.AddMonitor(mon, keys);
81 }
82
RemoveInputHandler(SessionPtr sess,int32_t handlerId)83 void EventPreMonitorHandler::RemoveInputHandler(SessionPtr sess, int32_t handlerId)
84 {
85 CALL_INFO_TRACE;
86 monitors_.RemoveMonitor(sess, handlerId);
87 }
88
89 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
OnHandleEvent(std::shared_ptr<KeyEvent> keyEvent)90 bool EventPreMonitorHandler::OnHandleEvent(std::shared_ptr<KeyEvent> keyEvent)
91 {
92 MMI_HILOGD("Handle KeyEvent");
93 CHKPF(keyEvent);
94 auto keyHandler = InputHandler->GetEventNormalizeHandler();
95 CHKPF(keyHandler);
96 if (keyEvent->GetKeyCode() != keyHandler->GetCurrentHandleKeyCode()) {
97 MMI_HILOGW("Keycode has been changed");
98 }
99 if (keyEvent->HasFlag(InputEvent::EVENT_FLAG_NO_MONITOR)) {
100 MMI_HILOGD("This event has been tagged as not to be monitored");
101 } else {
102 if (monitors_.HandleEvent(keyEvent)) {
103 MMI_HILOGD("Key event was consumed");
104 return true;
105 }
106 }
107 return false;
108 }
109 #endif // OHOS_BUILD_ENABLE_KEYBOARD
110
InitSessionLostCallback()111 void EventPreMonitorHandler::InitSessionLostCallback()
112 {
113 if (sessionLostCallbackInitialized_) {
114 return;
115 }
116 auto udsServerPtr = InputHandler->GetUDSServer();
117 CHKPV(udsServerPtr);
118 udsServerPtr->AddSessionDeletedCallback([this] (SessionPtr session) {
119 return this->OnSessionLost(session);
120 });
121 sessionLostCallbackInitialized_ = true;
122 MMI_HILOGD("The callback on session deleted is registered successfully");
123 }
124
OnSessionLost(SessionPtr session)125 void EventPreMonitorHandler::OnSessionLost(SessionPtr session)
126 {
127 monitors_.OnSessionLost(session);
128 }
129
SendToClient(std::shared_ptr<KeyEvent> keyEvent,NetPacket & pkt,int32_t handlerId) const130 void EventPreMonitorHandler::SessionHandler::SendToClient(
131 std::shared_ptr<KeyEvent> keyEvent, NetPacket &pkt, int32_t handlerId) const
132 {
133 CHKPV(keyEvent);
134 CHKPV(session_);
135 pkt.Clean();
136 if (InputEventDataTransformation::KeyEventToNetPacket(keyEvent, pkt) != RET_OK) {
137 MMI_HILOGE("Packet key event failed, errCode:%{public}d", STREAM_BUF_WRITE_FAIL);
138 return;
139 }
140 int32_t fd = session_->GetFd();
141 pkt << fd << handlerId;
142 if (!session_->SendMsg(pkt)) {
143 MMI_HILOGE("Send message failed, errCode:%{public}d", MSG_SEND_FAIL);
144 }
145 }
146
AddMonitor(const std::shared_ptr<SessionHandler> monitor,std::vector<int32_t> keys)147 int32_t EventPreMonitorHandler::MonitorCollection::AddMonitor(
148 const std::shared_ptr<SessionHandler> monitor, std::vector<int32_t> keys)
149 {
150 if (sessionHandlers_.size() >= MAX_N_INPUT_MONITORS) {
151 MMI_HILOGE("The number of monitors exceeds the maximum:%{public}zu, monitors errCode:%{public}d",
152 sessionHandlers_.size(),
153 INVALID_MONITOR_MON);
154 return RET_ERR;
155 }
156 for (auto &iter : sessionHandlers_) {
157 if (IsEqualsKeys(keys, iter.first)) {
158 iter.second.push_back(monitor);
159 return RET_OK;
160 }
161 }
162 sessionHandlers_[keys] = std::list<std::shared_ptr<SessionHandler>>();
163 sessionHandlers_[keys].push_back(monitor);
164
165 return RET_OK;
166 }
167
IsEqualsKeys(std::vector<int32_t> newKeys,std::vector<int32_t> oldKeys)168 bool EventPreMonitorHandler::MonitorCollection::IsEqualsKeys(std::vector<int32_t> newKeys, std::vector<int32_t> oldKeys)
169 {
170 if (newKeys.size() != oldKeys.size()) {
171 MMI_HILOGE("The size of preKeys is not match");
172 return false;
173 }
174
175 for (const auto &newKey : newKeys) {
176 auto it = std::find(oldKeys.begin(), oldKeys.end(), newKey);
177 if (it == oldKeys.end()) {
178 MMI_HILOGE("Can't find the key");
179 return false;
180 }
181 }
182
183 return true;
184 }
185
RemoveMonitor(SessionPtr sess,int32_t handlerId)186 void EventPreMonitorHandler::MonitorCollection::RemoveMonitor(SessionPtr sess, int32_t handlerId)
187 {
188 for (auto iter = sessionHandlers_.begin(); iter != sessionHandlers_.end();) {
189 auto &sessionHandlers = iter->second;
190 for (auto it = sessionHandlers.begin(); it != sessionHandlers.end();) {
191 CHKPC(*it);
192 if ((*it)->handlerId_ == handlerId && (*it)->session_ == sess) {
193 it = sessionHandlers.erase(it);
194 } else {
195 ++it;
196 }
197 }
198 if (sessionHandlers.empty()) {
199 iter = sessionHandlers_.erase(iter);
200 } else {
201 ++iter;
202 }
203 }
204 }
205
206 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleEvent(std::shared_ptr<KeyEvent> keyEvent)207 bool EventPreMonitorHandler::MonitorCollection::HandleEvent(std::shared_ptr<KeyEvent> keyEvent)
208 {
209 CHKPF(keyEvent);
210 MMI_HILOGD("Handle KeyEvent");
211 NetPacket pkt(MmiMessageId::ON_PRE_KEY_EVENT);
212 if (pkt.ChkRWError()) {
213 MMI_HILOGE("Packet write key event failed");
214 return false;
215 }
216 for (auto iter = sessionHandlers_.begin(); iter != sessionHandlers_.end(); iter++) {
217 auto &sessionHandlers = iter->second;
218 for (auto it = sessionHandlers.begin(); it != sessionHandlers.end(); it++) {
219 CHKPC(*it);
220 auto keys = (*it)->keys_;
221 auto keyIter = std::find(keys.begin(), keys.end(), keyEvent->GetKeyCode());
222 if (keyIter != keys.end()) {
223 (*it)->SendToClient(keyEvent, pkt, (*it)->handlerId_);
224 }
225 }
226 }
227 return false;
228 }
229 #endif // OHOS_BUILD_ENABLE_KEYBOARD
230
231 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)232 bool EventPreMonitorHandler::MonitorCollection::HandleEvent(std::shared_ptr<PointerEvent> pointerEvent)
233 {
234 return false;
235 }
236 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
237
OnSessionLost(SessionPtr session)238 void EventPreMonitorHandler::MonitorCollection::OnSessionLost(SessionPtr session)
239 {
240 CALL_INFO_TRACE;
241 for (auto iter = sessionHandlers_.begin(); iter != sessionHandlers_.end();) {
242 auto &handlers = iter->second;
243 for (auto inner = handlers.begin(); inner != handlers.end();) {
244 auto handler = *inner;
245 if (handler->session_ == session) {
246 inner = handlers.erase(inner);
247 } else {
248 ++inner;
249 }
250 }
251 if (handlers.empty()) {
252 iter = sessionHandlers_.erase(iter);
253 } else {
254 ++iter;
255 }
256 }
257 }
258
Dump(int32_t fd,const std::vector<std::string> & args)259 void EventPreMonitorHandler::Dump(int32_t fd, const std::vector<std::string> &args)
260 {
261 return monitors_.Dump(fd, args);
262 }
263
Dump(int32_t fd,const std::vector<std::string> & args)264 void EventPreMonitorHandler::MonitorCollection::Dump(int32_t fd, const std::vector<std::string> &args)
265 {
266 CALL_DEBUG_ENTER;
267 mprintf(fd, "Monitor information:\t");
268 mprintf(fd, "monitors: count=%zu", sessionHandlers_.size());
269 for (const auto &item : sessionHandlers_) {
270 const std::list<std::shared_ptr<SessionHandler>> &handlers = item.second;
271 for (const auto &handler : handlers) {
272 CHKPC(handler);
273 SessionPtr session = handler->session_;
274 if (!session) {
275 continue;
276 }
277 mprintf(fd,
278 "EventType:%d | Pid:%d | Uid:%d | Fd:%d "
279 "| EarliestEventTime:%" PRId64 " | Descript:%s "
280 "| ProgramName:%s \t",
281 handler->eventType_, session->GetPid(),
282 session->GetUid(), session->GetFd(),
283 session->GetEarliestEventTime(), session->GetDescript().c_str(),
284 session->GetProgramName().c_str());
285 }
286 }
287 }
288 } // namespace MMI
289 } // namespace OHOS
290