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