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_mouse_autoclick.h"
17 #include "accessible_ability_manager_service.h"
18 #include "hilog_wrapper.h"
19 #include "utils.h"
20
21 namespace OHOS {
22 namespace Accessibility {
23 namespace {
24 constexpr size_t POINTER_COUNT_1 = 1;
25 constexpr uint32_t AUTOCLICK_TIMEOUT_MSG = 1;
26 } // namespace
27
AccessibilityMouseAutoclick()28 AccessibilityMouseAutoclick::AccessibilityMouseAutoclick()
29 {
30 HILOG_DEBUG();
31
32 std::shared_ptr<AppExecFwk::EventRunner> runner =
33 Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner();
34 if (!runner) {
35 HILOG_ERROR("get runner failed");
36 return;
37 }
38
39 timeoutHandler_ = std::make_shared<MouseAutoclickEventHandler>(runner, *this);
40 if (!timeoutHandler_) {
41 HILOG_ERROR("create event handler failed");
42 }
43 }
44
~AccessibilityMouseAutoclick()45 AccessibilityMouseAutoclick::~AccessibilityMouseAutoclick()
46 {
47 HILOG_DEBUG();
48
49 timeoutHandler_ = nullptr;
50 lastMouseEvent_ = nullptr;
51 }
52
OnPointerEvent(MMI::PointerEvent & event)53 bool AccessibilityMouseAutoclick::OnPointerEvent(MMI::PointerEvent &event)
54 {
55 HILOG_DEBUG();
56
57 int32_t source = event.GetSourceType();
58 int32_t action = event.GetPointerAction();
59 std::vector<int32_t> pointers = event.GetPointerIds();
60 size_t pointerCount = pointers.size();
61 if ((source != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
62 (action != MMI::PointerEvent::POINTER_ACTION_MOVE) ||
63 (pointerCount != POINTER_COUNT_1)) {
64 CancelAutoclick();
65 } else {
66 RecognizeAutoclick(event);
67 }
68
69 EventTransmission::OnPointerEvent(event);
70 return false;
71 }
72
SendMouseClickEvent()73 void AccessibilityMouseAutoclick::SendMouseClickEvent()
74 {
75 HILOG_DEBUG();
76
77 if (!lastMouseEvent_) {
78 HILOG_DEBUG("No mouse event to be sent.");
79 return;
80 }
81
82 int64_t nowTime = GetSystemTime();
83 // Update event information.
84 lastMouseEvent_->SetActionTime(nowTime);
85 lastMouseEvent_->SetActionStartTime(nowTime);
86 lastMouseEvent_->SetButtonId(MMI::PointerEvent::MOUSE_BUTTON_LEFT);
87 lastMouseEvent_->SetButtonPressed(MMI::PointerEvent::MOUSE_BUTTON_LEFT);
88
89 // Update pointer item information.
90 int32_t pointerId = lastMouseEvent_->GetPointerId();
91 MMI::PointerEvent::PointerItem item;
92 lastMouseEvent_->GetPointerItem(pointerId, item);
93 item.SetDownTime(nowTime);
94 item.SetPressed(true);
95 lastMouseEvent_->UpdatePointerItem(pointerId, item);
96
97 // Send mouse left button down event.
98 lastMouseEvent_->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
99 EventTransmission::OnPointerEvent(*lastMouseEvent_);
100
101 // Send mouse left button up event.
102 lastMouseEvent_->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_BUTTON_UP);
103 EventTransmission::OnPointerEvent(*lastMouseEvent_);
104 }
105
ResetAutoclickInfo()106 void AccessibilityMouseAutoclick::ResetAutoclickInfo()
107 {
108 HILOG_DEBUG();
109
110 lastMouseEvent_ = nullptr;
111 }
112
DestroyEvents()113 void AccessibilityMouseAutoclick::DestroyEvents()
114 {
115 HILOG_DEBUG();
116
117 CancelAutoclick();
118 EventTransmission::DestroyEvents();
119 }
120
RecognizeAutoclick(MMI::PointerEvent & event)121 void AccessibilityMouseAutoclick::RecognizeAutoclick(MMI::PointerEvent &event)
122 {
123 HILOG_DEBUG();
124
125 bool isMove = IsMouseMovement(event);
126 if (!isMove) {
127 HILOG_DEBUG("Mouse is not moving.");
128 return;
129 }
130
131 lastMouseEvent_ = std::make_shared<MMI::PointerEvent>(event);
132 if (!timeoutHandler_) {
133 HILOG_ERROR("handler is null.");
134 return;
135 }
136 int64_t delayTime = GetDelayTime();
137 timeoutHandler_->RemoveEvent(AUTOCLICK_TIMEOUT_MSG);
138 timeoutHandler_->SendEvent(AUTOCLICK_TIMEOUT_MSG, 0, delayTime);
139 }
140
IsMouseMovement(MMI::PointerEvent & event)141 bool AccessibilityMouseAutoclick::IsMouseMovement(MMI::PointerEvent &event)
142 {
143 HILOG_DEBUG();
144
145 if (!lastMouseEvent_) {
146 return true;
147 }
148
149 int32_t pointerId = event.GetPointerId();
150 MMI::PointerEvent::PointerItem item;
151 event.GetPointerItem(pointerId, item);
152 int32_t newX = item.GetDisplayX();
153 int32_t newY = item.GetDisplayY();
154
155 pointerId = lastMouseEvent_->GetPointerId();
156 lastMouseEvent_->GetPointerItem(pointerId, item);
157 int32_t oldX = item.GetDisplayX();
158 int32_t oldY = item.GetDisplayY();
159 if ((newX != oldX) || (newY != oldY)) {
160 HILOG_DEBUG("Mouse is moving.");
161 return true;
162 }
163 return false;
164 }
165
CancelAutoclick()166 void AccessibilityMouseAutoclick::CancelAutoclick()
167 {
168 HILOG_DEBUG();
169
170 ResetAutoclickInfo();
171 timeoutHandler_->RemoveEvent(AUTOCLICK_TIMEOUT_MSG);
172 }
173
GetSystemTime()174 int64_t AccessibilityMouseAutoclick::GetSystemTime()
175 {
176 HILOG_DEBUG();
177
178 int64_t microsecond = Utils::GetSystemTime() * 1000;
179 return microsecond;
180 }
181
GetDelayTime()182 int64_t AccessibilityMouseAutoclick::GetDelayTime()
183 {
184 HILOG_DEBUG();
185
186 sptr<AccessibilityAccountData> accountData =
187 Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountData();
188 if (!accountData) {
189 HILOG_ERROR("GetCurrentAccountData failed");
190 return 0;
191 }
192
193 int32_t delayTime = accountData->GetConfig()->GetMouseAutoClick();
194 return delayTime;
195 }
196
MouseAutoclickEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner,AccessibilityMouseAutoclick & mouseAutoclick)197 AccessibilityMouseAutoclick::MouseAutoclickEventHandler::MouseAutoclickEventHandler(
198 const std::shared_ptr<AppExecFwk::EventRunner> &runner,
199 AccessibilityMouseAutoclick &mouseAutoclick)
200 : AppExecFwk::EventHandler(runner), mouseAutoclick_(mouseAutoclick)
201 {
202 HILOG_DEBUG();
203 }
204
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)205 void AccessibilityMouseAutoclick::MouseAutoclickEventHandler::ProcessEvent(
206 const AppExecFwk::InnerEvent::Pointer &event)
207 {
208 HILOG_DEBUG();
209
210 switch (event->GetInnerEventId()) {
211 case AUTOCLICK_TIMEOUT_MSG:
212 mouseAutoclick_.SendMouseClickEvent();
213 mouseAutoclick_.ResetAutoclickInfo();
214 break;
215 default:
216 break;
217 }
218 }
219 } // namespace Accessibility
220 } // namespace OHOS