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_SHORTCUT_MANAGER_H 17 #define KEY_SHORTCUT_MANAGER_H 18 19 #include <functional> 20 #include <map> 21 #include <optional> 22 #include <set> 23 24 #include <cJSON.h> 25 #include <nocopyable.h> 26 27 #include "key_command_handler.h" 28 #include "key_event.h" 29 #include "key_option.h" 30 31 namespace OHOS { 32 namespace MMI { 33 enum KeyShortcutError : int32_t { 34 KEY_SHORTCUT_ERROR_BASE = -1, 35 KEY_SHORTCUT_ERROR_CONFIG = (KEY_SHORTCUT_ERROR_BASE - 1), 36 KEY_SHORTCUT_ERROR_COMBINATION_KEY = (KEY_SHORTCUT_ERROR_BASE - 2), 37 KEY_SHORTCUT_ERROR_TAKEN = (KEY_SHORTCUT_ERROR_BASE - 3), 38 }; 39 40 class KeyShortcutManager final { 41 public: 42 static inline constexpr uint32_t SHORTCUT_MODIFIER_ALT { 0x1 }; 43 static inline constexpr uint32_t SHORTCUT_MODIFIER_SHIFT { SHORTCUT_MODIFIER_ALT << 1U }; 44 static inline constexpr uint32_t SHORTCUT_MODIFIER_CTRL { SHORTCUT_MODIFIER_ALT << 2U }; 45 static inline constexpr uint32_t SHORTCUT_MODIFIER_LOGO { SHORTCUT_MODIFIER_ALT << 3U }; 46 static inline constexpr uint32_t SHORTCUT_MODIFIER_MASK { 47 SHORTCUT_MODIFIER_ALT | SHORTCUT_MODIFIER_SHIFT | SHORTCUT_MODIFIER_CTRL | SHORTCUT_MODIFIER_LOGO }; 48 static inline constexpr int32_t SHORTCUT_PURE_MODIFIERS { -1 }; 49 static inline constexpr int32_t MOUSE_BUTTON_LEFT { 25001 }; 50 static inline constexpr int32_t MOUSE_BUTTON_RIGHT { MOUSE_BUTTON_LEFT + 1 }; 51 52 enum ShortcutTriggerType : int32_t { 53 SHORTCUT_TRIGGER_TYPE_DOWN = 0, 54 SHORTCUT_TRIGGER_TYPE_UP, 55 }; 56 57 struct SystemShortcutKey { 58 std::set<int32_t> modifiers; 59 int32_t finalKey; 60 int32_t longPressTime; // ms 61 ShortcutTriggerType triggerType; 62 int32_t session; 63 std::function<void(std::shared_ptr<KeyEvent>)> callback; 64 }; 65 66 struct HotKey { 67 std::set<int32_t> modifiers; 68 int32_t finalKey; 69 int32_t longPressTime; // ms 70 int32_t session; 71 std::function<void(std::shared_ptr<KeyEvent>)> callback; 72 }; 73 74 KeyShortcutManager(); 75 ~KeyShortcutManager() = default; 76 DISALLOW_COPY_AND_MOVE(KeyShortcutManager); 77 78 int32_t RegisterSystemKey(const SystemShortcutKey &key); 79 void UnregisterSystemKey(int32_t shortcutId); 80 int32_t RegisterHotKey(const HotKey &key); 81 void UnregisterHotKey(int32_t shortcutId); 82 bool HandleEvent(std::shared_ptr<KeyEvent> keyEvent); 83 void ResetAll(); 84 int32_t GetAllSystemHotkeys(std::vector<std::unique_ptr<KeyOption>> &sysKeys); 85 void ResetCheckState(); 86 bool IsCheckUpShortcut(const std::shared_ptr<KeyEvent> &keyEvent); 87 88 bool HaveShortcutConsumed(std::shared_ptr<KeyEvent> keyEvent); 89 void UpdateShortcutConsumed(std::shared_ptr<KeyEvent> keyEvent); 90 void MarkShortcutConsumed(const ShortcutKey &shortcut); 91 void MarkShortcutConsumed(const KeyOption &shortcut); 92 93 static std::shared_ptr<KeyShortcutManager> GetInstance(); 94 95 private: 96 struct SystemKey { 97 uint32_t modifiers; 98 int32_t finalKey; 99 100 bool operator<(const SystemKey &other) const; 101 }; 102 103 struct ExceptionalSystemKey { 104 std::set<int32_t> preKeys; 105 int32_t finalKey; 106 int32_t longPressTime; // ms 107 ShortcutTriggerType triggerType; 108 109 bool operator<(const ExceptionalSystemKey &other) const; 110 }; 111 112 struct KeyShortcut { 113 uint32_t modifiers; 114 int32_t finalKey; 115 int32_t longPressTime; // ms 116 ShortcutTriggerType triggerType; 117 int32_t session; 118 std::function<void(std::shared_ptr<KeyEvent>)> callback; 119 }; 120 121 struct SystemHotkey { 122 std::set<int32_t> preKeys; 123 int32_t finalKey; 124 125 bool operator<(const SystemHotkey &other) const; 126 }; 127 128 void LoadSystemKeys(); 129 void ReadSystemKeys(const std::string &cfgPath); 130 int32_t ReadSystemKey(cJSON *jsonSysKey); 131 int32_t AddSystemKey(const std::set<int32_t> &preKeys, int32_t finalKey); 132 void LoadExceptionalSystemKeys(); 133 void ReadExceptionalSystemKeys(const std::string &cfgPath); 134 int32_t ReadExceptionalSystemKey(cJSON *jsonSysKey); 135 void AddExceptionalSystemKey(const ExceptionalSystemKey &sysKey); 136 std::string FormatModifiers(const std::set<int32_t> &modifiers) const; 137 int32_t GenerateId() const; 138 bool IsExceptionalSystemKey(const ExceptionalSystemKey &sysKey) const; 139 bool IsModifier(int32_t keyCode) const; 140 bool CheckSystemKey(const SystemShortcutKey &key, KeyShortcut &shortcut) const; 141 bool IsValid(const ShortcutTriggerType triggerType) const; 142 bool IsReservedSystemKey(const KeyShortcut &shortcut) const; 143 bool CheckGlobalKey(const HotKey &key, KeyShortcut &shortcut) const; 144 bool HaveRegisteredGlobalKey(const KeyShortcut &key) const; 145 std::string FormatPressedKeys(std::shared_ptr<KeyEvent> keyEvent) const; 146 std::set<int32_t> GetForegroundPids() const; 147 bool HandleKeyDown(std::shared_ptr<KeyEvent> keyEvent); 148 bool HandleKeyUp(std::shared_ptr<KeyEvent> keyEvent); 149 bool HandleKeyCancel(std::shared_ptr<KeyEvent> keyEvent); 150 bool CheckCombination(std::shared_ptr<KeyEvent> keyEvent, const KeyShortcut &shortcut) const; 151 bool CheckPureModifiers(std::shared_ptr<KeyEvent> keyEvent, const KeyShortcut &shortcut) const; 152 bool CheckModifiers(std::shared_ptr<KeyEvent> keyEvent, const KeyShortcut &shortcut) const; 153 void TriggerDown(std::shared_ptr<KeyEvent> keyEvent, int32_t shortcutId, const KeyShortcut &shortcut); 154 void RunShortcut(std::shared_ptr<KeyEvent> keyEvent, int32_t shortcutId); 155 void TriggerUp(std::shared_ptr<KeyEvent> keyEvent, int32_t shortcutId, const KeyShortcut &shortcut); 156 void ResetTriggering(std::shared_ptr<KeyEvent> keyEvent); 157 bool WillResetOnKeyDown(int32_t keyCode, const KeyShortcut &shortcut) const; 158 bool WillResetOnKeyUp(int32_t keyCode, const KeyShortcut &shortcut) const; 159 void ResetTriggering(int32_t shortcutId); 160 void LoadHotkeys(); 161 void ReadHotkeys(const std::string &cfgPath); 162 int32_t ReadHotkey(cJSON *jsonSysKey); 163 int32_t AddHotkey(const std::set<int32_t> &preKeys, int32_t finalKey); 164 165 std::set<int32_t> shortcutConsumed_; 166 std::set<SystemKey> systemKeys_; 167 std::set<ExceptionalSystemKey> exceptSysKeys_; 168 std::map<int32_t, KeyShortcut> shortcuts_; 169 std::map<int32_t, int32_t> triggering_; 170 static const std::map<int32_t, uint32_t> modifiers_; 171 static std::mutex mutex_; 172 static std::shared_ptr<KeyShortcutManager> instance_; 173 std::set<SystemHotkey> hotkeys_; 174 bool isCheckShortcut_ { true }; 175 }; 176 177 #define KEY_SHORTCUT_MGR KeyShortcutManager::GetInstance() 178 } // namespace MMI 179 } // namespace OHOS 180 #endif // KEY_SHORTCUT_MANAGER_H 181