1885b47fbSopenharmony_ci/*
2885b47fbSopenharmony_ci * Copyright (C) 2022 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 "accessibility_touch_guider.h"
17885b47fbSopenharmony_ci#include "accessibility_window_manager.h"
18885b47fbSopenharmony_ci#include "accessibility_event_info.h"
19885b47fbSopenharmony_ci#include "hilog_wrapper.h"
20885b47fbSopenharmony_ci#include "securec.h"
21885b47fbSopenharmony_ci#include "utils.h"
22885b47fbSopenharmony_ci
23885b47fbSopenharmony_cinamespace OHOS {
24885b47fbSopenharmony_cinamespace Accessibility {
25885b47fbSopenharmony_cinamespace {
26885b47fbSopenharmony_ci    constexpr int32_t POINTER_COUNT_1 = 1;
27885b47fbSopenharmony_ci    constexpr int32_t POINTER_COUNT_2 = 2;
28885b47fbSopenharmony_ci    constexpr int32_t SCREEN_AXIS_NUM = 2;
29885b47fbSopenharmony_ci    constexpr int32_t REMOVE_POINTER_ID_1 = 1;
30885b47fbSopenharmony_ci    constexpr int64_t IGNORE_REPEAT_EXECUTE_INTERVAL = 300;
31885b47fbSopenharmony_ci} // namespace
32885b47fbSopenharmony_ci
33885b47fbSopenharmony_ciTGEventHandler::TGEventHandler(
34885b47fbSopenharmony_ci    const std::shared_ptr<AppExecFwk::EventRunner> &runner, TouchGuider &tgServer)
35885b47fbSopenharmony_ci    : AppExecFwk::EventHandler(runner), tgServer_(tgServer)
36885b47fbSopenharmony_ci{
37885b47fbSopenharmony_ci}
38885b47fbSopenharmony_ci
39885b47fbSopenharmony_ciint64_t TouchGuider::lastDoubleTapTime = 0;
40885b47fbSopenharmony_ci
41885b47fbSopenharmony_ciTouchGuider::TouchGuider()
42885b47fbSopenharmony_ci{
43885b47fbSopenharmony_ci    HILOG_DEBUG();
44885b47fbSopenharmony_ci    currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
45885b47fbSopenharmony_ci}
46885b47fbSopenharmony_ci
47885b47fbSopenharmony_civoid TouchGuider::StartUp()
48885b47fbSopenharmony_ci{
49885b47fbSopenharmony_ci    HILOG_DEBUG();
50885b47fbSopenharmony_ci    touchGuideListener_ = std::make_unique<TouchGuideListener>(*this);
51885b47fbSopenharmony_ci    gestureRecognizer_.RegisterListener(*touchGuideListener_.get());
52885b47fbSopenharmony_ci    multiFingerGestureRecognizer_.RegisterListener(*touchGuideListener_.get());
53885b47fbSopenharmony_ci
54885b47fbSopenharmony_ci    runner_ = Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner();
55885b47fbSopenharmony_ci    if (!runner_) {
56885b47fbSopenharmony_ci        HILOG_ERROR("get runner failed");
57885b47fbSopenharmony_ci        return;
58885b47fbSopenharmony_ci    }
59885b47fbSopenharmony_ci
60885b47fbSopenharmony_ci    handler_ = std::make_shared<TGEventHandler>(runner_, *this);
61885b47fbSopenharmony_ci    if (!handler_) {
62885b47fbSopenharmony_ci        HILOG_ERROR("create event handler failed");
63885b47fbSopenharmony_ci        return;
64885b47fbSopenharmony_ci    }
65885b47fbSopenharmony_ci}
66885b47fbSopenharmony_ci
67885b47fbSopenharmony_civoid TGEventHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
68885b47fbSopenharmony_ci{
69885b47fbSopenharmony_ci    HILOG_DEBUG();
70885b47fbSopenharmony_ci    switch (event->GetInnerEventId()) {
71885b47fbSopenharmony_ci        case TouchGuider::EXIT_GESTURE_REC_MSG:
72885b47fbSopenharmony_ci            tgServer_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_END);
73885b47fbSopenharmony_ci            break;
74885b47fbSopenharmony_ci        case TouchGuider::SEND_HOVER_ENTER_MOVE_MSG:
75885b47fbSopenharmony_ci            HoverEnterAndMoveRunner();
76885b47fbSopenharmony_ci            break;
77885b47fbSopenharmony_ci        case TouchGuider::SEND_HOVER_EXIT_MSG:
78885b47fbSopenharmony_ci            HoverExitRunner();
79885b47fbSopenharmony_ci            break;
80885b47fbSopenharmony_ci        case TouchGuider::SEND_TOUCH_GUIDE_END_MSG:
81885b47fbSopenharmony_ci            tgServer_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_END);
82885b47fbSopenharmony_ci            break;
83885b47fbSopenharmony_ci        default:
84885b47fbSopenharmony_ci            break;
85885b47fbSopenharmony_ci    }
86885b47fbSopenharmony_ci}
87885b47fbSopenharmony_ci
88885b47fbSopenharmony_civoid TouchGuider::SendTouchEventToAA(MMI::PointerEvent &event)
89885b47fbSopenharmony_ci{
90885b47fbSopenharmony_ci    HILOG_DEBUG();
91885b47fbSopenharmony_ci
92885b47fbSopenharmony_ci    if (event.GetPointerIds().size() != POINTER_COUNT_1) {
93885b47fbSopenharmony_ci        return;
94885b47fbSopenharmony_ci    }
95885b47fbSopenharmony_ci
96885b47fbSopenharmony_ci    MMI::PointerEvent::PointerItem pointerIterm = {};
97885b47fbSopenharmony_ci    if (!event.GetPointerItem(event.GetPointerId(), pointerIterm)) {
98885b47fbSopenharmony_ci        HILOG_WARN("GetPointerItem(%{public}d) failed", event.GetPointerId());
99885b47fbSopenharmony_ci    }
100885b47fbSopenharmony_ci
101885b47fbSopenharmony_ci    if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN) {
102885b47fbSopenharmony_ci        SendAccessibilityEventToAA(EventType::TYPE_TOUCH_BEGIN);
103885b47fbSopenharmony_ci    } else if (!pointerIterm.IsPressed()) {
104885b47fbSopenharmony_ci        SendAccessibilityEventToAA(EventType::TYPE_TOUCH_END);
105885b47fbSopenharmony_ci    }
106885b47fbSopenharmony_ci}
107885b47fbSopenharmony_ci
108885b47fbSopenharmony_cibool TouchGuider::OnPointerEvent(MMI::PointerEvent &event)
109885b47fbSopenharmony_ci{
110885b47fbSopenharmony_ci    HILOG_DEBUG();
111885b47fbSopenharmony_ci    if (event.GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
112885b47fbSopenharmony_ci        EventTransmission::OnPointerEvent(event);
113885b47fbSopenharmony_ci        return false;
114885b47fbSopenharmony_ci    }
115885b47fbSopenharmony_ci
116885b47fbSopenharmony_ci    if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN ||
117885b47fbSopenharmony_ci        event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP) {
118885b47fbSopenharmony_ci        HILOG_INFO("PointerAction:%{public}d, PointerId:%{public}d.", event.GetPointerAction(),
119885b47fbSopenharmony_ci            event.GetPointerId());
120885b47fbSopenharmony_ci    }
121885b47fbSopenharmony_ci    SendTouchEventToAA(event);
122885b47fbSopenharmony_ci
123885b47fbSopenharmony_ci    if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
124885b47fbSopenharmony_ci        if ((static_cast<TouchGuideState>(currentState_) == TouchGuideState::DRAGGING) &&
125885b47fbSopenharmony_ci            event.GetPointerId() == currentPid_) {
126885b47fbSopenharmony_ci            EventTransmission::OnPointerEvent(event);
127885b47fbSopenharmony_ci        } else if (static_cast<TouchGuideState>(currentState_) != TouchGuideState::DRAGGING) {
128885b47fbSopenharmony_ci            Clear(event);
129885b47fbSopenharmony_ci        }
130885b47fbSopenharmony_ci        event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_HOVER_CANCEL);
131885b47fbSopenharmony_ci        EventTransmission::OnPointerEvent(event);
132885b47fbSopenharmony_ci        return true;
133885b47fbSopenharmony_ci    }
134885b47fbSopenharmony_ci    RecordReceivedEvent(event);
135885b47fbSopenharmony_ci
136885b47fbSopenharmony_ci    bool gestureRecognizedFlag = false;
137885b47fbSopenharmony_ci    if (!multiFingerGestureRecognizer_.IsMultiFingerGestureStarted() &&
138885b47fbSopenharmony_ci        gestureRecognizer_.OnPointerEvent(event)) {
139885b47fbSopenharmony_ci        gestureRecognizedFlag = true;
140885b47fbSopenharmony_ci    }
141885b47fbSopenharmony_ci    if (gestureRecognizer_.GetIsDoubleTap() && gestureRecognizer_.GetIsLongpress()) {
142885b47fbSopenharmony_ci        HILOG_DEBUG("recognize doubleTap and longpress");
143885b47fbSopenharmony_ci        if (doubleTapLongPressDownEvent_ != nullptr) {
144885b47fbSopenharmony_ci            SendEventToMultimodal(*doubleTapLongPressDownEvent_, NO_CHANGE);
145885b47fbSopenharmony_ci            doubleTapLongPressDownEvent_ = nullptr;
146885b47fbSopenharmony_ci        }
147885b47fbSopenharmony_ci        SendEventToMultimodal(event, NO_CHANGE);
148885b47fbSopenharmony_ci        gestureRecognizedFlag = true;
149885b47fbSopenharmony_ci    }
150885b47fbSopenharmony_ci
151885b47fbSopenharmony_ci    multiFingerGestureRecognizer_.OnPointerEvent(event);
152885b47fbSopenharmony_ci
153885b47fbSopenharmony_ci    if (!gestureRecognizedFlag) {
154885b47fbSopenharmony_ci        HandlePointerEvent(event);
155885b47fbSopenharmony_ci    }
156885b47fbSopenharmony_ci    return true;
157885b47fbSopenharmony_ci}
158885b47fbSopenharmony_ci
159885b47fbSopenharmony_civoid TouchGuider::HandlePointerEvent(MMI::PointerEvent &event)
160885b47fbSopenharmony_ci{
161885b47fbSopenharmony_ci    switch (static_cast<TouchGuideState>(currentState_)) {
162885b47fbSopenharmony_ci        case TouchGuideState::TOUCH_GUIDING:
163885b47fbSopenharmony_ci            if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN &&
164885b47fbSopenharmony_ci                event.GetPointerIds().size() == POINTER_COUNT_1) {
165885b47fbSopenharmony_ci                cachedPointerEvents_.clear();
166885b47fbSopenharmony_ci            }
167885b47fbSopenharmony_ci            cachedPointerEvents_.push_back(event);
168885b47fbSopenharmony_ci            HandleTouchGuidingState(event);
169885b47fbSopenharmony_ci            break;
170885b47fbSopenharmony_ci        case TouchGuideState::DRAGGING:
171885b47fbSopenharmony_ci            HandleDraggingState(event);
172885b47fbSopenharmony_ci            break;
173885b47fbSopenharmony_ci        case TouchGuideState::TRANSMITTING:
174885b47fbSopenharmony_ci            HandleTransmitingState(event);
175885b47fbSopenharmony_ci            break;
176885b47fbSopenharmony_ci        case TouchGuideState::PASSING_THROUGH:
177885b47fbSopenharmony_ci            HandlePassingThroughState(event);
178885b47fbSopenharmony_ci            break;
179885b47fbSopenharmony_ci        default:
180885b47fbSopenharmony_ci            break;
181885b47fbSopenharmony_ci    }
182885b47fbSopenharmony_ci}
183885b47fbSopenharmony_ci
184885b47fbSopenharmony_civoid TouchGuider::DestroyEvents()
185885b47fbSopenharmony_ci{
186885b47fbSopenharmony_ci    HILOG_DEBUG();
187885b47fbSopenharmony_ci
188885b47fbSopenharmony_ci    Clear();
189885b47fbSopenharmony_ci    EventTransmission::DestroyEvents();
190885b47fbSopenharmony_ci}
191885b47fbSopenharmony_ci
192885b47fbSopenharmony_civoid TouchGuider::SendAccessibilityEventToAA(EventType eventType)
193885b47fbSopenharmony_ci{
194885b47fbSopenharmony_ci    HILOG_DEBUG("eventType is 0x%{public}x.", eventType);
195885b47fbSopenharmony_ci
196885b47fbSopenharmony_ci    AccessibilityEventInfo eventInfo {};
197885b47fbSopenharmony_ci    eventInfo.SetEventType(eventType);
198885b47fbSopenharmony_ci    int32_t windowsId = Singleton<AccessibilityWindowManager>::GetInstance().GetActiveWindowId();
199885b47fbSopenharmony_ci    eventInfo.SetWindowId(windowsId);
200885b47fbSopenharmony_ci    Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(eventInfo);
201885b47fbSopenharmony_ci    if (eventType == EventType::TYPE_TOUCH_GUIDE_BEGIN) {
202885b47fbSopenharmony_ci        isTouchGuiding_ = true;
203885b47fbSopenharmony_ci    } else if (eventType == EventType::TYPE_TOUCH_GUIDE_END) {
204885b47fbSopenharmony_ci        isTouchGuiding_ = false;
205885b47fbSopenharmony_ci    }
206885b47fbSopenharmony_ci}
207885b47fbSopenharmony_ci
208885b47fbSopenharmony_civoid TouchGuider::SendGestureEventToAA(GestureType gestureId)
209885b47fbSopenharmony_ci{
210885b47fbSopenharmony_ci    HILOG_DEBUG("gestureId is %{public}d.", gestureId);
211885b47fbSopenharmony_ci
212885b47fbSopenharmony_ci    AccessibilityEventInfo eventInfo {};
213885b47fbSopenharmony_ci    int32_t windowsId = Singleton<AccessibilityWindowManager>::GetInstance().GetActiveWindowId();
214885b47fbSopenharmony_ci    eventInfo.SetWindowId(windowsId);
215885b47fbSopenharmony_ci    eventInfo.SetEventType(EventType::TYPE_GESTURE_EVENT);
216885b47fbSopenharmony_ci    eventInfo.SetGestureType(gestureId);
217885b47fbSopenharmony_ci    Singleton<AccessibleAbilityManagerService>::GetInstance().SendEvent(eventInfo);
218885b47fbSopenharmony_ci}
219885b47fbSopenharmony_ci
220885b47fbSopenharmony_civoid TouchGuider::OffsetEvent(MMI::PointerEvent &event)
221885b47fbSopenharmony_ci{
222885b47fbSopenharmony_ci    HILOG_DEBUG("OffsetEvent");
223885b47fbSopenharmony_ci    MMI::PointerEvent::PointerItem pointer = {};
224885b47fbSopenharmony_ci    event.GetPointerItem(event.GetPointerId(), pointer);
225885b47fbSopenharmony_ci
226885b47fbSopenharmony_ci    // add offset
227885b47fbSopenharmony_ci    int32_t newDisplayX = pointer.GetDisplayX() + static_cast<int>(longPressOffsetX_);
228885b47fbSopenharmony_ci    int32_t newDisplayY = pointer.GetDisplayY() + static_cast<int>(longPressOffsetY_);
229885b47fbSopenharmony_ci
230885b47fbSopenharmony_ci    HILOG_DEBUG("newDisplayX: %{public}d, newDisplayY: %{public}d", newDisplayX, newDisplayY);
231885b47fbSopenharmony_ci    pointer.SetDisplayX(newDisplayX);
232885b47fbSopenharmony_ci    pointer.SetDisplayY(newDisplayY);
233885b47fbSopenharmony_ci    event.RemovePointerItem(event.GetPointerId());
234885b47fbSopenharmony_ci    event.AddPointerItem(pointer);
235885b47fbSopenharmony_ci}
236885b47fbSopenharmony_ci
237885b47fbSopenharmony_civoid TouchGuider::SendEventToMultimodal(MMI::PointerEvent &event, int32_t action)
238885b47fbSopenharmony_ci{
239885b47fbSopenharmony_ci    HILOG_DEBUG("action:%{public}d, SourceType:%{public}d.", action, event.GetSourceType());
240885b47fbSopenharmony_ci
241885b47fbSopenharmony_ci    if (gestureRecognizer_.GetIsDoubleTap() && gestureRecognizer_.GetIsLongpress()) {
242885b47fbSopenharmony_ci        bool focusedElementExistFlag = true;
243885b47fbSopenharmony_ci        if (!focusedElementExist_) {
244885b47fbSopenharmony_ci            HILOG_DEBUG("send long press event to multimodal, but no focused element.");
245885b47fbSopenharmony_ci            focusedElementExistFlag = false;
246885b47fbSopenharmony_ci        }
247885b47fbSopenharmony_ci        OffsetEvent(event);
248885b47fbSopenharmony_ci        if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP &&
249885b47fbSopenharmony_ci            event.GetPointerIds().size() == POINTER_COUNT_1) {
250885b47fbSopenharmony_ci            HILOG_INFO("doubleTap and longpress end");
251885b47fbSopenharmony_ci            Clear(event);
252885b47fbSopenharmony_ci        }
253885b47fbSopenharmony_ci        if (!focusedElementExistFlag) {
254885b47fbSopenharmony_ci            return;
255885b47fbSopenharmony_ci        }
256885b47fbSopenharmony_ci    }
257885b47fbSopenharmony_ci
258885b47fbSopenharmony_ci    switch (action) {
259885b47fbSopenharmony_ci        case HOVER_MOVE:
260885b47fbSopenharmony_ci            if (event.GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
261885b47fbSopenharmony_ci                event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_HOVER_MOVE);
262885b47fbSopenharmony_ci            }
263885b47fbSopenharmony_ci            break;
264885b47fbSopenharmony_ci        case POINTER_DOWN:
265885b47fbSopenharmony_ci            if (event.GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
266885b47fbSopenharmony_ci                event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_DOWN);
267885b47fbSopenharmony_ci            }
268885b47fbSopenharmony_ci            break;
269885b47fbSopenharmony_ci        case POINTER_UP:
270885b47fbSopenharmony_ci            if (event.GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
271885b47fbSopenharmony_ci                event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_UP);
272885b47fbSopenharmony_ci            }
273885b47fbSopenharmony_ci            break;
274885b47fbSopenharmony_ci        case HOVER_ENTER:
275885b47fbSopenharmony_ci            if (event.GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
276885b47fbSopenharmony_ci                event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_HOVER_ENTER);
277885b47fbSopenharmony_ci            }
278885b47fbSopenharmony_ci            break;
279885b47fbSopenharmony_ci        case HOVER_EXIT:
280885b47fbSopenharmony_ci            if (event.GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
281885b47fbSopenharmony_ci                event.SetPointerAction(MMI::PointerEvent::POINTER_ACTION_HOVER_EXIT);
282885b47fbSopenharmony_ci            }
283885b47fbSopenharmony_ci            break;
284885b47fbSopenharmony_ci        default:
285885b47fbSopenharmony_ci            break;
286885b47fbSopenharmony_ci    }
287885b47fbSopenharmony_ci    EventTransmission::OnPointerEvent(event);
288885b47fbSopenharmony_ci    RecordInjectedEvent(event);
289885b47fbSopenharmony_ci}
290885b47fbSopenharmony_ci
291885b47fbSopenharmony_cistd::list<MMI::PointerEvent> TouchGuider::getHoverEnterAndMoveEvent()
292885b47fbSopenharmony_ci{
293885b47fbSopenharmony_ci    HILOG_DEBUG();
294885b47fbSopenharmony_ci
295885b47fbSopenharmony_ci    return pointerEvents_;
296885b47fbSopenharmony_ci}
297885b47fbSopenharmony_ci
298885b47fbSopenharmony_civoid TouchGuider::ClearHoverEnterAndMoveEvent()
299885b47fbSopenharmony_ci{
300885b47fbSopenharmony_ci    HILOG_DEBUG();
301885b47fbSopenharmony_ci
302885b47fbSopenharmony_ci    pointerEvents_.clear();
303885b47fbSopenharmony_ci    gestureRecognizer_.Clear();
304885b47fbSopenharmony_ci}
305885b47fbSopenharmony_ci
306885b47fbSopenharmony_cistd::shared_ptr<MMI::PointerEvent> TouchGuider::getLastReceivedEvent()
307885b47fbSopenharmony_ci{
308885b47fbSopenharmony_ci    HILOG_DEBUG();
309885b47fbSopenharmony_ci
310885b47fbSopenharmony_ci    return receivedRecorder_.lastEvent;
311885b47fbSopenharmony_ci}
312885b47fbSopenharmony_ci
313885b47fbSopenharmony_cibool TouchGuider::TouchGuideListener::OnDoubleTap(MMI::PointerEvent &event)
314885b47fbSopenharmony_ci{
315885b47fbSopenharmony_ci    HILOG_INFO();
316885b47fbSopenharmony_ci
317885b47fbSopenharmony_ci    if (server_.currentState_ != static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING)) {
318885b47fbSopenharmony_ci        return false;
319885b47fbSopenharmony_ci    }
320885b47fbSopenharmony_ci    server_.OnTouchInteractionEnd();
321885b47fbSopenharmony_ci    server_.CancelPostEventIfNeed(server_.SEND_HOVER_ENTER_MOVE_MSG);
322885b47fbSopenharmony_ci    server_.CancelPostEventIfNeed(server_.SEND_HOVER_EXIT_MSG);
323885b47fbSopenharmony_ci    server_.ForceSendAndRemoveEvent(server_.SEND_TOUCH_GUIDE_END_MSG, event);
324885b47fbSopenharmony_ci
325885b47fbSopenharmony_ci    return server_.ExecuteActionOnAccessibilityFocused(ActionType::ACCESSIBILITY_ACTION_CLICK);
326885b47fbSopenharmony_ci}
327885b47fbSopenharmony_ci
328885b47fbSopenharmony_cibool TouchGuider::TouchGuideListener::OnStarted()
329885b47fbSopenharmony_ci{
330885b47fbSopenharmony_ci    HILOG_DEBUG();
331885b47fbSopenharmony_ci
332885b47fbSopenharmony_ci    server_.currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
333885b47fbSopenharmony_ci    server_.CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
334885b47fbSopenharmony_ci    server_.CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
335885b47fbSopenharmony_ci    server_.PostGestureRecognizeExit();
336885b47fbSopenharmony_ci    server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_BEGIN);
337885b47fbSopenharmony_ci    return true;
338885b47fbSopenharmony_ci}
339885b47fbSopenharmony_ci
340885b47fbSopenharmony_civoid TouchGuider::TouchGuideListener::MultiFingerGestureOnStarted(bool isTwoFingerGesture)
341885b47fbSopenharmony_ci{
342885b47fbSopenharmony_ci    HILOG_DEBUG();
343885b47fbSopenharmony_ci
344885b47fbSopenharmony_ci    if (!isTwoFingerGesture) {
345885b47fbSopenharmony_ci        server_.currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
346885b47fbSopenharmony_ci        return;
347885b47fbSopenharmony_ci    }
348885b47fbSopenharmony_ci
349885b47fbSopenharmony_ci    server_.CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
350885b47fbSopenharmony_ci    server_.CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
351885b47fbSopenharmony_ci    server_.PostGestureRecognizeExit();
352885b47fbSopenharmony_ci    server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_BEGIN);
353885b47fbSopenharmony_ci}
354885b47fbSopenharmony_ci
355885b47fbSopenharmony_cibool TouchGuider::TouchGuideListener::OnCompleted(GestureType gestureId)
356885b47fbSopenharmony_ci{
357885b47fbSopenharmony_ci    HILOG_INFO("gestureId is %{public}d", gestureId);
358885b47fbSopenharmony_ci
359885b47fbSopenharmony_ci    if (server_.currentState_ != static_cast<int32_t>(TouchGuideState::TRANSMITTING)) {
360885b47fbSopenharmony_ci        HILOG_DEBUG("OnCompleted, state is not transmitting.");
361885b47fbSopenharmony_ci        return false;
362885b47fbSopenharmony_ci    }
363885b47fbSopenharmony_ci    server_.OnTouchInteractionEnd();
364885b47fbSopenharmony_ci    server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_END);
365885b47fbSopenharmony_ci    server_.CancelPostEvent(EXIT_GESTURE_REC_MSG);
366885b47fbSopenharmony_ci    server_.currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
367885b47fbSopenharmony_ci
368885b47fbSopenharmony_ci    // Send customize gesture type to aa
369885b47fbSopenharmony_ci    server_.SendGestureEventToAA(gestureId);
370885b47fbSopenharmony_ci    return true;
371885b47fbSopenharmony_ci}
372885b47fbSopenharmony_ci
373885b47fbSopenharmony_civoid TouchGuider::TouchGuideListener::MultiFingerGestureOnCompleted(GestureType gestureId)
374885b47fbSopenharmony_ci{
375885b47fbSopenharmony_ci    HILOG_INFO("gestureId is %{public}d", gestureId);
376885b47fbSopenharmony_ci
377885b47fbSopenharmony_ci    server_.OnTouchInteractionEnd();
378885b47fbSopenharmony_ci    server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_END);
379885b47fbSopenharmony_ci    server_.CancelPostEvent(EXIT_GESTURE_REC_MSG);
380885b47fbSopenharmony_ci    server_.currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
381885b47fbSopenharmony_ci
382885b47fbSopenharmony_ci    // Send customize gesture type to aa
383885b47fbSopenharmony_ci    server_.SendGestureEventToAA(gestureId);
384885b47fbSopenharmony_ci}
385885b47fbSopenharmony_ci
386885b47fbSopenharmony_cibool TouchGuider::TouchGuideListener::OnCancelled(MMI::PointerEvent &event)
387885b47fbSopenharmony_ci{
388885b47fbSopenharmony_ci    HILOG_DEBUG();
389885b47fbSopenharmony_ci
390885b47fbSopenharmony_ci    switch (static_cast<TouchGuideState>(server_.currentState_)) {
391885b47fbSopenharmony_ci        case TouchGuideState::TRANSMITTING:
392885b47fbSopenharmony_ci            server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_END);
393885b47fbSopenharmony_ci            if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP &&
394885b47fbSopenharmony_ci                event.GetPointerIds().size() == POINTER_COUNT_1) {
395885b47fbSopenharmony_ci                server_.OnTouchInteractionEnd();
396885b47fbSopenharmony_ci            }
397885b47fbSopenharmony_ci            server_.CancelPostEvent(EXIT_GESTURE_REC_MSG);
398885b47fbSopenharmony_ci            server_.currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
399885b47fbSopenharmony_ci            break;
400885b47fbSopenharmony_ci        case TouchGuideState::TOUCH_GUIDING:
401885b47fbSopenharmony_ci            server_.pointerEvents_.push_back(event);
402885b47fbSopenharmony_ci            server_.ForceSendAndRemoveEvent(SEND_HOVER_ENTER_MOVE_MSG, event);
403885b47fbSopenharmony_ci            server_.CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
404885b47fbSopenharmony_ci            server_.SendEventToMultimodal(event, HOVER_MOVE);
405885b47fbSopenharmony_ci            break;
406885b47fbSopenharmony_ci        default:
407885b47fbSopenharmony_ci            return false;
408885b47fbSopenharmony_ci    }
409885b47fbSopenharmony_ci    return true;
410885b47fbSopenharmony_ci}
411885b47fbSopenharmony_ci
412885b47fbSopenharmony_civoid TouchGuider::TouchGuideListener::MultiFingerGestureOnCancelled(const bool isNoDelayFlag)
413885b47fbSopenharmony_ci{
414885b47fbSopenharmony_ci    HILOG_DEBUG();
415885b47fbSopenharmony_ci
416885b47fbSopenharmony_ci    if (static_cast<TouchGuideState>(server_.currentState_) == TouchGuideState::TRANSMITTING) {
417885b47fbSopenharmony_ci        server_.currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
418885b47fbSopenharmony_ci    }
419885b47fbSopenharmony_ci    server_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_GESTURE_END);
420885b47fbSopenharmony_ci    server_.CancelPostEvent(EXIT_GESTURE_REC_MSG);
421885b47fbSopenharmony_ci    if (isNoDelayFlag) {
422885b47fbSopenharmony_ci        server_.OnTouchInteractionEnd();
423885b47fbSopenharmony_ci    }
424885b47fbSopenharmony_ci}
425885b47fbSopenharmony_ci
426885b47fbSopenharmony_civoid TouchGuider::ElementOperatorCallbackImpl::SetFindFocusedElementInfoResult(const AccessibilityElementInfo &info,
427885b47fbSopenharmony_ci    const int32_t requestId)
428885b47fbSopenharmony_ci{
429885b47fbSopenharmony_ci    HILOG_DEBUG("Response [requestId:%{public}d]", requestId);
430885b47fbSopenharmony_ci    accessibilityInfoResult_ = info;
431885b47fbSopenharmony_ci    promise_.set_value();
432885b47fbSopenharmony_ci}
433885b47fbSopenharmony_ci
434885b47fbSopenharmony_civoid TouchGuider::ElementOperatorCallbackImpl::SetSearchElementInfoByTextResult(
435885b47fbSopenharmony_ci    const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)
436885b47fbSopenharmony_ci{
437885b47fbSopenharmony_ci    HILOG_DEBUG("Response [requestId:%{public}d]", requestId);
438885b47fbSopenharmony_ci    elementInfosResult_ = infos;
439885b47fbSopenharmony_ci    promise_.set_value();
440885b47fbSopenharmony_ci}
441885b47fbSopenharmony_ci
442885b47fbSopenharmony_civoid TouchGuider::ElementOperatorCallbackImpl::SetSearchElementInfoByAccessibilityIdResult(
443885b47fbSopenharmony_ci    const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)
444885b47fbSopenharmony_ci{
445885b47fbSopenharmony_ci    HILOG_DEBUG("Response [requestId:%{public}d]", requestId);
446885b47fbSopenharmony_ci    elementInfosResult_ = infos;
447885b47fbSopenharmony_ci    promise_.set_value();
448885b47fbSopenharmony_ci}
449885b47fbSopenharmony_ci
450885b47fbSopenharmony_civoid TouchGuider::ElementOperatorCallbackImpl::SetFocusMoveSearchResult(const AccessibilityElementInfo &info,
451885b47fbSopenharmony_ci    const int32_t requestId)
452885b47fbSopenharmony_ci{
453885b47fbSopenharmony_ci    HILOG_DEBUG("Response [requestId:%{public}d]", requestId);
454885b47fbSopenharmony_ci    accessibilityInfoResult_ = info;
455885b47fbSopenharmony_ci    promise_.set_value();
456885b47fbSopenharmony_ci}
457885b47fbSopenharmony_ci
458885b47fbSopenharmony_civoid TouchGuider::ElementOperatorCallbackImpl::SetExecuteActionResult(const bool succeeded, const int32_t requestId)
459885b47fbSopenharmony_ci{
460885b47fbSopenharmony_ci    HILOG_DEBUG("Response [result:%{public}d, requestId:%{public}d]", succeeded, requestId);
461885b47fbSopenharmony_ci    executeActionResult_ = succeeded;
462885b47fbSopenharmony_ci    promise_.set_value();
463885b47fbSopenharmony_ci}
464885b47fbSopenharmony_ci
465885b47fbSopenharmony_civoid TouchGuider::HandleTouchGuidingState(MMI::PointerEvent &event)
466885b47fbSopenharmony_ci{
467885b47fbSopenharmony_ci    HILOG_DEBUG("action: %{public}d", event.GetPointerAction());
468885b47fbSopenharmony_ci
469885b47fbSopenharmony_ci    switch (event.GetPointerAction()) {
470885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_DOWN:
471885b47fbSopenharmony_ci            if (event.GetPointerIds().size() == POINTER_COUNT_1) {
472885b47fbSopenharmony_ci                HandleTouchGuidingStateInnerDown(event);
473885b47fbSopenharmony_ci            } else if (gestureRecognizer_.GetIsDoubleTap() && gestureRecognizer_.GetIsLongpress()) {
474885b47fbSopenharmony_ci                SendEventToMultimodal(event, NO_CHANGE);
475885b47fbSopenharmony_ci            } else {
476885b47fbSopenharmony_ci                CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
477885b47fbSopenharmony_ci                CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
478885b47fbSopenharmony_ci            }
479885b47fbSopenharmony_ci            break;
480885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_MOVE:
481885b47fbSopenharmony_ci            HandleTouchGuidingStateInnerMove(event);
482885b47fbSopenharmony_ci            break;
483885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_UP:
484885b47fbSopenharmony_ci            if (event.GetPointerIds().size() == POINTER_COUNT_1 && !IsTouchInteractionEnd() &&
485885b47fbSopenharmony_ci                !multiFingerGestureRecognizer_.IsMultiFingerRecognize()) {
486885b47fbSopenharmony_ci                if (gestureRecognizer_.GetIsDoubleTap() && gestureRecognizer_.GetIsLongpress()) {
487885b47fbSopenharmony_ci                    HILOG_DEBUG();
488885b47fbSopenharmony_ci                    SendEventToMultimodal(event, NO_CHANGE);
489885b47fbSopenharmony_ci                    Clear(event);
490885b47fbSopenharmony_ci                    break;
491885b47fbSopenharmony_ci                }
492885b47fbSopenharmony_ci                OnTouchInteractionEnd();
493885b47fbSopenharmony_ci                if (HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
494885b47fbSopenharmony_ci                    PostHoverExit();
495885b47fbSopenharmony_ci                } else if (isTouchGuiding_) {
496885b47fbSopenharmony_ci                    SendExitEvents();
497885b47fbSopenharmony_ci                    PostHoverExit();
498885b47fbSopenharmony_ci                }
499885b47fbSopenharmony_ci            }
500885b47fbSopenharmony_ci            break;
501885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_PULL_MOVE:
502885b47fbSopenharmony_ci            SendEventToMultimodal(event, NO_CHANGE);
503885b47fbSopenharmony_ci            break;
504885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_PULL_UP:
505885b47fbSopenharmony_ci            SendEventToMultimodal(event, NO_CHANGE);
506885b47fbSopenharmony_ci            break;
507885b47fbSopenharmony_ci        default:
508885b47fbSopenharmony_ci            break;
509885b47fbSopenharmony_ci    }
510885b47fbSopenharmony_ci}
511885b47fbSopenharmony_ci
512885b47fbSopenharmony_civoid TouchGuider::HandleDraggingState(MMI::PointerEvent &event)
513885b47fbSopenharmony_ci{
514885b47fbSopenharmony_ci    HILOG_DEBUG();
515885b47fbSopenharmony_ci    std::vector<int32_t> pIds = event.GetPointerIds();
516885b47fbSopenharmony_ci    switch (event.GetPointerAction()) {
517885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_DOWN:
518885b47fbSopenharmony_ci            if (event.GetPointerIds().size() == POINTER_COUNT_1) {
519885b47fbSopenharmony_ci                Clear(event);
520885b47fbSopenharmony_ci            } else {
521885b47fbSopenharmony_ci                currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
522885b47fbSopenharmony_ci                SendAllUpEvents(event);
523885b47fbSopenharmony_ci            }
524885b47fbSopenharmony_ci            break;
525885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_MOVE:
526885b47fbSopenharmony_ci            if (event.GetPointerId() == currentPid_) {
527885b47fbSopenharmony_ci                HandleDraggingStateInnerMove(event);
528885b47fbSopenharmony_ci            }
529885b47fbSopenharmony_ci            break;
530885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_UP:
531885b47fbSopenharmony_ci            if (pIds.size() == POINTER_COUNT_1) {
532885b47fbSopenharmony_ci                if (event.GetPointerId() == currentPid_) {
533885b47fbSopenharmony_ci                    HILOG_DEBUG("single currentPid_ move: %{public}d", event.GetPointerId());
534885b47fbSopenharmony_ci                    OnTouchInteractionEnd();
535885b47fbSopenharmony_ci                    SendEventToMultimodal(event, NO_CHANGE);
536885b47fbSopenharmony_ci                    currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
537885b47fbSopenharmony_ci                }
538885b47fbSopenharmony_ci            } else {
539885b47fbSopenharmony_ci                if (event.GetPointerId() == currentPid_ && pIds.size() == POINTER_COUNT_2) {
540885b47fbSopenharmony_ci                    HILOG_DEBUG("double currentPid_ move: %{public}d", event.GetPointerId());
541885b47fbSopenharmony_ci                    int32_t removePid = currentPid_ == pIds[0]? pIds[1] : pIds[0];
542885b47fbSopenharmony_ci                    event.RemovePointerItem(removePid);
543885b47fbSopenharmony_ci                    OnTouchInteractionEnd();
544885b47fbSopenharmony_ci                    SendEventToMultimodal(event, NO_CHANGE);
545885b47fbSopenharmony_ci                    currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
546885b47fbSopenharmony_ci                }
547885b47fbSopenharmony_ci            }
548885b47fbSopenharmony_ci
549885b47fbSopenharmony_ci            break;
550885b47fbSopenharmony_ci        default:
551885b47fbSopenharmony_ci            break;
552885b47fbSopenharmony_ci    }
553885b47fbSopenharmony_ci}
554885b47fbSopenharmony_ci
555885b47fbSopenharmony_civoid TouchGuider::HandleTransmitingState(MMI::PointerEvent &event)
556885b47fbSopenharmony_ci{
557885b47fbSopenharmony_ci    HILOG_DEBUG();
558885b47fbSopenharmony_ci
559885b47fbSopenharmony_ci    switch (event.GetPointerAction()) {
560885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_DOWN:
561885b47fbSopenharmony_ci            if (event.GetPointerIds().size() == POINTER_COUNT_1) {
562885b47fbSopenharmony_ci                Clear(event);
563885b47fbSopenharmony_ci            }
564885b47fbSopenharmony_ci            break;
565885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_UP:
566885b47fbSopenharmony_ci            if (event.GetPointerIds().size() == POINTER_COUNT_1 && !IsTouchInteractionEnd() &&
567885b47fbSopenharmony_ci                !multiFingerGestureRecognizer_.IsMultiFingerRecognize()) {
568885b47fbSopenharmony_ci                if (longPressPointId_ >= 0) {
569885b47fbSopenharmony_ci                    // Adjust this event's location.
570885b47fbSopenharmony_ci                    MMI::PointerEvent::PointerItem pointer = {};
571885b47fbSopenharmony_ci                    event.GetPointerItem(event.GetPointerId(), pointer);
572885b47fbSopenharmony_ci                    pointer.SetDisplayX(pointer.GetDisplayX() + longPressOffsetX_);
573885b47fbSopenharmony_ci                    pointer.SetDisplayY(pointer.GetDisplayY() + longPressOffsetY_);
574885b47fbSopenharmony_ci                    event.RemovePointerItem(event.GetPointerId());
575885b47fbSopenharmony_ci                    event.AddPointerItem(pointer);
576885b47fbSopenharmony_ci                    longPressPointId_ = INIT_POINT_ID;
577885b47fbSopenharmony_ci                    longPressOffsetX_ = INIT_MMIPOINT;
578885b47fbSopenharmony_ci                    longPressOffsetY_ = INIT_MMIPOINT;
579885b47fbSopenharmony_ci                }
580885b47fbSopenharmony_ci                SendEventToMultimodal(event, NO_CHANGE);
581885b47fbSopenharmony_ci                OnTouchInteractionEnd();
582885b47fbSopenharmony_ci                currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
583885b47fbSopenharmony_ci            }
584885b47fbSopenharmony_ci            break;
585885b47fbSopenharmony_ci        default:
586885b47fbSopenharmony_ci            MMI::PointerEvent::PointerItem pointerItem = {};
587885b47fbSopenharmony_ci            for (auto& pid : event.GetPointerIds()) {
588885b47fbSopenharmony_ci                event.GetPointerItem(pid, pointerItem);
589885b47fbSopenharmony_ci                pointerItem.SetPressed(false);
590885b47fbSopenharmony_ci                event.RemovePointerItem(pid);
591885b47fbSopenharmony_ci                event.AddPointerItem(pointerItem);
592885b47fbSopenharmony_ci            }
593885b47fbSopenharmony_ci            SendEventToMultimodal(event, NO_CHANGE);
594885b47fbSopenharmony_ci            break;
595885b47fbSopenharmony_ci    }
596885b47fbSopenharmony_ci}
597885b47fbSopenharmony_ci
598885b47fbSopenharmony_civoid TouchGuider::HandlePassingThroughState(MMI::PointerEvent &event)
599885b47fbSopenharmony_ci{
600885b47fbSopenharmony_ci    HILOG_DEBUG();
601885b47fbSopenharmony_ci
602885b47fbSopenharmony_ci    if (event.GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP &&
603885b47fbSopenharmony_ci        event.GetPointerIds().size() == POINTER_COUNT_1) {
604885b47fbSopenharmony_ci        SendEventToMultimodal(event, NO_CHANGE);
605885b47fbSopenharmony_ci        OnTouchInteractionEnd();
606885b47fbSopenharmony_ci        currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
607885b47fbSopenharmony_ci        return;
608885b47fbSopenharmony_ci    }
609885b47fbSopenharmony_ci
610885b47fbSopenharmony_ci    SendEventToMultimodal(event, NO_CHANGE);
611885b47fbSopenharmony_ci    return;
612885b47fbSopenharmony_ci}
613885b47fbSopenharmony_ci
614885b47fbSopenharmony_civoid TouchGuider::Clear(MMI::PointerEvent &event)
615885b47fbSopenharmony_ci{
616885b47fbSopenharmony_ci    HILOG_DEBUG();
617885b47fbSopenharmony_ci
618885b47fbSopenharmony_ci    if (currentState_ == static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING)) {
619885b47fbSopenharmony_ci        SendExitEvents();
620885b47fbSopenharmony_ci    } else if (currentState_ == static_cast<int32_t>(TouchGuideState::DRAGGING) ||
621885b47fbSopenharmony_ci        currentState_ == static_cast<int32_t>(TouchGuideState::TRANSMITTING)) {
622885b47fbSopenharmony_ci        SendUpForAllInjectedEvent(event);
623885b47fbSopenharmony_ci    }
624885b47fbSopenharmony_ci
625885b47fbSopenharmony_ci    CancelPostEvent(EXIT_GESTURE_REC_MSG);
626885b47fbSopenharmony_ci    CancelPostEvent(SEND_TOUCH_GUIDE_END_MSG);
627885b47fbSopenharmony_ci    CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
628885b47fbSopenharmony_ci    CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
629885b47fbSopenharmony_ci    ClearInjectedEventRecorder();
630885b47fbSopenharmony_ci    ClearReceivedEventRecorder();
631885b47fbSopenharmony_ci    pointerEvents_.clear();
632885b47fbSopenharmony_ci    currentState_ = static_cast<int32_t>(TouchGuideState::TOUCH_GUIDING);
633885b47fbSopenharmony_ci    isTouchGuiding_ = false;
634885b47fbSopenharmony_ci    gestureRecognizer_.Clear();
635885b47fbSopenharmony_ci    longPressPointId_ = INIT_POINT_ID;
636885b47fbSopenharmony_ci    longPressOffsetX_ = INIT_MMIPOINT;
637885b47fbSopenharmony_ci    longPressOffsetY_ = INIT_MMIPOINT;
638885b47fbSopenharmony_ci    leftTopX_ = INIT_POINT_DISPLAY;
639885b47fbSopenharmony_ci    leftTopY_ = INIT_POINT_DISPLAY;
640885b47fbSopenharmony_ci    rightBottomX_ = INIT_POINT_DISPLAY;
641885b47fbSopenharmony_ci    rightBottomY_ = INIT_POINT_DISPLAY;
642885b47fbSopenharmony_ci    focusedElementExist_ = false;
643885b47fbSopenharmony_ci    currentPid_ = -1;
644885b47fbSopenharmony_ci    cachedPointerEvents_.clear();
645885b47fbSopenharmony_ci    OnTouchInteractionEnd();
646885b47fbSopenharmony_ci}
647885b47fbSopenharmony_ci
648885b47fbSopenharmony_civoid TouchGuider::Clear()
649885b47fbSopenharmony_ci{
650885b47fbSopenharmony_ci    HILOG_DEBUG();
651885b47fbSopenharmony_ci
652885b47fbSopenharmony_ci    std::shared_ptr<MMI::PointerEvent> event = getLastReceivedEvent();
653885b47fbSopenharmony_ci    if (event) {
654885b47fbSopenharmony_ci        Clear(*event);
655885b47fbSopenharmony_ci    }
656885b47fbSopenharmony_ci}
657885b47fbSopenharmony_ci
658885b47fbSopenharmony_civoid TouchGuider::SendExitEvents()
659885b47fbSopenharmony_ci{
660885b47fbSopenharmony_ci    HILOG_DEBUG();
661885b47fbSopenharmony_ci
662885b47fbSopenharmony_ci    if (!HasEventPending(SEND_TOUCH_GUIDE_END_MSG)) {
663885b47fbSopenharmony_ci        PostAccessibilityEvent(SEND_TOUCH_GUIDE_END_MSG);
664885b47fbSopenharmony_ci    }
665885b47fbSopenharmony_ci}
666885b47fbSopenharmony_ci
667885b47fbSopenharmony_civoid TouchGuider::HandleTouchGuidingStateInnerDown(MMI::PointerEvent &event)
668885b47fbSopenharmony_ci{
669885b47fbSopenharmony_ci    HILOG_DEBUG();
670885b47fbSopenharmony_ci
671885b47fbSopenharmony_ci    OnTouchInteractionStart();
672885b47fbSopenharmony_ci    CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
673885b47fbSopenharmony_ci    CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
674885b47fbSopenharmony_ci    if (isTouchGuiding_) {
675885b47fbSopenharmony_ci        SendExitEvents();
676885b47fbSopenharmony_ci    }
677885b47fbSopenharmony_ci    if (!gestureRecognizer_.IsfirstTap() && !multiFingerGestureRecognizer_.IsMultiFingerGestureStarted()) {
678885b47fbSopenharmony_ci        ForceSendAndRemoveEvent(SEND_TOUCH_GUIDE_END_MSG, event);
679885b47fbSopenharmony_ci        if (!isTouchGuiding_) {
680885b47fbSopenharmony_ci            if (!HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
681885b47fbSopenharmony_ci                PostHoverEnterAndMove(event);
682885b47fbSopenharmony_ci            } else {
683885b47fbSopenharmony_ci                pointerEvents_.push_back(event);
684885b47fbSopenharmony_ci            }
685885b47fbSopenharmony_ci        }
686885b47fbSopenharmony_ci    } else if (gestureRecognizer_.GetIsDoubleTap() && !multiFingerGestureRecognizer_.IsMultiFingerGestureStarted()) {
687885b47fbSopenharmony_ci        doubleTapLongPressDownEvent_ = nullptr;
688885b47fbSopenharmony_ci
689885b47fbSopenharmony_ci        AccessibilityElementInfo focusedElementInfo = {};
690885b47fbSopenharmony_ci        if (!FindFocusedElement(focusedElementInfo)) {
691885b47fbSopenharmony_ci            HILOG_ERROR("FindFocusedElement failed.");
692885b47fbSopenharmony_ci            return;
693885b47fbSopenharmony_ci        }
694885b47fbSopenharmony_ci        HILOG_DEBUG("FindFocusedElement success");
695885b47fbSopenharmony_ci        MMI::PointerEvent::PointerItem pointerIterm = {};
696885b47fbSopenharmony_ci        if (!event.GetPointerItem(event.GetPointerId(), pointerIterm)) {
697885b47fbSopenharmony_ci            HILOG_ERROR("event.GetPointerItem failed");
698885b47fbSopenharmony_ci            return;
699885b47fbSopenharmony_ci        }
700885b47fbSopenharmony_ci        HILOG_DEBUG("GetPointerItem success");
701885b47fbSopenharmony_ci        focusedElementExist_ = true;
702885b47fbSopenharmony_ci
703885b47fbSopenharmony_ci        // set point x,y range and offset
704885b47fbSopenharmony_ci        leftTopX_ = focusedElementInfo.GetRectInScreen().GetLeftTopXScreenPostion();
705885b47fbSopenharmony_ci        leftTopY_ = focusedElementInfo.GetRectInScreen().GetLeftTopYScreenPostion();
706885b47fbSopenharmony_ci        rightBottomX_ = focusedElementInfo.GetRectInScreen().GetRightBottomXScreenPostion();
707885b47fbSopenharmony_ci        rightBottomY_ = focusedElementInfo.GetRectInScreen().GetRightBottomYScreenPostion();
708885b47fbSopenharmony_ci        longPressOffsetX_ = static_cast<float>(DIVIDE_2(leftTopX_ + rightBottomX_) - pointerIterm.GetDisplayX());
709885b47fbSopenharmony_ci        longPressOffsetY_ = static_cast<float>(DIVIDE_2(leftTopY_ + rightBottomY_) - pointerIterm.GetDisplayY());
710885b47fbSopenharmony_ci
711885b47fbSopenharmony_ci        doubleTapLongPressDownEvent_ = std::make_shared<MMI::PointerEvent>(event);
712885b47fbSopenharmony_ci    }
713885b47fbSopenharmony_ci}
714885b47fbSopenharmony_ci
715885b47fbSopenharmony_civoid TouchGuider::SendPointerDownEventToMultimodal(MMI::PointerEvent event, int32_t action)
716885b47fbSopenharmony_ci{
717885b47fbSopenharmony_ci    currentPid_ = event.GetPointerId();
718885b47fbSopenharmony_ci    int32_t xPointDown = 0;
719885b47fbSopenharmony_ci    int32_t yPointDown = 0;
720885b47fbSopenharmony_ci    int64_t actionTime = 0;
721885b47fbSopenharmony_ci
722885b47fbSopenharmony_ci    if (receivedRecorder_.pointerDownX.find(currentPid_) != receivedRecorder_.pointerDownX.end()) {
723885b47fbSopenharmony_ci        xPointDown = receivedRecorder_.pointerDownX.find(currentPid_)->second;
724885b47fbSopenharmony_ci        yPointDown = receivedRecorder_.pointerDownY.find(currentPid_)->second;
725885b47fbSopenharmony_ci        actionTime = receivedRecorder_.pointerActionTime.find(currentPid_)->second;
726885b47fbSopenharmony_ci    }
727885b47fbSopenharmony_ci
728885b47fbSopenharmony_ci    HILOG_DEBUG("first down point info is: xPos: %{public}d, yPos: %{public}d, actionTime: [%{public}" PRId64 "], "
729885b47fbSopenharmony_ci        "currentTime: [%{public}" PRId64 "]", xPointDown, yPointDown, actionTime, event.GetActionTime());
730885b47fbSopenharmony_ci    MMI::PointerEvent::PointerItem pointer = {};
731885b47fbSopenharmony_ci    event.GetPointerItem(currentPid_, pointer);
732885b47fbSopenharmony_ci    pointer.SetDisplayX(xPointDown);
733885b47fbSopenharmony_ci    pointer.SetDisplayY(yPointDown);
734885b47fbSopenharmony_ci    event.RemovePointerItem(currentPid_);
735885b47fbSopenharmony_ci    event.AddPointerItem(pointer);
736885b47fbSopenharmony_ci    event.SetActionTime(actionTime);
737885b47fbSopenharmony_ci    int32_t removePid = currentPid_ == 0 ? REMOVE_POINTER_ID_1 : 0;
738885b47fbSopenharmony_ci    event.RemovePointerItem(removePid);
739885b47fbSopenharmony_ci    SendEventToMultimodal(event, action);
740885b47fbSopenharmony_ci}
741885b47fbSopenharmony_ci
742885b47fbSopenharmony_civoid TouchGuider::HandleTouchGuidingStateInnerMove(MMI::PointerEvent &event)
743885b47fbSopenharmony_ci{
744885b47fbSopenharmony_ci    HILOG_DEBUG();
745885b47fbSopenharmony_ci
746885b47fbSopenharmony_ci    switch (event.GetPointerIds().size()) {
747885b47fbSopenharmony_ci        case POINTER_COUNT_1:
748885b47fbSopenharmony_ci            if (HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
749885b47fbSopenharmony_ci                pointerEvents_.push_back(event);
750885b47fbSopenharmony_ci            } else if (isTouchGuiding_) {
751885b47fbSopenharmony_ci                SendEventToMultimodal(event, HOVER_MOVE);
752885b47fbSopenharmony_ci            } else if (gestureRecognizer_.GetIsDoubleTap() && gestureRecognizer_.GetIsLongpress()) {
753885b47fbSopenharmony_ci                HILOG_DEBUG();
754885b47fbSopenharmony_ci                if (doubleTapLongPressDownEvent_ != nullptr) {
755885b47fbSopenharmony_ci                    HILOG_DEBUG("doubleTapLongPressDownEvent_ is not null");
756885b47fbSopenharmony_ci                    SendEventToMultimodal(*doubleTapLongPressDownEvent_, NO_CHANGE);
757885b47fbSopenharmony_ci                    doubleTapLongPressDownEvent_ = nullptr;
758885b47fbSopenharmony_ci                }
759885b47fbSopenharmony_ci                SendEventToMultimodal(event, NO_CHANGE);
760885b47fbSopenharmony_ci            } else {
761885b47fbSopenharmony_ci                HILOG_DEBUG("other case");
762885b47fbSopenharmony_ci            }
763885b47fbSopenharmony_ci            break;
764885b47fbSopenharmony_ci        case POINTER_COUNT_2:
765885b47fbSopenharmony_ci            CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
766885b47fbSopenharmony_ci            CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
767885b47fbSopenharmony_ci            if (!IsRealMoveState(event)) {
768885b47fbSopenharmony_ci                HILOG_DEBUG("not a move");
769885b47fbSopenharmony_ci                break;
770885b47fbSopenharmony_ci            }
771885b47fbSopenharmony_ci            if (IsDragGestureAccept(event)) {
772885b47fbSopenharmony_ci                currentState_ = static_cast<int32_t>(TouchGuideState::DRAGGING);
773885b47fbSopenharmony_ci                SendPointerDownEventToMultimodal(event, POINTER_DOWN);
774885b47fbSopenharmony_ci                SendEventToMultimodal(event, NO_CHANGE);
775885b47fbSopenharmony_ci            } else {
776885b47fbSopenharmony_ci                for (auto iter = cachedPointerEvents_.begin(); iter != cachedPointerEvents_.end(); ++iter) {
777885b47fbSopenharmony_ci                    EventTransmission::OnPointerEvent(*iter);
778885b47fbSopenharmony_ci                }
779885b47fbSopenharmony_ci                cachedPointerEvents_.clear();
780885b47fbSopenharmony_ci                currentState_ = static_cast<int32_t>(TouchGuideState::PASSING_THROUGH);
781885b47fbSopenharmony_ci            }
782885b47fbSopenharmony_ci            break;
783885b47fbSopenharmony_ci        default:
784885b47fbSopenharmony_ci            if (HasEventPending(SEND_HOVER_ENTER_MOVE_MSG)) {
785885b47fbSopenharmony_ci                CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
786885b47fbSopenharmony_ci                CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
787885b47fbSopenharmony_ci            } else {
788885b47fbSopenharmony_ci                SendExitEvents();
789885b47fbSopenharmony_ci            }
790885b47fbSopenharmony_ci            currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
791885b47fbSopenharmony_ci            break;
792885b47fbSopenharmony_ci    }
793885b47fbSopenharmony_ci}
794885b47fbSopenharmony_ci
795885b47fbSopenharmony_civoid TouchGuider::HandleDraggingStateInnerMove(MMI::PointerEvent &event)
796885b47fbSopenharmony_ci{
797885b47fbSopenharmony_ci    HILOG_DEBUG();
798885b47fbSopenharmony_ci    std::vector<int32_t> pIds = event.GetPointerIds();
799885b47fbSopenharmony_ci    uint32_t pointCount = pIds.size();
800885b47fbSopenharmony_ci    if (pointCount == POINTER_COUNT_1) {
801885b47fbSopenharmony_ci        HILOG_DEBUG("Only two pointers can be received in the dragging state");
802885b47fbSopenharmony_ci    } else if (pointCount == POINTER_COUNT_2) {
803885b47fbSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
804885b47fbSopenharmony_ci        // Get densityPixels from WMS
805885b47fbSopenharmony_ci        AccessibilityDisplayManager &displayMgr = Singleton<AccessibilityDisplayManager>::GetInstance();
806885b47fbSopenharmony_ci        auto display = displayMgr.GetDefaultDisplay();
807885b47fbSopenharmony_ci        float densityPixels = display->GetVirtualPixelRatio();
808885b47fbSopenharmony_ci        int32_t miniZoomPointerDistance = static_cast<int32_t>(MINI_POINTER_DISTANCE_DIP * densityPixels);
809885b47fbSopenharmony_ci#else
810885b47fbSopenharmony_ci        HILOG_DEBUG("not support display manager");
811885b47fbSopenharmony_ci        int32_t miniZoomPointerDistance = static_cast<int32_t>(MINI_POINTER_DISTANCE_DIP * 1);
812885b47fbSopenharmony_ci#endif
813885b47fbSopenharmony_ci        MMI::PointerEvent::PointerItem pointerF = {};
814885b47fbSopenharmony_ci        MMI::PointerEvent::PointerItem pointerS = {};
815885b47fbSopenharmony_ci        event.GetPointerItem(pIds[INDEX_0], pointerF);
816885b47fbSopenharmony_ci        event.GetPointerItem(pIds[INDEX_1], pointerS);
817885b47fbSopenharmony_ci        float xPointF = pointerF.GetDisplayX();
818885b47fbSopenharmony_ci        float xPointS = pointerS.GetDisplayX();
819885b47fbSopenharmony_ci        float yPointF = pointerF.GetDisplayY();
820885b47fbSopenharmony_ci        float yPointS = pointerS.GetDisplayY();
821885b47fbSopenharmony_ci        float offsetX = abs(xPointF - xPointS);
822885b47fbSopenharmony_ci        float offsetY = abs(yPointF - yPointS);
823885b47fbSopenharmony_ci        double duration = hypot(offsetX, offsetY);
824885b47fbSopenharmony_ci        if (duration > miniZoomPointerDistance) {
825885b47fbSopenharmony_ci            // Adjust this event's location.
826885b47fbSopenharmony_ci            MMI::PointerEvent::PointerItem pointer = {};
827885b47fbSopenharmony_ci            event.GetPointerItem(event.GetPointerId(), pointer);
828885b47fbSopenharmony_ci            pointer.SetDisplayX(pointer.GetDisplayX() + DIVIDE_2(offsetX));
829885b47fbSopenharmony_ci            pointer.SetDisplayY(pointer.GetDisplayY() + DIVIDE_2(offsetY));
830885b47fbSopenharmony_ci            event.RemovePointerItem(event.GetPointerId());
831885b47fbSopenharmony_ci            event.AddPointerItem(pointer);
832885b47fbSopenharmony_ci        }
833885b47fbSopenharmony_ci        int32_t removePid = currentPid_ == pIds[0]? pIds[1] : pIds[0];
834885b47fbSopenharmony_ci        HILOG_DEBUG("removePid when move: (%{public}d)", removePid);
835885b47fbSopenharmony_ci        event.RemovePointerItem(removePid);
836885b47fbSopenharmony_ci        SendEventToMultimodal(event, NO_CHANGE);
837885b47fbSopenharmony_ci    } else {
838885b47fbSopenharmony_ci        currentState_ = static_cast<int32_t>(TouchGuideState::TRANSMITTING);
839885b47fbSopenharmony_ci        SendAllUpEvents(event);
840885b47fbSopenharmony_ci    }
841885b47fbSopenharmony_ci}
842885b47fbSopenharmony_ci
843885b47fbSopenharmony_cifloat TouchGuider::GetAngleCos(float offsetX, float offsetY, bool isGetX)
844885b47fbSopenharmony_ci{
845885b47fbSopenharmony_ci    HILOG_DEBUG();
846885b47fbSopenharmony_ci
847885b47fbSopenharmony_ci    float ret = isGetX ? offsetX : offsetY;
848885b47fbSopenharmony_ci    double duration = hypot(offsetX, offsetY);
849885b47fbSopenharmony_ci    if (duration < - EPSINON || duration > EPSINON) {
850885b47fbSopenharmony_ci        ret = ret / duration;
851885b47fbSopenharmony_ci    }
852885b47fbSopenharmony_ci    return ret;
853885b47fbSopenharmony_ci}
854885b47fbSopenharmony_ci
855885b47fbSopenharmony_civoid TouchGuider::GetPointOffset(MMI::PointerEvent &event, std::vector<float> &firstPointOffset,
856885b47fbSopenharmony_ci    std::vector<float> &secondPointOffset) const
857885b47fbSopenharmony_ci{
858885b47fbSopenharmony_ci    HILOG_DEBUG();
859885b47fbSopenharmony_ci
860885b47fbSopenharmony_ci    std::vector<int32_t> pIds = event.GetPointerIds();
861885b47fbSopenharmony_ci    if (pIds.size() != POINTER_COUNT_2) {
862885b47fbSopenharmony_ci        return;
863885b47fbSopenharmony_ci    }
864885b47fbSopenharmony_ci
865885b47fbSopenharmony_ci    MMI::PointerEvent::PointerItem pointerF = {};
866885b47fbSopenharmony_ci    MMI::PointerEvent::PointerItem pointerS = {};
867885b47fbSopenharmony_ci    if (!event.GetPointerItem(pIds[0], pointerF)) {
868885b47fbSopenharmony_ci        HILOG_ERROR("GetPointerItem(%{public}d) failed", pIds[0]);
869885b47fbSopenharmony_ci        return;
870885b47fbSopenharmony_ci    }
871885b47fbSopenharmony_ci
872885b47fbSopenharmony_ci    if (!event.GetPointerItem(pIds[1], pointerS)) {
873885b47fbSopenharmony_ci        HILOG_ERROR("GetPointerItem(%{public}d) failed", pIds[1]);
874885b47fbSopenharmony_ci        return;
875885b47fbSopenharmony_ci    }
876885b47fbSopenharmony_ci
877885b47fbSopenharmony_ci    float xPointF = pointerF.GetDisplayX();
878885b47fbSopenharmony_ci    float xPointS = pointerS.GetDisplayX();
879885b47fbSopenharmony_ci    float yPointF = pointerF.GetDisplayY();
880885b47fbSopenharmony_ci    float yPointS = pointerS.GetDisplayY();
881885b47fbSopenharmony_ci    float xPointDownF = 0;
882885b47fbSopenharmony_ci    float xPointDownS = 0;
883885b47fbSopenharmony_ci    float yPointDownF = 0;
884885b47fbSopenharmony_ci    float yPointDownS = 0;
885885b47fbSopenharmony_ci    if (receivedRecorder_.pointerDownX.find(INDEX_0) != receivedRecorder_.pointerDownX.end()) {
886885b47fbSopenharmony_ci        xPointDownF = receivedRecorder_.pointerDownX.find(INDEX_0)->second;
887885b47fbSopenharmony_ci        yPointDownF = receivedRecorder_.pointerDownY.find(INDEX_0)->second;
888885b47fbSopenharmony_ci    }
889885b47fbSopenharmony_ci    if (receivedRecorder_.pointerDownX.find(INDEX_1) != receivedRecorder_.pointerDownX.end()) {
890885b47fbSopenharmony_ci        xPointDownS = receivedRecorder_.pointerDownX.find(INDEX_1)->second;
891885b47fbSopenharmony_ci        yPointDownS = receivedRecorder_.pointerDownY.find(INDEX_1)->second;
892885b47fbSopenharmony_ci    }
893885b47fbSopenharmony_ci
894885b47fbSopenharmony_ci    firstPointOffset.push_back(xPointF - xPointDownF); // firstOffsetX
895885b47fbSopenharmony_ci    firstPointOffset.push_back(yPointF - yPointDownF); // firstOffsetY
896885b47fbSopenharmony_ci    secondPointOffset.push_back(xPointS - xPointDownS); // secondOffsetX
897885b47fbSopenharmony_ci    secondPointOffset.push_back(yPointS - yPointDownS); // secondOffsetY
898885b47fbSopenharmony_ci}
899885b47fbSopenharmony_ci
900885b47fbSopenharmony_cibool TouchGuider::IsDragGestureAccept(MMI::PointerEvent &event)
901885b47fbSopenharmony_ci{
902885b47fbSopenharmony_ci    HILOG_DEBUG();
903885b47fbSopenharmony_ci
904885b47fbSopenharmony_ci    std::vector<float> firstPointOffset;
905885b47fbSopenharmony_ci    std::vector<float> secondPointOffset;
906885b47fbSopenharmony_ci    GetPointOffset(event, firstPointOffset, secondPointOffset);
907885b47fbSopenharmony_ci    if (firstPointOffset.size() != SCREEN_AXIS_NUM || secondPointOffset.size() != SCREEN_AXIS_NUM) {
908885b47fbSopenharmony_ci        return false;
909885b47fbSopenharmony_ci    }
910885b47fbSopenharmony_ci
911885b47fbSopenharmony_ci    float firstOffsetX = firstPointOffset[0];
912885b47fbSopenharmony_ci    float firstOffsetY = firstPointOffset[1];
913885b47fbSopenharmony_ci    float secondOffsetX = secondPointOffset[0];
914885b47fbSopenharmony_ci    float secondOffsetY = secondPointOffset[1];
915885b47fbSopenharmony_ci    if ((!firstOffsetX && !firstOffsetY) ||
916885b47fbSopenharmony_ci        (!secondOffsetX && !secondOffsetY)) {
917885b47fbSopenharmony_ci        return true;
918885b47fbSopenharmony_ci    }
919885b47fbSopenharmony_ci
920885b47fbSopenharmony_ci    float firstXCos = GetAngleCos(firstOffsetX, firstOffsetY, true);
921885b47fbSopenharmony_ci    float firstYCos = GetAngleCos(firstOffsetX, firstOffsetY, false);
922885b47fbSopenharmony_ci    float secondXCos = GetAngleCos(secondOffsetX, secondOffsetY, true);
923885b47fbSopenharmony_ci    float secondYCos = GetAngleCos(secondOffsetX, secondOffsetY, false);
924885b47fbSopenharmony_ci    if ((firstXCos * secondXCos + firstYCos * secondYCos) < MAX_DRAG_GESTURE_COSINE) {
925885b47fbSopenharmony_ci        return false;
926885b47fbSopenharmony_ci    }
927885b47fbSopenharmony_ci    return true;
928885b47fbSopenharmony_ci}
929885b47fbSopenharmony_ci
930885b47fbSopenharmony_cibool TouchGuider::IsRealMoveState(MMI::PointerEvent &event) const
931885b47fbSopenharmony_ci{
932885b47fbSopenharmony_ci    HILOG_DEBUG("moveThreshold: %{public}f", multiFingerGestureRecognizer_.GetTouchSlop());
933885b47fbSopenharmony_ci
934885b47fbSopenharmony_ci    std::vector<float> firstPointOffset;
935885b47fbSopenharmony_ci    std::vector<float> secondPointOffset;
936885b47fbSopenharmony_ci    GetPointOffset(event, firstPointOffset, secondPointOffset);
937885b47fbSopenharmony_ci    if (firstPointOffset.size() != SCREEN_AXIS_NUM || secondPointOffset.size() != SCREEN_AXIS_NUM) {
938885b47fbSopenharmony_ci        return false;
939885b47fbSopenharmony_ci    }
940885b47fbSopenharmony_ci
941885b47fbSopenharmony_ci    HILOG_DEBUG("offset of fisrt down points and current points: %{public}f, %{public}f,%{public}f, %{public}f",
942885b47fbSopenharmony_ci        firstPointOffset[0], firstPointOffset[1], secondPointOffset[0], secondPointOffset[1]);
943885b47fbSopenharmony_ci    if (hypot(firstPointOffset[0], firstPointOffset[1]) >= multiFingerGestureRecognizer_.GetTouchSlop() &&
944885b47fbSopenharmony_ci        hypot(secondPointOffset[0], secondPointOffset[1]) >= multiFingerGestureRecognizer_.GetTouchSlop()) {
945885b47fbSopenharmony_ci        return true;
946885b47fbSopenharmony_ci    }
947885b47fbSopenharmony_ci    return false;
948885b47fbSopenharmony_ci}
949885b47fbSopenharmony_ci
950885b47fbSopenharmony_civoid TouchGuider::RecordInjectedEvent(MMI::PointerEvent &event)
951885b47fbSopenharmony_ci{
952885b47fbSopenharmony_ci    HILOG_DEBUG();
953885b47fbSopenharmony_ci
954885b47fbSopenharmony_ci    int32_t pointerId = event.GetPointerId();
955885b47fbSopenharmony_ci    switch (event.GetPointerAction()) {
956885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_DOWN:
957885b47fbSopenharmony_ci            injectedRecorder_.downPointerNum++;
958885b47fbSopenharmony_ci            injectedRecorder_.downPointers.insert(pointerId);
959885b47fbSopenharmony_ci            injectedRecorder_.lastDownTime = event.GetActionTime() / US_TO_MS;
960885b47fbSopenharmony_ci            break;
961885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_UP:
962885b47fbSopenharmony_ci            injectedRecorder_.downPointers.erase(pointerId);
963885b47fbSopenharmony_ci            if (injectedRecorder_.downPointerNum > 0) {
964885b47fbSopenharmony_ci                injectedRecorder_.downPointerNum--;
965885b47fbSopenharmony_ci            }
966885b47fbSopenharmony_ci            if (injectedRecorder_.downPointers.empty()) {
967885b47fbSopenharmony_ci                injectedRecorder_.lastDownTime = 0;
968885b47fbSopenharmony_ci            }
969885b47fbSopenharmony_ci            break;
970885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_MOVE:
971885b47fbSopenharmony_ci            injectedRecorder_.lastHoverEvent = std::make_shared<MMI::PointerEvent>(event);
972885b47fbSopenharmony_ci            break;
973885b47fbSopenharmony_ci        default:
974885b47fbSopenharmony_ci            break;
975885b47fbSopenharmony_ci    }
976885b47fbSopenharmony_ci}
977885b47fbSopenharmony_ci
978885b47fbSopenharmony_civoid TouchGuider::RecordReceivedEvent(MMI::PointerEvent &event)
979885b47fbSopenharmony_ci{
980885b47fbSopenharmony_ci    HILOG_DEBUG();
981885b47fbSopenharmony_ci
982885b47fbSopenharmony_ci    int32_t pointId = event.GetPointerId();
983885b47fbSopenharmony_ci    MMI::PointerEvent::PointerItem pointer;
984885b47fbSopenharmony_ci    if (!event.GetPointerItem(pointId, pointer)) {
985885b47fbSopenharmony_ci        HILOG_ERROR("GetPointerItem(%{public}d) failed", pointId);
986885b47fbSopenharmony_ci    }
987885b47fbSopenharmony_ci    receivedRecorder_.lastEvent = std::make_shared<MMI::PointerEvent>(event);
988885b47fbSopenharmony_ci    switch (event.GetPointerAction()) {
989885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_DOWN:
990885b47fbSopenharmony_ci            receivedRecorder_.pointerDownX[pointId] = pointer.GetDisplayX();
991885b47fbSopenharmony_ci            receivedRecorder_.pointerDownY[pointId] = pointer.GetDisplayY();
992885b47fbSopenharmony_ci            receivedRecorder_.pointerActionTime[pointId] = event.GetActionTime();
993885b47fbSopenharmony_ci            break;
994885b47fbSopenharmony_ci        case MMI::PointerEvent::POINTER_ACTION_UP:
995885b47fbSopenharmony_ci            receivedRecorder_.pointerDownX.erase(pointId);
996885b47fbSopenharmony_ci            receivedRecorder_.pointerDownY.erase(pointId);
997885b47fbSopenharmony_ci            receivedRecorder_.pointerActionTime.erase(pointId);
998885b47fbSopenharmony_ci            break;
999885b47fbSopenharmony_ci        default:
1000885b47fbSopenharmony_ci            break;
1001885b47fbSopenharmony_ci    }
1002885b47fbSopenharmony_ci}
1003885b47fbSopenharmony_ci
1004885b47fbSopenharmony_civoid TouchGuider::ClearReceivedEventRecorder()
1005885b47fbSopenharmony_ci{
1006885b47fbSopenharmony_ci    HILOG_DEBUG();
1007885b47fbSopenharmony_ci
1008885b47fbSopenharmony_ci    receivedRecorder_.pointerDownX.clear();
1009885b47fbSopenharmony_ci    receivedRecorder_.pointerDownY.clear();
1010885b47fbSopenharmony_ci    receivedRecorder_.pointerActionTime.clear();
1011885b47fbSopenharmony_ci    receivedRecorder_.lastEvent = nullptr;
1012885b47fbSopenharmony_ci}
1013885b47fbSopenharmony_ci
1014885b47fbSopenharmony_civoid TouchGuider::ClearInjectedEventRecorder()
1015885b47fbSopenharmony_ci{
1016885b47fbSopenharmony_ci    HILOG_DEBUG();
1017885b47fbSopenharmony_ci
1018885b47fbSopenharmony_ci    injectedRecorder_.downPointerNum = 0;
1019885b47fbSopenharmony_ci    injectedRecorder_.downPointers.clear();
1020885b47fbSopenharmony_ci    injectedRecorder_.lastHoverEvent = nullptr;
1021885b47fbSopenharmony_ci}
1022885b47fbSopenharmony_ci
1023885b47fbSopenharmony_civoid TouchGuider::SendAllDownEvents(MMI::PointerEvent &event)
1024885b47fbSopenharmony_ci{
1025885b47fbSopenharmony_ci    HILOG_DEBUG();
1026885b47fbSopenharmony_ci
1027885b47fbSopenharmony_ci    std::vector<int32_t> pIds = event.GetPointerIds();
1028885b47fbSopenharmony_ci    for (auto& pId : pIds) {
1029885b47fbSopenharmony_ci        if (injectedRecorder_.downPointers.find(pId) == injectedRecorder_.downPointers.end()) {
1030885b47fbSopenharmony_ci            event.SetPointerId(pId);
1031885b47fbSopenharmony_ci            SendEventToMultimodal(event, POINTER_DOWN);
1032885b47fbSopenharmony_ci        }
1033885b47fbSopenharmony_ci    }
1034885b47fbSopenharmony_ci}
1035885b47fbSopenharmony_ci
1036885b47fbSopenharmony_civoid TouchGuider::SendAllUpEvents(MMI::PointerEvent &event)
1037885b47fbSopenharmony_ci{
1038885b47fbSopenharmony_ci    HILOG_DEBUG();
1039885b47fbSopenharmony_ci
1040885b47fbSopenharmony_ci    std::vector<int32_t> pIds = event.GetPointerIds();
1041885b47fbSopenharmony_ci    for (auto& pId : pIds) {
1042885b47fbSopenharmony_ci        event.SetPointerId(pId);
1043885b47fbSopenharmony_ci        SendEventToMultimodal(event, POINTER_UP);
1044885b47fbSopenharmony_ci    }
1045885b47fbSopenharmony_ci}
1046885b47fbSopenharmony_ci
1047885b47fbSopenharmony_civoid TouchGuider::SendUpForAllInjectedEvent(MMI::PointerEvent &event)
1048885b47fbSopenharmony_ci{
1049885b47fbSopenharmony_ci    HILOG_DEBUG();
1050885b47fbSopenharmony_ci
1051885b47fbSopenharmony_ci    std::vector<int32_t> pIds = event.GetPointerIds();
1052885b47fbSopenharmony_ci    for (const auto& pId : pIds) {
1053885b47fbSopenharmony_ci        if (injectedRecorder_.downPointers.find(pId) == injectedRecorder_.downPointers.end()) {
1054885b47fbSopenharmony_ci            continue;
1055885b47fbSopenharmony_ci        }
1056885b47fbSopenharmony_ci        SendEventToMultimodal(event, POINTER_UP);
1057885b47fbSopenharmony_ci    }
1058885b47fbSopenharmony_ci}
1059885b47fbSopenharmony_ci
1060885b47fbSopenharmony_civoid TouchGuider::PostGestureRecognizeExit()
1061885b47fbSopenharmony_ci{
1062885b47fbSopenharmony_ci    HILOG_DEBUG();
1063885b47fbSopenharmony_ci
1064885b47fbSopenharmony_ci    handler_->SendEvent(EXIT_GESTURE_REC_MSG, 0, EXIT_GESTURE_REC_TIMEOUT);
1065885b47fbSopenharmony_ci}
1066885b47fbSopenharmony_ci
1067885b47fbSopenharmony_civoid TouchGuider::PostHoverEnterAndMove(MMI::PointerEvent &event)
1068885b47fbSopenharmony_ci{
1069885b47fbSopenharmony_ci    HILOG_DEBUG();
1070885b47fbSopenharmony_ci
1071885b47fbSopenharmony_ci    CancelPostEventIfNeed(SEND_HOVER_ENTER_MOVE_MSG);
1072885b47fbSopenharmony_ci    pointerEvents_.push_back(event);
1073885b47fbSopenharmony_ci    handler_->SendEvent(SEND_HOVER_ENTER_MOVE_MSG, 0, DOUBLE_TAP_TIMEOUT / US_TO_MS);
1074885b47fbSopenharmony_ci}
1075885b47fbSopenharmony_ci
1076885b47fbSopenharmony_civoid TouchGuider::PostHoverExit()
1077885b47fbSopenharmony_ci{
1078885b47fbSopenharmony_ci    HILOG_DEBUG();
1079885b47fbSopenharmony_ci
1080885b47fbSopenharmony_ci    CancelPostEventIfNeed(SEND_HOVER_EXIT_MSG);
1081885b47fbSopenharmony_ci    handler_->SendEvent(SEND_HOVER_EXIT_MSG, 0, DOUBLE_TAP_TIMEOUT / US_TO_MS);
1082885b47fbSopenharmony_ci}
1083885b47fbSopenharmony_ci
1084885b47fbSopenharmony_civoid TouchGuider::PostAccessibilityEvent(uint32_t innerEventID)
1085885b47fbSopenharmony_ci{
1086885b47fbSopenharmony_ci    HILOG_DEBUG();
1087885b47fbSopenharmony_ci
1088885b47fbSopenharmony_ci    handler_->SendEvent(innerEventID, 0, EXIT_GESTURE_REC_TIMEOUT);
1089885b47fbSopenharmony_ci}
1090885b47fbSopenharmony_ci
1091885b47fbSopenharmony_civoid TouchGuider::CancelPostEvent(uint32_t innerEventID)
1092885b47fbSopenharmony_ci{
1093885b47fbSopenharmony_ci    HILOG_DEBUG();
1094885b47fbSopenharmony_ci
1095885b47fbSopenharmony_ci    handler_->RemoveEvent(innerEventID);
1096885b47fbSopenharmony_ci}
1097885b47fbSopenharmony_ci
1098885b47fbSopenharmony_civoid TouchGuider::CancelPostEventIfNeed(uint32_t innerEventID)
1099885b47fbSopenharmony_ci{
1100885b47fbSopenharmony_ci    HILOG_DEBUG();
1101885b47fbSopenharmony_ci
1102885b47fbSopenharmony_ci    if (HasEventPending(innerEventID)) {
1103885b47fbSopenharmony_ci        handler_->RemoveEvent(innerEventID);
1104885b47fbSopenharmony_ci        if (innerEventID == SEND_HOVER_ENTER_MOVE_MSG) {
1105885b47fbSopenharmony_ci            pointerEvents_.clear();
1106885b47fbSopenharmony_ci        }
1107885b47fbSopenharmony_ci    }
1108885b47fbSopenharmony_ci}
1109885b47fbSopenharmony_ci
1110885b47fbSopenharmony_cibool TouchGuider::HasEventPending(uint32_t innerEventID)
1111885b47fbSopenharmony_ci{
1112885b47fbSopenharmony_ci    HILOG_DEBUG();
1113885b47fbSopenharmony_ci
1114885b47fbSopenharmony_ci    return handler_->HasInnerEvent(innerEventID);
1115885b47fbSopenharmony_ci}
1116885b47fbSopenharmony_ci
1117885b47fbSopenharmony_civoid TouchGuider::ForceSendAndRemoveEvent(uint32_t innerEventID, MMI::PointerEvent &event)
1118885b47fbSopenharmony_ci{
1119885b47fbSopenharmony_ci    HILOG_DEBUG();
1120885b47fbSopenharmony_ci
1121885b47fbSopenharmony_ci    if (!HasEventPending(innerEventID)) {
1122885b47fbSopenharmony_ci        HILOG_DEBUG("No pending event.");
1123885b47fbSopenharmony_ci        return;
1124885b47fbSopenharmony_ci    }
1125885b47fbSopenharmony_ci
1126885b47fbSopenharmony_ci    switch (innerEventID) {
1127885b47fbSopenharmony_ci        case SEND_HOVER_ENTER_MOVE_MSG:
1128885b47fbSopenharmony_ci            SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_BEGIN);
1129885b47fbSopenharmony_ci            if (pointerEvents_.empty()) {
1130885b47fbSopenharmony_ci                break;
1131885b47fbSopenharmony_ci            }
1132885b47fbSopenharmony_ci            for (auto iter = pointerEvents_.begin(); iter != pointerEvents_.end(); ++iter) {
1133885b47fbSopenharmony_ci                if (iter->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN) {
1134885b47fbSopenharmony_ci                    SendEventToMultimodal(*iter, HOVER_ENTER);
1135885b47fbSopenharmony_ci                } else {
1136885b47fbSopenharmony_ci                    SendEventToMultimodal(*iter, HOVER_MOVE);
1137885b47fbSopenharmony_ci                }
1138885b47fbSopenharmony_ci            }
1139885b47fbSopenharmony_ci            pointerEvents_.clear();
1140885b47fbSopenharmony_ci            break;
1141885b47fbSopenharmony_ci        case SEND_TOUCH_GUIDE_END_MSG:
1142885b47fbSopenharmony_ci            SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_END);
1143885b47fbSopenharmony_ci            break;
1144885b47fbSopenharmony_ci        default:
1145885b47fbSopenharmony_ci            break;
1146885b47fbSopenharmony_ci    }
1147885b47fbSopenharmony_ci    CancelPostEvent(innerEventID);
1148885b47fbSopenharmony_ci}
1149885b47fbSopenharmony_ci
1150885b47fbSopenharmony_cibool TouchGuider::IgnoreRepeatExecuteAction()
1151885b47fbSopenharmony_ci{
1152885b47fbSopenharmony_ci    HILOG_DEBUG();
1153885b47fbSopenharmony_ci    int64_t time = Utils::GetSystemTime();
1154885b47fbSopenharmony_ci    if (time - lastDoubleTapTime < IGNORE_REPEAT_EXECUTE_INTERVAL) {
1155885b47fbSopenharmony_ci        HILOG_DEBUG("time interval < 300ms");
1156885b47fbSopenharmony_ci        lastDoubleTapTime = time;
1157885b47fbSopenharmony_ci        return true;
1158885b47fbSopenharmony_ci    }
1159885b47fbSopenharmony_ci
1160885b47fbSopenharmony_ci    lastDoubleTapTime = time;
1161885b47fbSopenharmony_ci    return false;
1162885b47fbSopenharmony_ci}
1163885b47fbSopenharmony_ci
1164885b47fbSopenharmony_cibool TouchGuider::ExecuteActionOnAccessibilityFocused(const ActionType &action)
1165885b47fbSopenharmony_ci{
1166885b47fbSopenharmony_ci    HILOG_DEBUG();
1167885b47fbSopenharmony_ci    if (IgnoreRepeatExecuteAction()) {
1168885b47fbSopenharmony_ci        return true;
1169885b47fbSopenharmony_ci    }
1170885b47fbSopenharmony_ci    return Singleton<AccessibleAbilityManagerService>::GetInstance().ExecuteActionOnAccessibilityFocused(action);
1171885b47fbSopenharmony_ci}
1172885b47fbSopenharmony_ci
1173885b47fbSopenharmony_cibool TouchGuider::FindFocusedElement(AccessibilityElementInfo &elementInfo)
1174885b47fbSopenharmony_ci{
1175885b47fbSopenharmony_ci    HILOG_DEBUG();
1176885b47fbSopenharmony_ci    return Singleton<AccessibleAbilityManagerService>::GetInstance().FindFocusedElement(elementInfo);
1177885b47fbSopenharmony_ci}
1178885b47fbSopenharmony_ci
1179885b47fbSopenharmony_civoid TGEventHandler::HoverEnterAndMoveRunner()
1180885b47fbSopenharmony_ci{
1181885b47fbSopenharmony_ci    HILOG_DEBUG();
1182885b47fbSopenharmony_ci
1183885b47fbSopenharmony_ci    std::list<MMI::PointerEvent> motionEvent = tgServer_.getHoverEnterAndMoveEvent();
1184885b47fbSopenharmony_ci    tgServer_.SendAccessibilityEventToAA(EventType::TYPE_TOUCH_GUIDE_BEGIN);
1185885b47fbSopenharmony_ci    if (!motionEvent.empty()) {
1186885b47fbSopenharmony_ci        for (auto iter = motionEvent.begin(); iter != motionEvent.end(); ++iter) {
1187885b47fbSopenharmony_ci            if (iter->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN) {
1188885b47fbSopenharmony_ci                tgServer_.SendEventToMultimodal(*iter, HOVER_ENTER);
1189885b47fbSopenharmony_ci            } else {
1190885b47fbSopenharmony_ci                tgServer_.SendEventToMultimodal(*iter, HOVER_MOVE);
1191885b47fbSopenharmony_ci            }
1192885b47fbSopenharmony_ci        }
1193885b47fbSopenharmony_ci    }
1194885b47fbSopenharmony_ci    tgServer_.ClearHoverEnterAndMoveEvent();
1195885b47fbSopenharmony_ci}
1196885b47fbSopenharmony_ci
1197885b47fbSopenharmony_civoid TGEventHandler::HoverExitRunner()
1198885b47fbSopenharmony_ci{
1199885b47fbSopenharmony_ci    HILOG_DEBUG();
1200885b47fbSopenharmony_ci
1201885b47fbSopenharmony_ci    std::shared_ptr<MMI::PointerEvent> pEvent = tgServer_.getLastReceivedEvent();
1202885b47fbSopenharmony_ci    tgServer_.SendEventToMultimodal(*pEvent, HOVER_EXIT);
1203885b47fbSopenharmony_ci    if (!HasInnerEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG)) {
1204885b47fbSopenharmony_ci        RemoveEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG);
1205885b47fbSopenharmony_ci        SendEvent(TouchGuider::SEND_TOUCH_GUIDE_END_MSG, 0, EXIT_GESTURE_REC_TIMEOUT);
1206885b47fbSopenharmony_ci    }
1207885b47fbSopenharmony_ci}
1208885b47fbSopenharmony_ci} // namespace Accessibility
1209885b47fbSopenharmony_ci} // namespace OHOS