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