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 29namespace OHOS { 30namespace Accessibility { 31sptr<AccessibilityInputInterceptor> AccessibilityInputInterceptor::instance_ = nullptr; 32sptr<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 46AccessibilityInputInterceptor::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 55AccessibilityInputInterceptor::~AccessibilityInputInterceptor() 56{ 57 HILOG_DEBUG(); 58 59 availableFunctions_ = 0; 60 DestroyInterceptor(); 61 DestroyTransmitters(); 62 inputManager_ = nullptr; 63 inputEventConsumer_ = nullptr; 64} 65 66bool 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 80bool 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 95void 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 105void 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 119void 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 147void 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 205void 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 226void 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 254void 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 268void 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 292void 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 310void 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 332void AccessibilityInputInterceptor::SetNextEventTransmitter(sptr<EventTransmission> &header, 333 sptr<EventTransmission> ¤t, 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 345AccessibilityInputEventConsumer::AccessibilityInputEventConsumer() 346{ 347 HILOG_DEBUG(); 348 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>( 349 Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner()); 350} 351 352AccessibilityInputEventConsumer::~AccessibilityInputEventConsumer() 353{ 354 HILOG_DEBUG(); 355 356 eventHandler_ = nullptr; 357} 358 359void 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 382void 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