1885b47fbSopenharmony_ci/*
2885b47fbSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
3885b47fbSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4885b47fbSopenharmony_ci * you may not use this file except in compliance with the License.
5885b47fbSopenharmony_ci * You may obtain a copy of the License at
6885b47fbSopenharmony_ci *
7885b47fbSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8885b47fbSopenharmony_ci *
9885b47fbSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10885b47fbSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11885b47fbSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12885b47fbSopenharmony_ci * See the License for the specific language governing permissions and
13885b47fbSopenharmony_ci * limitations under the License.
14885b47fbSopenharmony_ci */
15885b47fbSopenharmony_ci
16885b47fbSopenharmony_ci#include <map>
17885b47fbSopenharmony_ci#include "accessibility_screen_touch.h"
18885b47fbSopenharmony_ci#include "accessibility_circle_drawing_manager.h"
19885b47fbSopenharmony_ci#include "accessible_ability_manager_service.h"
20885b47fbSopenharmony_ci#include "hilog_wrapper.h"
21885b47fbSopenharmony_ci#include "utils.h"
22885b47fbSopenharmony_ci#include "parameters.h"
23885b47fbSopenharmony_ci
24885b47fbSopenharmony_cinamespace OHOS {
25885b47fbSopenharmony_cinamespace Accessibility {
26885b47fbSopenharmony_ci
27885b47fbSopenharmony_ciconstexpr int32_t POINTER_COUNT_1 = 1;
28885b47fbSopenharmony_ci
29885b47fbSopenharmony_ciconstexpr uint32_t CLICK_RESPONSE_DELAY_SHORT = 0;
30885b47fbSopenharmony_ciconstexpr uint32_t CLICK_RESPONSE_DELAY_MEDIUM = 1;
31885b47fbSopenharmony_ciconstexpr uint32_t CLICK_RESPONSE_DELAY_LONG = 2;
32885b47fbSopenharmony_ci
33885b47fbSopenharmony_ciconstexpr uint32_t CLICK_RESPONSE_TIME_SHORT = 0; // ms
34885b47fbSopenharmony_ciconstexpr uint32_t CLICK_RESPONSE_TIME_MEDIUM = 300; // ms
35885b47fbSopenharmony_ciconstexpr uint32_t CLICK_RESPONSE_TIME_LONG = 600; // ms
36885b47fbSopenharmony_ci
37885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_SHORTEST = 0;
38885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_SHORT = 1;
39885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_MEDIUM = 2;
40885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_LONG = 3;
41885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_LONGEST = 4;
42885b47fbSopenharmony_ci
43885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_TIME_SHORTEST = 100; // ms
44885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_TIME_SHORT = 400; // ms
45885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_TIME_MEDIUM = 700; // ms
46885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_TIME_LONG = 1000; // ms
47885b47fbSopenharmony_ciconstexpr uint32_t IGNORE_REPEAT_CLICK_TIME_LONGEST = 1300; // ms
48885b47fbSopenharmony_ci
49885b47fbSopenharmony_ciconstexpr uint32_t CIRCLE_ANGLE = 360;
50885b47fbSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
51885b47fbSopenharmony_ciconstexpr uint32_t START_ANGLE_PORTRAIT = -90;
52885b47fbSopenharmony_ciconstexpr uint32_t START_ANGLE_LANDSCAPE = 180;
53885b47fbSopenharmony_ciconstexpr uint32_t START_ANGLE_PORTRAIT_INVERTED = 90;
54885b47fbSopenharmony_ciconstexpr uint32_t START_ANGLE_LANDSCAPE_INVERTED = 0;
55885b47fbSopenharmony_ci#endif
56885b47fbSopenharmony_ciconstexpr uint32_t NUMBER_10 = 10;
57885b47fbSopenharmony_ci
58885b47fbSopenharmony_ciconstexpr float TOUCH_SLOP = 8.0f;
59885b47fbSopenharmony_ci
60885b47fbSopenharmony_ciconst int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0);
61885b47fbSopenharmony_ciconst std::string FOLDABLE = system::GetParameter("const.window.foldabledevice.rotate_policy", "");
62885b47fbSopenharmony_ciconstexpr int32_t WINDOW_ROTATE = 0;
63885b47fbSopenharmony_ciconstexpr int32_t SCREEN_ROTATE = 1;
64885b47fbSopenharmony_ciconstexpr int32_t FOLDABLE_DEVICE = 2;
65885b47fbSopenharmony_ciconstexpr int32_t SUBSCRIPT_TWO = 2;
66885b47fbSopenharmony_ciconstexpr int32_t SUBSCRIPT_ZERO = 0;
67885b47fbSopenharmony_ciconstexpr char FOLDABLE_SCREEN_ROTATE = '1';
68885b47fbSopenharmony_ci
69885b47fbSopenharmony_ciconst std::map<uint32_t, uint32_t> CLICK_RESPONSE_TIME_MAP = {
70885b47fbSopenharmony_ci    {CLICK_RESPONSE_DELAY_SHORT, CLICK_RESPONSE_TIME_SHORT},
71885b47fbSopenharmony_ci    {CLICK_RESPONSE_DELAY_MEDIUM, CLICK_RESPONSE_TIME_MEDIUM},
72885b47fbSopenharmony_ci    {CLICK_RESPONSE_DELAY_LONG, CLICK_RESPONSE_TIME_LONG}
73885b47fbSopenharmony_ci};
74885b47fbSopenharmony_ci
75885b47fbSopenharmony_ciconst std::map<uint32_t, uint32_t> IGNORE_REPEAT_CLICK_TIME_MAP = {
76885b47fbSopenharmony_ci    {IGNORE_REPEAT_CLICK_SHORTEST, IGNORE_REPEAT_CLICK_TIME_SHORTEST},
77885b47fbSopenharmony_ci    {IGNORE_REPEAT_CLICK_SHORT, IGNORE_REPEAT_CLICK_TIME_SHORT},
78885b47fbSopenharmony_ci    {IGNORE_REPEAT_CLICK_MEDIUM, IGNORE_REPEAT_CLICK_TIME_MEDIUM},
79885b47fbSopenharmony_ci    {IGNORE_REPEAT_CLICK_LONG, IGNORE_REPEAT_CLICK_TIME_LONG},
80885b47fbSopenharmony_ci    {IGNORE_REPEAT_CLICK_LONGEST, IGNORE_REPEAT_CLICK_TIME_LONGEST}
81885b47fbSopenharmony_ci};
82885b47fbSopenharmony_ci
83885b47fbSopenharmony_ciint64_t AccessibilityScreenTouch::lastUpTime = 0; // global last up time
84885b47fbSopenharmony_ci
85885b47fbSopenharmony_ciScreenTouchHandler::ScreenTouchHandler(const std::shared_ptr<AppExecFwk::EventRunner> &runner,
86885b47fbSopenharmony_ci    AccessibilityScreenTouch &server) : AppExecFwk::EventHandler(runner), server_(server)
87885b47fbSopenharmony_ci{
88885b47fbSopenharmony_ci}
89885b47fbSopenharmony_ci
90885b47fbSopenharmony_ciAccessibilityScreenTouch::AccessibilityScreenTouch()
91885b47fbSopenharmony_ci{
92885b47fbSopenharmony_ci    HILOG_DEBUG();
93885b47fbSopenharmony_ci    // get from account data directly
94885b47fbSopenharmony_ci    sptr<AccessibilityAccountData> accountData =
95885b47fbSopenharmony_ci        Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountData();
96885b47fbSopenharmony_ci    clickResponseTime_ = accountData->GetConfig()->GetClickResponseTime();
97885b47fbSopenharmony_ci    ignoreRepeatClickState_ = accountData->GetConfig()->GetIgnoreRepeatClickState();
98885b47fbSopenharmony_ci    ignoreRepeatClickTime_ = accountData->GetConfig()->GetIgnoreRepeatClickTime();
99885b47fbSopenharmony_ci
100885b47fbSopenharmony_ci    if (clickResponseTime_ > 0 && ignoreRepeatClickState_ == true) {
101885b47fbSopenharmony_ci        currentState_ = BOTH_RESPONSE_DELAY_IGNORE_REPEAT_CLICK;
102885b47fbSopenharmony_ci    } else if (clickResponseTime_ > 0) {
103885b47fbSopenharmony_ci        currentState_ = CLICK_RESPONSE_DELAY_STATE;
104885b47fbSopenharmony_ci    } else if (ignoreRepeatClickState_ == true) {
105885b47fbSopenharmony_ci        currentState_ = IGNORE_REPEAT_CLICK_STATE;
106885b47fbSopenharmony_ci    } else {
107885b47fbSopenharmony_ci        currentState_ = DEFAULT_STATE;
108885b47fbSopenharmony_ci    }
109885b47fbSopenharmony_ci
110885b47fbSopenharmony_ci    lastUpTime_ = lastUpTime;
111885b47fbSopenharmony_ci
112885b47fbSopenharmony_ci    runner_ = Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner();
113885b47fbSopenharmony_ci    if (!runner_) {
114885b47fbSopenharmony_ci        HILOG_ERROR("get runner failed");
115885b47fbSopenharmony_ci        return;
116885b47fbSopenharmony_ci    }
117885b47fbSopenharmony_ci    handler_ = std::make_shared<ScreenTouchHandler>(runner_, *this);
118885b47fbSopenharmony_ci    if (!handler_) {
119885b47fbSopenharmony_ci        HILOG_ERROR("create event handler failed");
120885b47fbSopenharmony_ci        return;
121885b47fbSopenharmony_ci    }
122885b47fbSopenharmony_ci}
123885b47fbSopenharmony_ci
124885b47fbSopenharmony_civoid ScreenTouchHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
125885b47fbSopenharmony_ci{
126885b47fbSopenharmony_ci    HILOG_DEBUG();
127885b47fbSopenharmony_ci    switch (event->GetInnerEventId()) {
128885b47fbSopenharmony_ci        case AccessibilityScreenTouch::FINGER_DOWN_DELAY_MSG:
129885b47fbSopenharmony_ci            server_.SendInterceptedEvent();
130885b47fbSopenharmony_ci            break;
131885b47fbSopenharmony_ci        default:
132885b47fbSopenharmony_ci            break;
133885b47fbSopenharmony_ci    }
134885b47fbSopenharmony_ci}
135885b47fbSopenharmony_ci
136885b47fbSopenharmony_ciAccessibilityScreenTouch::~AccessibilityScreenTouch()
137885b47fbSopenharmony_ci{
138885b47fbSopenharmony_ci    lastUpTime = lastUpTime_;
139885b47fbSopenharmony_ci    if (drawCircleThread_ && drawCircleThread_->joinable()) {
140885b47fbSopenharmony_ci        drawCircleThread_->join();
141885b47fbSopenharmony_ci    }
142885b47fbSopenharmony_ci    drawCircleThread_ = nullptr;
143885b47fbSopenharmony_ci    AccessibilityCircleDrawingManager::DeleteInstance();
144885b47fbSopenharmony_ci}
145885b47fbSopenharmony_ci
146885b47fbSopenharmony_civoid AccessibilityScreenTouch::SendInterceptedEvent()
147885b47fbSopenharmony_ci{
148885b47fbSopenharmony_ci    HILOG_DEBUG();
149885b47fbSopenharmony_ci    isStopDrawCircle_ = true;
150885b47fbSopenharmony_ci
151885b47fbSopenharmony_ci    if (cachedDownPointerEvents_.empty()) {
152885b47fbSopenharmony_ci        HILOG_ERROR("Cached down pointer event is empty!");
153885b47fbSopenharmony_ci        return;
154885b47fbSopenharmony_ci    }
155885b47fbSopenharmony_ci
156885b47fbSopenharmony_ci    for (auto iter = cachedDownPointerEvents_.begin(); iter != cachedDownPointerEvents_.end(); ++iter) {
157885b47fbSopenharmony_ci        iter->SetActionTime(Utils::GetSystemTime() * US_TO_MS);
158885b47fbSopenharmony_ci        EventTransmission::OnPointerEvent(*iter);
159885b47fbSopenharmony_ci    }
160885b47fbSopenharmony_ci}
161885b47fbSopenharmony_ci
162885b47fbSopenharmony_ciuint32_t AccessibilityScreenTouch::GetRealClickResponseTime()
163885b47fbSopenharmony_ci{
164885b47fbSopenharmony_ci    auto iter = CLICK_RESPONSE_TIME_MAP.find(clickResponseTime_);
165885b47fbSopenharmony_ci    if (iter != CLICK_RESPONSE_TIME_MAP.end()) {
166885b47fbSopenharmony_ci        return iter->second;
167885b47fbSopenharmony_ci    }
168885b47fbSopenharmony_ci
169885b47fbSopenharmony_ci    return CLICK_RESPONSE_TIME_MAP.at(CLICK_RESPONSE_DELAY_SHORT);
170885b47fbSopenharmony_ci}
171885b47fbSopenharmony_ci
172885b47fbSopenharmony_ciuint32_t AccessibilityScreenTouch::GetRealIgnoreRepeatClickTime()
173885b47fbSopenharmony_ci{
174885b47fbSopenharmony_ci    auto iter = IGNORE_REPEAT_CLICK_TIME_MAP.find(ignoreRepeatClickTime_);
175885b47fbSopenharmony_ci    if (iter != IGNORE_REPEAT_CLICK_TIME_MAP.end()) {
176885b47fbSopenharmony_ci        return iter->second;
177885b47fbSopenharmony_ci    }
178885b47fbSopenharmony_ci
179885b47fbSopenharmony_ci    return IGNORE_REPEAT_CLICK_TIME_MAP.at(IGNORE_REPEAT_CLICK_SHORTEST);
180885b47fbSopenharmony_ci}
181885b47fbSopenharmony_ci
182885b47fbSopenharmony_cibool AccessibilityScreenTouch::GetRealIgnoreRepeatClickState()
183885b47fbSopenharmony_ci{
184885b47fbSopenharmony_ci    return ignoreRepeatClickState_;
185885b47fbSopenharmony_ci}
186885b47fbSopenharmony_ci
187885b47fbSopenharmony_civoid AccessibilityScreenTouch::ConversionCoordinates(int32_t originalX, int32_t originalY)
188885b47fbSopenharmony_ci{
189885b47fbSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
190885b47fbSopenharmony_ci    AccessibilityDisplayManager &displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance();
191885b47fbSopenharmony_ci    int32_t displayWidth = displayMgr.GetWidth();
192885b47fbSopenharmony_ci    int32_t displayHeight = displayMgr.GetHeight();
193885b47fbSopenharmony_ci
194885b47fbSopenharmony_ci    OHOS::Rosen::DisplayOrientation orientation = displayMgr.GetOrientation();
195885b47fbSopenharmony_ci    switch (orientation) {
196885b47fbSopenharmony_ci        case OHOS::Rosen::DisplayOrientation::PORTRAIT:
197885b47fbSopenharmony_ci            circleCenterPhysicalX_ = originalX;
198885b47fbSopenharmony_ci            circleCenterPhysicalY_ = originalY;
199885b47fbSopenharmony_ci            startAngle_ = START_ANGLE_PORTRAIT;
200885b47fbSopenharmony_ci            break;
201885b47fbSopenharmony_ci        case OHOS::Rosen::DisplayOrientation::LANDSCAPE:
202885b47fbSopenharmony_ci            circleCenterPhysicalX_ = originalY;
203885b47fbSopenharmony_ci            circleCenterPhysicalY_ = displayWidth - originalX;
204885b47fbSopenharmony_ci            startAngle_ = START_ANGLE_LANDSCAPE;
205885b47fbSopenharmony_ci            break;
206885b47fbSopenharmony_ci        case OHOS::Rosen::DisplayOrientation::PORTRAIT_INVERTED:
207885b47fbSopenharmony_ci            circleCenterPhysicalX_ = displayWidth - originalX;
208885b47fbSopenharmony_ci            circleCenterPhysicalY_ = displayHeight - originalY;
209885b47fbSopenharmony_ci            startAngle_ = START_ANGLE_PORTRAIT_INVERTED;
210885b47fbSopenharmony_ci            break;
211885b47fbSopenharmony_ci        case OHOS::Rosen::DisplayOrientation::LANDSCAPE_INVERTED:
212885b47fbSopenharmony_ci            circleCenterPhysicalX_ = displayHeight - originalY;
213885b47fbSopenharmony_ci            circleCenterPhysicalY_ = originalX;
214885b47fbSopenharmony_ci            startAngle_ = START_ANGLE_LANDSCAPE_INVERTED;
215885b47fbSopenharmony_ci            break;
216885b47fbSopenharmony_ci        default:
217885b47fbSopenharmony_ci            break;
218885b47fbSopenharmony_ci    }
219885b47fbSopenharmony_ci#endif
220885b47fbSopenharmony_ci}
221885b47fbSopenharmony_ci
222885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleCoordinates(MMI::PointerEvent::PointerItem &pointerItem)
223885b47fbSopenharmony_ci{
224885b47fbSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
225885b47fbSopenharmony_ci    AccessibilityDisplayManager &displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance();
226885b47fbSopenharmony_ci    int32_t originalX = pointerItem.GetDisplayX();
227885b47fbSopenharmony_ci    int32_t originalY = pointerItem.GetDisplayY();
228885b47fbSopenharmony_ci
229885b47fbSopenharmony_ci    switch (ROTATE_POLICY) {
230885b47fbSopenharmony_ci        case WINDOW_ROTATE:
231885b47fbSopenharmony_ci            ConversionCoordinates(originalX, originalY);
232885b47fbSopenharmony_ci            break;
233885b47fbSopenharmony_ci        case SCREEN_ROTATE:
234885b47fbSopenharmony_ci            circleCenterPhysicalX_ = originalX;
235885b47fbSopenharmony_ci            circleCenterPhysicalY_ = originalY;
236885b47fbSopenharmony_ci            startAngle_ = START_ANGLE_PORTRAIT;
237885b47fbSopenharmony_ci            break;
238885b47fbSopenharmony_ci        case FOLDABLE_DEVICE:
239885b47fbSopenharmony_ci            if ((displayMgr.GetFoldStatus() == Rosen::FoldStatus::EXPAND &&
240885b47fbSopenharmony_ci                FOLDABLE[SUBSCRIPT_TWO] == FOLDABLE_SCREEN_ROTATE) ||
241885b47fbSopenharmony_ci                (displayMgr.GetFoldStatus() == Rosen::FoldStatus::FOLDED &&
242885b47fbSopenharmony_ci                FOLDABLE[SUBSCRIPT_ZERO] == FOLDABLE_SCREEN_ROTATE)) {
243885b47fbSopenharmony_ci                circleCenterPhysicalX_ = originalX;
244885b47fbSopenharmony_ci                circleCenterPhysicalY_ = originalY;
245885b47fbSopenharmony_ci                startAngle_ = START_ANGLE_PORTRAIT;
246885b47fbSopenharmony_ci            } else {
247885b47fbSopenharmony_ci                ConversionCoordinates(originalX, originalY);
248885b47fbSopenharmony_ci            }
249885b47fbSopenharmony_ci            break;
250885b47fbSopenharmony_ci        default:
251885b47fbSopenharmony_ci            HILOG_WARN("unknown rotate policy");
252885b47fbSopenharmony_ci            ConversionCoordinates(originalX, originalY);
253885b47fbSopenharmony_ci            break;
254885b47fbSopenharmony_ci    }
255885b47fbSopenharmony_ci#endif
256885b47fbSopenharmony_ci}
257885b47fbSopenharmony_ci
258885b47fbSopenharmony_civoid AccessibilityScreenTouch::DrawCircleProgress()
259885b47fbSopenharmony_ci{
260885b47fbSopenharmony_ci    HILOG_DEBUG();
261885b47fbSopenharmony_ci
262885b47fbSopenharmony_ci    AccessibilityCircleDrawingManager::GetInstance()->DrawPointer(circleCenterPhysicalX_,
263885b47fbSopenharmony_ci        circleCenterPhysicalY_, 0, screenId_, startAngle_);
264885b47fbSopenharmony_ci    AccessibilityCircleDrawingManager::GetInstance()->UpdatePointerVisible(true);
265885b47fbSopenharmony_ci    uint32_t times = GetRealClickResponseTime() / NUMBER_10;
266885b47fbSopenharmony_ci    uint32_t step = CIRCLE_ANGLE / times;
267885b47fbSopenharmony_ci    uint32_t time = 0;
268885b47fbSopenharmony_ci    while (time < times && isStopDrawCircle_ == false) {
269885b47fbSopenharmony_ci        AccessibilityCircleDrawingManager::GetInstance()->DrawPointer(circleCenterPhysicalX_,
270885b47fbSopenharmony_ci            circleCenterPhysicalY_, step * time, screenId_, startAngle_);
271885b47fbSopenharmony_ci        time++;
272885b47fbSopenharmony_ci        std::this_thread::yield();
273885b47fbSopenharmony_ci        std::this_thread::sleep_for(std::chrono::milliseconds(NUMBER_10));
274885b47fbSopenharmony_ci    }
275885b47fbSopenharmony_ci
276885b47fbSopenharmony_ci    AccessibilityCircleDrawingManager::GetInstance()->UpdatePointerVisible(false);
277885b47fbSopenharmony_ci}
278885b47fbSopenharmony_ci
279885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleResponseDelayStateInnerDown(MMI::PointerEvent &event)
280885b47fbSopenharmony_ci{
281885b47fbSopenharmony_ci    HILOG_DEBUG();
282885b47fbSopenharmony_ci    MMI::PointerEvent::PointerItem pointerItem;
283885b47fbSopenharmony_ci    if (!event.GetPointerItem(event.GetPointerId(), pointerItem)) {
284885b47fbSopenharmony_ci        HILOG_WARN("get GetPointerItem %{public}d failed", event.GetPointerId());
285885b47fbSopenharmony_ci    }
286885b47fbSopenharmony_ci
287885b47fbSopenharmony_ci    if (event.GetPointerIds().size() > POINTER_COUNT_1) {
288885b47fbSopenharmony_ci        if (cachedDownPointerEvents_.empty()) {
289885b47fbSopenharmony_ci            HILOG_ERROR("cached down pointer event is empty!");
290885b47fbSopenharmony_ci            return;
291885b47fbSopenharmony_ci        }
292885b47fbSopenharmony_ci        if (isMoveBeyondThreshold_ == true) {
293885b47fbSopenharmony_ci            cachedDownPointerEvents_.push_back(event);
294885b47fbSopenharmony_ci            EventTransmission::OnPointerEvent(event);
295885b47fbSopenharmony_ci            return;
296885b47fbSopenharmony_ci        } else if (isStopDrawCircle_ == true) {
297885b47fbSopenharmony_ci            return;
298885b47fbSopenharmony_ci        } else {
299885b47fbSopenharmony_ci            cachedDownPointerEvents_.push_back(event);
300885b47fbSopenharmony_ci            return;
301885b47fbSopenharmony_ci        }
302885b47fbSopenharmony_ci    }
303885b47fbSopenharmony_ci
304885b47fbSopenharmony_ci    screenId_ = event.GetTargetDisplayId();
305885b47fbSopenharmony_ci    startTime_ = event.GetActionTime();
306885b47fbSopenharmony_ci    startPointer_ = std::make_shared<MMI::PointerEvent::PointerItem>(pointerItem);
307885b47fbSopenharmony_ci    isMoveBeyondThreshold_ = false;
308885b47fbSopenharmony_ci
309885b47fbSopenharmony_ci    HILOG_INFO("ROTATE_POLICY = %{public}d, FOLDABLE = %{public}s", ROTATE_POLICY, FOLDABLE.c_str());
310885b47fbSopenharmony_ci    HandleCoordinates(pointerItem);
311885b47fbSopenharmony_ci    isStopDrawCircle_ = false;
312885b47fbSopenharmony_ci    if (drawCircleThread_ && drawCircleThread_->joinable()) {
313885b47fbSopenharmony_ci        drawCircleThread_->join();
314885b47fbSopenharmony_ci    }
315885b47fbSopenharmony_ci
316885b47fbSopenharmony_ci    drawCircleThread_ = nullptr;
317885b47fbSopenharmony_ci    drawCircleThread_ = std::make_shared<std::thread>([this] {this->DrawCircleProgress();});
318885b47fbSopenharmony_ci    if (drawCircleThread_ == nullptr) {
319885b47fbSopenharmony_ci        HILOG_ERROR("create draw circle progress fail");
320885b47fbSopenharmony_ci    }
321885b47fbSopenharmony_ci
322885b47fbSopenharmony_ci    handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
323885b47fbSopenharmony_ci    cachedDownPointerEvents_.clear();
324885b47fbSopenharmony_ci    cachedDownPointerEvents_.push_back(event);
325885b47fbSopenharmony_ci    handler_->SendEvent(FINGER_DOWN_DELAY_MSG, 0, static_cast<int32_t>(GetRealClickResponseTime()));
326885b47fbSopenharmony_ci}
327885b47fbSopenharmony_ci
328885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleResponseDelayStateInnerMove(MMI::PointerEvent &event)
329885b47fbSopenharmony_ci{
330885b47fbSopenharmony_ci    HILOG_DEBUG();
331885b47fbSopenharmony_ci    if (cachedDownPointerEvents_.empty()) {
332885b47fbSopenharmony_ci        HILOG_ERROR("cached down pointer event is empty!");
333885b47fbSopenharmony_ci        return;
334885b47fbSopenharmony_ci    }
335885b47fbSopenharmony_ci
336885b47fbSopenharmony_ci    if (isMoveBeyondThreshold_ == true) {
337885b47fbSopenharmony_ci        handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
338885b47fbSopenharmony_ci        EventTransmission::OnPointerEvent(event);
339885b47fbSopenharmony_ci        return;
340885b47fbSopenharmony_ci    }
341885b47fbSopenharmony_ci
342885b47fbSopenharmony_ci    if (startPointer_ == nullptr) {
343885b47fbSopenharmony_ci        return;
344885b47fbSopenharmony_ci    }
345885b47fbSopenharmony_ci
346885b47fbSopenharmony_ci    if (event.GetPointerId() != startPointer_->GetPointerId()) {
347885b47fbSopenharmony_ci        if (isStopDrawCircle_ == true) {
348885b47fbSopenharmony_ci            EventTransmission::OnPointerEvent(event);
349885b47fbSopenharmony_ci        }
350885b47fbSopenharmony_ci        return;
351885b47fbSopenharmony_ci    }
352885b47fbSopenharmony_ci
353885b47fbSopenharmony_ci    MMI::PointerEvent::PointerItem pointerItem;
354885b47fbSopenharmony_ci    if (!event.GetPointerItem(event.GetPointerId(), pointerItem)) {
355885b47fbSopenharmony_ci        HILOG_WARN("get GetPointerItem %{public}d failed", event.GetPointerId());
356885b47fbSopenharmony_ci    }
357885b47fbSopenharmony_ci
358885b47fbSopenharmony_ci    float offsetX = startPointer_->GetDisplayX() - pointerItem.GetDisplayX();
359885b47fbSopenharmony_ci    float offsetY = startPointer_->GetDisplayY() - pointerItem.GetDisplayY();
360885b47fbSopenharmony_ci    double duration = hypot(offsetX, offsetY);
361885b47fbSopenharmony_ci    if (duration > TOUCH_SLOP) {
362885b47fbSopenharmony_ci        handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
363885b47fbSopenharmony_ci        if (isStopDrawCircle_ != true && !cachedDownPointerEvents_.empty()) {
364885b47fbSopenharmony_ci            for (auto iter = cachedDownPointerEvents_.begin(); iter != cachedDownPointerEvents_.end(); ++iter) {
365885b47fbSopenharmony_ci                iter->SetActionTime(Utils::GetSystemTime() * US_TO_MS);
366885b47fbSopenharmony_ci                EventTransmission::OnPointerEvent(*iter);
367885b47fbSopenharmony_ci            }
368885b47fbSopenharmony_ci        }
369885b47fbSopenharmony_ci        EventTransmission::OnPointerEvent(event);
370885b47fbSopenharmony_ci        isMoveBeyondThreshold_ = true;
371885b47fbSopenharmony_ci        isStopDrawCircle_ = true;
372885b47fbSopenharmony_ci        return;
373885b47fbSopenharmony_ci    }
374885b47fbSopenharmony_ci
375885b47fbSopenharmony_ci    if (isStopDrawCircle_ != true) {
376885b47fbSopenharmony_ci        HandleCoordinates(pointerItem);
377885b47fbSopenharmony_ci        return;
378885b47fbSopenharmony_ci    }
379885b47fbSopenharmony_ci
380885b47fbSopenharmony_ci    EventTransmission::OnPointerEvent(event);
381885b47fbSopenharmony_ci}
382885b47fbSopenharmony_ci
383885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleResponseDelayStateInnerUp(MMI::PointerEvent &event)
384885b47fbSopenharmony_ci{
385885b47fbSopenharmony_ci    HILOG_DEBUG();
386885b47fbSopenharmony_ci
387885b47fbSopenharmony_ci    if (cachedDownPointerEvents_.empty()) {
388885b47fbSopenharmony_ci        HILOG_ERROR("cached down pointer event is empty!");
389885b47fbSopenharmony_ci        handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
390885b47fbSopenharmony_ci        isStopDrawCircle_ = true;
391885b47fbSopenharmony_ci        return;
392885b47fbSopenharmony_ci    }
393885b47fbSopenharmony_ci
394885b47fbSopenharmony_ci    if (isStopDrawCircle_ == true) {
395885b47fbSopenharmony_ci        for (auto iter = cachedDownPointerEvents_.begin(); iter != cachedDownPointerEvents_.end(); ++iter) {
396885b47fbSopenharmony_ci            if (iter->GetPointerId() == event.GetPointerId()) {
397885b47fbSopenharmony_ci                EventTransmission::OnPointerEvent(event);
398885b47fbSopenharmony_ci            }
399885b47fbSopenharmony_ci        }
400885b47fbSopenharmony_ci        if (event.GetPointerIds().size() == POINTER_COUNT_1) {
401885b47fbSopenharmony_ci            cachedDownPointerEvents_.clear();
402885b47fbSopenharmony_ci        }
403885b47fbSopenharmony_ci        return;
404885b47fbSopenharmony_ci    }
405885b47fbSopenharmony_ci
406885b47fbSopenharmony_ci    if (startPointer_ != nullptr && event.GetPointerId() == startPointer_->GetPointerId()) {
407885b47fbSopenharmony_ci        handler_->RemoveEvent(FINGER_DOWN_DELAY_MSG);
408885b47fbSopenharmony_ci        isStopDrawCircle_ = true;
409885b47fbSopenharmony_ci        cachedDownPointerEvents_.clear();
410885b47fbSopenharmony_ci    } else {
411885b47fbSopenharmony_ci        auto iter = std::find_if(cachedDownPointerEvents_.begin(), cachedDownPointerEvents_.end(),
412885b47fbSopenharmony_ci            [&](const MMI::PointerEvent &e) {
413885b47fbSopenharmony_ci                return e.GetPointerId() == event.GetPointerId();
414885b47fbSopenharmony_ci            });
415885b47fbSopenharmony_ci        if (iter != cachedDownPointerEvents_.end()) {
416885b47fbSopenharmony_ci            cachedDownPointerEvents_.erase(iter);
417885b47fbSopenharmony_ci        }
418885b47fbSopenharmony_ci    }
419885b47fbSopenharmony_ci}
420885b47fbSopenharmony_ci
421885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleResponseDelayState(MMI::PointerEvent &event)
422885b47fbSopenharmony_ci{
423885b47fbSopenharmony_ci    HILOG_DEBUG();
424885b47fbSopenharmony_ci
425885b47fbSopenharmony_ci    switch (event.GetPointerAction()) {
426885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_DOWN:
427885b47fbSopenharmony_ci            HandleResponseDelayStateInnerDown(event);
428885b47fbSopenharmony_ci            break;
429885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_MOVE:
430885b47fbSopenharmony_ci            HandleResponseDelayStateInnerMove(event);
431885b47fbSopenharmony_ci            break;
432885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_UP:
433885b47fbSopenharmony_ci            HandleResponseDelayStateInnerUp(event);
434885b47fbSopenharmony_ci            break;
435885b47fbSopenharmony_ci        default:
436885b47fbSopenharmony_ci            EventTransmission::OnPointerEvent(event);
437885b47fbSopenharmony_ci            break;
438885b47fbSopenharmony_ci    }
439885b47fbSopenharmony_ci}
440885b47fbSopenharmony_ci
441885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleIgnoreRepeatClickStateInnerDown(MMI::PointerEvent &event)
442885b47fbSopenharmony_ci{
443885b47fbSopenharmony_ci    HILOG_DEBUG();
444885b47fbSopenharmony_ci
445885b47fbSopenharmony_ci    int64_t downTime = event.GetActionTime();
446885b47fbSopenharmony_ci    if ((event.GetPointerIds().size() == POINTER_COUNT_1) &&
447885b47fbSopenharmony_ci        ((downTime - lastUpTime_) / US_TO_MS < GetRealIgnoreRepeatClickTime())) {
448885b47fbSopenharmony_ci        isInterceptClick_ = true;
449885b47fbSopenharmony_ci        return;
450885b47fbSopenharmony_ci    } else if ((event.GetPointerIds().size() > POINTER_COUNT_1) && (isInterceptClick_ == true)) {
451885b47fbSopenharmony_ci        return;
452885b47fbSopenharmony_ci    }
453885b47fbSopenharmony_ci
454885b47fbSopenharmony_ci    EventTransmission::OnPointerEvent(event);
455885b47fbSopenharmony_ci    isInterceptClick_ = false;
456885b47fbSopenharmony_ci}
457885b47fbSopenharmony_ci
458885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleIgnoreRepeatClickStateInnerMove(MMI::PointerEvent &event)
459885b47fbSopenharmony_ci{
460885b47fbSopenharmony_ci    HILOG_DEBUG();
461885b47fbSopenharmony_ci
462885b47fbSopenharmony_ci    if (isInterceptClick_ == false) {
463885b47fbSopenharmony_ci        EventTransmission::OnPointerEvent(event);
464885b47fbSopenharmony_ci    }
465885b47fbSopenharmony_ci}
466885b47fbSopenharmony_ci
467885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleIgnoreRepeatClickStateInnerUp(MMI::PointerEvent &event)
468885b47fbSopenharmony_ci{
469885b47fbSopenharmony_ci    HILOG_DEBUG();
470885b47fbSopenharmony_ci
471885b47fbSopenharmony_ci    if (isInterceptClick_ == false) {
472885b47fbSopenharmony_ci        EventTransmission::OnPointerEvent(event);
473885b47fbSopenharmony_ci        if (event.GetPointerIds().size() == POINTER_COUNT_1) {
474885b47fbSopenharmony_ci            lastUpTime_ = event.GetActionTime();
475885b47fbSopenharmony_ci        }
476885b47fbSopenharmony_ci    }
477885b47fbSopenharmony_ci}
478885b47fbSopenharmony_ci
479885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleIgnoreRepeatClickState(MMI::PointerEvent &event)
480885b47fbSopenharmony_ci{
481885b47fbSopenharmony_ci    HILOG_DEBUG();
482885b47fbSopenharmony_ci    switch (event.GetPointerAction()) {
483885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_DOWN:
484885b47fbSopenharmony_ci            HandleIgnoreRepeatClickStateInnerDown(event);
485885b47fbSopenharmony_ci            break;
486885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_MOVE:
487885b47fbSopenharmony_ci            HandleIgnoreRepeatClickStateInnerMove(event);
488885b47fbSopenharmony_ci            break;
489885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_UP:
490885b47fbSopenharmony_ci            HandleIgnoreRepeatClickStateInnerUp(event);
491885b47fbSopenharmony_ci            break;
492885b47fbSopenharmony_ci        default:
493885b47fbSopenharmony_ci            EventTransmission::OnPointerEvent(event);
494885b47fbSopenharmony_ci            break;
495885b47fbSopenharmony_ci    }
496885b47fbSopenharmony_ci}
497885b47fbSopenharmony_ci
498885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleBothStateInnerDown(MMI::PointerEvent &event)
499885b47fbSopenharmony_ci{
500885b47fbSopenharmony_ci    HILOG_DEBUG();
501885b47fbSopenharmony_ci
502885b47fbSopenharmony_ci    int64_t downTime = event.GetActionTime();
503885b47fbSopenharmony_ci    if ((event.GetPointerIds().size() == POINTER_COUNT_1) &&
504885b47fbSopenharmony_ci        ((downTime - lastUpTime_) / US_TO_MS < GetRealIgnoreRepeatClickTime())) {
505885b47fbSopenharmony_ci        isInterceptClick_ = true;
506885b47fbSopenharmony_ci        return;
507885b47fbSopenharmony_ci    } else if ((event.GetPointerIds().size() > POINTER_COUNT_1) && (isInterceptClick_ == true)) {
508885b47fbSopenharmony_ci        return;
509885b47fbSopenharmony_ci    }
510885b47fbSopenharmony_ci
511885b47fbSopenharmony_ci    isInterceptClick_ = false;
512885b47fbSopenharmony_ci
513885b47fbSopenharmony_ci    HandleResponseDelayStateInnerDown(event);
514885b47fbSopenharmony_ci}
515885b47fbSopenharmony_ci
516885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleBothStateInnerMove(MMI::PointerEvent &event)
517885b47fbSopenharmony_ci{
518885b47fbSopenharmony_ci    HILOG_DEBUG();
519885b47fbSopenharmony_ci
520885b47fbSopenharmony_ci    if (isInterceptClick_ == true) {
521885b47fbSopenharmony_ci        return;
522885b47fbSopenharmony_ci    }
523885b47fbSopenharmony_ci
524885b47fbSopenharmony_ci    HandleResponseDelayStateInnerMove(event);
525885b47fbSopenharmony_ci}
526885b47fbSopenharmony_ci
527885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleBothStateInnerUp(MMI::PointerEvent &event)
528885b47fbSopenharmony_ci{
529885b47fbSopenharmony_ci    HILOG_DEBUG();
530885b47fbSopenharmony_ci
531885b47fbSopenharmony_ci    if (isInterceptClick_ == true) {
532885b47fbSopenharmony_ci        return;
533885b47fbSopenharmony_ci    }
534885b47fbSopenharmony_ci
535885b47fbSopenharmony_ci    if (event.GetPointerIds().size() == POINTER_COUNT_1) {
536885b47fbSopenharmony_ci        lastUpTime_ = event.GetActionTime();
537885b47fbSopenharmony_ci    }
538885b47fbSopenharmony_ci
539885b47fbSopenharmony_ci    HandleResponseDelayStateInnerUp(event);
540885b47fbSopenharmony_ci}
541885b47fbSopenharmony_ci
542885b47fbSopenharmony_civoid AccessibilityScreenTouch::HandleBothState(MMI::PointerEvent &event)
543885b47fbSopenharmony_ci{
544885b47fbSopenharmony_ci    HILOG_DEBUG();
545885b47fbSopenharmony_ci    switch (event.GetPointerAction()) {
546885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_DOWN:
547885b47fbSopenharmony_ci            HandleBothStateInnerDown(event);
548885b47fbSopenharmony_ci            break;
549885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_MOVE:
550885b47fbSopenharmony_ci            HandleBothStateInnerMove(event);
551885b47fbSopenharmony_ci            break;
552885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_UP:
553885b47fbSopenharmony_ci            HandleBothStateInnerUp(event);
554885b47fbSopenharmony_ci            break;
555885b47fbSopenharmony_ci        default:
556885b47fbSopenharmony_ci            EventTransmission::OnPointerEvent(event);
557885b47fbSopenharmony_ci            break;
558885b47fbSopenharmony_ci    }
559885b47fbSopenharmony_ci}
560885b47fbSopenharmony_ci
561885b47fbSopenharmony_civoid AccessibilityScreenTouch::Clear()
562885b47fbSopenharmony_ci{
563885b47fbSopenharmony_ci    isMoveBeyondThreshold_ = false;
564885b47fbSopenharmony_ci    isInterceptClick_ = false;
565885b47fbSopenharmony_ci    startPointer_ = nullptr;
566885b47fbSopenharmony_ci}
567885b47fbSopenharmony_ci
568885b47fbSopenharmony_cibool AccessibilityScreenTouch::OnPointerEvent(MMI::PointerEvent &event)
569885b47fbSopenharmony_ci{
570885b47fbSopenharmony_ci    HILOG_DEBUG();
571885b47fbSopenharmony_ci    MMI::PointerEvent::PointerItem pointerItem;
572885b47fbSopenharmony_ci    if (!event.GetPointerItem(event.GetPointerId(), pointerItem)) {
573885b47fbSopenharmony_ci        HILOG_WARN("get GetPointerItem %{public}d failed", event.GetPointerId());
574885b47fbSopenharmony_ci        return false;
575885b47fbSopenharmony_ci    }
576885b47fbSopenharmony_ci    if (pointerItem.GetToolType() == MMI::PointerEvent::TOOL_TYPE_KNUCKLE) {
577885b47fbSopenharmony_ci        EventTransmission::OnPointerEvent(event);
578885b47fbSopenharmony_ci        return false;
579885b47fbSopenharmony_ci    }
580885b47fbSopenharmony_ci
581885b47fbSopenharmony_ci    if (event.GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
582885b47fbSopenharmony_ci        EventTransmission::OnPointerEvent(event);
583885b47fbSopenharmony_ci        return false;
584885b47fbSopenharmony_ci    }
585885b47fbSopenharmony_ci
586885b47fbSopenharmony_ci    if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
587885b47fbSopenharmony_ci        Clear();
588885b47fbSopenharmony_ci        return true;
589885b47fbSopenharmony_ci    }
590885b47fbSopenharmony_ci
591885b47fbSopenharmony_ci    switch (currentState_) {
592885b47fbSopenharmony_ci        case ScreenTouchState::CLICK_RESPONSE_DELAY_STATE:
593885b47fbSopenharmony_ci            HandleResponseDelayState(event);
594885b47fbSopenharmony_ci            break;
595885b47fbSopenharmony_ci        case ScreenTouchState::IGNORE_REPEAT_CLICK_STATE:
596885b47fbSopenharmony_ci            HandleIgnoreRepeatClickState(event);
597885b47fbSopenharmony_ci            break;
598885b47fbSopenharmony_ci        case ScreenTouchState::BOTH_RESPONSE_DELAY_IGNORE_REPEAT_CLICK:
599885b47fbSopenharmony_ci            HandleBothState(event);
600885b47fbSopenharmony_ci            break;
601885b47fbSopenharmony_ci        case ScreenTouchState::DEFAULT_STATE:
602885b47fbSopenharmony_ci        default:
603885b47fbSopenharmony_ci            EventTransmission::OnPointerEvent(event);
604885b47fbSopenharmony_ci    }
605885b47fbSopenharmony_ci
606885b47fbSopenharmony_ci    return true;
607885b47fbSopenharmony_ci}
608885b47fbSopenharmony_ci} // namespace Accessibility
609885b47fbSopenharmony_ci} // namespace OHOS