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