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().GetMainRunner();
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 ((displayMgr.GetFoldStatus() == Rosen::FoldStatus::EXPAND &&
240                 FOLDABLE[SUBSCRIPT_TWO] == FOLDABLE_SCREEN_ROTATE) ||
241                 (displayMgr.GetFoldStatus() == Rosen::FoldStatus::FOLDED &&
242                 FOLDABLE[SUBSCRIPT_ZERO] == FOLDABLE_SCREEN_ROTATE)) {
243                 circleCenterPhysicalX_ = originalX;
244                 circleCenterPhysicalY_ = originalY;
245                 startAngle_ = START_ANGLE_PORTRAIT;
246             } else {
247                 ConversionCoordinates(originalX, originalY);
248             }
249             break;
250         default:
251             HILOG_WARN("unknown rotate policy");
252             ConversionCoordinates(originalX, originalY);
253             break;
254     }
255 #endif
256 }
257 
DrawCircleProgress()258 void AccessibilityScreenTouch::DrawCircleProgress()
259 {
260     HILOG_DEBUG();
261 
262     AccessibilityCircleDrawingManager::GetInstance()->DrawPointer(circleCenterPhysicalX_,
263         circleCenterPhysicalY_, 0, screenId_, startAngle_);
264     AccessibilityCircleDrawingManager::GetInstance()->UpdatePointerVisible(true);
265     uint32_t times = GetRealClickResponseTime() / NUMBER_10;
266     uint32_t step = CIRCLE_ANGLE / times;
267     uint32_t time = 0;
268     while (time < times && isStopDrawCircle_ == false) {
269         AccessibilityCircleDrawingManager::GetInstance()->DrawPointer(circleCenterPhysicalX_,
270             circleCenterPhysicalY_, step * time, screenId_, startAngle_);
271         time++;
272         std::this_thread::yield();
273         std::this_thread::sleep_for(std::chrono::milliseconds(NUMBER_10));
274     }
275 
276     AccessibilityCircleDrawingManager::GetInstance()->UpdatePointerVisible(false);
277 }
278 
HandleResponseDelayStateInnerDown(MMI::PointerEvent &event)279 void AccessibilityScreenTouch::HandleResponseDelayStateInnerDown(MMI::PointerEvent &event)
280 {
281     HILOG_DEBUG();
282     MMI::PointerEvent::PointerItem pointerItem;
283     if (!event.GetPointerItem(event.GetPointerId(), pointerItem)) {
284         HILOG_WARN("get GetPointerItem %{public}d failed", event.GetPointerId());
285     }
286 
287     if (event.GetPointerIds().size() > POINTER_COUNT_1) {
288         if (cachedDownPointerEvents_.empty()) {
289             HILOG_ERROR("cached down pointer event is empty!");
290             return;
291         }
292         if (isMoveBeyondThreshold_ == true) {
293             cachedDownPointerEvents_.push_back(event);
294             EventTransmission::OnPointerEvent(event);
295             return;
296         } else if (isStopDrawCircle_ == true) {
297             return;
298         } else {
299             cachedDownPointerEvents_.push_back(event);
300             return;
301         }
302     }
303 
304     screenId_ = event.GetTargetDisplayId();
305     startTime_ = event.GetActionTime();
306     startPointer_ = std::make_shared<MMI::PointerEvent::PointerItem>(pointerItem);
307     isMoveBeyondThreshold_ = false;
308 
309     HILOG_INFO("ROTATE_POLICY = %{public}d, FOLDABLE = %{public}s", ROTATE_POLICY, FOLDABLE.c_str());
310     HandleCoordinates(pointerItem);
311     isStopDrawCircle_ = false;
312     if (drawCircleThread_ && drawCircleThread_->joinable()) {
313         drawCircleThread_->join();
314     }
315 
316     drawCircleThread_ = nullptr;
317     drawCircleThread_ = std::make_shared<std::thread>([this] {this->DrawCircleProgress();});
318     if (drawCircleThread_ == nullptr) {
319         HILOG_ERROR("create draw circle progress fail");
320     }
321 
322     handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
323     cachedDownPointerEvents_.clear();
324     cachedDownPointerEvents_.push_back(event);
325     handler_->SendEvent(FINGER_DOWN_DELAY_MSG, 0, static_cast<int32_t>(GetRealClickResponseTime()));
326 }
327 
HandleResponseDelayStateInnerMove(MMI::PointerEvent &event)328 void AccessibilityScreenTouch::HandleResponseDelayStateInnerMove(MMI::PointerEvent &event)
329 {
330     HILOG_DEBUG();
331     if (cachedDownPointerEvents_.empty()) {
332         HILOG_ERROR("cached down pointer event is empty!");
333         return;
334     }
335 
336     if (isMoveBeyondThreshold_ == true) {
337         handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
338         EventTransmission::OnPointerEvent(event);
339         return;
340     }
341 
342     if (startPointer_ == nullptr) {
343         return;
344     }
345 
346     if (event.GetPointerId() != startPointer_->GetPointerId()) {
347         if (isStopDrawCircle_ == true) {
348             EventTransmission::OnPointerEvent(event);
349         }
350         return;
351     }
352 
353     MMI::PointerEvent::PointerItem pointerItem;
354     if (!event.GetPointerItem(event.GetPointerId(), pointerItem)) {
355         HILOG_WARN("get GetPointerItem %{public}d failed", event.GetPointerId());
356     }
357 
358     float offsetX = startPointer_->GetDisplayX() - pointerItem.GetDisplayX();
359     float offsetY = startPointer_->GetDisplayY() - pointerItem.GetDisplayY();
360     double duration = hypot(offsetX, offsetY);
361     if (duration > TOUCH_SLOP) {
362         handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
363         if (isStopDrawCircle_ != true && !cachedDownPointerEvents_.empty()) {
364             for (auto iter = cachedDownPointerEvents_.begin(); iter != cachedDownPointerEvents_.end(); ++iter) {
365                 iter->SetActionTime(Utils::GetSystemTime() * US_TO_MS);
366                 EventTransmission::OnPointerEvent(*iter);
367             }
368         }
369         EventTransmission::OnPointerEvent(event);
370         isMoveBeyondThreshold_ = true;
371         isStopDrawCircle_ = true;
372         return;
373     }
374 
375     if (isStopDrawCircle_ != true) {
376         HandleCoordinates(pointerItem);
377         return;
378     }
379 
380     EventTransmission::OnPointerEvent(event);
381 }
382 
HandleResponseDelayStateInnerUp(MMI::PointerEvent &event)383 void AccessibilityScreenTouch::HandleResponseDelayStateInnerUp(MMI::PointerEvent &event)
384 {
385     HILOG_DEBUG();
386 
387     if (cachedDownPointerEvents_.empty()) {
388         HILOG_ERROR("cached down pointer event is empty!");
389         handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
390         isStopDrawCircle_ = true;
391         return;
392     }
393 
394     if (isStopDrawCircle_ == true) {
395         for (auto iter = cachedDownPointerEvents_.begin(); iter != cachedDownPointerEvents_.end(); ++iter) {
396             if (iter->GetPointerId() == event.GetPointerId()) {
397                 EventTransmission::OnPointerEvent(event);
398             }
399         }
400         if (event.GetPointerIds().size() == POINTER_COUNT_1) {
401             cachedDownPointerEvents_.clear();
402         }
403         return;
404     }
405 
406     if (startPointer_ != nullptr && event.GetPointerId() == startPointer_->GetPointerId()) {
407         handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
408         isStopDrawCircle_ = true;
409         cachedDownPointerEvents_.clear();
410     } else {
411         auto iter = std::find_if(cachedDownPointerEvents_.begin(), cachedDownPointerEvents_.end(),
412             [&](const MMI::PointerEvent &e) {
413                 return e.GetPointerId() == event.GetPointerId();
414             });
415         if (iter != cachedDownPointerEvents_.end()) {
416             cachedDownPointerEvents_.erase(iter);
417         }
418     }
419 }
420 
HandleResponseDelayState(MMI::PointerEvent &event)421 void AccessibilityScreenTouch::HandleResponseDelayState(MMI::PointerEvent &event)
422 {
423     HILOG_DEBUG();
424 
425     switch (event.GetPointerAction()) {
426         case MMI::PointerEvent::POINTER_ACTION_DOWN:
427             HandleResponseDelayStateInnerDown(event);
428             break;
429         case MMI::PointerEvent::POINTER_ACTION_MOVE:
430             HandleResponseDelayStateInnerMove(event);
431             break;
432         case MMI::PointerEvent::POINTER_ACTION_UP:
433             HandleResponseDelayStateInnerUp(event);
434             break;
435         default:
436             EventTransmission::OnPointerEvent(event);
437             break;
438     }
439 }
440 
HandleIgnoreRepeatClickStateInnerDown(MMI::PointerEvent &event)441 void AccessibilityScreenTouch::HandleIgnoreRepeatClickStateInnerDown(MMI::PointerEvent &event)
442 {
443     HILOG_DEBUG();
444 
445     int64_t downTime = event.GetActionTime();
446     if ((event.GetPointerIds().size() == POINTER_COUNT_1) &&
447         ((downTime - lastUpTime_) / US_TO_MS < GetRealIgnoreRepeatClickTime())) {
448         isInterceptClick_ = true;
449         return;
450     } else if ((event.GetPointerIds().size() > POINTER_COUNT_1) && (isInterceptClick_ == true)) {
451         return;
452     }
453 
454     EventTransmission::OnPointerEvent(event);
455     isInterceptClick_ = false;
456 }
457 
HandleIgnoreRepeatClickStateInnerMove(MMI::PointerEvent &event)458 void AccessibilityScreenTouch::HandleIgnoreRepeatClickStateInnerMove(MMI::PointerEvent &event)
459 {
460     HILOG_DEBUG();
461 
462     if (isInterceptClick_ == false) {
463         EventTransmission::OnPointerEvent(event);
464     }
465 }
466 
HandleIgnoreRepeatClickStateInnerUp(MMI::PointerEvent &event)467 void AccessibilityScreenTouch::HandleIgnoreRepeatClickStateInnerUp(MMI::PointerEvent &event)
468 {
469     HILOG_DEBUG();
470 
471     if (isInterceptClick_ == false) {
472         EventTransmission::OnPointerEvent(event);
473         if (event.GetPointerIds().size() == POINTER_COUNT_1) {
474             lastUpTime_ = event.GetActionTime();
475         }
476     }
477 }
478 
HandleIgnoreRepeatClickState(MMI::PointerEvent &event)479 void AccessibilityScreenTouch::HandleIgnoreRepeatClickState(MMI::PointerEvent &event)
480 {
481     HILOG_DEBUG();
482     switch (event.GetPointerAction()) {
483         case MMI::PointerEvent::POINTER_ACTION_DOWN:
484             HandleIgnoreRepeatClickStateInnerDown(event);
485             break;
486         case MMI::PointerEvent::POINTER_ACTION_MOVE:
487             HandleIgnoreRepeatClickStateInnerMove(event);
488             break;
489         case MMI::PointerEvent::POINTER_ACTION_UP:
490             HandleIgnoreRepeatClickStateInnerUp(event);
491             break;
492         default:
493             EventTransmission::OnPointerEvent(event);
494             break;
495     }
496 }
497 
HandleBothStateInnerDown(MMI::PointerEvent &event)498 void AccessibilityScreenTouch::HandleBothStateInnerDown(MMI::PointerEvent &event)
499 {
500     HILOG_DEBUG();
501 
502     int64_t downTime = event.GetActionTime();
503     if ((event.GetPointerIds().size() == POINTER_COUNT_1) &&
504         ((downTime - lastUpTime_) / US_TO_MS < GetRealIgnoreRepeatClickTime())) {
505         isInterceptClick_ = true;
506         return;
507     } else if ((event.GetPointerIds().size() > POINTER_COUNT_1) && (isInterceptClick_ == true)) {
508         return;
509     }
510 
511     isInterceptClick_ = false;
512 
513     HandleResponseDelayStateInnerDown(event);
514 }
515 
HandleBothStateInnerMove(MMI::PointerEvent &event)516 void AccessibilityScreenTouch::HandleBothStateInnerMove(MMI::PointerEvent &event)
517 {
518     HILOG_DEBUG();
519 
520     if (isInterceptClick_ == true) {
521         return;
522     }
523 
524     HandleResponseDelayStateInnerMove(event);
525 }
526 
HandleBothStateInnerUp(MMI::PointerEvent &event)527 void AccessibilityScreenTouch::HandleBothStateInnerUp(MMI::PointerEvent &event)
528 {
529     HILOG_DEBUG();
530 
531     if (isInterceptClick_ == true) {
532         return;
533     }
534 
535     if (event.GetPointerIds().size() == POINTER_COUNT_1) {
536         lastUpTime_ = event.GetActionTime();
537     }
538 
539     HandleResponseDelayStateInnerUp(event);
540 }
541 
HandleBothState(MMI::PointerEvent &event)542 void AccessibilityScreenTouch::HandleBothState(MMI::PointerEvent &event)
543 {
544     HILOG_DEBUG();
545     switch (event.GetPointerAction()) {
546         case MMI::PointerEvent::POINTER_ACTION_DOWN:
547             HandleBothStateInnerDown(event);
548             break;
549         case MMI::PointerEvent::POINTER_ACTION_MOVE:
550             HandleBothStateInnerMove(event);
551             break;
552         case MMI::PointerEvent::POINTER_ACTION_UP:
553             HandleBothStateInnerUp(event);
554             break;
555         default:
556             EventTransmission::OnPointerEvent(event);
557             break;
558     }
559 }
560 
Clear()561 void AccessibilityScreenTouch::Clear()
562 {
563     isMoveBeyondThreshold_ = false;
564     isInterceptClick_ = false;
565     startPointer_ = nullptr;
566 }
567 
OnPointerEvent(MMI::PointerEvent &event)568 bool AccessibilityScreenTouch::OnPointerEvent(MMI::PointerEvent &event)
569 {
570     HILOG_DEBUG();
571     MMI::PointerEvent::PointerItem pointerItem;
572     if (!event.GetPointerItem(event.GetPointerId(), pointerItem)) {
573         HILOG_WARN("get GetPointerItem %{public}d failed", event.GetPointerId());
574         return false;
575     }
576     if (pointerItem.GetToolType() == MMI::PointerEvent::TOOL_TYPE_KNUCKLE) {
577         EventTransmission::OnPointerEvent(event);
578         return false;
579     }
580 
581     if (event.GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
582         EventTransmission::OnPointerEvent(event);
583         return false;
584     }
585 
586     if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
587         Clear();
588         return true;
589     }
590 
591     switch (currentState_) {
592         case ScreenTouchState::CLICK_RESPONSE_DELAY_STATE:
593             HandleResponseDelayState(event);
594             break;
595         case ScreenTouchState::IGNORE_REPEAT_CLICK_STATE:
596             HandleIgnoreRepeatClickState(event);
597             break;
598         case ScreenTouchState::BOTH_RESPONSE_DELAY_IGNORE_REPEAT_CLICK:
599             HandleBothState(event);
600             break;
601         case ScreenTouchState::DEFAULT_STATE:
602         default:
603             EventTransmission::OnPointerEvent(event);
604     }
605 
606     return true;
607 }
608 } // namespace Accessibility
609 } // namespace OHOS