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