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