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()40         int32_t GetId() const
41         {
42             return id_;
43         }
44 
GetPid()45         int32_t GetPid() const
46         {
47             return pid_;
48         }
49 
GetLongPressTime()50         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 
GetKeyEvent()60         std::shared_ptr<KeyEvent> GetKeyEvent()
61         {
62             return keyEvent_;
63         }
64 
65         void ResetTimer();
66         void Trigger(std::shared_ptr<KeyEvent> keyEvent);
67         void Run(std::shared_ptr<KeyEvent> keyEvent) const;
68         void RunPending();
69 
70     private:
71         int32_t id_ { -1 };
72         int32_t pid_ { -1 };
73         int32_t longPressTime_ { -1 };
74         int32_t timerId_ { -1 };
75         std::shared_ptr<KeyEvent> keyEvent_;
76         std::function<void(std::shared_ptr<KeyEvent>)> callback_;
77     };
78 
79     class KeyGesture {
80     public:
81         KeyGesture() = default;
82         virtual ~KeyGesture() = default;
83 
84         virtual bool IsWorking();
85         virtual bool ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const = 0;
86         virtual bool Intercept(std::shared_ptr<KeyEvent> KeyEvent) = 0;
87         virtual void Dump(std::ostringstream &output) const = 0;
88         virtual int32_t AddHandler(int32_t pid, int32_t longPressTime,
89             std::function<void(std::shared_ptr<KeyEvent>)> callback);
90         bool RemoveHandler(int32_t id);
91         void Reset();
92         bool IsActive() const;
93         void MarkActive(bool active);
94 
95     protected:
96         void ResetTimers();
97         std::set<int32_t> GetForegroundPids() const;
98         bool HaveForegroundHandler(const std::set<int32_t> &foregroundApps) const;
99         void TriggerHandlers(std::shared_ptr<KeyEvent> keyEvent);
100         void RunHandler(int32_t handlerId, std::shared_ptr<KeyEvent> keyEvent);
101         void NotifyHandlers(std::shared_ptr<KeyEvent> keyEvent);
102 
103         bool active_ { false };
104         std::set<int32_t> keys_;
105         std::vector<Handler> handlers_;
106     };
107 
108     class LongPressSingleKey : public KeyGesture {
109     public:
LongPressSingleKey(int32_t keyCode)110         LongPressSingleKey(int32_t keyCode) : keyCode_(keyCode) {}
111         ~LongPressSingleKey() = default;
112 
113         bool ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const override;
114         bool Intercept(std::shared_ptr<KeyEvent> KeyEvent) override;
115         void Dump(std::ostringstream &output) const override;
116 
117     private:
118         void RunPendingHandlers();
119 
120         int32_t keyCode_ { -1 };
121         int64_t firstDownTime_ {};
122     };
123 
124     class LongPressCombinationKey : public KeyGesture {
125     public:
LongPressCombinationKey(const std::set<int32_t> & keys)126         LongPressCombinationKey(const std::set<int32_t> &keys) : keys_(keys) {}
127         ~LongPressCombinationKey() = default;
128 
129         bool ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const override;
130         bool Intercept(std::shared_ptr<KeyEvent> keyEvent) override;
131         void Dump(std::ostringstream &output) const override;
132 
133     protected:
OnTriggerAll(std::shared_ptr<KeyEvent> keyEvent)134         virtual void OnTriggerAll(std::shared_ptr<KeyEvent> keyEvent) {}
135 
136     private:
137         bool RecognizeGesture(std::shared_ptr<KeyEvent> keyEvent);
138         void TriggerAll(std::shared_ptr<KeyEvent> keyEvent);
139 
140         int64_t firstDownTime_ {};
141         std::set<int32_t> keys_;
142     };
143 
144     class PullUpAccessibility final : public LongPressCombinationKey {
145     public:
146         PullUpAccessibility();
147         ~PullUpAccessibility() = default;
148 
149         bool IsWorking() override;
150         int32_t AddHandler(int32_t pid, int32_t longPressTime,
151             std::function<void(std::shared_ptr<KeyEvent>)> callback) override;
152         void OnTriggerAll(std::shared_ptr<KeyEvent> keyEvent) override;
153     };
154 
155 public:
156     KeyGestureManager();
157     ~KeyGestureManager() = default;
158     DISALLOW_COPY_AND_MOVE(KeyGestureManager);
159 
160     bool ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const;
161     int32_t AddKeyGesture(int32_t pid, std::shared_ptr<KeyOption> keyOption,
162         std::function<void(std::shared_ptr<KeyEvent>)> callback);
163     void RemoveKeyGesture(int32_t id);
164     bool Intercept(std::shared_ptr<KeyEvent> KeyEvent);
165     void ResetAll();
166     void Dump() const;
167 
168 private:
169     std::vector<std::unique_ptr<KeyGesture>> keyGestures_;
170 };
171 
IsActive()172 inline bool KeyGestureManager::KeyGesture::IsActive() const
173 {
174     return active_;
175 }
176 
MarkActive(bool active)177 inline void KeyGestureManager::KeyGesture::MarkActive(bool active)
178 {
179     active_ = active;
180 }
181 } // namespace MMI
182 } // namespace OHOS
183 #endif // KEY_GESTURE_MANAGER_H
184