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_touchEvent_injector.h"
17 #include "accessible_ability_manager_service.h"
18
19 namespace OHOS {
20 namespace Accessibility {
21 const int value_1000 = 1000;
22 const int value_1000000 = 1000000;
23 const int MS_TO_US = 1000;
TouchInjectHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner,TouchEventInjector & server)24 TouchInjectHandler::TouchInjectHandler(const std::shared_ptr<AppExecFwk::EventRunner> &runner,
25 TouchEventInjector &server) : AppExecFwk::EventHandler(runner), server_(server)
26 {
27 }
28
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)29 void TouchInjectHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
30 {
31 std::shared_ptr<SendEventArgs> parameters = nullptr;
32 switch (event->GetInnerEventId()) {
33 case TouchEventInjector::SEND_TOUCH_EVENT_MSG:
34 parameters = event->GetSharedObject<SendEventArgs>();
35 server_.SendPointerEvent(*parameters->event_);
36 if (parameters->isLastEvent_) {
37 server_.GetCurrentGestureService()->OnGestureSimulateResult(server_.GetSequence(), true);
38 }
39 break;
40 case TouchEventInjector::INJECT_EVENT_MSG:
41 server_.InjectEventsInner();
42 break;
43 default:
44 break;
45 }
46 }
47
TouchEventInjector()48 TouchEventInjector::TouchEventInjector()
49 {
50 runner_ = DelayedSingleton<AccessibleAbilityManagerService>::GetInstance()->GetMainRunner();
51 if (!runner_) {
52 HILOG_ERROR("get runner failed");
53 return;
54 }
55 handler_ = std::make_shared<TouchInjectHandler>(runner_, *this);
56 if (!handler_) {
57 HILOG_ERROR("create event handler failed");
58 return;
59 }
60 }
61
OnPointerEvent(MMI::PointerEvent & event)62 void TouchEventInjector::OnPointerEvent(MMI::PointerEvent &event)
63 {
64 HILOG_DEBUG("TouchEventInjector::OnPointerEvent: start");
65
66 EventTransmission::OnPointerEvent(event);
67 }
68
ClearEvents(uint32_t inputSource)69 void TouchEventInjector::ClearEvents(uint32_t inputSource)
70 {
71 if (!handler_->HasInnerEvent(SEND_TOUCH_EVENT_MSG)) {
72 isGestureUnderway_ = false;
73 }
74 EventTransmission::ClearEvents(inputSource);
75 }
76
DestroyEvents()77 void TouchEventInjector::DestroyEvents()
78 {
79 HILOG_INFO("TouchEventInjector::DestroyEvents: start");
80 CancelInjectedEvents();
81 isDestroyEvent_ = true;
82 EventTransmission::DestroyEvents();
83 }
84
GetTapsEvents(int64_t startTime)85 void TouchEventInjector::GetTapsEvents(int64_t startTime)
86 {
87 HILOG_INFO("TouchEventInjector::GetTapsEvents: start");
88 std::shared_ptr<MMI::PointerEvent> event;
89 MMI::PointerEvent::PointerItem pointer = {};
90 int64_t downTime = startTime;
91 int64_t nowTime = startTime;
92 pointer.SetPointerId(1);
93 for (unsigned int i = 0; i < gesturePath_.size(); i++) {
94 /* append down event */
95 float px = gesturePath_[i].GetStartPosition().GetPositionX();
96 float py = gesturePath_[i].GetStartPosition().GetPositionY();
97 pointer.SetGlobalX(px);
98 pointer.SetGlobalY(py);
99 pointer.SetDownTime(downTime * MS_TO_US);
100 event = obtainTouchEvent(MMI::PointerEvent::POINTER_ACTION_DOWN, pointer, downTime);
101 HILOG_INFO("append down event");
102 injectedEvents_.push_back(event);
103
104 nowTime += gesturePath_[i].GetDurationTime();
105 /* append up event */
106 px = gesturePath_[i].GetEndPosition().GetPositionX();
107 py = gesturePath_[i].GetEndPosition().GetPositionY();
108 pointer.SetGlobalX(px);
109 pointer.SetGlobalY(py);
110 pointer.SetDownTime(downTime * MS_TO_US);
111 event = obtainTouchEvent(MMI::PointerEvent::POINTER_ACTION_UP, pointer, nowTime);
112 HILOG_INFO("append up event");
113 injectedEvents_.push_back(event);
114 nowTime += DOUBLE_TAP_MIN_TIME;
115 downTime += DOUBLE_TAP_MIN_TIME;
116 }
117 }
118
GetMovesEvents(int64_t startTime)119 void TouchEventInjector::GetMovesEvents(int64_t startTime)
120 {
121 HILOG_INFO("TouchEventInjector::GetTapsEvents: start");
122 std::shared_ptr<MMI::PointerEvent> event;
123 MMI::PointerEvent::PointerItem pointer = {};
124 int64_t downTime = startTime;
125 int64_t nowTime = startTime;
126 /* append down event */
127 float px = gesturePath_[0].GetStartPosition().GetPositionX();
128 float py = gesturePath_[0].GetStartPosition().GetPositionY();
129 pointer.SetPointerId(1);
130 pointer.SetGlobalX(px);
131 pointer.SetGlobalY(py);
132 pointer.SetDownTime(downTime * MS_TO_US);
133 event = obtainTouchEvent(MMI::PointerEvent::POINTER_ACTION_DOWN, pointer, downTime);
134 HILOG_INFO("append down event");
135 injectedEvents_.push_back(event);
136 for (unsigned int i = 0; i < gesturePath_.size(); i++) {
137 px = gesturePath_[i].GetEndPosition().GetPositionX();
138 py = gesturePath_[i].GetEndPosition().GetPositionY();
139 pointer.SetGlobalX(px);
140 pointer.SetGlobalY(py);
141 pointer.SetDownTime(downTime * MS_TO_US);
142 HILOG_INFO("append move event");
143 nowTime += gesturePath_[i].GetDurationTime();
144 event = obtainTouchEvent(MMI::PointerEvent::POINTER_ACTION_MOVE, pointer, nowTime);
145 injectedEvents_.push_back(event);
146 }
147 /* append up event */
148 px = gesturePath_[gesturePath_.size() - 1].GetEndPosition().GetPositionX();
149 py = gesturePath_[gesturePath_.size() - 1].GetEndPosition().GetPositionY();
150 pointer.SetGlobalX(px);
151 pointer.SetGlobalY(py);
152 pointer.SetDownTime(downTime * MS_TO_US);
153 event = obtainTouchEvent(MMI::PointerEvent::POINTER_ACTION_UP, pointer, nowTime);
154 HILOG_INFO("append up event");
155 injectedEvents_.push_back(event);
156 }
157
InjectEvents(const std::vector<GesturePathDefine> & gesturePath,const sptr<IAccessibleAbilityClient> & service,int sequence)158 void TouchEventInjector::InjectEvents(const std::vector<GesturePathDefine> &gesturePath,
159 const sptr<IAccessibleAbilityClient> &service, int sequence)
160 {
161 sequence_ = sequence;
162 currentGestureService_ = service;
163 gesturePath_ = gesturePath;
164 handler_->SendEvent(INJECT_EVENT_MSG, 0, 0);
165 }
166
InjectEventsInner()167 void TouchEventInjector::InjectEventsInner()
168 {
169 HILOG_INFO("TouchEventInjector::InjectEventsInner: start");
170
171 int64_t curTime = getSystemTime();
172 if (isDestroyEvent_ || !GetNext()) {
173 currentGestureService_->OnGestureSimulateResult(sequence_, false);
174 return;
175 }
176 CancelInjectedEvents();
177 CancelGesture();
178
179 GetTouchEventsFromGesturePath(curTime);
180
181 if (injectedEvents_.empty()) {
182 currentGestureService_->OnGestureSimulateResult(sequence_, false);
183 return;
184 }
185 for (unsigned int i = 0; i < injectedEvents_.size(); i++) {
186 std::shared_ptr<SendEventArgs> parameters = std::make_shared<SendEventArgs>();
187 parameters->isLastEvent_ = (i == injectedEvents_.size() - 1) ? true : false;
188 parameters->event_ = injectedEvents_[i];
189 int64_t timeout = injectedEvents_[i]->GetActionTime() / MS_TO_US - curTime;
190
191 handler_->SendEvent(SEND_TOUCH_EVENT_MSG, parameters, timeout);
192 }
193 injectedEvents_.clear();
194 }
195
SendPointerEvent(MMI::PointerEvent & event)196 void TouchEventInjector::SendPointerEvent(MMI::PointerEvent &event)
197 {
198 HILOG_INFO("TouchEventInjector::SendPointerEvent: start");
199 if (GetNext() != nullptr) {
200 EventTransmission::OnPointerEvent(event);
201 if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN) {
202 isGestureUnderway_ = true;
203 }
204 if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP) {
205 isGestureUnderway_ = false;
206 }
207 }
208 }
209
CancelGesture()210 void TouchEventInjector::CancelGesture()
211 {
212 HILOG_INFO("TouchEventInjector::CancelGesture: start");
213 std::shared_ptr<MMI::PointerEvent> event;
214 MMI::PointerEvent::PointerItem pointer = {};
215 pointer.SetPointerId(1);
216 int64_t time = getSystemTime();
217 pointer.SetDownTime(time * MS_TO_US);
218 pointer.SetPointerId(1);
219 if (GetNext() != nullptr && isGestureUnderway_) {
220 event = obtainTouchEvent(MMI::PointerEvent::POINTER_ACTION_CANCEL, pointer, time);
221 SendPointerEvent(*event);
222 isGestureUnderway_ = false;
223 }
224 }
225
CancelInjectedEvents()226 void TouchEventInjector::CancelInjectedEvents()
227 {
228 HILOG_INFO("TouchEventInjector::CancelInjectedEvents: start");
229 if (handler_->HasInnerEvent(SEND_TOUCH_EVENT_MSG)) {
230 handler_->RemoveEvent(SEND_TOUCH_EVENT_MSG);
231 CancelGesture();
232 currentGestureService_->OnGestureSimulateResult(sequence_, false);
233 }
234 }
235
GetTouchEventsFromGesturePath(int64_t startTime)236 void TouchEventInjector::GetTouchEventsFromGesturePath(int64_t startTime)
237 {
238 HILOG_INFO("TouchEventInjector::GetTouchEventsFromGesturePath: start");
239 if (gesturePath_[0].GetStartPosition().GetPositionX() == gesturePath_[0].GetEndPosition().GetPositionX() &&
240 gesturePath_[0].GetStartPosition().GetPositionY() == gesturePath_[0].GetEndPosition().GetPositionY()) {
241 GetTapsEvents(startTime);
242 } else {
243 GetMovesEvents(startTime);
244 }
245 }
246
obtainTouchEvent(int action,MMI::PointerEvent::PointerItem point,int64_t actionTime)247 std::shared_ptr<MMI::PointerEvent> TouchEventInjector::obtainTouchEvent(int action,
248 MMI::PointerEvent::PointerItem point, int64_t actionTime)
249 {
250 HILOG_INFO("TouchEventInjector::obtainTouchEvent: start");
251 std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
252 pointerEvent->SetPointerId(point.GetPointerId());
253 pointerEvent->SetPointerAction(action);
254 pointerEvent->SetActionTime(actionTime * MS_TO_US);
255 pointerEvent->SetActionStartTime(point.GetDownTime());
256 pointerEvent->AddPointerItem(point);
257 pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
258 return pointerEvent;
259 }
260
getSystemTime()261 int64_t TouchEventInjector::getSystemTime()
262 {
263 HILOG_INFO("TouchEventInjector::getSystemTime: start");
264 struct timespec times = {0, 0};
265 clock_gettime(CLOCK_MONOTONIC, ×);
266 int64_t millisecond = (int64_t)(times.tv_sec * value_1000 + times.tv_nsec / value_1000000);
267
268 return millisecond;
269 }
270 } // namespace Accessibility
271 } // namespace OHOS