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 "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 if (i.filter->HandleKeyEvent(event)) {
179 MMI_HILOGD("Call HandleKeyEventFilter return true");
180 return true;
181 }
182 }
183 return false;
184 }
185
HandlePointerEventFilter(std::shared_ptr<PointerEvent> event)186 bool EventFilterHandler::HandlePointerEventFilter(std::shared_ptr<PointerEvent> event)
187 {
188 CALL_DEBUG_ENTER;
189 CHKPF(event);
190 std::lock_guard<std::mutex> guard(lockFilter_);
191 if (filters_.empty()) {
192 return false;
193 }
194 std::shared_ptr<InputDevice> inputDevice = INPUT_DEV_MGR->GetInputDevice(event->GetDeviceId());
195 for (auto &i: filters_) {
196 if (inputDevice != nullptr && !inputDevice->HasCapability(i.deviceTags)) {
197 continue;
198 }
199 if (inputDevice == nullptr && !CheckCapability(i.deviceTags, event)) {
200 continue;
201 }
202 if (i.filter->HandlePointerEvent(event)) {
203 int32_t action = event->GetPointerAction();
204 if (action == PointerEvent::POINTER_ACTION_MOVE ||
205 action == PointerEvent::POINTER_ACTION_AXIS_UPDATE ||
206 action == PointerEvent::POINTER_ACTION_ROTATE_UPDATE ||
207 action == PointerEvent::POINTER_ACTION_PULL_MOVE ||
208 action == PointerEvent::POINTER_ACTION_HOVER_MOVE ||
209 action == PointerEvent::POINTER_ACTION_SWIPE_UPDATE) {
210 MMI_HILOGD("Call HandlePointerEvent return true");
211 } else {
212 MMI_HILOGW("Call HandlePointerEvent return true");
213 }
214 return true;
215 }
216 }
217 return false;
218 }
219
CheckCapability(uint32_t deviceTags,std::shared_ptr<PointerEvent> event)220 bool EventFilterHandler::CheckCapability(uint32_t deviceTags, std::shared_ptr<PointerEvent> event)
221 {
222 CALL_DEBUG_ENTER;
223 int32_t min = static_cast<int32_t>(INPUT_DEV_CAP_KEYBOARD);
224 int32_t max = static_cast<int32_t>(INPUT_DEV_CAP_MAX);
225 for (int32_t cap = min; cap < max; ++cap) {
226 InputDeviceCapability capability = static_cast<InputDeviceCapability>(cap);
227 uint32_t tags = CapabilityToTags(capability);
228 if ((tags & deviceTags) == tags) {
229 if (capability == INPUT_DEV_CAP_POINTER && event->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE) {
230 return true;
231 } else if (capability == INPUT_DEV_CAP_TOUCH &&
232 event->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
233 return true;
234 }
235 }
236 }
237 return false;
238 }
239
240 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
TouchPadKnuckleDoubleClickHandle(std::shared_ptr<KeyEvent> event)241 bool EventFilterHandler::TouchPadKnuckleDoubleClickHandle(std::shared_ptr<KeyEvent> event)
242 {
243 CHKPF(event);
244 CHKPF(nextHandler_);
245 if (event->GetKeyAction() != KNUCKLE_1F_DOUBLE_CLICK &&
246 event->GetKeyAction() != KNUCKLE_2F_DOUBLE_CLICK) {
247 return false;
248 }
249 MMI_HILOGI("Current is touchPad knuckle double click action");
250 nextHandler_->HandleKeyEvent(event);
251 return true;
252 }
253 #endif // OHOS_BUILD_ENABLE_KEYBOARD
254 } // namespace MMI
255 } // namespace OHOS
256