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