1c29fa5a6Sopenharmony_ci/*
2c29fa5a6Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3c29fa5a6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4c29fa5a6Sopenharmony_ci * you may not use this file except in compliance with the License.
5c29fa5a6Sopenharmony_ci * You may obtain a copy of the License at
6c29fa5a6Sopenharmony_ci *
7c29fa5a6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8c29fa5a6Sopenharmony_ci *
9c29fa5a6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10c29fa5a6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11c29fa5a6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12c29fa5a6Sopenharmony_ci * See the License for the specific language governing permissions and
13c29fa5a6Sopenharmony_ci * limitations under the License.
14c29fa5a6Sopenharmony_ci */
15c29fa5a6Sopenharmony_ci
16c29fa5a6Sopenharmony_ci#ifndef KEY_GESTURE_MANAGER_H
17c29fa5a6Sopenharmony_ci#define KEY_GESTURE_MANAGER_H
18c29fa5a6Sopenharmony_ci
19c29fa5a6Sopenharmony_ci#include <functional>
20c29fa5a6Sopenharmony_ci#include <set>
21c29fa5a6Sopenharmony_ci#include <sstream>
22c29fa5a6Sopenharmony_ci
23c29fa5a6Sopenharmony_ci#include <nocopyable.h>
24c29fa5a6Sopenharmony_ci
25c29fa5a6Sopenharmony_ci#include "key_event.h"
26c29fa5a6Sopenharmony_ci#include "key_option.h"
27c29fa5a6Sopenharmony_ci
28c29fa5a6Sopenharmony_cinamespace OHOS {
29c29fa5a6Sopenharmony_cinamespace MMI {
30c29fa5a6Sopenharmony_ci
31c29fa5a6Sopenharmony_ciclass KeyGestureManager final {
32c29fa5a6Sopenharmony_ciprivate:
33c29fa5a6Sopenharmony_ci    class Handler final {
34c29fa5a6Sopenharmony_ci    public:
35c29fa5a6Sopenharmony_ci        Handler(int32_t id, int32_t pid, int32_t longPressTime,
36c29fa5a6Sopenharmony_ci                std::function<void(std::shared_ptr<KeyEvent>)> callback)
37c29fa5a6Sopenharmony_ci            : id_(id), pid_(pid), longPressTime_(longPressTime), callback_(callback) {}
38c29fa5a6Sopenharmony_ci        ~Handler();
39c29fa5a6Sopenharmony_ci
40c29fa5a6Sopenharmony_ci        int32_t GetId() const
41c29fa5a6Sopenharmony_ci        {
42c29fa5a6Sopenharmony_ci            return id_;
43c29fa5a6Sopenharmony_ci        }
44c29fa5a6Sopenharmony_ci
45c29fa5a6Sopenharmony_ci        int32_t GetPid() const
46c29fa5a6Sopenharmony_ci        {
47c29fa5a6Sopenharmony_ci            return pid_;
48c29fa5a6Sopenharmony_ci        }
49c29fa5a6Sopenharmony_ci
50c29fa5a6Sopenharmony_ci        int32_t GetLongPressTime() const
51c29fa5a6Sopenharmony_ci        {
52c29fa5a6Sopenharmony_ci            return longPressTime_;
53c29fa5a6Sopenharmony_ci        }
54c29fa5a6Sopenharmony_ci
55c29fa5a6Sopenharmony_ci        void SetLongPressTime(int32_t longPressTime)
56c29fa5a6Sopenharmony_ci        {
57c29fa5a6Sopenharmony_ci            longPressTime_ = longPressTime;
58c29fa5a6Sopenharmony_ci        }
59c29fa5a6Sopenharmony_ci
60c29fa5a6Sopenharmony_ci        void ResetTimer();
61c29fa5a6Sopenharmony_ci        void Trigger(std::shared_ptr<KeyEvent> keyEvent);
62c29fa5a6Sopenharmony_ci        void Run(std::shared_ptr<KeyEvent> keyEvent) const;
63c29fa5a6Sopenharmony_ci        void RunPending();
64c29fa5a6Sopenharmony_ci
65c29fa5a6Sopenharmony_ci    private:
66c29fa5a6Sopenharmony_ci        int32_t id_ { -1 };
67c29fa5a6Sopenharmony_ci        int32_t pid_ { -1 };
68c29fa5a6Sopenharmony_ci        int32_t longPressTime_ { -1 };
69c29fa5a6Sopenharmony_ci        int32_t timerId_ { -1 };
70c29fa5a6Sopenharmony_ci        std::shared_ptr<KeyEvent> keyEvent_;
71c29fa5a6Sopenharmony_ci        std::function<void(std::shared_ptr<KeyEvent>)> callback_;
72c29fa5a6Sopenharmony_ci    };
73c29fa5a6Sopenharmony_ci
74c29fa5a6Sopenharmony_ci    class KeyGesture {
75c29fa5a6Sopenharmony_ci    public:
76c29fa5a6Sopenharmony_ci        KeyGesture() = default;
77c29fa5a6Sopenharmony_ci        virtual ~KeyGesture() = default;
78c29fa5a6Sopenharmony_ci
79c29fa5a6Sopenharmony_ci        virtual bool IsWorking();
80c29fa5a6Sopenharmony_ci        virtual bool ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const = 0;
81c29fa5a6Sopenharmony_ci        virtual bool Intercept(std::shared_ptr<KeyEvent> KeyEvent) = 0;
82c29fa5a6Sopenharmony_ci        virtual void Dump(std::ostringstream &output) const = 0;
83c29fa5a6Sopenharmony_ci        virtual int32_t AddHandler(int32_t pid, int32_t longPressTime,
84c29fa5a6Sopenharmony_ci            std::function<void(std::shared_ptr<KeyEvent>)> callback);
85c29fa5a6Sopenharmony_ci        bool RemoveHandler(int32_t id);
86c29fa5a6Sopenharmony_ci        void Reset();
87c29fa5a6Sopenharmony_ci        bool IsActive() const;
88c29fa5a6Sopenharmony_ci        void MarkActive(bool active);
89c29fa5a6Sopenharmony_ci
90c29fa5a6Sopenharmony_ci    protected:
91c29fa5a6Sopenharmony_ci        void ResetTimers();
92c29fa5a6Sopenharmony_ci        std::set<int32_t> GetForegroundPids() const;
93c29fa5a6Sopenharmony_ci        bool HaveForegroundHandler(const std::set<int32_t> &foregroundApps) const;
94c29fa5a6Sopenharmony_ci        void TriggerHandlers(std::shared_ptr<KeyEvent> keyEvent);
95c29fa5a6Sopenharmony_ci        void RunHandler(int32_t handlerId, std::shared_ptr<KeyEvent> keyEvent);
96c29fa5a6Sopenharmony_ci        void NotifyHandlers(std::shared_ptr<KeyEvent> keyEvent);
97c29fa5a6Sopenharmony_ci        void ShowHandlers(const std::string &prefix, const std::set<int32_t> &foregroundApps) const;
98c29fa5a6Sopenharmony_ci
99c29fa5a6Sopenharmony_ci        bool active_ { false };
100c29fa5a6Sopenharmony_ci        std::set<int32_t> keys_;
101c29fa5a6Sopenharmony_ci        std::vector<Handler> handlers_;
102c29fa5a6Sopenharmony_ci    };
103c29fa5a6Sopenharmony_ci
104c29fa5a6Sopenharmony_ciprivate:
105c29fa5a6Sopenharmony_ci    class LongPressSingleKey : public KeyGesture {
106c29fa5a6Sopenharmony_ci    public:
107c29fa5a6Sopenharmony_ci        LongPressSingleKey(int32_t keyCode) : keyCode_(keyCode) {}
108c29fa5a6Sopenharmony_ci        ~LongPressSingleKey() = default;
109c29fa5a6Sopenharmony_ci
110c29fa5a6Sopenharmony_ci        bool ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const override;
111c29fa5a6Sopenharmony_ci        bool Intercept(std::shared_ptr<KeyEvent> KeyEvent) override;
112c29fa5a6Sopenharmony_ci        void Dump(std::ostringstream &output) const override;
113c29fa5a6Sopenharmony_ci
114c29fa5a6Sopenharmony_ci    private:
115c29fa5a6Sopenharmony_ci        void RunPendingHandlers();
116c29fa5a6Sopenharmony_ci
117c29fa5a6Sopenharmony_ci        int32_t keyCode_ { -1 };
118c29fa5a6Sopenharmony_ci        int64_t firstDownTime_ {};
119c29fa5a6Sopenharmony_ci    };
120c29fa5a6Sopenharmony_ci
121c29fa5a6Sopenharmony_ci    class LongPressCombinationKey : public KeyGesture {
122c29fa5a6Sopenharmony_ci    public:
123c29fa5a6Sopenharmony_ci        LongPressCombinationKey(const std::set<int32_t> &keys) : keys_(keys) {}
124c29fa5a6Sopenharmony_ci        ~LongPressCombinationKey() = default;
125c29fa5a6Sopenharmony_ci
126c29fa5a6Sopenharmony_ci        bool ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const override;
127c29fa5a6Sopenharmony_ci        bool Intercept(std::shared_ptr<KeyEvent> keyEvent) override;
128c29fa5a6Sopenharmony_ci        void Dump(std::ostringstream &output) const override;
129c29fa5a6Sopenharmony_ci
130c29fa5a6Sopenharmony_ci    protected:
131c29fa5a6Sopenharmony_ci        virtual void OnTriggerAll(std::shared_ptr<KeyEvent> keyEvent) {}
132c29fa5a6Sopenharmony_ci
133c29fa5a6Sopenharmony_ci    private:
134c29fa5a6Sopenharmony_ci        bool RecognizeGesture(std::shared_ptr<KeyEvent> keyEvent);
135c29fa5a6Sopenharmony_ci        void TriggerAll(std::shared_ptr<KeyEvent> keyEvent);
136c29fa5a6Sopenharmony_ci
137c29fa5a6Sopenharmony_ci        int64_t firstDownTime_ {};
138c29fa5a6Sopenharmony_ci        std::set<int32_t> keys_;
139c29fa5a6Sopenharmony_ci    };
140c29fa5a6Sopenharmony_ci
141c29fa5a6Sopenharmony_ci    class PullUpAccessibility final : public LongPressCombinationKey {
142c29fa5a6Sopenharmony_ci    public:
143c29fa5a6Sopenharmony_ci        PullUpAccessibility();
144c29fa5a6Sopenharmony_ci        ~PullUpAccessibility() = default;
145c29fa5a6Sopenharmony_ci
146c29fa5a6Sopenharmony_ci        bool IsWorking() override;
147c29fa5a6Sopenharmony_ci        int32_t AddHandler(int32_t pid, int32_t longPressTime,
148c29fa5a6Sopenharmony_ci            std::function<void(std::shared_ptr<KeyEvent>)> callback) override;
149c29fa5a6Sopenharmony_ci        void OnTriggerAll(std::shared_ptr<KeyEvent> keyEvent) override;
150c29fa5a6Sopenharmony_ci    };
151c29fa5a6Sopenharmony_ci
152c29fa5a6Sopenharmony_cipublic:
153c29fa5a6Sopenharmony_ci    KeyGestureManager();
154c29fa5a6Sopenharmony_ci    ~KeyGestureManager() = default;
155c29fa5a6Sopenharmony_ci    DISALLOW_COPY_AND_MOVE(KeyGestureManager);
156c29fa5a6Sopenharmony_ci
157c29fa5a6Sopenharmony_ci    bool ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const;
158c29fa5a6Sopenharmony_ci    int32_t AddKeyGesture(int32_t pid, std::shared_ptr<KeyOption> keyOption,
159c29fa5a6Sopenharmony_ci        std::function<void(std::shared_ptr<KeyEvent>)> callback);
160c29fa5a6Sopenharmony_ci    void RemoveKeyGesture(int32_t id);
161c29fa5a6Sopenharmony_ci    bool Intercept(std::shared_ptr<KeyEvent> KeyEvent);
162c29fa5a6Sopenharmony_ci    void ResetAll();
163c29fa5a6Sopenharmony_ci    void Dump() const;
164c29fa5a6Sopenharmony_ci
165c29fa5a6Sopenharmony_ciprivate:
166c29fa5a6Sopenharmony_ci    std::vector<std::unique_ptr<KeyGesture>> keyGestures_;
167c29fa5a6Sopenharmony_ci};
168c29fa5a6Sopenharmony_ci
169c29fa5a6Sopenharmony_ciinline bool KeyGestureManager::KeyGesture::IsActive() const
170c29fa5a6Sopenharmony_ci{
171c29fa5a6Sopenharmony_ci    return active_;
172c29fa5a6Sopenharmony_ci}
173c29fa5a6Sopenharmony_ci
174c29fa5a6Sopenharmony_ciinline void KeyGestureManager::KeyGesture::MarkActive(bool active)
175c29fa5a6Sopenharmony_ci{
176c29fa5a6Sopenharmony_ci    active_ = active;
177c29fa5a6Sopenharmony_ci}
178c29fa5a6Sopenharmony_ci} // namespace MMI
179c29fa5a6Sopenharmony_ci} // namespace OHOS
180c29fa5a6Sopenharmony_ci#endif // KEY_GESTURE_MANAGER_H