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().GetMainRunner();
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 eventMaps_.clear();
59 }
60
OnKeyEvent(MMI::KeyEvent & event)61 bool KeyEventFilter::OnKeyEvent(MMI::KeyEvent &event)
62 {
63 HILOG_DEBUG();
64
65 bool whetherIntercept = IsWantedKeyEvent(event);
66 if (whetherIntercept) {
67 DispatchKeyEvent(event);
68 return true;
69 }
70 EventTransmission::OnKeyEvent(event);
71 return false;
72 }
73
SetServiceOnKeyEventResult(AccessibleAbilityConnection & connection,bool isHandled,uint32_t sequenceNum)74 void KeyEventFilter::SetServiceOnKeyEventResult(AccessibleAbilityConnection &connection, bool isHandled,
75 uint32_t sequenceNum)
76 {
77 HILOG_DEBUG("isHandled[%{public}d], sequenceNum[%{public}u].", isHandled, sequenceNum);
78
79 std::shared_ptr<ProcessingEvent> processingEvent = FindProcessingEvent(connection, sequenceNum);
80 if (!processingEvent) {
81 HILOG_DEBUG("No event being processed.");
82 return;
83 }
84
85 if (!isHandled) {
86 if (!processingEvent->usedCount_) {
87 timeoutHandler_->RemoveEvent(processingEvent->seqNum_);
88 EventTransmission::OnKeyEvent(*processingEvent->event_);
89 }
90 } else {
91 timeoutHandler_->RemoveEvent(processingEvent->seqNum_);
92 RemoveProcessingEvent(processingEvent);
93 }
94 }
95
ClearServiceKeyEvents(AccessibleAbilityConnection & connection)96 void KeyEventFilter::ClearServiceKeyEvents(AccessibleAbilityConnection &connection)
97 {
98 HILOG_DEBUG();
99
100 for (auto iter = eventMaps_.begin(); iter != eventMaps_.end(); iter++) {
101 if (iter->first.GetRefPtr() != &connection) {
102 continue;
103 }
104
105 for (auto &val : iter->second) {
106 val->usedCount_--;
107 if (!val->usedCount_) {
108 EventTransmission::OnKeyEvent(*val->event_);
109 }
110 }
111 eventMaps_.erase(iter);
112 break;
113 }
114 }
115
DispatchKeyEvent(MMI::KeyEvent & event)116 void KeyEventFilter::DispatchKeyEvent(MMI::KeyEvent &event)
117 {
118 HILOG_DEBUG();
119
120 sptr<AccessibilityAccountData> accountData =
121 Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountData();
122 std::map<std::string, sptr<AccessibleAbilityConnection>> connectionMaps = accountData->GetConnectedA11yAbilities();
123
124 std::shared_ptr<ProcessingEvent> processingEvent = nullptr;
125 std::shared_ptr<MMI::KeyEvent> copyEvent = nullptr;
126 sequenceNum_++;
127 for (auto iter = connectionMaps.begin(); iter != connectionMaps.end(); iter++) {
128 if (iter->second->OnKeyPressEvent(event, sequenceNum_)) {
129 if (!processingEvent) {
130 processingEvent = std::make_shared<ProcessingEvent>();
131 copyEvent = std::make_shared<MMI::KeyEvent>(event);
132 processingEvent->event_ = copyEvent;
133 processingEvent->seqNum_ = sequenceNum_;
134 }
135 processingEvent->usedCount_++;
136
137 if (eventMaps_.find(iter->second) == eventMaps_.end()) {
138 std::vector<std::shared_ptr<ProcessingEvent>> processingEvens;
139 eventMaps_.insert(std::make_pair(iter->second, processingEvens));
140 }
141 eventMaps_.at(iter->second).emplace_back(processingEvent);
142 }
143 }
144
145 if (!processingEvent) {
146 HILOG_DEBUG("No service handles the event.");
147 sequenceNum_--;
148 EventTransmission::OnKeyEvent(event);
149 return;
150 }
151
152 timeoutHandler_->SendEvent(sequenceNum_, processingEvent, g_taskTime);
153 }
154
RemoveProcessingEvent(std::shared_ptr<ProcessingEvent> event)155 bool KeyEventFilter::RemoveProcessingEvent(std::shared_ptr<ProcessingEvent> event)
156 {
157 HILOG_DEBUG();
158
159 bool haveEvent = false;
160 for (auto iter = eventMaps_.begin(); iter != eventMaps_.end(); iter++) {
161 for (auto val = iter->second.begin(); val != iter->second.end(); val++) {
162 if (*val != event) {
163 continue;
164 }
165 (*val)->usedCount_--;
166 iter->second.erase(val);
167 haveEvent = true;
168 break;
169 }
170 }
171
172 return haveEvent;
173 }
174
FindProcessingEvent(AccessibleAbilityConnection & connection,uint32_t sequenceNum)175 std::shared_ptr<KeyEventFilter::ProcessingEvent> KeyEventFilter::FindProcessingEvent(
176 AccessibleAbilityConnection &connection, uint32_t sequenceNum)
177 {
178 HILOG_DEBUG();
179
180 std::shared_ptr<ProcessingEvent> processingEvent = nullptr;
181
182 for (auto iter = eventMaps_.begin(); iter != eventMaps_.end(); iter++) {
183 if (iter->first.GetRefPtr() != &connection) {
184 continue;
185 }
186
187 for (auto val = iter->second.begin(); val != iter->second.end(); val++) {
188 if ((*val)->seqNum_ != sequenceNum) {
189 continue;
190 }
191 processingEvent = *val;
192 iter->second.erase(val);
193 processingEvent->usedCount_--;
194 break;
195 }
196 break;
197 }
198
199 return processingEvent;
200 }
201
DestroyEvents()202 void KeyEventFilter::DestroyEvents()
203 {
204 HILOG_DEBUG();
205
206 timeoutHandler_->RemoveAllEvents();
207 eventMaps_.clear();
208 EventTransmission::DestroyEvents();
209 }
210
SendEventToNext(MMI::KeyEvent & event)211 void KeyEventFilter::SendEventToNext(MMI::KeyEvent &event)
212 {
213 HILOG_DEBUG();
214 EventTransmission::OnKeyEvent(event);
215 }
216
KeyEventFilterEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner,KeyEventFilter & keyEventFilter)217 KeyEventFilterEventHandler::KeyEventFilterEventHandler(
218 const std::shared_ptr<AppExecFwk::EventRunner> &runner, KeyEventFilter &keyEventFilter)
219 : AppExecFwk::EventHandler(runner), keyEventFilter_(keyEventFilter)
220 {
221 HILOG_DEBUG();
222 }
223
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)224 void KeyEventFilterEventHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
225 {
226 HILOG_DEBUG();
227
228 if (!event) {
229 HILOG_ERROR("event is null.");
230 return;
231 }
232
233 auto processingEvent = event->GetSharedObject<KeyEventFilter::ProcessingEvent>();
234 if (processingEvent == nullptr) {
235 HILOG_ERROR("processingEvent is nullptr");
236 return;
237 }
238 if (processingEvent->seqNum_ != event->GetInnerEventId()) {
239 HILOG_ERROR("event is wrong.");
240 return;
241 }
242
243 bool haveEvent = keyEventFilter_.RemoveProcessingEvent(processingEvent);
244 if (haveEvent) {
245 keyEventFilter_.SendEventToNext(*processingEvent->event_);
246 }
247 }
248 } // namespace Accessibility
249 } // namespace OHOS