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