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_input_interceptor.h"
17 #include "accessibility_keyevent_filter.h"
18 #include "accessibility_touch_guider.h"
19 #include "accessibility_touchEvent_injector.h"
20 #include "accessibility_zoom_handler.h"
21 #include "accessible_ability_manager_service.h"
22 #include "hilog_wrapper.h"
23 #include "key_event.h"
24 #include "input_event.h"
25
26 namespace OHOS {
27 namespace Accessibility {
28 sptr<AccessibilityInputInterceptor> AccessibilityInputInterceptor::instance_ = nullptr;
GetInstance()29 sptr<AccessibilityInputInterceptor> AccessibilityInputInterceptor::GetInstance()
30 {
31 HILOG_DEBUG();
32
33 if (!instance_) {
34 instance_ = new(std::nothrow) AccessibilityInputInterceptor();
35 if (!instance_) {
36 HILOG_ERROR("instance_ is null");
37 return nullptr;
38 }
39 }
40 return instance_;
41 }
42
AccessibilityInputInterceptor()43 AccessibilityInputInterceptor::AccessibilityInputInterceptor()
44 {
45 HILOG_DEBUG();
46
47 aams_ = nullptr;
48 pointerEventTransmitters_ = nullptr;
49 keyEventTransmitters_ = nullptr;
50 aams_ = DelayedSingleton<AccessibleAbilityManagerService>::GetInstance();
51 if (!aams_) {
52 HILOG_DEBUG("aams_ is null.");
53 return;
54 }
55 inputManager_ = MMI::InputManager::GetInstance();
56 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(aams_->GetMainRunner());
57 }
58
~AccessibilityInputInterceptor()59 AccessibilityInputInterceptor::~AccessibilityInputInterceptor()
60 {
61 HILOG_DEBUG();
62
63 DestroyInterceptor();
64 DestroyTransmitters();
65 aams_ = nullptr;
66 pointerEventTransmitters_ = nullptr;
67 keyEventTransmitters_ = nullptr;
68 interceptorId_ = -1;
69 keyEventInterceptorId_ = -1;
70 inputManager_ = nullptr;
71 inputEventConsumer_ = nullptr;
72 }
73
OnKeyEvent(MMI::KeyEvent & event)74 void AccessibilityInputInterceptor::OnKeyEvent(MMI::KeyEvent &event)
75 {
76 HILOG_DEBUG();
77
78 event.AddFlag(MMI::InputEvent::EVENT_FLAG_NO_INTERCEPT);
79 std::shared_ptr<MMI::KeyEvent> keyEvent = std::make_shared<MMI::KeyEvent>(event);
80 if (inputManager_ != nullptr) {
81 inputManager_->SimulateInputEvent(keyEvent);
82 } else {
83 HILOG_DEBUG("inputManager_ is null.");
84 }
85 }
86
OnPointerEvent(MMI::PointerEvent & event)87 void AccessibilityInputInterceptor::OnPointerEvent(MMI::PointerEvent &event)
88 {
89 HILOG_DEBUG();
90 HILOG_DEBUG("PointerAction is %{public}d.", event.GetPointerAction());
91 HILOG_DEBUG("SourceType is %{public}d.", event.GetSourceType());
92 HILOG_DEBUG("PointerId is %{public}d.", event.GetPointerId());
93
94 event.AddFlag(MMI::InputEvent::EVENT_FLAG_NO_INTERCEPT);
95 std::shared_ptr<MMI::PointerEvent> pointerEvent = std::make_shared<MMI::PointerEvent>(event);
96 if (inputManager_ != nullptr) {
97 inputManager_->SimulateInputEvent(pointerEvent);
98 } else {
99 HILOG_DEBUG("inputManager_ is null.");
100 }
101 }
102
SetAvailableFunctions(uint32_t availableFunctions)103 void AccessibilityInputInterceptor::SetAvailableFunctions(uint32_t availableFunctions)
104 {
105 HILOG_DEBUG("function[%{public}d].", availableFunctions);
106
107 if (availableFunctions_ == availableFunctions) {
108 return;
109 }
110 availableFunctions_ = availableFunctions;
111 DestroyTransmitters();
112 CreateTransmitters();
113 }
114
CreateTransmitters()115 void AccessibilityInputInterceptor::CreateTransmitters()
116 {
117 HILOG_DEBUG("function[%{public}d].", availableFunctions_);
118
119 if (!availableFunctions_) {
120 DestroyInterceptor();
121 return;
122 }
123
124 sptr<EventTransmission> header = nullptr;
125 sptr<EventTransmission> current = nullptr;
126
127 if (availableFunctions_& FEATURE_INJECT_TOUCH_EVENTS) {
128 sptr<TouchEventInjector> touchEventInjector = new(std::nothrow) TouchEventInjector();
129 if (!touchEventInjector) {
130 HILOG_ERROR("touchEventInjector is null");
131 return;
132 }
133 SetNextEventTransmitter(header, current, touchEventInjector);
134 aams_->SetTouchEventInjector(touchEventInjector);
135 }
136
137 if (availableFunctions_& FEATURE_SCREEN_MAGNIFICATION) {
138 sptr<AccessibilityZoomHandler> zoomHandler = new(std::nothrow) AccessibilityZoomHandler(0);
139 if (!zoomHandler) {
140 HILOG_ERROR("zoomHandler is null");
141 return;
142 }
143 SetNextEventTransmitter(header, current, zoomHandler);
144 }
145
146 if (availableFunctions_& FEATURE_TOUCH_EXPLORATION) {
147 sptr<TouchGuider> touchGuider = new(std::nothrow) TouchGuider();
148 if (!touchGuider) {
149 HILOG_ERROR("touchGuider is null");
150 return;
151 }
152 touchGuider->StartUp();
153 SetNextEventTransmitter(header, current, touchGuider);
154 }
155
156 SetNextEventTransmitter(header, current, instance_);
157 pointerEventTransmitters_ = header;
158
159 if (availableFunctions_& FEATURE_FILTER_KEY_EVENTS) {
160 sptr<KeyEventFilter> keyEventFilter = new(std::nothrow) KeyEventFilter();
161 if (!keyEventFilter) {
162 HILOG_ERROR("keyEventFilter is null");
163 return;
164 }
165 aams_->SetKeyEventFilter(keyEventFilter);
166 keyEventFilter->SetNext(instance_);
167 keyEventTransmitters_ = keyEventFilter;
168 }
169
170 CreateInterceptor();
171 }
172
CreateInterceptor()173 void AccessibilityInputInterceptor::CreateInterceptor()
174 {
175 HILOG_DEBUG();
176
177 if (!inputManager_) {
178 HILOG_DEBUG("inputManger is null.");
179 return;
180 }
181
182 if (interceptorId_ == -1) {
183 inputEventConsumer_ = std::make_shared<AccessibilityInputEventConsumer>();
184 if ((availableFunctions_ & FEATURE_TOUCH_EXPLORATION) ||
185 (availableFunctions_ & FEATURE_SCREEN_MAGNIFICATION)) {
186 interceptorId_ = inputManager_->AddInterceptor(inputEventConsumer_);
187 HILOG_DEBUG("interceptorId_ is %{public}d.", interceptorId_);
188 }
189 }
190
191 if (keyEventInterceptorId_ == -1) {
192 if (availableFunctions_ & FEATURE_FILTER_KEY_EVENTS) {
193 keyEventInterceptorId_ = inputManager_->AddInterceptor(InterceptKeyEventCallback);
194 HILOG_DEBUG("keyEventInterceptorId_ is %{public}d.", keyEventInterceptorId_);
195 }
196 }
197 }
198
InterceptKeyEventCallback(std::shared_ptr<MMI::KeyEvent> keyEvent)199 void AccessibilityInputInterceptor::InterceptKeyEventCallback(std::shared_ptr<MMI::KeyEvent> keyEvent)
200 {
201 HILOG_DEBUG(" start.");
202
203 if (!instance_ || !instance_->eventHandler_) {
204 HILOG_ERROR("eventHandler is nullptr.");
205 return;
206 }
207 auto task = std::bind(&AccessibilityInputInterceptor::ProcessKeyEvent, instance_, keyEvent);
208 instance_->eventHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::LOW);
209 HILOG_DEBUG(" end.");
210 }
211
DestroyInterceptor()212 void AccessibilityInputInterceptor::DestroyInterceptor()
213 {
214 HILOG_DEBUG();
215
216 if (!inputManager_) {
217 HILOG_DEBUG("inputManager_ is null.");
218 return;
219 }
220 if (keyEventInterceptorId_ != -1) {
221 inputManager_->RemoveInterceptor(keyEventInterceptorId_);
222 keyEventInterceptorId_ = -1;
223 }
224
225 if (interceptorId_ != -1) {
226 inputManager_->RemoveInterceptor(interceptorId_);
227 interceptorId_ = -1;
228 }
229 }
230
DestroyTransmitters()231 void AccessibilityInputInterceptor::DestroyTransmitters()
232 {
233 HILOG_DEBUG();
234
235 if (pointerEventTransmitters_ != nullptr) {
236 pointerEventTransmitters_->DestroyEvents();
237 aams_->SetTouchEventInjector(nullptr);
238 pointerEventTransmitters_= nullptr;
239 }
240 if (keyEventTransmitters_ != nullptr) {
241 keyEventTransmitters_->DestroyEvents();
242 aams_->SetKeyEventFilter(nullptr);
243 keyEventTransmitters_ = nullptr;
244 }
245 }
246
NotifyAccessibilityEvent(AccessibilityEventInfo & event) const247 void AccessibilityInputInterceptor::NotifyAccessibilityEvent(AccessibilityEventInfo &event) const
248 {
249 HILOG_DEBUG();
250
251 if (pointerEventTransmitters_ != nullptr) {
252 pointerEventTransmitters_->OnAccessibilityEvent(event);
253 }
254 if (keyEventTransmitters_ != nullptr) {
255 keyEventTransmitters_->OnAccessibilityEvent(event);
256 }
257 }
258
ProcessPointerEvent(std::shared_ptr<MMI::PointerEvent> event) const259 void AccessibilityInputInterceptor::ProcessPointerEvent(std::shared_ptr<MMI::PointerEvent> event) const
260 {
261 HILOG_DEBUG();
262
263 if (!pointerEventTransmitters_) {
264 HILOG_DEBUG("pointerEventTransmitters_ is empty.");
265 return;
266 }
267
268 pointerEventTransmitters_->OnPointerEvent(*event);
269 }
270
ProcessKeyEvent(std::shared_ptr<MMI::KeyEvent> event) const271 void AccessibilityInputInterceptor::ProcessKeyEvent(std::shared_ptr<MMI::KeyEvent> event) const
272 {
273 HILOG_DEBUG();
274
275 if (!keyEventTransmitters_) {
276 HILOG_DEBUG("keyEventTransmitters_ is empty.");
277 return;
278 }
279
280 keyEventTransmitters_->OnKeyEvent(*event);
281 }
282
SetNextEventTransmitter(sptr<EventTransmission> & header,sptr<EventTransmission> & current,const sptr<EventTransmission> & next)283 void AccessibilityInputInterceptor::SetNextEventTransmitter(sptr<EventTransmission> &header,
284 sptr<EventTransmission> ¤t, const sptr<EventTransmission> &next)
285 {
286 HILOG_DEBUG();
287
288 if (current != nullptr) {
289 current->SetNext(next);
290 } else {
291 header = next;
292 }
293 current = next;
294 }
295
AccessibilityInputEventConsumer()296 AccessibilityInputEventConsumer::AccessibilityInputEventConsumer()
297 {
298 HILOG_DEBUG();
299
300 auto aams = DelayedSingleton<AccessibleAbilityManagerService>::GetInstance();
301 if (aams != nullptr) {
302 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(aams->GetMainRunner());
303 }
304 }
305
~AccessibilityInputEventConsumer()306 AccessibilityInputEventConsumer::~AccessibilityInputEventConsumer()
307 {
308 HILOG_DEBUG();
309
310 eventHandler_ = nullptr;
311 }
312
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const313 void AccessibilityInputEventConsumer::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const
314 {
315 HILOG_DEBUG("OnInputEvent keyEvent start.");
316
317 auto interceptor = AccessibilityInputInterceptor::GetInstance();
318 if (!interceptor) {
319 HILOG_DEBUG("interceptor is null.");
320 return;
321 }
322
323 if (!eventHandler_) {
324 HILOG_DEBUG("eventHandler_ is empty.");
325 return;
326 }
327
328 auto task = std::bind(&AccessibilityInputInterceptor::ProcessKeyEvent, interceptor, keyEvent);
329 eventHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::LOW);
330 HILOG_DEBUG("OnInputEvent keyEvent end.");
331 }
332
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const333 void AccessibilityInputEventConsumer::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
334 {
335 HILOG_DEBUG("OnInputEvent pointerEvent start.");
336 HILOG_DEBUG("PointerAction is %{public}d.", pointerEvent->GetPointerAction());
337 HILOG_DEBUG("SourceType is %{public}d.", pointerEvent->GetSourceType());
338 HILOG_DEBUG("PointerId is %{public}d.", pointerEvent->GetPointerId());
339
340 auto interceptor = AccessibilityInputInterceptor::GetInstance();
341 if (!interceptor) {
342 HILOG_DEBUG("interceptor is null.");
343 return;
344 }
345
346 if (!eventHandler_) {
347 HILOG_DEBUG("eventHandler_ is empty.");
348 return;
349 }
350 auto task = std::bind(&AccessibilityInputInterceptor::ProcessPointerEvent, interceptor, pointerEvent);
351 eventHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::LOW);
352 HILOG_DEBUG("OnInputEvent pointerEvent end.");
353 }
354 } // namespace Accessibility
355 } // namespace OHOS