1 /*
2  * Copyright (c) 2021-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_COMMAND_HANDLER_H
17 #define KEY_COMMAND_HANDLER_H
18 
19 #include <chrono>
20 #include <condition_variable>
21 #include <functional>
22 #include <fstream>
23 #include <map>
24 #include <mutex>
25 #include <set>
26 #include <thread>
27 #include <vector>
28 
29 #include "nocopyable.h"
30 #include "preferences.h"
31 #include "preferences_errno.h"
32 #include "preferences_helper.h"
33 #include "window_info.h"
34 
35 #include "i_input_event_handler.h"
36 #include "key_event.h"
37 #include "struct_multimodal.h"
38 
39 namespace OHOS {
40 namespace MMI {
41 enum KeyCommandType : int32_t {
42     TYPE_SHORTKEY = 0,
43     TYPE_SEQUENCE = 1,
44     TYPE_FINGERSCENE = 2,
45     TYPE_REPEAT_KEY = 3,
46     TYPE_MULTI_FINGERS = 4,
47 };
48 
49 enum class KnuckleType : int32_t {
50     KNUCKLE_TYPE_SINGLE = 0,
51     KNUCKLE_TYPE_DOUBLE = 1,
52 };
53 
54 enum class NotifyType : int32_t {
55     CANCEL,
56     INCONSISTENTGESTURE,
57     REGIONGESTURE,
58     LETTERGESTURE,
59     OTHER
60 };
61 
62 struct Ability {
63     std::string bundleName;
64     std::string abilityName;
65     std::string action;
66     std::string type;
67     std::string deviceId;
68     std::string uri;
69     std::string abilityType;
70     std::vector<std::string> entities;
71     std::map<std::string, std::string> params;
72 };
73 
74 struct ShortcutKey {
75     std::set<int32_t> preKeys;
76     std::string businessId;
77     std::string statusConfig;
78     bool statusConfigValue { true };
79     int32_t finalKey { -1 };
80     int32_t keyDownDuration { 0 };
81     int32_t triggerType { KeyEvent::KEY_ACTION_DOWN };
82     int32_t timerId { -1 };
83     Ability ability;
84     void Print() const;
85 };
86 
87 struct SequenceKey {
88     int32_t keyCode { -1 };
89     int32_t keyAction { 0 };
90     int64_t actionTime { 0 };
91     int64_t delay { 0 };
92     bool operator!=(const SequenceKey &sequenceKey)
93     {
94         return (keyCode != sequenceKey.keyCode) || (keyAction != sequenceKey.keyAction);
95     }
96 };
97 
98 struct ExcludeKey {
99     int32_t keyCode { -1 };
100     int32_t keyAction { -1 };
101     int64_t delay { 0 };
102 };
103 
104 struct Sequence {
105     std::vector<SequenceKey> sequenceKeys;
106     std::string statusConfig;
107     bool statusConfigValue { true };
108     int64_t abilityStartDelay { 0 };
109     int32_t timerId { -1 };
110     Ability ability;
111     friend std::ostream& operator<<(std::ostream&, const Sequence&);
112 };
113 
114 struct TwoFingerGesture {
115     inline static constexpr auto MAX_TOUCH_NUM = 2;
116     bool active = false;
117     int32_t timerId = -1;
118     int64_t abilityStartDelay = 0;
119     Ability ability;
120     struct {
121         int32_t id { 0 };
122         int32_t x { 0 };
123         int32_t y { 0 };
124         int64_t downTime { 0 };
125     } touches[MAX_TOUCH_NUM];
126 };
127 
128 struct KnuckleGesture {
129     std::shared_ptr<PointerEvent> lastPointerDownEvent { nullptr };
130     bool state { false };
131     int64_t lastPointerUpTime { 0 };
132     int64_t downToPrevUpTime { 0 };
133     float doubleClickDistance { 0.0f };
134     Ability ability;
135     struct {
136         int32_t id { 0 };
137         int32_t x { 0 };
138         int32_t y { 0 };
139     } lastDownPointer;
140 };
141 
142 struct RepeatKey {
143     int32_t keyCode { -1 };
144     int32_t keyAction { 0 };
145     int32_t times { 0 };
146     int64_t actionTime { 0 };
147     int64_t delay { 0 };
148     std::string statusConfig;
149     bool statusConfigValue { true };
150     Ability ability;
151 };
152 
153 struct MultiFingersTap {
154     Ability ability;
155 };
156 
157 struct KnuckleSwitch {
158     std::string statusConfig { "" };
159     bool statusConfigValue { false };
160 };
161 
162 class KeyCommandHandler final : public IInputEventHandler {
163 public:
164     KeyCommandHandler() = default;
165     DISALLOW_COPY_AND_MOVE(KeyCommandHandler);
166     ~KeyCommandHandler() override = default;
167     int32_t UpdateSettingsXml(const std::string &businessId, int32_t delay);
168     int32_t EnableCombineKey(bool enable);
169     KnuckleGesture GetSingleKnuckleGesture() const;
170     KnuckleGesture GetDoubleKnuckleGesture() const;
171     void Dump(int32_t fd, const std::vector<std::string> &args);
172     void PrintGestureInfo(int32_t fd);
173     std::string ConvertKeyActionToString(int32_t keyAction);
174 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
175     void HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent) override;
176 #endif // OHOS_BUILD_ENABLE_KEYBOARD
177 #ifdef OHOS_BUILD_ENABLE_POINTER
178     void HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent) override;
179 #endif // OHOS_BUILD_ENABLE_POINTER
180 #ifdef OHOS_BUILD_ENABLE_TOUCH
181     void HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent) override;
182     void HandlePointerActionDownEvent(const std::shared_ptr<PointerEvent> touchEvent);
183     void HandlePointerActionMoveEvent(const std::shared_ptr<PointerEvent> touchEvent);
184     void HandlePointerActionUpEvent(const std::shared_ptr<PointerEvent> touchEvent);
185 #endif // OHOS_BUILD_ENABLE_TOUCH
186     void SetKnuckleDoubleTapIntervalTime(int64_t interval);
187     void SetKnuckleDoubleTapDistance(float distance);
188     bool GetKnuckleSwitchValue();
189     bool CheckInputMethodArea(const std::shared_ptr<PointerEvent> touchEvent);
190 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
191     bool OnHandleEvent(const std::shared_ptr<KeyEvent> keyEvent);
192     int32_t SetIsFreezePowerKey(const std::string pageName);
193 #endif // OHOS_BUILD_ENABLE_KEYBOARD
194 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
195     bool OnHandleEvent(const std::shared_ptr<PointerEvent> pointerEvent);
196 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
197     void InitKeyObserver();
198     bool PreHandleEvent();
199 private:
200     void Print();
201     void PrintSeq();
202     void PrintExcludeKeys();
203     bool ParseConfig();
204     bool ParseExcludeConfig();
205     bool ParseJson(const std::string &configFile);
206     bool ParseExcludeJson(const std::string &configFile);
207     void ParseRepeatKeyMaxCount();
208     void ParseStatusConfigObserver();
209     void LaunchAbility(const Ability &ability);
210     void LaunchAbility(const Ability &ability, int64_t delay);
211     void LaunchAbility(const ShortcutKey &key);
212     void LaunchAbility(const Sequence &sequence);
213     void LaunchRepeatKeyAbility(const RepeatKey &item, bool &isLaunched, const std::shared_ptr<KeyEvent> keyEvent);
214     bool IsKeyMatch(const ShortcutKey &shortcutKey, const std::shared_ptr<KeyEvent> &key);
215     bool IsRepeatKeyEvent(const SequenceKey &sequenceKey);
216     bool HandleKeyUp(const std::shared_ptr<KeyEvent> &keyEvent, const ShortcutKey &shortcutKey);
217     bool HandleKeyDown(ShortcutKey &shortcutKey);
218     bool HandleKeyCancel(ShortcutKey &shortcutKey);
219     bool PreHandleEvent(const std::shared_ptr<KeyEvent> key);
220     bool HandleEvent(const std::shared_ptr<KeyEvent> key);
221     bool HandleKeyUpCancel(const RepeatKey &item, const std::shared_ptr<KeyEvent> keyEvent);
222     bool HandleRepeatKeyCount(const RepeatKey &item, const std::shared_ptr<KeyEvent> keyEvent);
223     void HandleRepeatKeyOwnCount(const RepeatKey &item);
224     bool HandleRepeatKey(const RepeatKey& item, bool &isLaunchAbility, const std::shared_ptr<KeyEvent> keyEvent);
225     bool HandleRepeatKeys(const std::shared_ptr<KeyEvent> keyEvent);
226     bool HandleRepeatKeyAbility(const RepeatKey &item, bool &isLaunched,
227         const std::shared_ptr<KeyEvent> keyEvent, bool isMaxTimes);
228     bool HandleSequence(Sequence& sequence, bool &isLaunchAbility);
229     bool HandleNormalSequence(Sequence& sequence, bool &isLaunchAbility);
230     bool HandleMatchedSequence(Sequence& sequence, bool &isLaunchAbility);
231     bool HandleScreenLocked(Sequence& sequence, bool &isLaunchAbility);
232     bool IsActiveSequenceRepeating(std::shared_ptr<KeyEvent> keyEvent) const;
233     void MarkActiveSequence(bool active);
234     bool HandleSequences(const std::shared_ptr<KeyEvent> keyEvent);
235     bool HandleShortKeys(const std::shared_ptr<KeyEvent> keyEvent);
236     bool HandleConsumedKeyEvent(const std::shared_ptr<KeyEvent> keyEvent);
237     bool HandleMulFingersTap(const std::shared_ptr<PointerEvent> pointerEvent);
238     bool AddSequenceKey(const std::shared_ptr<KeyEvent> keyEvent);
239     std::shared_ptr<KeyEvent> CreateKeyEvent(int32_t keyCode, int32_t keyAction, bool isPressed);
240     bool IsEnableCombineKey(const std::shared_ptr<KeyEvent> key);
241     bool IsExcludeKey(const std::shared_ptr<KeyEvent> key);
242     void RemoveSubscribedTimer(int32_t keyCode);
243     void HandleSpecialKeys(int32_t keyCode, int32_t keyAction);
244     void InterruptTimers();
245     void HandlePointerVisibleKeys(const std::shared_ptr<KeyEvent> &keyEvent);
246     int32_t GetKeyDownDurationFromXml(const std::string &businessId);
247     void SendKeyEvent();
248     bool CheckSpecialRepeatKey(RepeatKey& item, const std::shared_ptr<KeyEvent> keyEvent);
249     bool IsMusicActivate();
250     template <class T>
251     void CreateStatusConfigObserver(T& item);
ResetLastMatchedKey()252     void ResetLastMatchedKey()
253     {
254         lastMatchedKey_.preKeys.clear();
255         lastMatchedKey_.finalKey = -1;
256         lastMatchedKey_.timerId = -1;
257         lastMatchedKey_.keyDownDuration = 0;
258     }
ResetCurrentLaunchAbilityKey()259     void ResetCurrentLaunchAbilityKey()
260     {
261         currentLaunchAbilityKey_.preKeys.clear();
262         currentLaunchAbilityKey_.finalKey = -1;
263         currentLaunchAbilityKey_.timerId = -1;
264         currentLaunchAbilityKey_.keyDownDuration = 0;
265     }
266 
ResetSequenceKeys()267     void ResetSequenceKeys()
268     {
269         keys_.clear();
270         filterSequences_.clear();
271     }
272     bool SkipFinalKey(const int32_t keyCode, const std::shared_ptr<KeyEvent> &key);
273 #ifdef OHOS_BUILD_ENABLE_TOUCH
274     void OnHandleTouchEvent(const std::shared_ptr<PointerEvent> touchEvent);
275 #endif // OHOS_BUILD_ENABLE_TOUCH
276 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
277     void StartTwoFingerGesture();
278     void StopTwoFingerGesture();
279     bool CheckTwoFingerGestureAction() const;
280 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
281 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
282     void HandleFingerGestureDownEvent(const std::shared_ptr<PointerEvent> touchEvent);
283     void HandleFingerGestureUpEvent(const std::shared_ptr<PointerEvent> touchEvent);
284     void HandleKnuckleGestureDownEvent(const std::shared_ptr<PointerEvent> touchEvent);
285     void HandleKnuckleGestureUpEvent(const std::shared_ptr<PointerEvent> touchEvent);
286     std::pair<int32_t, int32_t> CalcDrawCoordinate(const DisplayInfo& displayInfo,
287         PointerEvent::PointerItem pointerItem);
288     void SingleKnuckleGestureProcesser(const std::shared_ptr<PointerEvent> touchEvent);
289     void DoubleKnuckleGestureProcesser(const std::shared_ptr<PointerEvent> touchEvent);
290     void ReportKnuckleScreenCapture(const std::shared_ptr<PointerEvent> touchEvent);
291     void KnuckleGestureProcessor(std::shared_ptr<PointerEvent> touchEvent,
292         KnuckleGesture &knuckleGesture, KnuckleType type);
293     void UpdateKnuckleGestureInfo(const std::shared_ptr<PointerEvent> touchEvent, KnuckleGesture &knuckleGesture);
294     void AdjustTimeIntervalConfigIfNeed(int64_t intervalTime);
295     void AdjustDistanceConfigIfNeed(float distance);
296     bool CheckKnuckleCondition(std::shared_ptr<PointerEvent> touchEvent);
297 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
298 #ifdef OHOS_BUILD_ENABLE_TOUCH
299     int32_t ConvertVPToPX(int32_t vp) const;
300 #endif // OHOS_BUILD_ENABLE_TOUCH
301 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
302     void HandleKnuckleGestureEvent(std::shared_ptr<PointerEvent> touchEvent);
303     void HandleKnuckleGestureTouchDown(std::shared_ptr<PointerEvent> touchEvent);
304     void HandleKnuckleGestureTouchMove(std::shared_ptr<PointerEvent> touchEvent);
305     void HandleKnuckleGestureTouchUp(std::shared_ptr<PointerEvent> touchEvent);
306     void ProcessKnuckleGestureTouchUp(NotifyType type);
307     void ResetKnuckleGesture();
308     std::string GesturePointsToStr() const;
309     bool IsValidAction(int32_t action);
310     void ReportIfNeed();
311     void ReportRegionGesture();
312     void ReportLetterGesture();
313     void ReportGestureInfo();
314     bool IsMatchedAbility(std::vector<float> gesturePoints_, float gestureLastX, float gestureLastY);
315 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
316     void CheckAndUpdateTappingCountAtDown(std::shared_ptr<PointerEvent> touchEvent);
317     void SendNotSupportMsg(std::shared_ptr<PointerEvent> touchEvent);
318 
319 private:
320     Sequence matchedSequence_;
321     ShortcutKey lastMatchedKey_;
322     ShortcutKey currentLaunchAbilityKey_;
323     std::map<std::string, ShortcutKey> shortcutKeys_;
324     std::vector<Sequence> sequences_;
325     std::vector<ExcludeKey> excludeKeys_;
326     std::vector<Sequence> filterSequences_;
327     std::vector<SequenceKey> keys_;
328     std::vector<RepeatKey> repeatKeys_;
329     std::vector<std::string> businessIds_;
330     bool isParseConfig_ { false };
331     bool isParseExcludeConfig_ { false };
332     std::map<int32_t, int32_t> specialKeys_;
333     std::map<int32_t, std::list<int32_t>> specialTimers_;
334     std::map<int32_t, int32_t> repeatKeyMaxTimes_;
335     std::map<std::string, int32_t> repeatKeyTimerIds_;
336     std::map<std::string, int32_t> repeatKeyCountMap_;
337     TwoFingerGesture twoFingerGesture_;
338     KnuckleGesture singleKnuckleGesture_;
339     KnuckleGesture doubleKnuckleGesture_;
340     MultiFingersTap threeFingersTap_;
341     bool isTimeConfig_ { false };
342     bool isDistanceConfig_ { false };
343     bool isKnuckleSwitchConfig_ { false };
344     struct KnuckleSwitch knuckleSwitch_;
345     int32_t checkAdjustIntervalTimeCount_ { 0 };
346     int32_t checkAdjustDistanceCount_ { 0 };
347     int64_t downToPrevUpTimeConfig_ { 0 };
348     float downToPrevDownDistanceConfig_ { 0.0f };
349     float distanceDefaultConfig_ { 0.0f };
350     float distanceLongConfig_ { 0.0f };
351     bool enableCombineKey_ { true };
352     RepeatKey repeatKey_;
353     int32_t maxCount_ { 0 };
354     int32_t count_ { 0 };
355     int32_t repeatTimerId_ { -1 };
356     int32_t knuckleCount_ { 0 };
357     int32_t sosDelayTimerId_ { -1 };
358     int64_t downActionTime_ { 0 };
359     int64_t lastDownActionTime_ { 0 };
360     int64_t lastVolumeDownActionTime_ { 0 };
361     int64_t upActionTime_ { 0 };
362     int32_t launchAbilityCount_ { 0 };
363     int64_t intervalTime_ { 120000 };
364     std::atomic<bool> isFreezePowerKey_ { false };
365     bool isDownStart_ { false };
366     bool isKeyCancel_ { false };
367     bool sequenceOccurred_ { false };
368     bool isHandleSequence_ { false };
369     bool isParseMaxCount_ { false };
370     bool isParseStatusConfig_ { false };
371     bool isDoubleClick_ { false };
372     int32_t lastKeyEventCode_ { -1 };
373     int32_t screenRecordingSuccessCount_ { 0 };
374     std::string sessionKey_ { };
375     bool isStartBase_ { false };
376 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
377     bool isGesturing_ { false };
378     bool isLetterGesturing_ { false };
379     bool isLastGestureSucceed_ { false };
380     float gestureLastX_ { 0.0f };
381     float gestureLastY_ { 0.0f };
382     float gestureTrackLength_ { 0.0f };
383     std::vector<float> gesturePoints_;
384     std::vector<int64_t> gestureTimeStamps_;
385     int64_t drawOFailTimestamp_ { 0 };
386     int64_t drawOSuccTimestamp_ { 0 };
387     Direction lastDirection_ { DIRECTION0 };
388 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
389     int64_t lastDownTime_ { 0 };
390     int64_t previousUpTime_ { 0 };
391     int32_t tappingCount_ { 0 };
392     std::map<int32_t, int64_t> lastPointerDownTime_;
393     std::mutex mutex_;
394     int64_t walletLaunchDelayTimes_ { 0 };
395     int64_t sosLaunchTime_ { -1 };
396     int64_t powerUpTime_ { 0 };
397 };
398 } // namespace MMI
399 } // namespace OHOS
400 #endif // KEY_COMMAND_HANDLER_H