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_mouse_autoclick.h"
19 #include "accessibility_short_key.h"
20 #include "accessibility_touch_guider.h"
21 #include "accessibility_touchEvent_injector.h"
22 #include "accessibility_zoom_gesture.h"
23 #include "accessible_ability_manager_service.h"
24 #include "hilog_wrapper.h"
25 #include "key_event.h"
26 #include "input_event.h"
27
28 namespace OHOS {
29 namespace Accessibility {
30 sptr<AccessibilityInputInterceptor> AccessibilityInputInterceptor::instance_ = nullptr;
GetInstance()31 sptr<AccessibilityInputInterceptor> AccessibilityInputInterceptor::GetInstance()
32 {
33 HILOG_DEBUG();
34
35 if (!instance_) {
36 instance_ = new(std::nothrow) AccessibilityInputInterceptor();
37 if (!instance_) {
38 HILOG_ERROR("instance_ is null");
39 return nullptr;
40 }
41 }
42 return instance_;
43 }
44
AccessibilityInputInterceptor()45 AccessibilityInputInterceptor::AccessibilityInputInterceptor()
46 {
47 HILOG_DEBUG();
48
49 inputManager_ = MMI::InputManager::GetInstance();
50 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(
51 Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner());
52 }
53
~AccessibilityInputInterceptor()54 AccessibilityInputInterceptor::~AccessibilityInputInterceptor()
55 {
56 HILOG_DEBUG();
57
58 availableFunctions_ = 0;
59 DestroyInterceptor();
60 DestroyTransmitters();
61 inputManager_ = nullptr;
62 inputEventConsumer_ = nullptr;
63 }
64
OnKeyEvent(MMI::KeyEvent & event)65 bool AccessibilityInputInterceptor::OnKeyEvent(MMI::KeyEvent &event)
66 {
67 HILOG_DEBUG();
68
69 event.AddFlag(MMI::InputEvent::EVENT_FLAG_NO_INTERCEPT);
70 std::shared_ptr<MMI::KeyEvent> keyEvent = std::make_shared<MMI::KeyEvent>(event);
71 if (inputManager_) {
72 inputManager_->SimulateInputEvent(keyEvent);
73 } else {
74 HILOG_ERROR("inputManager_ is null.");
75 }
76 return true;
77 }
78
OnPointerEvent(MMI::PointerEvent & event)79 bool AccessibilityInputInterceptor::OnPointerEvent(MMI::PointerEvent &event)
80 {
81 HILOG_DEBUG("PointerAction:%{public}d, SourceType:%{public}d, PointerId:%{public}d",
82 event.GetPointerAction(), event.GetSourceType(), event.GetPointerId());
83
84 event.AddFlag(MMI::InputEvent::EVENT_FLAG_NO_INTERCEPT);
85 std::shared_ptr<MMI::PointerEvent> pointerEvent = std::make_shared<MMI::PointerEvent>(event);
86 if (inputManager_) {
87 inputManager_->SimulateInputEvent(pointerEvent);
88 } else {
89 HILOG_ERROR("inputManager_ is null.");
90 }
91 return true;
92 }
93
OnMoveMouse(int32_t offsetX,int32_t offsetY)94 void AccessibilityInputInterceptor::OnMoveMouse(int32_t offsetX, int32_t offsetY)
95 {
96 HILOG_DEBUG("offsetX:%{public}d, offsetY:%{public}d", offsetX, offsetY);
97 if (inputManager_) {
98 inputManager_->MoveMouse(offsetX, offsetY);
99 } else {
100 HILOG_ERROR("inputManager_ is null.");
101 }
102 }
103
SetAvailableFunctions(uint32_t availableFunctions)104 void AccessibilityInputInterceptor::SetAvailableFunctions(uint32_t availableFunctions)
105 {
106 HILOG_INFO("function[%{public}d].", availableFunctions);
107
108 if (availableFunctions_ == availableFunctions) {
109 return;
110 }
111 availableFunctions_ = availableFunctions;
112 DestroyTransmitters();
113 CreateTransmitters();
114 UpdateInterceptor();
115 }
116
CreateTransmitters()117 void AccessibilityInputInterceptor::CreateTransmitters()
118 {
119 HILOG_DEBUG("function[%{public}u].", availableFunctions_);
120
121 if (!availableFunctions_) {
122 return;
123 }
124
125 if ((availableFunctions_ & FEATURE_MOUSE_KEY) && (!mouseKey_)) {
126 mouseKey_ = new(std::nothrow) AccessibilityMouseKey();
127 if (mouseKey_) {
128 mouseKey_->SetNext(instance_);
129 }
130 }
131
132 if ((availableFunctions_ & FEATURE_MOUSE_AUTOCLICK) ||
133 (availableFunctions_ & FEATURE_INJECT_TOUCH_EVENTS) ||
134 (availableFunctions_ & FEATURE_TOUCH_EXPLORATION) ||
135 (availableFunctions_ & FEATURE_SCREEN_MAGNIFICATION)) {
136 CreatePointerEventTransmitters();
137 }
138
139 if ((availableFunctions_ & FEATURE_SHORT_KEY) ||
140 (availableFunctions_ & FEATURE_FILTER_KEY_EVENTS)) {
141 CreateKeyEventTransmitters();
142 }
143 }
144
CreatePointerEventTransmitters()145 void AccessibilityInputInterceptor::CreatePointerEventTransmitters()
146 {
147 HILOG_DEBUG();
148
149 sptr<EventTransmission> header = nullptr;
150 sptr<EventTransmission> current = nullptr;
151
152 if (availableFunctions_& FEATURE_MOUSE_AUTOCLICK) {
153 sptr<AccessibilityMouseAutoclick> mouseAutoclick = new(std::nothrow) AccessibilityMouseAutoclick();
154 if (!mouseAutoclick) {
155 HILOG_ERROR("mouseAutoclick is null");
156 return;
157 }
158 SetNextEventTransmitter(header, current, mouseAutoclick);
159 }
160
161 if (availableFunctions_& FEATURE_INJECT_TOUCH_EVENTS) {
162 sptr<TouchEventInjector> touchEventInjector = new(std::nothrow) TouchEventInjector();
163 if (!touchEventInjector) {
164 HILOG_ERROR("touchEventInjector is null");
165 return;
166 }
167 SetNextEventTransmitter(header, current, touchEventInjector);
168 Singleton<AccessibleAbilityManagerService>::GetInstance().SetTouchEventInjector(touchEventInjector);
169 }
170
171 if (availableFunctions_& FEATURE_SCREEN_MAGNIFICATION) {
172 sptr<AccessibilityZoomGesture> zoomGesture = new(std::nothrow) AccessibilityZoomGesture();
173 if (!zoomGesture) {
174 HILOG_ERROR("zoomGesture is null");
175 return;
176 }
177 SetNextEventTransmitter(header, current, zoomGesture);
178 }
179
180 if (availableFunctions_& FEATURE_TOUCH_EXPLORATION) {
181 sptr<TouchGuider> touchGuider = new(std::nothrow) TouchGuider();
182 if (!touchGuider) {
183 HILOG_ERROR("touchGuider is null");
184 return;
185 }
186 touchGuider->StartUp();
187 SetNextEventTransmitter(header, current, touchGuider);
188 }
189
190 SetNextEventTransmitter(header, current, instance_);
191 pointerEventTransmitters_ = header;
192 }
193
CreateKeyEventTransmitters()194 void AccessibilityInputInterceptor::CreateKeyEventTransmitters()
195 {
196 HILOG_DEBUG();
197
198 sptr<EventTransmission> header = nullptr;
199 sptr<EventTransmission> current = nullptr;
200
201 if (availableFunctions_& FEATURE_SHORT_KEY) {
202 sptr<AccessibilityShortKey> shortKey = new(std::nothrow) AccessibilityShortKey();
203 if (!shortKey) {
204 HILOG_ERROR("shortKey is null");
205 return;
206 }
207 SetNextEventTransmitter(header, current, shortKey);
208 }
209
210 if (availableFunctions_& FEATURE_FILTER_KEY_EVENTS) {
211 sptr<KeyEventFilter> keyEventFilter = new(std::nothrow) KeyEventFilter();
212 if (!keyEventFilter) {
213 HILOG_ERROR("keyEventFilter is null");
214 return;
215 }
216 Singleton<AccessibleAbilityManagerService>::GetInstance().SetKeyEventFilter(keyEventFilter);
217 SetNextEventTransmitter(header, current, keyEventFilter);
218 }
219
220 SetNextEventTransmitter(header, current, instance_);
221 keyEventTransmitters_ = header;
222 }
223
UpdateInterceptor()224 void AccessibilityInputInterceptor::UpdateInterceptor()
225 {
226 HILOG_DEBUG();
227 if (!inputManager_) {
228 HILOG_ERROR("inputManger is null.");
229 return;
230 }
231
232 HILOG_INFO("interceptorId:%{public}d", interceptorId_);
233 if ((availableFunctions_ & FEATURE_MOUSE_AUTOCLICK) ||
234 (availableFunctions_ & FEATURE_TOUCH_EXPLORATION) ||
235 (availableFunctions_ & FEATURE_SCREEN_MAGNIFICATION) ||
236 (availableFunctions_ & FEATURE_FILTER_KEY_EVENTS) ||
237 (availableFunctions_ & FEATURE_MOUSE_KEY) ||
238 (availableFunctions_ & FEATURE_SHORT_KEY)) {
239 if (interceptorId_ < 0) {
240 inputEventConsumer_ = std::make_shared<AccessibilityInputEventConsumer>();
241 interceptorId_ = inputManager_->AddInterceptor(inputEventConsumer_);
242 HILOG_DEBUG("interceptorId:%{public}d.", interceptorId_);
243 }
244 } else {
245 if (interceptorId_ >= 0) {
246 inputManager_->RemoveInterceptor(interceptorId_);
247 }
248 interceptorId_ = -1;
249 }
250 }
251
DestroyInterceptor()252 void AccessibilityInputInterceptor::DestroyInterceptor()
253 {
254 HILOG_DEBUG("interceptorId:%{public}d.", interceptorId_);
255
256 if (!inputManager_) {
257 HILOG_ERROR("inputManager_ is null.");
258 return;
259 }
260 if (interceptorId_ >= 0) {
261 inputManager_->RemoveInterceptor(interceptorId_);
262 }
263 interceptorId_ = -1;
264 }
265
DestroyTransmitters()266 void AccessibilityInputInterceptor::DestroyTransmitters()
267 {
268 HILOG_DEBUG();
269
270 if ((availableFunctions_ & FEATURE_MOUSE_KEY) != FEATURE_MOUSE_KEY) {
271 if (mouseKey_) {
272 mouseKey_->DestroyEvents();
273 mouseKey_ = nullptr;
274 }
275 }
276
277 if (pointerEventTransmitters_ != nullptr) {
278 pointerEventTransmitters_->DestroyEvents();
279 Singleton<AccessibleAbilityManagerService>::GetInstance().SetTouchEventInjector(nullptr);
280 pointerEventTransmitters_= nullptr;
281 }
282 if (keyEventTransmitters_ != nullptr) {
283 keyEventTransmitters_->DestroyEvents();
284 Singleton<AccessibleAbilityManagerService>::GetInstance().SetKeyEventFilter(nullptr);
285 keyEventTransmitters_ = nullptr;
286 }
287 }
288
ProcessPointerEvent(std::shared_ptr<MMI::PointerEvent> event) const289 void AccessibilityInputInterceptor::ProcessPointerEvent(std::shared_ptr<MMI::PointerEvent> event) const
290 {
291 HILOG_DEBUG();
292
293 if (mouseKey_) {
294 mouseKey_->OnPointerEvent(*event);
295 }
296
297 if (!pointerEventTransmitters_) {
298 HILOG_DEBUG("pointerEventTransmitters_ is empty.");
299 const_cast<AccessibilityInputInterceptor*>(this)->OnPointerEvent(*event);
300 return;
301 }
302
303 pointerEventTransmitters_->OnPointerEvent(*event);
304 }
305
ProcessKeyEvent(std::shared_ptr<MMI::KeyEvent> event) const306 void AccessibilityInputInterceptor::ProcessKeyEvent(std::shared_ptr<MMI::KeyEvent> event) const
307 {
308 HILOG_DEBUG();
309
310 if (mouseKey_) {
311 bool result = mouseKey_->OnKeyEvent(*event);
312 if (result) {
313 HILOG_DEBUG("The event is mouse key event.");
314 return;
315 }
316 }
317
318 if (!keyEventTransmitters_) {
319 HILOG_DEBUG("keyEventTransmitters_ is empty.");
320 const_cast<AccessibilityInputInterceptor*>(this)->OnKeyEvent(*event);
321 return;
322 }
323
324 keyEventTransmitters_->OnKeyEvent(*event);
325 }
326
SetNextEventTransmitter(sptr<EventTransmission> & header,sptr<EventTransmission> & current,const sptr<EventTransmission> & next)327 void AccessibilityInputInterceptor::SetNextEventTransmitter(sptr<EventTransmission> &header,
328 sptr<EventTransmission> ¤t, const sptr<EventTransmission> &next)
329 {
330 HILOG_DEBUG();
331
332 if (current != nullptr) {
333 current->SetNext(next);
334 } else {
335 header = next;
336 }
337 current = next;
338 }
339
AccessibilityInputEventConsumer()340 AccessibilityInputEventConsumer::AccessibilityInputEventConsumer()
341 {
342 HILOG_DEBUG();
343 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(
344 Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner());
345 }
346
~AccessibilityInputEventConsumer()347 AccessibilityInputEventConsumer::~AccessibilityInputEventConsumer()
348 {
349 HILOG_DEBUG();
350
351 eventHandler_ = nullptr;
352 }
353
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const354 void AccessibilityInputEventConsumer::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const
355 {
356 HILOG_DEBUG();
357 if (!keyEvent) {
358 HILOG_WARN("keyEvent is null.");
359 return;
360 }
361
362 auto interceptor = AccessibilityInputInterceptor::GetInstance();
363 if (!interceptor) {
364 HILOG_ERROR("interceptor is null.");
365 return;
366 }
367
368 if (!eventHandler_) {
369 HILOG_ERROR("eventHandler is empty.");
370 return;
371 }
372
373 auto task = std::bind(&AccessibilityInputInterceptor::ProcessKeyEvent, interceptor, keyEvent);
374 eventHandler_->PostTask(task, "InputKeyEvent");
375 }
376
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const377 void AccessibilityInputEventConsumer::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
378 {
379 if (!pointerEvent) {
380 HILOG_WARN("pointerEvent is null.");
381 return;
382 }
383 HILOG_DEBUG("PointerAction:%{public}d, SourceType:%{public}d, PointerId:%{public}d.",
384 pointerEvent->GetPointerAction(), pointerEvent->GetSourceType(), pointerEvent->GetPointerId());
385
386 auto interceptor = AccessibilityInputInterceptor::GetInstance();
387 if (!interceptor) {
388 HILOG_ERROR("interceptor is null.");
389 return;
390 }
391
392 if (!eventHandler_) {
393 HILOG_ERROR("eventHandler is empty.");
394 return;
395 }
396 auto task = std::bind(&AccessibilityInputInterceptor::ProcessPointerEvent, interceptor, pointerEvent);
397 eventHandler_->PostTask(task, "InputPointerEvent");
398 }
399 } // namespace Accessibility
400 } // namespace OHOS