1 /*
2  * Copyright (c) 2024 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 KEY_GESTURE_MANAGER_H
17 #define KEY_GESTURE_MANAGER_H
18 
19 #include <functional>
20 #include <set>
21 #include <sstream>
22 
23 #include <nocopyable.h>
24 
25 #include "key_event.h"
26 #include "key_option.h"
27 
28 namespace OHOS {
29 namespace MMI {
30 
31 class KeyGestureManager final {
32 private:
33     class Handler final {
34     public:
Handler(int32_t id, int32_t pid, int32_t longPressTime, std::function<void(std::shared_ptr<KeyEvent>)> callback)35         Handler(int32_t id, int32_t pid, int32_t longPressTime,
36                 std::function<void(std::shared_ptr<KeyEvent>)> callback)
37             : id_(id), pid_(pid), longPressTime_(longPressTime), callback_(callback) {}
38         ~Handler();
39 
GetId() const40         int32_t GetId() const
41         {
42             return id_;
43         }
44 
GetPid() const45         int32_t GetPid() const
46         {
47             return pid_;
48         }
49 
GetLongPressTime() const50         int32_t GetLongPressTime() const
51         {
52             return longPressTime_;
53         }
54 
SetLongPressTime(int32_t longPressTime)55         void SetLongPressTime(int32_t longPressTime)
56         {
57             longPressTime_ = longPressTime;
58         }
59 
60         void ResetTimer();
61         void Trigger(std::shared_ptr<KeyEvent> keyEvent);
62         void Run(std::shared_ptr<KeyEvent> keyEvent) const;
63         void RunPending();
64 
65     private:
66         int32_t id_ { -1 };
67         int32_t pid_ { -1 };
68         int32_t longPressTime_ { -1 };
69         int32_t timerId_ { -1 };
70         std::shared_ptr<KeyEvent> keyEvent_;
71         std::function<void(std::shared_ptr<KeyEvent>)> callback_;
72     };
73 
74     class KeyGesture {
75     public:
76         KeyGesture() = default;
77         virtual ~KeyGesture() = default;
78 
79         virtual bool IsWorking();
80         virtual bool ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const = 0;
81         virtual bool Intercept(std::shared_ptr<KeyEvent> KeyEvent) = 0;
82         virtual void Dump(std::ostringstream &output) const = 0;
83         virtual int32_t AddHandler(int32_t pid, int32_t longPressTime,
84             std::function<void(std::shared_ptr<KeyEvent>)> callback);
85         bool RemoveHandler(int32_t id);
86         void Reset();
87         bool IsActive() const;
88         void MarkActive(bool active);
89 
90     protected:
91         void ResetTimers();
92         std::set<int32_t> GetForegroundPids() const;
93         bool HaveForegroundHandler(const std::set<int32_t> &foregroundApps) const;
94         void TriggerHandlers(std::shared_ptr<KeyEvent> keyEvent);
95         void RunHandler(int32_t handlerId, std::shared_ptr<KeyEvent> keyEvent);
96         void NotifyHandlers(std::shared_ptr<KeyEvent> keyEvent);
97         void ShowHandlers(const std::string &prefix, const std::set<int32_t> &foregroundApps) const;
98 
99         bool active_ { false };
100         std::set<int32_t> keys_;
101         std::vector<Handler> handlers_;
102     };
103 
104 private:
105     class LongPressSingleKey : public KeyGesture {
106     public:
LongPressSingleKey(int32_t keyCode)107         LongPressSingleKey(int32_t keyCode) : keyCode_(keyCode) {}
108         ~LongPressSingleKey() = default;
109 
110         bool ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const override;
111         bool Intercept(std::shared_ptr<KeyEvent> KeyEvent) override;
112         void Dump(std::ostringstream &output) const override;
113 
114     private:
115         void RunPendingHandlers();
116 
117         int32_t keyCode_ { -1 };
118         int64_t firstDownTime_ {};
119     };
120 
121     class LongPressCombinationKey : public KeyGesture {
122     public:
LongPressCombinationKey(const std::set<int32_t> &keys)123         LongPressCombinationKey(const std::set<int32_t> &keys) : keys_(keys) {}
124         ~LongPressCombinationKey() = default;
125 
126         bool ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const override;
127         bool Intercept(std::shared_ptr<KeyEvent> keyEvent) override;
128         void Dump(std::ostringstream &output) const override;
129 
130     protected:
OnTriggerAll(std::shared_ptr<KeyEvent> keyEvent)131         virtual void OnTriggerAll(std::shared_ptr<KeyEvent> keyEvent) {}
132 
133     private:
134         bool RecognizeGesture(std::shared_ptr<KeyEvent> keyEvent);
135         void TriggerAll(std::shared_ptr<KeyEvent> keyEvent);
136 
137         int64_t firstDownTime_ {};
138         std::set<int32_t> keys_;
139     };
140 
141     class PullUpAccessibility final : public LongPressCombinationKey {
142     public:
143         PullUpAccessibility();
144         ~PullUpAccessibility() = default;
145 
146         bool IsWorking() override;
147         int32_t AddHandler(int32_t pid, int32_t longPressTime,
148             std::function<void(std::shared_ptr<KeyEvent>)> callback) override;
149         void OnTriggerAll(std::shared_ptr<KeyEvent> keyEvent) override;
150     };
151 
152 public:
153     KeyGestureManager();
154     ~KeyGestureManager() = default;
155     DISALLOW_COPY_AND_MOVE(KeyGestureManager);
156 
157     bool ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const;
158     int32_t AddKeyGesture(int32_t pid, std::shared_ptr<KeyOption> keyOption,
159         std::function<void(std::shared_ptr<KeyEvent>)> callback);
160     void RemoveKeyGesture(int32_t id);
161     bool Intercept(std::shared_ptr<KeyEvent> KeyEvent);
162     void ResetAll();
163     void Dump() const;
164 
165 private:
166     std::vector<std::unique_ptr<KeyGesture>> keyGestures_;
167 };
168 
IsActive() const169 inline bool KeyGestureManager::KeyGesture::IsActive() const
170 {
171     return active_;
172 }
173 
MarkActive(bool active)174 inline void KeyGestureManager::KeyGesture::MarkActive(bool active)
175 {
176     active_ = active;
177 }
178 } // namespace MMI
179 } // namespace OHOS
180 #endif // KEY_GESTURE_MANAGER_H