1 /*
2  * Copyright (C) 2023 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 <map>
17 #include "accessibility_screen_touch.h"
18 #include "accessibility_circle_drawing_manager.h"
19 #include "accessible_ability_manager_service.h"
20 #include "hilog_wrapper.h"
21 #include "utils.h"
22 #include "parameters.h"
23 
24 namespace OHOS {
25 namespace Accessibility {
26 
27 constexpr int32_t POINTER_COUNT_1 = 1;
28 
29 constexpr uint32_t CLICK_RESPONSE_DELAY_SHORT = 0;
30 constexpr uint32_t CLICK_RESPONSE_DELAY_MEDIUM = 1;
31 constexpr uint32_t CLICK_RESPONSE_DELAY_LONG = 2;
32 
33 constexpr uint32_t CLICK_RESPONSE_TIME_SHORT = 0; // ms
34 constexpr uint32_t CLICK_RESPONSE_TIME_MEDIUM = 300; // ms
35 constexpr uint32_t CLICK_RESPONSE_TIME_LONG = 600; // ms
36 
37 constexpr uint32_t IGNORE_REPEAT_CLICK_SHORTEST = 0;
38 constexpr uint32_t IGNORE_REPEAT_CLICK_SHORT = 1;
39 constexpr uint32_t IGNORE_REPEAT_CLICK_MEDIUM = 2;
40 constexpr uint32_t IGNORE_REPEAT_CLICK_LONG = 3;
41 constexpr uint32_t IGNORE_REPEAT_CLICK_LONGEST = 4;
42 
43 constexpr uint32_t IGNORE_REPEAT_CLICK_TIME_SHORTEST = 100; // ms
44 constexpr uint32_t IGNORE_REPEAT_CLICK_TIME_SHORT = 400; // ms
45 constexpr uint32_t IGNORE_REPEAT_CLICK_TIME_MEDIUM = 700; // ms
46 constexpr uint32_t IGNORE_REPEAT_CLICK_TIME_LONG = 1000; // ms
47 constexpr uint32_t IGNORE_REPEAT_CLICK_TIME_LONGEST = 1300; // ms
48 
49 constexpr uint32_t CIRCLE_ANGLE = 360;
50 constexpr uint32_t START_ANGLE_PORTRAIT = -90;
51 constexpr uint32_t START_ANGLE_LANDSCAPE = 180;
52 constexpr uint32_t START_ANGLE_PORTRAIT_INVERTED = 90;
53 constexpr uint32_t START_ANGLE_LANDSCAPE_INVERTED = 0;
54 
55 constexpr uint32_t NUMBER_10 = 10;
56 
57 constexpr float TOUCH_SLOP = 8.0f;
58 
59 const int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0);
60 const std::string FOLDABLE = system::GetParameter("const.window.foldabledevice.rotate_policy", "");
61 constexpr int32_t WINDOW_ROTATE = 0;
62 constexpr int32_t SCREEN_ROTATE = 1;
63 constexpr int32_t FOLDABLE_DEVICE = 2;
64 constexpr int32_t SUBSCRIPT_TWO = 2;
65 constexpr int32_t SUBSCRIPT_ZERO = 0;
66 constexpr char FOLDABLE_SCREEN_ROTATE = '1';
67 
68 const std::map<uint32_t, uint32_t> CLICK_RESPONSE_TIME_MAP = {
69     {CLICK_RESPONSE_DELAY_SHORT, CLICK_RESPONSE_TIME_SHORT},
70     {CLICK_RESPONSE_DELAY_MEDIUM, CLICK_RESPONSE_TIME_MEDIUM},
71     {CLICK_RESPONSE_DELAY_LONG, CLICK_RESPONSE_TIME_LONG}
72 };
73 
74 const std::map<uint32_t, uint32_t> IGNORE_REPEAT_CLICK_TIME_MAP = {
75     {IGNORE_REPEAT_CLICK_SHORTEST, IGNORE_REPEAT_CLICK_TIME_SHORTEST},
76     {IGNORE_REPEAT_CLICK_SHORT, IGNORE_REPEAT_CLICK_TIME_SHORT},
77     {IGNORE_REPEAT_CLICK_MEDIUM, IGNORE_REPEAT_CLICK_TIME_MEDIUM},
78     {IGNORE_REPEAT_CLICK_LONG, IGNORE_REPEAT_CLICK_TIME_LONG},
79     {IGNORE_REPEAT_CLICK_LONGEST, IGNORE_REPEAT_CLICK_TIME_LONGEST}
80 };
81 
82 int64_t AccessibilityScreenTouch::lastUpTime = 0; // global last up time
83 
ScreenTouchHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner,AccessibilityScreenTouch & server)84 ScreenTouchHandler::ScreenTouchHandler(const std::shared_ptr<AppExecFwk::EventRunner> &runner,
85     AccessibilityScreenTouch &server) : AppExecFwk::EventHandler(runner), server_(server)
86 {
87 }
88 
AccessibilityScreenTouch()89 AccessibilityScreenTouch::AccessibilityScreenTouch()
90 {
91     HILOG_DEBUG();
92     // get from account data directly
93     sptr<AccessibilityAccountData> accountData =
94         Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountData();
95     clickResponseTime_ = accountData->GetConfig()->GetClickResponseTime();
96     ignoreRepeatClickState_ = accountData->GetConfig()->GetIgnoreRepeatClickState();
97     ignoreRepeatClickTime_ = accountData->GetConfig()->GetIgnoreRepeatClickTime();
98 
99     if (clickResponseTime_ > 0 && ignoreRepeatClickState_ == true) {
100         currentState_ = BOTH_RESPONSE_DELAY_IGNORE_REPEAT_CLICK;
101     } else if (clickResponseTime_ > 0) {
102         currentState_ = CLICK_RESPONSE_DELAY_STATE;
103     } else if (ignoreRepeatClickState_ == true) {
104         currentState_ = IGNORE_REPEAT_CLICK_STATE;
105     } else {
106         currentState_ = DEFAULT_STATE;
107     }
108 
109     lastUpTime_ = lastUpTime;
110 
111     runner_ = Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner();
112     if (!runner_) {
113         HILOG_ERROR("get runner failed");
114         return;
115     }
116     handler_ = std::make_shared<ScreenTouchHandler>(runner_, *this);
117     if (!handler_) {
118         HILOG_ERROR("create event handler failed");
119         return;
120     }
121 }
122 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)123 void ScreenTouchHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
124 {
125     HILOG_DEBUG();
126     switch (event->GetInnerEventId()) {
127         case AccessibilityScreenTouch::FINGER_DOWN_DELAY_MSG:
128             server_.SendInterceptedEvent();
129             break;
130         default:
131             break;
132     }
133 }
134 
~AccessibilityScreenTouch()135 AccessibilityScreenTouch::~AccessibilityScreenTouch()
136 {
137     lastUpTime = lastUpTime_;
138     if (drawCircleThread_ && drawCircleThread_->joinable()) {
139         drawCircleThread_->join();
140     }
141     drawCircleThread_ = nullptr;
142     AccessibilityCircleDrawingManager::DeleteInstance();
143 }
144 
SendInterceptedEvent()145 void AccessibilityScreenTouch::SendInterceptedEvent()
146 {
147     HILOG_DEBUG();
148     isStopDrawCircle_ = true;
149 
150     if (cachedDownPointerEvents_.empty()) {
151         HILOG_ERROR("Cached down pointer event is empty!");
152         return;
153     }
154 
155     for (auto iter = cachedDownPointerEvents_.begin(); iter != cachedDownPointerEvents_.end(); ++iter) {
156         iter->SetActionTime(Utils::GetSystemTime() * US_TO_MS);
157         EventTransmission::OnPointerEvent(*iter);
158     }
159 }
160 
GetRealClickResponseTime()161 uint32_t AccessibilityScreenTouch::GetRealClickResponseTime()
162 {
163     auto iter = CLICK_RESPONSE_TIME_MAP.find(clickResponseTime_);
164     if (iter != CLICK_RESPONSE_TIME_MAP.end()) {
165         return iter->second;
166     }
167 
168     return CLICK_RESPONSE_TIME_MAP.at(CLICK_RESPONSE_DELAY_SHORT);
169 }
170 
GetRealIgnoreRepeatClickTime()171 uint32_t AccessibilityScreenTouch::GetRealIgnoreRepeatClickTime()
172 {
173     auto iter = IGNORE_REPEAT_CLICK_TIME_MAP.find(ignoreRepeatClickTime_);
174     if (iter != IGNORE_REPEAT_CLICK_TIME_MAP.end()) {
175         return iter->second;
176     }
177 
178     return IGNORE_REPEAT_CLICK_TIME_MAP.at(IGNORE_REPEAT_CLICK_SHORTEST);
179 }
180 
GetRealIgnoreRepeatClickState()181 bool AccessibilityScreenTouch::GetRealIgnoreRepeatClickState()
182 {
183     return ignoreRepeatClickState_;
184 }
185 
ConversionCoordinates(int32_t originalX,int32_t originalY)186 void AccessibilityScreenTouch::ConversionCoordinates(int32_t originalX, int32_t originalY)
187 {
188 #ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
189     AccessibilityDisplayManager &displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance();
190     int32_t displayWidth = displayMgr.GetWidth();
191     int32_t displayHeight = displayMgr.GetHeight();
192 
193     OHOS::Rosen::DisplayOrientation orientation = displayMgr.GetOrientation();
194     switch (orientation) {
195         case OHOS::Rosen::DisplayOrientation::PORTRAIT:
196             circleCenterPhysicalX_ = originalX;
197             circleCenterPhysicalY_ = originalY;
198             startAngle_ = START_ANGLE_PORTRAIT;
199             break;
200         case OHOS::Rosen::DisplayOrientation::LANDSCAPE:
201             circleCenterPhysicalX_ = originalY;
202             circleCenterPhysicalY_ = displayWidth - originalX;
203             startAngle_ = START_ANGLE_LANDSCAPE;
204             break;
205         case OHOS::Rosen::DisplayOrientation::PORTRAIT_INVERTED:
206             circleCenterPhysicalX_ = displayWidth - originalX;
207             circleCenterPhysicalY_ = displayHeight - originalY;
208             startAngle_ = START_ANGLE_PORTRAIT_INVERTED;
209             break;
210         case OHOS::Rosen::DisplayOrientation::LANDSCAPE_INVERTED:
211             circleCenterPhysicalX_ = displayHeight - originalY;
212             circleCenterPhysicalY_ = originalX;
213             startAngle_ = START_ANGLE_LANDSCAPE_INVERTED;
214             break;
215         default:
216             break;
217     }
218 #endif
219 }
220 
HandleCoordinates(MMI::PointerEvent::PointerItem & pointerItem)221 void AccessibilityScreenTouch::HandleCoordinates(MMI::PointerEvent::PointerItem &pointerItem)
222 {
223     int32_t originalX = pointerItem.GetDisplayX();
224     int32_t originalY = pointerItem.GetDisplayY();
225 
226 #ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
227     AccessibilityDisplayManager &displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance();
228     switch (ROTATE_POLICY) {
229         case WINDOW_ROTATE:
230             ConversionCoordinates(originalX, originalY);
231             break;
232         case SCREEN_ROTATE:
233             circleCenterPhysicalX_ = originalX;
234             circleCenterPhysicalY_ = originalY;
235             startAngle_ = START_ANGLE_PORTRAIT;
236             break;
237         case FOLDABLE_DEVICE:
238             if ((displayMgr.GetFoldStatus() == Rosen::FoldStatus::EXPAND &&
239                 FOLDABLE[SUBSCRIPT_TWO] == FOLDABLE_SCREEN_ROTATE) ||
240                 (displayMgr.GetFoldStatus() == Rosen::FoldStatus::FOLDED &&
241                 FOLDABLE[SUBSCRIPT_ZERO] == FOLDABLE_SCREEN_ROTATE)) {
242                 circleCenterPhysicalX_ = originalX;
243                 circleCenterPhysicalY_ = originalY;
244                 startAngle_ = START_ANGLE_PORTRAIT;
245             } else {
246                 ConversionCoordinates(originalX, originalY);
247             }
248             break;
249         default:
250             HILOG_WARN("unknown rotate policy");
251             ConversionCoordinates(originalX, originalY);
252             break;
253     }
254 #else
255     HILOG_WARN("display manager is not enable");
256     circleCenterPhysicalX_ = originalX;
257     circleCenterPhysicalY_ = originalY;
258     startAngle_ = START_ANGLE_PORTRAIT;
259 #endif
260 }
261 
DrawCircleProgress()262 void AccessibilityScreenTouch::DrawCircleProgress()
263 {
264     HILOG_DEBUG();
265 
266     AccessibilityCircleDrawingManager::GetInstance()->DrawPointer(circleCenterPhysicalX_,
267         circleCenterPhysicalY_, 0, screenId_, startAngle_);
268     AccessibilityCircleDrawingManager::GetInstance()->UpdatePointerVisible(true);
269     uint32_t times = GetRealClickResponseTime() / NUMBER_10;
270     uint32_t step = CIRCLE_ANGLE / times;
271     uint32_t time = 0;
272     while (time < times && isStopDrawCircle_ == false) {
273         AccessibilityCircleDrawingManager::GetInstance()->DrawPointer(circleCenterPhysicalX_,
274             circleCenterPhysicalY_, step * time, screenId_, startAngle_);
275         time++;
276         std::this_thread::yield();
277         std::this_thread::sleep_for(std::chrono::milliseconds(NUMBER_10));
278     }
279 
280     AccessibilityCircleDrawingManager::GetInstance()->UpdatePointerVisible(false);
281 }
282 
HandleResponseDelayStateInnerDown(MMI::PointerEvent & event)283 void AccessibilityScreenTouch::HandleResponseDelayStateInnerDown(MMI::PointerEvent &event)
284 {
285     HILOG_DEBUG();
286     MMI::PointerEvent::PointerItem pointerItem;
287     if (!event.GetPointerItem(event.GetPointerId(), pointerItem)) {
288         HILOG_WARN("get GetPointerItem %{public}d failed", event.GetPointerId());
289     }
290 
291     if (event.GetPointerIds().size() > POINTER_COUNT_1) {
292         if (cachedDownPointerEvents_.empty()) {
293             HILOG_ERROR("cached down pointer event is empty!");
294             return;
295         }
296         if (isMoveBeyondThreshold_ == true) {
297             cachedDownPointerEvents_.push_back(event);
298             EventTransmission::OnPointerEvent(event);
299             return;
300         } else if (isStopDrawCircle_ == true) {
301             return;
302         } else {
303             cachedDownPointerEvents_.push_back(event);
304             return;
305         }
306     }
307 
308     screenId_ = event.GetTargetDisplayId();
309     startTime_ = event.GetActionTime();
310     startPointer_ = std::make_shared<MMI::PointerEvent::PointerItem>(pointerItem);
311     isMoveBeyondThreshold_ = false;
312 
313     HILOG_INFO("ROTATE_POLICY = %{public}d, FOLDABLE = %{public}s", ROTATE_POLICY, FOLDABLE.c_str());
314     HandleCoordinates(pointerItem);
315     isStopDrawCircle_ = false;
316     if (drawCircleThread_ && drawCircleThread_->joinable()) {
317         drawCircleThread_->join();
318     }
319 
320     drawCircleThread_ = nullptr;
321     drawCircleThread_ = std::make_shared<std::thread>([this] {this->DrawCircleProgress();});
322     if (drawCircleThread_ == nullptr) {
323         HILOG_ERROR("create draw circle progress fail");
324     }
325 
326     handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
327     cachedDownPointerEvents_.clear();
328     cachedDownPointerEvents_.push_back(event);
329     handler_->SendEvent(FINGER_DOWN_DELAY_MSG, 0, static_cast<int32_t>(GetRealClickResponseTime()));
330 }
331 
HandleResponseDelayStateInnerMove(MMI::PointerEvent & event)332 void AccessibilityScreenTouch::HandleResponseDelayStateInnerMove(MMI::PointerEvent &event)
333 {
334     HILOG_DEBUG();
335     if (cachedDownPointerEvents_.empty()) {
336         HILOG_ERROR("cached down pointer event is empty!");
337         return;
338     }
339 
340     if (isMoveBeyondThreshold_ == true) {
341         handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
342         EventTransmission::OnPointerEvent(event);
343         return;
344     }
345 
346     if (startPointer_ == nullptr) {
347         return;
348     }
349 
350     if (event.GetPointerId() != startPointer_->GetPointerId()) {
351         if (isStopDrawCircle_ == true) {
352             EventTransmission::OnPointerEvent(event);
353         }
354         return;
355     }
356 
357     MMI::PointerEvent::PointerItem pointerItem;
358     if (!event.GetPointerItem(event.GetPointerId(), pointerItem)) {
359         HILOG_WARN("get GetPointerItem %{public}d failed", event.GetPointerId());
360     }
361 
362     float offsetX = startPointer_->GetDisplayX() - pointerItem.GetDisplayX();
363     float offsetY = startPointer_->GetDisplayY() - pointerItem.GetDisplayY();
364     double duration = hypot(offsetX, offsetY);
365     if (duration > TOUCH_SLOP) {
366         handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
367         if (isStopDrawCircle_ != true && !cachedDownPointerEvents_.empty()) {
368             for (auto iter = cachedDownPointerEvents_.begin(); iter != cachedDownPointerEvents_.end(); ++iter) {
369                 iter->SetActionTime(Utils::GetSystemTime() * US_TO_MS);
370                 EventTransmission::OnPointerEvent(*iter);
371             }
372         }
373         EventTransmission::OnPointerEvent(event);
374         isMoveBeyondThreshold_ = true;
375         isStopDrawCircle_ = true;
376         return;
377     }
378 
379     if (isStopDrawCircle_ != true) {
380         HandleCoordinates(pointerItem);
381         return;
382     }
383 
384     EventTransmission::OnPointerEvent(event);
385 }
386 
HandleResponseDelayStateInnerUp(MMI::PointerEvent & event)387 void AccessibilityScreenTouch::HandleResponseDelayStateInnerUp(MMI::PointerEvent &event)
388 {
389     HILOG_DEBUG();
390 
391     if (cachedDownPointerEvents_.empty()) {
392         HILOG_ERROR("cached down pointer event is empty!");
393         handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
394         isStopDrawCircle_ = true;
395         return;
396     }
397 
398     if (isStopDrawCircle_ == true) {
399         for (auto iter = cachedDownPointerEvents_.begin(); iter != cachedDownPointerEvents_.end(); ++iter) {
400             if (iter->GetPointerId() == event.GetPointerId()) {
401                 EventTransmission::OnPointerEvent(event);
402             }
403         }
404         if (event.GetPointerIds().size() == POINTER_COUNT_1) {
405             cachedDownPointerEvents_.clear();
406         }
407         return;
408     }
409 
410     if (startPointer_ != nullptr && event.GetPointerId() == startPointer_->GetPointerId()) {
411         handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
412         isStopDrawCircle_ = true;
413         cachedDownPointerEvents_.clear();
414     } else {
415         auto iter = std::find_if(cachedDownPointerEvents_.begin(), cachedDownPointerEvents_.end(),
416             [&](const MMI::PointerEvent &e) {
417                 return e.GetPointerId() == event.GetPointerId();
418             });
419         if (iter != cachedDownPointerEvents_.end()) {
420             cachedDownPointerEvents_.erase(iter);
421         }
422     }
423 }
424 
HandleResponseDelayState(MMI::PointerEvent & event)425 void AccessibilityScreenTouch::HandleResponseDelayState(MMI::PointerEvent &event)
426 {
427     HILOG_DEBUG();
428 
429     switch (event.GetPointerAction()) {
430         case MMI::PointerEvent::POINTER_ACTION_DOWN:
431             HandleResponseDelayStateInnerDown(event);
432             break;
433         case MMI::PointerEvent::POINTER_ACTION_MOVE:
434             HandleResponseDelayStateInnerMove(event);
435             break;
436         case MMI::PointerEvent::POINTER_ACTION_UP:
437             HandleResponseDelayStateInnerUp(event);
438             break;
439         default:
440             EventTransmission::OnPointerEvent(event);
441             break;
442     }
443 }
444 
HandleIgnoreRepeatClickStateInnerDown(MMI::PointerEvent & event)445 void AccessibilityScreenTouch::HandleIgnoreRepeatClickStateInnerDown(MMI::PointerEvent &event)
446 {
447     HILOG_DEBUG();
448 
449     int64_t downTime = event.GetActionTime();
450     if ((event.GetPointerIds().size() == POINTER_COUNT_1) &&
451         ((downTime - lastUpTime_) / US_TO_MS < GetRealIgnoreRepeatClickTime())) {
452         isInterceptClick_ = true;
453         return;
454     } else if ((event.GetPointerIds().size() > POINTER_COUNT_1) && (isInterceptClick_ == true)) {
455         return;
456     }
457 
458     EventTransmission::OnPointerEvent(event);
459     isInterceptClick_ = false;
460 }
461 
HandleIgnoreRepeatClickStateInnerMove(MMI::PointerEvent & event)462 void AccessibilityScreenTouch::HandleIgnoreRepeatClickStateInnerMove(MMI::PointerEvent &event)
463 {
464     HILOG_DEBUG();
465 
466     if (isInterceptClick_ == false) {
467         EventTransmission::OnPointerEvent(event);
468     }
469 }
470 
HandleIgnoreRepeatClickStateInnerUp(MMI::PointerEvent & event)471 void AccessibilityScreenTouch::HandleIgnoreRepeatClickStateInnerUp(MMI::PointerEvent &event)
472 {
473     HILOG_DEBUG();
474 
475     if (isInterceptClick_ == false) {
476         EventTransmission::OnPointerEvent(event);
477         if (event.GetPointerIds().size() == POINTER_COUNT_1) {
478             lastUpTime_ = event.GetActionTime();
479         }
480     }
481 }
482 
HandleIgnoreRepeatClickState(MMI::PointerEvent & event)483 void AccessibilityScreenTouch::HandleIgnoreRepeatClickState(MMI::PointerEvent &event)
484 {
485     HILOG_DEBUG();
486     switch (event.GetPointerAction()) {
487         case MMI::PointerEvent::POINTER_ACTION_DOWN:
488             HandleIgnoreRepeatClickStateInnerDown(event);
489             break;
490         case MMI::PointerEvent::POINTER_ACTION_MOVE:
491             HandleIgnoreRepeatClickStateInnerMove(event);
492             break;
493         case MMI::PointerEvent::POINTER_ACTION_UP:
494             HandleIgnoreRepeatClickStateInnerUp(event);
495             break;
496         default:
497             EventTransmission::OnPointerEvent(event);
498             break;
499     }
500 }
501 
HandleBothStateInnerDown(MMI::PointerEvent & event)502 void AccessibilityScreenTouch::HandleBothStateInnerDown(MMI::PointerEvent &event)
503 {
504     HILOG_DEBUG();
505 
506     int64_t downTime = event.GetActionTime();
507     if ((event.GetPointerIds().size() == POINTER_COUNT_1) &&
508         ((downTime - lastUpTime_) / US_TO_MS < GetRealIgnoreRepeatClickTime())) {
509         isInterceptClick_ = true;
510         return;
511     } else if ((event.GetPointerIds().size() > POINTER_COUNT_1) && (isInterceptClick_ == true)) {
512         return;
513     }
514 
515     isInterceptClick_ = false;
516 
517     HandleResponseDelayStateInnerDown(event);
518 }
519 
HandleBothStateInnerMove(MMI::PointerEvent & event)520 void AccessibilityScreenTouch::HandleBothStateInnerMove(MMI::PointerEvent &event)
521 {
522     HILOG_DEBUG();
523 
524     if (isInterceptClick_ == true) {
525         return;
526     }
527 
528     HandleResponseDelayStateInnerMove(event);
529 }
530 
HandleBothStateInnerUp(MMI::PointerEvent & event)531 void AccessibilityScreenTouch::HandleBothStateInnerUp(MMI::PointerEvent &event)
532 {
533     HILOG_DEBUG();
534 
535     if (isInterceptClick_ == true) {
536         return;
537     }
538 
539     if (event.GetPointerIds().size() == POINTER_COUNT_1) {
540         lastUpTime_ = event.GetActionTime();
541     }
542 
543     HandleResponseDelayStateInnerUp(event);
544 }
545 
HandleBothState(MMI::PointerEvent & event)546 void AccessibilityScreenTouch::HandleBothState(MMI::PointerEvent &event)
547 {
548     HILOG_DEBUG();
549     switch (event.GetPointerAction()) {
550         case MMI::PointerEvent::POINTER_ACTION_DOWN:
551             HandleBothStateInnerDown(event);
552             break;
553         case MMI::PointerEvent::POINTER_ACTION_MOVE:
554             HandleBothStateInnerMove(event);
555             break;
556         case MMI::PointerEvent::POINTER_ACTION_UP:
557             HandleBothStateInnerUp(event);
558             break;
559         default:
560             EventTransmission::OnPointerEvent(event);
561             break;
562     }
563 }
564 
Clear()565 void AccessibilityScreenTouch::Clear()
566 {
567     isMoveBeyondThreshold_ = false;
568     isInterceptClick_ = false;
569     startPointer_ = nullptr;
570 }
571 
OnPointerEvent(MMI::PointerEvent & event)572 bool AccessibilityScreenTouch::OnPointerEvent(MMI::PointerEvent &event)
573 {
574     HILOG_DEBUG();
575     MMI::PointerEvent::PointerItem pointerItem;
576     if (!event.GetPointerItem(event.GetPointerId(), pointerItem)) {
577         HILOG_WARN("get GetPointerItem %{public}d failed", event.GetPointerId());
578         return false;
579     }
580     if (pointerItem.GetToolType() == MMI::PointerEvent::TOOL_TYPE_KNUCKLE) {
581         EventTransmission::OnPointerEvent(event);
582         return false;
583     }
584 
585     if (event.GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
586         EventTransmission::OnPointerEvent(event);
587         return false;
588     }
589 
590     if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
591         Clear();
592         return true;
593     }
594 
595     switch (currentState_) {
596         case ScreenTouchState::CLICK_RESPONSE_DELAY_STATE:
597             HandleResponseDelayState(event);
598             break;
599         case ScreenTouchState::IGNORE_REPEAT_CLICK_STATE:
600             HandleIgnoreRepeatClickState(event);
601             break;
602         case ScreenTouchState::BOTH_RESPONSE_DELAY_IGNORE_REPEAT_CLICK:
603             HandleBothState(event);
604             break;
605         case ScreenTouchState::DEFAULT_STATE:
606         default:
607             EventTransmission::OnPointerEvent(event);
608     }
609 
610     return true;
611 }
612 } // namespace Accessibility
613 } // namespace OHOS