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_ & FEATURE_SCREEN_MAGNIFICATION) != FEATURE_SCREEN_MAGNIFICATION) &&
110         (availableFunctions_ == availableFunctions) && ((availableFunctions & FEATURE_SCREEN_TOUCH) == 0)) {
111         return;
112     }
113     availableFunctions_ = availableFunctions;
114     DestroyTransmitters();
115     CreateTransmitters();
116     UpdateInterceptor();
117 }
118 
CreateTransmitters()119 void AccessibilityInputInterceptor::CreateTransmitters()
120 {
121     HILOG_DEBUG("function[%{public}u].", availableFunctions_);
122 
123     if (!availableFunctions_) {
124         return;
125     }
126 
127     if ((availableFunctions_ & FEATURE_MOUSE_KEY) && (!mouseKey_)) {
128         mouseKey_ = new(std::nothrow) AccessibilityMouseKey();
129         if (mouseKey_) {
130             mouseKey_->SetNext(instance_);
131         }
132     }
133 
134     if ((availableFunctions_ & FEATURE_MOUSE_AUTOCLICK) ||
135         (availableFunctions_ & FEATURE_INJECT_TOUCH_EVENTS) ||
136         (availableFunctions_ & FEATURE_TOUCH_EXPLORATION) ||
137         (availableFunctions_ & FEATURE_SCREEN_MAGNIFICATION) ||
138         (availableFunctions_ & FEATURE_SCREEN_TOUCH)) {
139         CreatePointerEventTransmitters();
140     }
141 
142     if (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_FILTER_KEY_EVENTS) {
213         sptr<KeyEventFilter> keyEventFilter = new(std::nothrow) KeyEventFilter();
214         if (!keyEventFilter) {
215             HILOG_ERROR("keyEventFilter is null");
216             return;
217         }
218         Singleton<AccessibleAbilityManagerService>::GetInstance().SetKeyEventFilter(keyEventFilter);
219         SetNextEventTransmitter(header, current, keyEventFilter);
220     }
221 
222     SetNextEventTransmitter(header, current, instance_);
223     keyEventTransmitters_ = header;
224 }
225 
UpdateInterceptor()226 void AccessibilityInputInterceptor::UpdateInterceptor()
227 {
228     HILOG_DEBUG();
229     if (!inputManager_) {
230         HILOG_ERROR("inputManger is null.");
231         return;
232     }
233 
234     if (interceptorId_ >= 0) {
235         inputManager_->RemoveInterceptor(interceptorId_);
236         interceptorId_ = -1;
237     }
238 
239     if ((availableFunctions_ & FEATURE_MOUSE_AUTOCLICK) ||
240         (availableFunctions_ & FEATURE_TOUCH_EXPLORATION) ||
241         (availableFunctions_ & FEATURE_SCREEN_MAGNIFICATION) ||
242         (availableFunctions_ & FEATURE_MOUSE_KEY) ||
243         (availableFunctions_ & FEATURE_SCREEN_TOUCH)) {
244             inputEventConsumer_ = std::make_shared<AccessibilityInputEventConsumer>();
245             interceptorId_ = inputManager_->AddInterceptor(inputEventConsumer_);
246     } else if (availableFunctions_ & FEATURE_FILTER_KEY_EVENTS) {
247             inputEventConsumer_ = std::make_shared<AccessibilityInputEventConsumer>();
248             interceptorId_ = inputManager_->AddInterceptor(inputEventConsumer_, PRIORITY_EVENT,
249                 MMI::CapabilityToTags(MMI::INPUT_DEV_CAP_KEYBOARD));
250     }
251     HILOG_INFO("interceptorId:%{public}d", interceptorId_);
252 }
253 
DestroyInterceptor()254 void AccessibilityInputInterceptor::DestroyInterceptor()
255 {
256     HILOG_DEBUG("interceptorId:%{public}d.", interceptorId_);
257 
258     if (!inputManager_) {
259         HILOG_ERROR("inputManager_ is null.");
260         return;
261     }
262     if (interceptorId_ >= 0) {
263         inputManager_->RemoveInterceptor(interceptorId_);
264     }
265     interceptorId_ = -1;
266 }
267 
DestroyTransmitters()268 void AccessibilityInputInterceptor::DestroyTransmitters()
269 {
270     std::lock_guard<ffrt::mutex> lock(mutex_);
271     HILOG_DEBUG();
272 
273     if ((availableFunctions_ & FEATURE_MOUSE_KEY) != FEATURE_MOUSE_KEY) {
274         if (mouseKey_) {
275             mouseKey_->DestroyEvents();
276             mouseKey_ = nullptr;
277         }
278     }
279 
280     if (pointerEventTransmitters_ != nullptr) {
281         pointerEventTransmitters_->DestroyEvents();
282         Singleton<AccessibleAbilityManagerService>::GetInstance().SetTouchEventInjector(nullptr);
283         pointerEventTransmitters_= nullptr;
284     }
285     if (keyEventTransmitters_ != nullptr) {
286         keyEventTransmitters_->DestroyEvents();
287         Singleton<AccessibleAbilityManagerService>::GetInstance().SetKeyEventFilter(nullptr);
288         keyEventTransmitters_ = nullptr;
289     }
290 }
291 
ProcessPointerEvent(std::shared_ptr<MMI::PointerEvent> event)292 void AccessibilityInputInterceptor::ProcessPointerEvent(std::shared_ptr<MMI::PointerEvent> event)
293 {
294     std::lock_guard<ffrt::mutex> lock(mutex_);
295     HILOG_DEBUG();
296 
297     if (mouseKey_) {
298         mouseKey_->OnPointerEvent(*event);
299     }
300 
301     if (!pointerEventTransmitters_) {
302         HILOG_DEBUG("pointerEventTransmitters_ is empty.");
303         const_cast<AccessibilityInputInterceptor*>(this)->OnPointerEvent(*event);
304         return;
305     }
306 
307     pointerEventTransmitters_->OnPointerEvent(*event);
308 }
309 
ProcessKeyEvent(std::shared_ptr<MMI::KeyEvent> event)310 void AccessibilityInputInterceptor::ProcessKeyEvent(std::shared_ptr<MMI::KeyEvent> event)
311 {
312     std::lock_guard<ffrt::mutex> lock(mutex_);
313     HILOG_DEBUG();
314 
315     if (mouseKey_) {
316         bool result = mouseKey_->OnKeyEvent(*event);
317         if (result) {
318             HILOG_DEBUG("The event is mouse key event.");
319             return;
320         }
321     }
322 
323     if (!keyEventTransmitters_) {
324         HILOG_DEBUG("keyEventTransmitters_ is empty.");
325         const_cast<AccessibilityInputInterceptor*>(this)->OnKeyEvent(*event);
326         return;
327     }
328 
329     keyEventTransmitters_->OnKeyEvent(*event);
330 }
331 
SetNextEventTransmitter(sptr<EventTransmission> & header,sptr<EventTransmission> & current,const sptr<EventTransmission> & next)332 void AccessibilityInputInterceptor::SetNextEventTransmitter(sptr<EventTransmission> &header,
333     sptr<EventTransmission> &current, const sptr<EventTransmission> &next)
334 {
335     HILOG_DEBUG();
336 
337     if (current != nullptr) {
338         current->SetNext(next);
339     } else {
340         header = next;
341     }
342     current = next;
343 }
344 
AccessibilityInputEventConsumer()345 AccessibilityInputEventConsumer::AccessibilityInputEventConsumer()
346 {
347     HILOG_DEBUG();
348     eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(
349         Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner());
350 }
351 
~AccessibilityInputEventConsumer()352 AccessibilityInputEventConsumer::~AccessibilityInputEventConsumer()
353 {
354     HILOG_DEBUG();
355 
356     eventHandler_ = nullptr;
357 }
358 
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const359 void AccessibilityInputEventConsumer::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const
360 {
361     HILOG_DEBUG();
362     if (!keyEvent) {
363         HILOG_WARN("keyEvent is null.");
364         return;
365     }
366 
367     auto interceptor = AccessibilityInputInterceptor::GetInstance();
368     if (!interceptor) {
369         HILOG_ERROR("interceptor is null.");
370         return;
371     }
372 
373     if (!eventHandler_) {
374         HILOG_ERROR("eventHandler is empty.");
375         return;
376     }
377 
378     auto task = [keyEvent, interceptor] {interceptor->ProcessKeyEvent(keyEvent);};
379     eventHandler_->PostTask(task, "InputKeyEvent");
380 }
381 
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const382 void AccessibilityInputEventConsumer::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
383 {
384     if (!pointerEvent) {
385         HILOG_WARN("pointerEvent is null.");
386         return;
387     }
388     HILOG_DEBUG("PointerAction:%{public}d, SourceType:%{public}d, PointerId:%{public}d.",
389         pointerEvent->GetPointerAction(), pointerEvent->GetSourceType(), pointerEvent->GetPointerId());
390 
391     auto interceptor = AccessibilityInputInterceptor::GetInstance();
392     if (!interceptor) {
393         HILOG_ERROR("interceptor is null.");
394         return;
395     }
396 
397     if (!eventHandler_) {
398         HILOG_ERROR("eventHandler is empty.");
399         return;
400     }
401     auto task = [pointerEvent, interceptor] {interceptor->ProcessPointerEvent(pointerEvent);};
402     eventHandler_->PostTask(task, "InputPointerEvent");
403 }
404 } // namespace Accessibility
405 } // namespace OHOS