1/*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef OHOS_ROSEN_DRAG_CONTROLLER_H
17#define OHOS_ROSEN_DRAG_CONTROLLER_H
18
19#include <refbase.h>
20
21#include "display_group_info.h"
22#include "display_info.h"
23#include "event_handler.h"
24#include "event_runner.h"
25#include "input_manager.h"
26#include "pointer_event.h"
27#include "vsync_station.h"
28#include "window_root.h"
29#include "wm_common.h"
30
31namespace OHOS {
32namespace Rosen {
33using EventRunner = OHOS::AppExecFwk::EventRunner;
34using EventHandler = OHOS::AppExecFwk::EventHandler;
35/*
36 * DragController is the class which is used to handle drag cross window
37 */
38class DragController : public RefBase {
39public:
40    explicit DragController(sptr<WindowRoot>& root) : windowRoot_(root) {}
41    ~DragController() = default;
42    void StartDrag(uint32_t windowId);
43    void UpdateDragInfo(uint32_t windowId);
44    void FinishDrag(uint32_t windowId);
45
46private:
47    sptr<WindowNode> GetHitWindow(DisplayId id, const PointInfo point);
48    bool GetHitPoint(uint32_t windowId, PointInfo& point);
49    sptr<WindowRoot> windowRoot_;
50    uint64_t hitWindowId_ = 0;
51};
52
53class DragInputEventListener : public MMI::IInputEventConsumer {
54public:
55    DragInputEventListener() = default;
56    void OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const override;
57    void OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const override;
58    void OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const override;
59};
60
61/*
62 * MoveDragController is the class which is used to handle move or drag floating window
63 */
64class MoveDragController : public RefBase {
65public:
66    MoveDragController() : windowProperty_(new WindowProperty()), moveDragProperty_(new MoveDragProperty())
67    {
68        vsyncCallback_->onCallback =
69            [this](int64_t timeStamp, int64_t _) { this->OnReceiveVsync(timeStamp); };
70    }
71    ~MoveDragController() = default;
72
73    bool Init();
74    void Stop();
75    void HandleReadyToMoveOrDrag(uint32_t windowId, sptr<WindowProperty>& windowProperty,
76        sptr<MoveDragProperty>& moveDragProperty);
77    void HandleEndUpMovingOrDragging(uint32_t windowId);
78    void HandleWindowRemovedOrDestroyed(uint32_t windowId);
79    void ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent);
80    uint32_t GetActiveWindowId() const;
81    void HandleDisplayLimitRectChange(const std::map<DisplayId, Rect>& limitRectMap);
82    void SetInputEventConsumer();
83    void SetWindowRoot(const sptr<WindowRoot>& windowRoot);
84
85private:
86    void SetDragProperty(const sptr<MoveDragProperty>& moveDragProperty);
87    void SetWindowProperty(const sptr<WindowProperty>& windowProperty);
88    void SetActiveWindowId(uint32_t);
89    const sptr<MoveDragProperty>& GetMoveDragProperty() const;
90    const sptr<WindowProperty>& GetWindowProperty() const;
91    Rect GetHotZoneRect();
92    void ConvertPointerPosToDisplayGroupPos(DisplayId displayId, int32_t& posX, int32_t& posY);
93
94    void HandlePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent);
95    void HandleDragEvent(DisplayId displayId, int32_t posX, int32_t posY, int32_t pointId, int32_t sourceType);
96    void HandleMoveEvent(DisplayId displayId, int32_t posX, int32_t posY, int32_t pointId, int32_t sourceType);
97    void OnReceiveVsync(int64_t timeStamp);
98    void ResetMoveOrDragState();
99    bool CheckWindowRect(DisplayId displayId, float vpr, const Rect& rect);
100    void CalculateNewWindowRect(Rect& newRect, DisplayId displayId, int32_t posX, int32_t posY);
101    std::shared_ptr<VsyncStation> GetVsyncStationByWindowId(uint32_t windowId);
102
103    sptr<WindowRoot> windowRoot_;
104    sptr<WindowProperty> windowProperty_;
105    sptr<MoveDragProperty> moveDragProperty_;
106    uint32_t activeWindowId_ = INVALID_WINDOW_ID;
107    std::shared_ptr<MMI::PointerEvent> moveEvent_ = nullptr;
108    std::shared_ptr<MMI::IInputEventConsumer> inputListener_ = nullptr;
109    std::shared_ptr<VsyncCallback> vsyncCallback_ = std::make_shared<VsyncCallback>(VsyncCallback());
110    std::map<DisplayId, Rect> limitRectMap_;
111    std::mutex mtx_;
112    std::map<NodeId, std::shared_ptr<VsyncStation>> vsyncStationMap_;
113
114    // event handler for input event
115    std::shared_ptr<EventHandler> inputEventHandler_;
116    const std::string INNER_WM_INPUT_THREAD_NAME = "InnerInputManager";
117};
118}
119}
120#endif // OHOS_ROSEN_DRAG_CONTROLLER_H
121
122