• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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