• 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_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> &current, 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