1 /*
2 * Copyright (c) 2021-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_filter_handler.h"
17
18 #include "dfx_hisysevent.h"
19
20 #undef MMI_LOG_DOMAIN
21 #define MMI_LOG_DOMAIN MMI_LOG_HANDLER
22 #undef MMI_LOG_TAG
23 #define MMI_LOG_TAG "EventFilterHandler"
24
25 namespace OHOS {
26 namespace MMI {
27 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)28 void EventFilterHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
29 {
30 CALL_DEBUG_ENTER;
31 CHKPV(keyEvent);
32 if (TouchPadKnuckleDoubleClickHandle(keyEvent)) {
33 return;
34 }
35 if (HandleKeyEventFilter(keyEvent)) {
36 DfxHisysevent::ReportKeyEvent("filter");
37 MMI_HILOGD("Key event is filtered");
38 return;
39 }
40 CHKPV(nextHandler_);
41 nextHandler_->HandleKeyEvent(keyEvent);
42 }
43 #endif // OHOS_BUILD_ENABLE_KEYBOARD
44
45 #ifdef OHOS_BUILD_ENABLE_POINTER
HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)46 void EventFilterHandler::HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)
47 {
48 CHKPV(pointerEvent);
49 if (HandlePointerEventFilter(pointerEvent)) {
50 return;
51 }
52 CHKPV(nextHandler_);
53 nextHandler_->HandlePointerEvent(pointerEvent);
54 }
55 #endif // OHOS_BUILD_ENABLE_POINTER
56
57 #ifdef OHOS_BUILD_ENABLE_TOUCH
HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)58 void EventFilterHandler::HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)
59 {
60 CHKPV(pointerEvent);
61 if (HandlePointerEventFilter(pointerEvent)) {
62 MMI_HILOGD("Touch event is filtered");
63 return;
64 }
65 CHKPV(nextHandler_);
66 nextHandler_->HandleTouchEvent(pointerEvent);
67 }
68 #endif // OHOS_BUILD_ENABLE_TOUCH
69
AddInputEventFilter(sptr<IEventFilter> filter,int32_t filterId,int32_t priority,uint32_t deviceTags,int32_t clientPid)70 int32_t EventFilterHandler::AddInputEventFilter(sptr<IEventFilter> filter,
71 int32_t filterId, int32_t priority, uint32_t deviceTags, int32_t clientPid)
72 {
73 CALL_INFO_TRACE;
74 std::lock_guard<std::mutex> guard(lockFilter_);
75 CHKPR(filter, ERROR_NULL_POINTER);
76 MMI_HILOGI("Add filter, filterId:%{public}d, priority:%{public}d, clientPid:%{public}d, filters_ size:%{public}zu",
77 filterId, priority, clientPid, filters_.size());
78
79 std::weak_ptr<EventFilterHandler> weakPtr = shared_from_this();
80 auto deathCallback = [weakPtr, filterId, clientPid](const wptr<IRemoteObject> &object) {
81 auto sharedPtr = weakPtr.lock();
82 if (sharedPtr != nullptr) {
83 auto ret = sharedPtr->RemoveInputEventFilter(filterId, clientPid);
84 if (ret != RET_OK) {
85 MMI_HILOGW("Remove filter on dead return:%{public}d, filterId:%{public}d, clientPid:%{public}d",
86 ret, filterId, clientPid);
87 } else {
88 MMI_HILOGW("Remove filter on dead success, filterId:%{public}d, clientPid:%{public}d",
89 filterId, clientPid);
90 }
91 }
92 };
93 sptr<IRemoteObject::DeathRecipient> deathRecipient = new (std::nothrow) EventFilterDeathRecipient(deathCallback);
94 CHKPR(deathRecipient, RET_ERR);
95 filter->AsObject()->AddDeathRecipient(deathRecipient);
96
97 FilterInfo info { .filter = filter, .deathRecipient = deathRecipient, .filterId = filterId,
98 .priority = priority, .deviceTags = deviceTags, .clientPid = clientPid };
99 auto it = filters_.cbegin();
100 for (; it != filters_.cend(); ++it) {
101 if (info.priority < it->priority) {
102 break;
103 }
104 }
105 auto it2 = filters_.emplace(it, std::move(info));
106 if (it2 == filters_.end()) {
107 MMI_HILOGE("Fail to add filter");
108 return ERROR_FILTER_ADD_FAIL;
109 }
110 return RET_OK;
111 }
112
RemoveInputEventFilter(int32_t filterId,int32_t clientPid)113 int32_t EventFilterHandler::RemoveInputEventFilter(int32_t filterId, int32_t clientPid)
114 {
115 CALL_INFO_TRACE;
116 std::lock_guard<std::mutex> guard(lockFilter_);
117 if (filters_.empty()) {
118 MMI_HILOGD("Filter is empty");
119 return RET_OK;
120 }
121 for (auto it = filters_.begin(); it != filters_.end();) {
122 if (filterId == -1) {
123 if (it->clientPid == clientPid) {
124 auto id = it->filterId;
125 filters_.erase(it++);
126 MMI_HILOGI("Filter remove success, filterId:%{public}d, clientPid:%{public}d", id, clientPid);
127 continue;
128 }
129 ++it;
130 continue;
131 }
132 if (it->IsSameClient(filterId, clientPid)) {
133 filters_.erase(it++);
134 MMI_HILOGI("Filter remove success, filterId:%{public}d, clientPid:%{public}d", filterId, clientPid);
135 return RET_OK;
136 }
137 ++it;
138 }
139 if (filterId == -1) {
140 return RET_OK;
141 }
142 MMI_HILOGI("Filter not found, filterId:%{public}d, clientPid:%{public}d", filterId, clientPid);
143 return RET_OK;
144 }
145
Dump(int32_t fd,const std::vector<std::string> & args)146 void EventFilterHandler::Dump(int32_t fd, const std::vector<std::string> &args)
147 {
148 CALL_DEBUG_ENTER;
149 std::lock_guard<std::mutex> guard(lockFilter_);
150 dprintf(fd, "Filter information:\n");
151 dprintf(fd, "Filters: count=%d\n", filters_.size());
152 for (const auto &item : filters_) {
153 dprintf(fd, "priority:%d | filterId:%d | Pid:%d\n", item.priority, item.filterId, item.clientPid);
154 }
155 }
156
HandleKeyEventFilter(std::shared_ptr<KeyEvent> event)157 bool EventFilterHandler::HandleKeyEventFilter(std::shared_ptr<KeyEvent> event)
158 {
159 CALL_DEBUG_ENTER;
160 CHKPF(event);
161 std::lock_guard<std::mutex> guard(lockFilter_);
162 if (filters_.empty()) {
163 return false;
164 }
165 std::vector<KeyEvent::KeyItem> keyItems = event->GetKeyItems();
166 if (keyItems.empty()) {
167 MMI_HILOGE("keyItems is empty");
168 DfxHisysevent::ReportFailHandleKey("HandleKeyEventFilter", event->GetKeyCode(),
169 DfxHisysevent::KEY_ERROR_CODE::INVALID_PARAMETER);
170 return false;
171 }
172 std::shared_ptr<InputDevice> inputDevice = INPUT_DEV_MGR->GetInputDevice(keyItems.front().GetDeviceId());
173 CHKPF(inputDevice);
174 for (auto &i: filters_) {
175 if (!inputDevice->HasCapability(i.deviceTags)) {
176 continue;
177 }
178 bool resultValue = false;
179 CHKPF(i.filter);
180 i.filter->HandleKeyEvent(event, resultValue);
181 if (resultValue) {
182 MMI_HILOGD("Call HandleKeyEventFilter return true");
183 return true;
184 }
185 }
186 return false;
187 }
188
HandlePointerEventFilter(std::shared_ptr<PointerEvent> event)189 bool EventFilterHandler::HandlePointerEventFilter(std::shared_ptr<PointerEvent> event)
190 {
191 CALL_DEBUG_ENTER;
192 CHKPF(event);
193 std::lock_guard<std::mutex> guard(lockFilter_);
194 if (filters_.empty()) {
195 return false;
196 }
197 std::shared_ptr<InputDevice> inputDevice = INPUT_DEV_MGR->GetInputDevice(event->GetDeviceId());
198 for (auto &i: filters_) {
199 if (inputDevice != nullptr && !inputDevice->HasCapability(i.deviceTags)) {
200 continue;
201 }
202 if (inputDevice == nullptr && !CheckCapability(i.deviceTags, event)) {
203 continue;
204 }
205 bool resultValue = false;
206 CHKPF(i.filter);
207 i.filter->HandlePointerEvent(event, resultValue);
208 if (resultValue) {
209 int32_t action = event->GetPointerAction();
210 if (action == PointerEvent::POINTER_ACTION_MOVE ||
211 action == PointerEvent::POINTER_ACTION_AXIS_UPDATE ||
212 action == PointerEvent::POINTER_ACTION_ROTATE_UPDATE ||
213 action == PointerEvent::POINTER_ACTION_PULL_MOVE ||
214 action == PointerEvent::POINTER_ACTION_HOVER_MOVE ||
215 action == PointerEvent::POINTER_ACTION_SWIPE_UPDATE) {
216 MMI_HILOGD("Call HandlePointerEvent return true");
217 } else {
218 MMI_HILOGW("Call HandlePointerEvent return true");
219 }
220 return true;
221 }
222 }
223 return false;
224 }
225
CheckCapability(uint32_t deviceTags,std::shared_ptr<PointerEvent> event)226 bool EventFilterHandler::CheckCapability(uint32_t deviceTags, std::shared_ptr<PointerEvent> event)
227 {
228 CALL_DEBUG_ENTER;
229 int32_t min = static_cast<int32_t>(INPUT_DEV_CAP_KEYBOARD);
230 int32_t max = static_cast<int32_t>(INPUT_DEV_CAP_MAX);
231 for (int32_t cap = min; cap < max; ++cap) {
232 InputDeviceCapability capability = static_cast<InputDeviceCapability>(cap);
233 uint32_t tags = CapabilityToTags(capability);
234 if ((tags & deviceTags) == tags) {
235 if (capability == INPUT_DEV_CAP_POINTER && event->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE) {
236 return true;
237 } else if (capability == INPUT_DEV_CAP_TOUCH &&
238 event->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
239 return true;
240 }
241 }
242 }
243 return false;
244 }
245
246 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
TouchPadKnuckleDoubleClickHandle(std::shared_ptr<KeyEvent> event)247 bool EventFilterHandler::TouchPadKnuckleDoubleClickHandle(std::shared_ptr<KeyEvent> event)
248 {
249 CHKPF(event);
250 CHKPF(nextHandler_);
251 if (event->GetKeyAction() != KNUCKLE_1F_DOUBLE_CLICK &&
252 event->GetKeyAction() != KNUCKLE_2F_DOUBLE_CLICK) {
253 return false;
254 }
255 MMI_HILOGI("Current is touchPad knuckle double click action");
256 nextHandler_->HandleKeyEvent(event);
257 return true;
258 }
259 #endif // OHOS_BUILD_ENABLE_KEYBOARD
260 } // namespace MMI
261 } // namespace OHOS
262