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 "error_multimodal.h"
19 #include "input_device_manager.h"
20 #include "mmi_log.h"
21 
22 #undef MMI_LOG_DOMAIN
23 #define MMI_LOG_DOMAIN MMI_LOG_HANDLER
24 #undef MMI_LOG_TAG
25 #define MMI_LOG_TAG "EventFilterHandler"
26 
27 namespace OHOS {
28 namespace MMI {
29 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)30 void EventFilterHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
31 {
32     CALL_DEBUG_ENTER;
33     CHKPV(keyEvent);
34     if (HandleKeyEventFilter(keyEvent)) {
35         MMI_HILOGD("Key event is filtered");
36         return;
37     }
38     CHKPV(nextHandler_);
39     nextHandler_->HandleKeyEvent(keyEvent);
40 }
41 #endif // OHOS_BUILD_ENABLE_KEYBOARD
42 
43 #ifdef OHOS_BUILD_ENABLE_POINTER
HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)44 void EventFilterHandler::HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)
45 {
46     CHKPV(pointerEvent);
47     if (HandlePointerEventFilter(pointerEvent)) {
48         return;
49     }
50     CHKPV(nextHandler_);
51     nextHandler_->HandlePointerEvent(pointerEvent);
52 }
53 #endif // OHOS_BUILD_ENABLE_POINTER
54 
55 #ifdef OHOS_BUILD_ENABLE_TOUCH
HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)56 void EventFilterHandler::HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)
57 {
58     CHKPV(pointerEvent);
59     if (HandlePointerEventFilter(pointerEvent)) {
60         MMI_HILOGD("Touch event is filtered");
61         return;
62     }
63     CHKPV(nextHandler_);
64     nextHandler_->HandleTouchEvent(pointerEvent);
65 }
66 #endif // OHOS_BUILD_ENABLE_TOUCH
67 
AddInputEventFilter(sptr<IEventFilter> filter,int32_t filterId,int32_t priority,uint32_t deviceTags,int32_t clientPid)68 int32_t EventFilterHandler::AddInputEventFilter(sptr<IEventFilter> filter,
69     int32_t filterId, int32_t priority, uint32_t deviceTags, int32_t clientPid)
70 {
71     CALL_INFO_TRACE;
72     std::lock_guard<std::mutex> guard(lockFilter_);
73     CHKPR(filter, ERROR_NULL_POINTER);
74     MMI_HILOGI("Add filter, filterId:%{public}d, priority:%{public}d, clientPid:%{public}d, filters_ size:%{public}zu",
75         filterId, priority, clientPid, filters_.size());
76     std::weak_ptr<EventFilterHandler> weakPtr = shared_from_this();
77     auto deathCallback = [weakPtr, filterId, clientPid](const wptr<IRemoteObject> &object) {
78         auto sharedPtr = weakPtr.lock();
79         if (sharedPtr != nullptr) {
80             auto ret = sharedPtr->RemoveInputEventFilter(filterId, clientPid);
81             if (ret != RET_OK) {
82                 MMI_HILOGW("Remove filter on dead return:%{public}d, filterId:%{public}d, clientPid:%{public}d",
83                     ret, filterId, clientPid);
84             } else {
85                 MMI_HILOGW("Remove filter on dead success, filterId:%{public}d, clientPid:%{public}d",
86                     filterId, clientPid);
87             }
88         }
89     };
90     sptr<IRemoteObject::DeathRecipient> deathRecipient = new (std::nothrow) EventFilterDeathRecipient(deathCallback);
91     CHKPR(deathRecipient, RET_ERR);
92     filter->AsObject()->AddDeathRecipient(deathRecipient);
93     FilterInfo info { .filter = filter, .deathRecipient = deathRecipient, .filterId = filterId,
94         .priority = priority, .deviceTags = deviceTags, .clientPid = clientPid };
95     auto it = filters_.cbegin();
96     for (; it != filters_.cend(); ++it) {
97         if (info.priority < it->priority) {
98             break;
99         }
100     }
101     auto it2 = filters_.emplace(it, std::move(info));
102     if (it2 == filters_.end()) {
103         MMI_HILOGE("Fail to add filter");
104         return ERROR_FILTER_ADD_FAIL;
105     }
106     return RET_OK;
107 }
108 
RemoveInputEventFilter(int32_t filterId,int32_t clientPid)109 int32_t EventFilterHandler::RemoveInputEventFilter(int32_t filterId, int32_t clientPid)
110 {
111     CALL_INFO_TRACE;
112     std::lock_guard<std::mutex> guard(lockFilter_);
113     if (filters_.empty()) {
114         MMI_HILOGD("Filter is empty");
115         return RET_OK;
116     }
117     for (auto it = filters_.begin(); it != filters_.end();) {
118         if (filterId == -1) {
119             if (it->clientPid == clientPid) {
120                 auto id = it->filterId;
121                 filters_.erase(it++);
122                 MMI_HILOGI("Filter remove success, filterId:%{public}d, clientPid:%{public}d", id, clientPid);
123                 continue;
124             }
125             ++it;
126             continue;
127         }
128         if (it->IsSameClient(filterId, clientPid)) {
129             filters_.erase(it++);
130             MMI_HILOGI("Filter remove success, filterId:%{public}d, clientPid:%{public}d", filterId, clientPid);
131             return RET_OK;
132         }
133         ++it;
134     }
135     if (filterId == -1) {
136         return RET_OK;
137     }
138     MMI_HILOGI("Filter not found, filterId:%{public}d, clientPid:%{public}d", filterId, clientPid);
139     return RET_OK;
140 }
141 
Dump(int32_t fd,const std::vector<std::string> & args)142 void EventFilterHandler::Dump(int32_t fd, const std::vector<std::string> &args)
143 {
144     CALL_DEBUG_ENTER;
145     std::lock_guard<std::mutex> guard(lockFilter_);
146     dprintf(fd, "Filter information:\n");
147     dprintf(fd, "Filters: count=%d\n", filters_.size());
148     for (const auto &item : filters_) {
149         dprintf(fd, "priority:%d | filterId:%d | Pid:%d\n", item.priority, item.filterId, item.clientPid);
150     }
151 }
152 
HandleKeyEventFilter(std::shared_ptr<KeyEvent> event)153 bool EventFilterHandler::HandleKeyEventFilter(std::shared_ptr<KeyEvent> event)
154 {
155     CALL_DEBUG_ENTER;
156     CHKPF(event);
157     std::lock_guard<std::mutex> guard(lockFilter_);
158     if (filters_.empty()) {
159         return false;
160     }
161     std::vector<KeyEvent::KeyItem> keyItems = event->GetKeyItems();
162     if (keyItems.empty()) {
163         MMI_HILOGE("keyItems is empty");
164         return false;
165     }
166     std::shared_ptr<InputDevice> inputDevice = INPUT_DEV_MGR->GetInputDevice(keyItems.front().GetDeviceId());
167     CHKPF(inputDevice);
168     for (auto &i: filters_) {
169         if (!inputDevice->HasCapability(i.deviceTags)) {
170             continue;
171         }
172         if (i.filter->HandleKeyEvent(event)) {
173             MMI_HILOGD("Call HandleKeyEventFilter return true");
174             return true;
175         }
176     }
177     return false;
178 }
179 
HandlePointerEventFilter(std::shared_ptr<PointerEvent> event)180 bool EventFilterHandler::HandlePointerEventFilter(std::shared_ptr<PointerEvent> event)
181 {
182     CALL_DEBUG_ENTER;
183     CHKPF(event);
184     std::lock_guard<std::mutex> guard(lockFilter_);
185     if (filters_.empty()) {
186         return false;
187     }
188     std::shared_ptr<InputDevice> inputDevice = INPUT_DEV_MGR->GetInputDevice(event->GetDeviceId());
189     CHKPF(inputDevice);
190     for (auto &i: filters_) {
191         if (!inputDevice->HasCapability(i.deviceTags)) {
192             continue;
193         }
194         if (i.filter->HandlePointerEvent(event)) {
195             MMI_HILOGD("Call HandlePointerEvent return true");
196             return true;
197         }
198     }
199     return false;
200 }
201 } // namespace MMI
202 } // namespace OHOS
203