1 /*
2 * Copyright (C) 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 "accessibility_keyevent_filter.h"
17 #include "accessible_ability_manager_service.h"
18 #include "hilog_wrapper.h"
19
20 namespace OHOS {
21 namespace Accessibility {
22 namespace {
23 int64_t g_taskTime = 500;
24 } // namespace
25
IsWantedKeyEvent(MMI::KeyEvent & event)26 static bool IsWantedKeyEvent(MMI::KeyEvent &event)
27 {
28 HILOG_DEBUG();
29
30 int32_t keyCode = event.GetKeyCode();
31 if (keyCode == MMI::KeyEvent::KEYCODE_VOLUME_UP || keyCode == MMI::KeyEvent::KEYCODE_VOLUME_DOWN) {
32 return true;
33 }
34 return false;
35 }
36
KeyEventFilter()37 KeyEventFilter::KeyEventFilter()
38 {
39 HILOG_DEBUG();
40
41 runner_ = Singleton<AccessibleAbilityManagerService>::GetInstance().GetInputManagerRunner();
42 if (!runner_) {
43 HILOG_ERROR("get runner failed");
44 return;
45 }
46
47 timeoutHandler_ = std::make_shared<KeyEventFilterEventHandler>(runner_, *this);
48 if (!timeoutHandler_) {
49 HILOG_ERROR("create event handler failed");
50 return;
51 }
52 }
53
~KeyEventFilter()54 KeyEventFilter::~KeyEventFilter()
55 {
56 HILOG_DEBUG();
57
58 std::lock_guard<ffrt::mutex> lock(mutex_);
59 eventMaps_.clear();
60 }
61
OnKeyEvent(MMI::KeyEvent & event)62 bool KeyEventFilter::OnKeyEvent(MMI::KeyEvent &event)
63 {
64 HILOG_DEBUG();
65
66 bool whetherIntercept = IsWantedKeyEvent(event);
67 if (whetherIntercept) {
68 DispatchKeyEvent(event);
69 return true;
70 }
71 EventTransmission::OnKeyEvent(event);
72 return false;
73 }
74
SetServiceOnKeyEventResult(AccessibleAbilityConnection & connection,bool isHandled,uint32_t sequenceNum)75 void KeyEventFilter::SetServiceOnKeyEventResult(AccessibleAbilityConnection &connection, bool isHandled,
76 uint32_t sequenceNum)
77 {
78 HILOG_DEBUG("isHandled[%{public}d], sequenceNum[%{public}u].", isHandled, sequenceNum);
79
80 std::shared_ptr<ProcessingEvent> processingEvent = FindProcessingEvent(connection, sequenceNum);
81 if (!processingEvent) {
82 HILOG_DEBUG("No event being processed.");
83 return;
84 }
85
86 if (!isHandled) {
87 if (!processingEvent->usedCount_) {
88 timeoutHandler_->RemoveEvent(processingEvent->seqNum_);
89 EventTransmission::OnKeyEvent(*processingEvent->event_);
90 }
91 } else {
92 timeoutHandler_->RemoveEvent(processingEvent->seqNum_);
93 RemoveProcessingEvent(processingEvent);
94 }
95 }
96
ClearServiceKeyEvents(AccessibleAbilityConnection & connection)97 void KeyEventFilter::ClearServiceKeyEvents(AccessibleAbilityConnection &connection)
98 {
99 HILOG_DEBUG();
100
101 std::lock_guard<ffrt::mutex> lock(mutex_);
102 for (auto iter = eventMaps_.begin(); iter != eventMaps_.end(); iter++) {
103 if (iter->first.GetRefPtr() != &connection) {
104 continue;
105 }
106
107 for (auto &val : iter->second) {
108 val->usedCount_--;
109 if (!val->usedCount_) {
110 EventTransmission::OnKeyEvent(*val->event_);
111 }
112 }
113 eventMaps_.erase(iter);
114 break;
115 }
116 }
117
DispatchKeyEvent(MMI::KeyEvent & event)118 void KeyEventFilter::DispatchKeyEvent(MMI::KeyEvent &event)
119 {
120 HILOG_DEBUG();
121
122 sptr<AccessibilityAccountData> accountData =
123 Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountData();
124 std::map<std::string, sptr<AccessibleAbilityConnection>> connectionMaps = accountData->GetConnectedA11yAbilities();
125
126 std::shared_ptr<ProcessingEvent> processingEvent = nullptr;
127 std::shared_ptr<MMI::KeyEvent> copyEvent = nullptr;
128 sequenceNum_++;
129 for (auto iter = connectionMaps.begin(); iter != connectionMaps.end(); iter++) {
130 if (iter->second->OnKeyPressEvent(event, sequenceNum_)) {
131 if (!processingEvent) {
132 processingEvent = std::make_shared<ProcessingEvent>();
133 copyEvent = std::make_shared<MMI::KeyEvent>(event);
134 processingEvent->event_ = copyEvent;
135 processingEvent->seqNum_ = sequenceNum_;
136 }
137 processingEvent->usedCount_++;
138
139 std::lock_guard<ffrt::mutex> lock(mutex_);
140 if (eventMaps_.find(iter->second) == eventMaps_.end()) {
141 std::vector<std::shared_ptr<ProcessingEvent>> processingEvens;
142 eventMaps_.insert(std::make_pair(iter->second, processingEvens));
143 }
144 eventMaps_.at(iter->second).emplace_back(processingEvent);
145 }
146 }
147
148 if (!processingEvent) {
149 HILOG_DEBUG("No service handles the event.");
150 sequenceNum_--;
151 EventTransmission::OnKeyEvent(event);
152 return;
153 }
154
155 timeoutHandler_->SendEvent(sequenceNum_, processingEvent, g_taskTime);
156 }
157
RemoveProcessingEvent(std::shared_ptr<ProcessingEvent> event)158 bool KeyEventFilter::RemoveProcessingEvent(std::shared_ptr<ProcessingEvent> event)
159 {
160 HILOG_DEBUG();
161
162 std::lock_guard<ffrt::mutex> lock(mutex_);
163 bool haveEvent = false;
164 for (auto iter = eventMaps_.begin(); iter != eventMaps_.end(); iter++) {
165 for (auto val = iter->second.begin(); val != iter->second.end(); val++) {
166 if (*val != event) {
167 continue;
168 }
169 (*val)->usedCount_--;
170 iter->second.erase(val);
171 haveEvent = true;
172 break;
173 }
174 }
175
176 return haveEvent;
177 }
178
FindProcessingEvent(AccessibleAbilityConnection & connection,uint32_t sequenceNum)179 std::shared_ptr<KeyEventFilter::ProcessingEvent> KeyEventFilter::FindProcessingEvent(
180 AccessibleAbilityConnection &connection, uint32_t sequenceNum)
181 {
182 HILOG_DEBUG();
183
184 std::shared_ptr<ProcessingEvent> processingEvent = nullptr;
185
186 std::lock_guard<ffrt::mutex> lock(mutex_);
187 for (auto iter = eventMaps_.begin(); iter != eventMaps_.end(); iter++) {
188 if (iter->first.GetRefPtr() != &connection) {
189 continue;
190 }
191
192 for (auto val = iter->second.begin(); val != iter->second.end(); val++) {
193 if ((*val) == nullptr) {
194 HILOG_ERROR("connection is null");
195 continue;
196 }
197 if ((*val)->seqNum_ != sequenceNum) {
198 continue;
199 }
200 processingEvent = *val;
201 iter->second.erase(val);
202 processingEvent->usedCount_--;
203 break;
204 }
205 break;
206 }
207
208 return processingEvent;
209 }
210
DestroyEvents()211 void KeyEventFilter::DestroyEvents()
212 {
213 HILOG_DEBUG();
214
215 std::lock_guard<ffrt::mutex> lock(mutex_);
216 timeoutHandler_->RemoveAllEvents();
217 eventMaps_.clear();
218 EventTransmission::DestroyEvents();
219 }
220
SendEventToNext(MMI::KeyEvent & event)221 void KeyEventFilter::SendEventToNext(MMI::KeyEvent &event)
222 {
223 HILOG_DEBUG();
224 EventTransmission::OnKeyEvent(event);
225 }
226
KeyEventFilterEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner,KeyEventFilter & keyEventFilter)227 KeyEventFilterEventHandler::KeyEventFilterEventHandler(
228 const std::shared_ptr<AppExecFwk::EventRunner> &runner, KeyEventFilter &keyEventFilter)
229 : AppExecFwk::EventHandler(runner), keyEventFilter_(keyEventFilter)
230 {
231 HILOG_DEBUG();
232 }
233
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)234 void KeyEventFilterEventHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
235 {
236 HILOG_DEBUG();
237
238 if (!event) {
239 HILOG_ERROR("event is null.");
240 return;
241 }
242
243 auto processingEvent = event->GetSharedObject<KeyEventFilter::ProcessingEvent>();
244 if (processingEvent == nullptr) {
245 HILOG_ERROR("processingEvent is nullptr");
246 return;
247 }
248 if (processingEvent->seqNum_ != event->GetInnerEventId()) {
249 HILOG_ERROR("event is wrong.");
250 return;
251 }
252
253 bool haveEvent = keyEventFilter_.RemoveProcessingEvent(processingEvent);
254 if (haveEvent) {
255 keyEventFilter_.SendEventToNext(*processingEvent->event_);
256 }
257 }
258 } // namespace Accessibility
259 } // namespace OHOS