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