• 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_touch_guider.h"
19 #include "accessibility_touchEvent_injector.h"
20 #include "accessibility_zoom_handler.h"
21 #include "accessible_ability_manager_service.h"
22 #include "hilog_wrapper.h"
23 #include "key_event.h"
24 #include "input_event.h"
25 
26 namespace OHOS {
27 namespace Accessibility {
28 sptr<AccessibilityInputInterceptor> AccessibilityInputInterceptor::instance_ = nullptr;
GetInstance()29 sptr<AccessibilityInputInterceptor> AccessibilityInputInterceptor::GetInstance()
30 {
31     HILOG_DEBUG();
32 
33     if (!instance_) {
34         instance_ = new(std::nothrow) AccessibilityInputInterceptor();
35         if (!instance_) {
36             HILOG_ERROR("instance_ is null");
37             return nullptr;
38         }
39     }
40     return instance_;
41 }
42 
AccessibilityInputInterceptor()43 AccessibilityInputInterceptor::AccessibilityInputInterceptor()
44 {
45     HILOG_DEBUG();
46 
47     aams_ = nullptr;
48     pointerEventTransmitters_ = nullptr;
49     keyEventTransmitters_ = nullptr;
50     aams_ = DelayedSingleton<AccessibleAbilityManagerService>::GetInstance();
51     if (!aams_) {
52         HILOG_DEBUG("aams_ is null.");
53         return;
54     }
55     inputManager_ = MMI::InputManager::GetInstance();
56     eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(aams_->GetMainRunner());
57 }
58 
~AccessibilityInputInterceptor()59 AccessibilityInputInterceptor::~AccessibilityInputInterceptor()
60 {
61     HILOG_DEBUG();
62 
63     DestroyInterceptor();
64     DestroyTransmitters();
65     aams_ = nullptr;
66     pointerEventTransmitters_ = nullptr;
67     keyEventTransmitters_ = nullptr;
68     interceptorId_ = -1;
69     keyEventInterceptorId_ = -1;
70     inputManager_ = nullptr;
71     inputEventConsumer_ = nullptr;
72 }
73 
OnKeyEvent(MMI::KeyEvent & event)74 void AccessibilityInputInterceptor::OnKeyEvent(MMI::KeyEvent &event)
75 {
76     HILOG_DEBUG();
77 
78     event.AddFlag(MMI::InputEvent::EVENT_FLAG_NO_INTERCEPT);
79     std::shared_ptr<MMI::KeyEvent> keyEvent = std::make_shared<MMI::KeyEvent>(event);
80     if (inputManager_ != nullptr) {
81         inputManager_->SimulateInputEvent(keyEvent);
82     } else {
83         HILOG_DEBUG("inputManager_ is null.");
84     }
85 }
86 
OnPointerEvent(MMI::PointerEvent & event)87 void AccessibilityInputInterceptor::OnPointerEvent(MMI::PointerEvent &event)
88 {
89     HILOG_DEBUG();
90     HILOG_DEBUG("PointerAction is %{public}d.", event.GetPointerAction());
91     HILOG_DEBUG("SourceType is %{public}d.", event.GetSourceType());
92     HILOG_DEBUG("PointerId is %{public}d.", event.GetPointerId());
93 
94     event.AddFlag(MMI::InputEvent::EVENT_FLAG_NO_INTERCEPT);
95     std::shared_ptr<MMI::PointerEvent> pointerEvent = std::make_shared<MMI::PointerEvent>(event);
96     if (inputManager_ != nullptr) {
97         inputManager_->SimulateInputEvent(pointerEvent);
98     } else {
99         HILOG_DEBUG("inputManager_ is null.");
100     }
101 }
102 
SetAvailableFunctions(uint32_t availableFunctions)103 void AccessibilityInputInterceptor::SetAvailableFunctions(uint32_t availableFunctions)
104 {
105     HILOG_DEBUG("function[%{public}d].", availableFunctions);
106 
107     if (availableFunctions_ == availableFunctions) {
108         return;
109     }
110     availableFunctions_ = availableFunctions;
111     DestroyTransmitters();
112     CreateTransmitters();
113 }
114 
CreateTransmitters()115 void AccessibilityInputInterceptor::CreateTransmitters()
116 {
117     HILOG_DEBUG("function[%{public}d].", availableFunctions_);
118 
119     if (!availableFunctions_) {
120         DestroyInterceptor();
121         return;
122     }
123 
124     sptr<EventTransmission> header = nullptr;
125     sptr<EventTransmission> current = nullptr;
126 
127     if (availableFunctions_& FEATURE_INJECT_TOUCH_EVENTS) {
128         sptr<TouchEventInjector> touchEventInjector = new(std::nothrow) TouchEventInjector();
129         if (!touchEventInjector) {
130             HILOG_ERROR("touchEventInjector is null");
131             return;
132         }
133         SetNextEventTransmitter(header, current, touchEventInjector);
134         aams_->SetTouchEventInjector(touchEventInjector);
135     }
136 
137     if (availableFunctions_& FEATURE_SCREEN_MAGNIFICATION) {
138         sptr<AccessibilityZoomHandler> zoomHandler = new(std::nothrow) AccessibilityZoomHandler(0);
139         if (!zoomHandler) {
140             HILOG_ERROR("zoomHandler is null");
141             return;
142         }
143         SetNextEventTransmitter(header, current, zoomHandler);
144     }
145 
146     if (availableFunctions_& FEATURE_TOUCH_EXPLORATION) {
147         sptr<TouchGuider> touchGuider = new(std::nothrow) TouchGuider();
148         if (!touchGuider) {
149             HILOG_ERROR("touchGuider is null");
150             return;
151         }
152         touchGuider->StartUp();
153         SetNextEventTransmitter(header, current, touchGuider);
154     }
155 
156     SetNextEventTransmitter(header, current, instance_);
157     pointerEventTransmitters_ = header;
158 
159     if (availableFunctions_& FEATURE_FILTER_KEY_EVENTS) {
160         sptr<KeyEventFilter> keyEventFilter = new(std::nothrow) KeyEventFilter();
161         if (!keyEventFilter) {
162             HILOG_ERROR("keyEventFilter is null");
163             return;
164         }
165         aams_->SetKeyEventFilter(keyEventFilter);
166         keyEventFilter->SetNext(instance_);
167         keyEventTransmitters_ = keyEventFilter;
168     }
169 
170     CreateInterceptor();
171 }
172 
CreateInterceptor()173 void AccessibilityInputInterceptor::CreateInterceptor()
174 {
175     HILOG_DEBUG();
176 
177     if (!inputManager_) {
178         HILOG_DEBUG("inputManger is null.");
179         return;
180     }
181 
182     if (interceptorId_ == -1) {
183         inputEventConsumer_ = std::make_shared<AccessibilityInputEventConsumer>();
184         if ((availableFunctions_ & FEATURE_TOUCH_EXPLORATION) ||
185             (availableFunctions_ & FEATURE_SCREEN_MAGNIFICATION)) {
186             interceptorId_ = inputManager_->AddInterceptor(inputEventConsumer_);
187             HILOG_DEBUG("interceptorId_ is %{public}d.", interceptorId_);
188         }
189     }
190 
191     if (keyEventInterceptorId_ == -1) {
192         if (availableFunctions_ & FEATURE_FILTER_KEY_EVENTS) {
193             keyEventInterceptorId_ = inputManager_->AddInterceptor(InterceptKeyEventCallback);
194             HILOG_DEBUG("keyEventInterceptorId_ is %{public}d.", keyEventInterceptorId_);
195         }
196     }
197 }
198 
InterceptKeyEventCallback(std::shared_ptr<MMI::KeyEvent> keyEvent)199 void AccessibilityInputInterceptor::InterceptKeyEventCallback(std::shared_ptr<MMI::KeyEvent> keyEvent)
200 {
201     HILOG_DEBUG(" start.");
202 
203     if (!instance_ || !instance_->eventHandler_) {
204         HILOG_ERROR("eventHandler is nullptr.");
205         return;
206     }
207     auto task = std::bind(&AccessibilityInputInterceptor::ProcessKeyEvent, instance_, keyEvent);
208     instance_->eventHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::LOW);
209     HILOG_DEBUG(" end.");
210 }
211 
DestroyInterceptor()212 void AccessibilityInputInterceptor::DestroyInterceptor()
213 {
214     HILOG_DEBUG();
215 
216     if (!inputManager_) {
217         HILOG_DEBUG("inputManager_ is null.");
218         return;
219     }
220     if (keyEventInterceptorId_ != -1) {
221         inputManager_->RemoveInterceptor(keyEventInterceptorId_);
222         keyEventInterceptorId_ = -1;
223     }
224 
225     if (interceptorId_ != -1) {
226         inputManager_->RemoveInterceptor(interceptorId_);
227         interceptorId_ = -1;
228     }
229 }
230 
DestroyTransmitters()231 void AccessibilityInputInterceptor::DestroyTransmitters()
232 {
233     HILOG_DEBUG();
234 
235     if (pointerEventTransmitters_ != nullptr) {
236         pointerEventTransmitters_->DestroyEvents();
237         aams_->SetTouchEventInjector(nullptr);
238         pointerEventTransmitters_= nullptr;
239     }
240     if (keyEventTransmitters_ != nullptr) {
241         keyEventTransmitters_->DestroyEvents();
242         aams_->SetKeyEventFilter(nullptr);
243         keyEventTransmitters_ = nullptr;
244     }
245 }
246 
NotifyAccessibilityEvent(AccessibilityEventInfo & event) const247 void AccessibilityInputInterceptor::NotifyAccessibilityEvent(AccessibilityEventInfo &event) const
248 {
249     HILOG_DEBUG();
250 
251     if (pointerEventTransmitters_ != nullptr) {
252         pointerEventTransmitters_->OnAccessibilityEvent(event);
253     }
254     if (keyEventTransmitters_ != nullptr) {
255         keyEventTransmitters_->OnAccessibilityEvent(event);
256     }
257 }
258 
ProcessPointerEvent(std::shared_ptr<MMI::PointerEvent> event) const259 void AccessibilityInputInterceptor::ProcessPointerEvent(std::shared_ptr<MMI::PointerEvent> event) const
260 {
261     HILOG_DEBUG();
262 
263     if (!pointerEventTransmitters_) {
264         HILOG_DEBUG("pointerEventTransmitters_ is empty.");
265         return;
266     }
267 
268     pointerEventTransmitters_->OnPointerEvent(*event);
269 }
270 
ProcessKeyEvent(std::shared_ptr<MMI::KeyEvent> event) const271 void AccessibilityInputInterceptor::ProcessKeyEvent(std::shared_ptr<MMI::KeyEvent> event) const
272 {
273     HILOG_DEBUG();
274 
275     if (!keyEventTransmitters_) {
276         HILOG_DEBUG("keyEventTransmitters_ is empty.");
277         return;
278     }
279 
280     keyEventTransmitters_->OnKeyEvent(*event);
281 }
282 
SetNextEventTransmitter(sptr<EventTransmission> & header,sptr<EventTransmission> & current,const sptr<EventTransmission> & next)283 void AccessibilityInputInterceptor::SetNextEventTransmitter(sptr<EventTransmission> &header,
284     sptr<EventTransmission> &current, const sptr<EventTransmission> &next)
285 {
286     HILOG_DEBUG();
287 
288     if (current != nullptr) {
289         current->SetNext(next);
290     } else {
291         header = next;
292     }
293     current = next;
294 }
295 
AccessibilityInputEventConsumer()296 AccessibilityInputEventConsumer::AccessibilityInputEventConsumer()
297 {
298     HILOG_DEBUG();
299 
300     auto aams = DelayedSingleton<AccessibleAbilityManagerService>::GetInstance();
301     if (aams != nullptr) {
302         eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(aams->GetMainRunner());
303     }
304 }
305 
~AccessibilityInputEventConsumer()306 AccessibilityInputEventConsumer::~AccessibilityInputEventConsumer()
307 {
308     HILOG_DEBUG();
309 
310     eventHandler_ = nullptr;
311 }
312 
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const313 void AccessibilityInputEventConsumer::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const
314 {
315     HILOG_DEBUG("OnInputEvent keyEvent start.");
316 
317     auto interceptor = AccessibilityInputInterceptor::GetInstance();
318     if (!interceptor) {
319         HILOG_DEBUG("interceptor is null.");
320         return;
321     }
322 
323     if (!eventHandler_) {
324         HILOG_DEBUG("eventHandler_ is empty.");
325         return;
326     }
327 
328     auto task = std::bind(&AccessibilityInputInterceptor::ProcessKeyEvent, interceptor, keyEvent);
329     eventHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::LOW);
330     HILOG_DEBUG("OnInputEvent keyEvent end.");
331 }
332 
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const333 void AccessibilityInputEventConsumer::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
334 {
335     HILOG_DEBUG("OnInputEvent pointerEvent start.");
336     HILOG_DEBUG("PointerAction is %{public}d.", pointerEvent->GetPointerAction());
337     HILOG_DEBUG("SourceType is %{public}d.", pointerEvent->GetSourceType());
338     HILOG_DEBUG("PointerId is %{public}d.", pointerEvent->GetPointerId());
339 
340     auto interceptor = AccessibilityInputInterceptor::GetInstance();
341     if (!interceptor) {
342         HILOG_DEBUG("interceptor is null.");
343         return;
344     }
345 
346     if (!eventHandler_) {
347         HILOG_DEBUG("eventHandler_ is empty.");
348         return;
349     }
350     auto task = std::bind(&AccessibilityInputInterceptor::ProcessPointerEvent, interceptor, pointerEvent);
351     eventHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::LOW);
352     HILOG_DEBUG("OnInputEvent pointerEvent end.");
353 }
354 } // namespace Accessibility
355 } // namespace OHOS