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