1c29fa5a6Sopenharmony_ci/* 2c29fa5a6Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3c29fa5a6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4c29fa5a6Sopenharmony_ci * you may not use this file except in compliance with the License. 5c29fa5a6Sopenharmony_ci * You may obtain a copy of the License at 6c29fa5a6Sopenharmony_ci * 7c29fa5a6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8c29fa5a6Sopenharmony_ci * 9c29fa5a6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10c29fa5a6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11c29fa5a6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12c29fa5a6Sopenharmony_ci * See the License for the specific language governing permissions and 13c29fa5a6Sopenharmony_ci * limitations under the License. 14c29fa5a6Sopenharmony_ci */ 15c29fa5a6Sopenharmony_ci 16c29fa5a6Sopenharmony_ci#ifndef KEY_SHORTCUT_MANAGER_H 17c29fa5a6Sopenharmony_ci#define KEY_SHORTCUT_MANAGER_H 18c29fa5a6Sopenharmony_ci 19c29fa5a6Sopenharmony_ci#include <functional> 20c29fa5a6Sopenharmony_ci#include <map> 21c29fa5a6Sopenharmony_ci#include <optional> 22c29fa5a6Sopenharmony_ci#include <set> 23c29fa5a6Sopenharmony_ci 24c29fa5a6Sopenharmony_ci#include <cJSON.h> 25c29fa5a6Sopenharmony_ci#include <nocopyable.h> 26c29fa5a6Sopenharmony_ci 27c29fa5a6Sopenharmony_ci#include "key_command_handler.h" 28c29fa5a6Sopenharmony_ci#include "key_event.h" 29c29fa5a6Sopenharmony_ci#include "key_option.h" 30c29fa5a6Sopenharmony_ci 31c29fa5a6Sopenharmony_cinamespace OHOS { 32c29fa5a6Sopenharmony_cinamespace MMI { 33c29fa5a6Sopenharmony_cienum KeyShortcutError : int32_t { 34c29fa5a6Sopenharmony_ci KEY_SHORTCUT_ERROR_BASE = -1, 35c29fa5a6Sopenharmony_ci KEY_SHORTCUT_ERROR_CONFIG = (KEY_SHORTCUT_ERROR_BASE - 1), 36c29fa5a6Sopenharmony_ci KEY_SHORTCUT_ERROR_COMBINATION_KEY = (KEY_SHORTCUT_ERROR_BASE - 2), 37c29fa5a6Sopenharmony_ci KEY_SHORTCUT_ERROR_TAKEN = (KEY_SHORTCUT_ERROR_BASE - 3), 38c29fa5a6Sopenharmony_ci}; 39c29fa5a6Sopenharmony_ci 40c29fa5a6Sopenharmony_ciclass KeyShortcutManager final { 41c29fa5a6Sopenharmony_cipublic: 42c29fa5a6Sopenharmony_ci static inline constexpr uint32_t SHORTCUT_MODIFIER_ALT { 0x1 }; 43c29fa5a6Sopenharmony_ci static inline constexpr uint32_t SHORTCUT_MODIFIER_SHIFT { SHORTCUT_MODIFIER_ALT << 1U }; 44c29fa5a6Sopenharmony_ci static inline constexpr uint32_t SHORTCUT_MODIFIER_CTRL { SHORTCUT_MODIFIER_ALT << 2U }; 45c29fa5a6Sopenharmony_ci static inline constexpr uint32_t SHORTCUT_MODIFIER_LOGO { SHORTCUT_MODIFIER_ALT << 3U }; 46c29fa5a6Sopenharmony_ci static inline constexpr uint32_t SHORTCUT_MODIFIER_MASK { 47c29fa5a6Sopenharmony_ci SHORTCUT_MODIFIER_ALT | SHORTCUT_MODIFIER_SHIFT | SHORTCUT_MODIFIER_CTRL | SHORTCUT_MODIFIER_LOGO }; 48c29fa5a6Sopenharmony_ci static inline constexpr int32_t SHORTCUT_PURE_MODIFIERS { -1 }; 49c29fa5a6Sopenharmony_ci static inline constexpr int32_t MOUSE_BUTTON_LEFT { 25001 }; 50c29fa5a6Sopenharmony_ci static inline constexpr int32_t MOUSE_BUTTON_RIGHT { MOUSE_BUTTON_LEFT + 1 }; 51c29fa5a6Sopenharmony_ci 52c29fa5a6Sopenharmony_ci enum ShortcutTriggerType : int32_t { 53c29fa5a6Sopenharmony_ci SHORTCUT_TRIGGER_TYPE_DOWN = 0, 54c29fa5a6Sopenharmony_ci SHORTCUT_TRIGGER_TYPE_UP, 55c29fa5a6Sopenharmony_ci }; 56c29fa5a6Sopenharmony_ci 57c29fa5a6Sopenharmony_ci struct SystemShortcutKey { 58c29fa5a6Sopenharmony_ci std::set<int32_t> modifiers; 59c29fa5a6Sopenharmony_ci int32_t finalKey; 60c29fa5a6Sopenharmony_ci int32_t longPressTime; // ms 61c29fa5a6Sopenharmony_ci ShortcutTriggerType triggerType; 62c29fa5a6Sopenharmony_ci int32_t session; 63c29fa5a6Sopenharmony_ci std::function<void(std::shared_ptr<KeyEvent>)> callback; 64c29fa5a6Sopenharmony_ci }; 65c29fa5a6Sopenharmony_ci 66c29fa5a6Sopenharmony_ci struct HotKey { 67c29fa5a6Sopenharmony_ci std::set<int32_t> modifiers; 68c29fa5a6Sopenharmony_ci int32_t finalKey; 69c29fa5a6Sopenharmony_ci int32_t longPressTime; // ms 70c29fa5a6Sopenharmony_ci int32_t session; 71c29fa5a6Sopenharmony_ci std::function<void(std::shared_ptr<KeyEvent>)> callback; 72c29fa5a6Sopenharmony_ci }; 73c29fa5a6Sopenharmony_ci 74c29fa5a6Sopenharmony_ci KeyShortcutManager(); 75c29fa5a6Sopenharmony_ci ~KeyShortcutManager() = default; 76c29fa5a6Sopenharmony_ci DISALLOW_COPY_AND_MOVE(KeyShortcutManager); 77c29fa5a6Sopenharmony_ci 78c29fa5a6Sopenharmony_ci int32_t RegisterSystemKey(const SystemShortcutKey &key); 79c29fa5a6Sopenharmony_ci void UnregisterSystemKey(int32_t shortcutId); 80c29fa5a6Sopenharmony_ci int32_t RegisterHotKey(const HotKey &key); 81c29fa5a6Sopenharmony_ci void UnregisterHotKey(int32_t shortcutId); 82c29fa5a6Sopenharmony_ci bool HandleEvent(std::shared_ptr<KeyEvent> keyEvent); 83c29fa5a6Sopenharmony_ci void ResetAll(); 84c29fa5a6Sopenharmony_ci int32_t GetAllSystemHotkeys(std::vector<std::unique_ptr<KeyOption>> &sysKeys); 85c29fa5a6Sopenharmony_ci void ResetCheckState(); 86c29fa5a6Sopenharmony_ci bool IsCheckUpShortcut(const std::shared_ptr<KeyEvent> &keyEvent); 87c29fa5a6Sopenharmony_ci 88c29fa5a6Sopenharmony_ci bool HaveShortcutConsumed(std::shared_ptr<KeyEvent> keyEvent); 89c29fa5a6Sopenharmony_ci void UpdateShortcutConsumed(std::shared_ptr<KeyEvent> keyEvent); 90c29fa5a6Sopenharmony_ci void MarkShortcutConsumed(const ShortcutKey &shortcut); 91c29fa5a6Sopenharmony_ci void MarkShortcutConsumed(const KeyOption &shortcut); 92c29fa5a6Sopenharmony_ci 93c29fa5a6Sopenharmony_ci static std::shared_ptr<KeyShortcutManager> GetInstance(); 94c29fa5a6Sopenharmony_ci 95c29fa5a6Sopenharmony_ciprivate: 96c29fa5a6Sopenharmony_ci struct SystemKey { 97c29fa5a6Sopenharmony_ci uint32_t modifiers; 98c29fa5a6Sopenharmony_ci int32_t finalKey; 99c29fa5a6Sopenharmony_ci 100c29fa5a6Sopenharmony_ci bool operator<(const SystemKey &other) const; 101c29fa5a6Sopenharmony_ci }; 102c29fa5a6Sopenharmony_ci 103c29fa5a6Sopenharmony_ci struct ExceptionalSystemKey { 104c29fa5a6Sopenharmony_ci std::set<int32_t> preKeys; 105c29fa5a6Sopenharmony_ci int32_t finalKey; 106c29fa5a6Sopenharmony_ci int32_t longPressTime; // ms 107c29fa5a6Sopenharmony_ci ShortcutTriggerType triggerType; 108c29fa5a6Sopenharmony_ci 109c29fa5a6Sopenharmony_ci bool operator<(const ExceptionalSystemKey &other) const; 110c29fa5a6Sopenharmony_ci }; 111c29fa5a6Sopenharmony_ci 112c29fa5a6Sopenharmony_ci struct KeyShortcut { 113c29fa5a6Sopenharmony_ci uint32_t modifiers; 114c29fa5a6Sopenharmony_ci int32_t finalKey; 115c29fa5a6Sopenharmony_ci int32_t longPressTime; // ms 116c29fa5a6Sopenharmony_ci ShortcutTriggerType triggerType; 117c29fa5a6Sopenharmony_ci int32_t session; 118c29fa5a6Sopenharmony_ci std::function<void(std::shared_ptr<KeyEvent>)> callback; 119c29fa5a6Sopenharmony_ci }; 120c29fa5a6Sopenharmony_ci 121c29fa5a6Sopenharmony_ci struct SystemHotkey { 122c29fa5a6Sopenharmony_ci std::set<int32_t> preKeys; 123c29fa5a6Sopenharmony_ci int32_t finalKey; 124c29fa5a6Sopenharmony_ci 125c29fa5a6Sopenharmony_ci bool operator<(const SystemHotkey &other) const; 126c29fa5a6Sopenharmony_ci }; 127c29fa5a6Sopenharmony_ci 128c29fa5a6Sopenharmony_ci void LoadSystemKeys(); 129c29fa5a6Sopenharmony_ci void ReadSystemKeys(const std::string &cfgPath); 130c29fa5a6Sopenharmony_ci int32_t ReadSystemKey(cJSON *jsonSysKey); 131c29fa5a6Sopenharmony_ci int32_t AddSystemKey(const std::set<int32_t> &preKeys, int32_t finalKey); 132c29fa5a6Sopenharmony_ci void LoadExceptionalSystemKeys(); 133c29fa5a6Sopenharmony_ci void ReadExceptionalSystemKeys(const std::string &cfgPath); 134c29fa5a6Sopenharmony_ci int32_t ReadExceptionalSystemKey(cJSON *jsonSysKey); 135c29fa5a6Sopenharmony_ci void AddExceptionalSystemKey(const ExceptionalSystemKey &sysKey); 136c29fa5a6Sopenharmony_ci std::string FormatModifiers(const std::set<int32_t> &modifiers) const; 137c29fa5a6Sopenharmony_ci int32_t GenerateId() const; 138c29fa5a6Sopenharmony_ci bool IsExceptionalSystemKey(const ExceptionalSystemKey &sysKey) const; 139c29fa5a6Sopenharmony_ci bool IsModifier(int32_t keyCode) const; 140c29fa5a6Sopenharmony_ci bool CheckSystemKey(const SystemShortcutKey &key, KeyShortcut &shortcut) const; 141c29fa5a6Sopenharmony_ci bool IsValid(const ShortcutTriggerType triggerType) const; 142c29fa5a6Sopenharmony_ci bool IsReservedSystemKey(const KeyShortcut &shortcut) const; 143c29fa5a6Sopenharmony_ci bool CheckGlobalKey(const HotKey &key, KeyShortcut &shortcut) const; 144c29fa5a6Sopenharmony_ci bool HaveRegisteredGlobalKey(const KeyShortcut &key) const; 145c29fa5a6Sopenharmony_ci std::string FormatPressedKeys(std::shared_ptr<KeyEvent> keyEvent) const; 146c29fa5a6Sopenharmony_ci std::set<int32_t> GetForegroundPids() const; 147c29fa5a6Sopenharmony_ci bool HandleKeyDown(std::shared_ptr<KeyEvent> keyEvent); 148c29fa5a6Sopenharmony_ci bool HandleKeyUp(std::shared_ptr<KeyEvent> keyEvent); 149c29fa5a6Sopenharmony_ci bool HandleKeyCancel(std::shared_ptr<KeyEvent> keyEvent); 150c29fa5a6Sopenharmony_ci bool CheckCombination(std::shared_ptr<KeyEvent> keyEvent, const KeyShortcut &shortcut) const; 151c29fa5a6Sopenharmony_ci bool CheckPureModifiers(std::shared_ptr<KeyEvent> keyEvent, const KeyShortcut &shortcut) const; 152c29fa5a6Sopenharmony_ci bool CheckModifiers(std::shared_ptr<KeyEvent> keyEvent, const KeyShortcut &shortcut) const; 153c29fa5a6Sopenharmony_ci void TriggerDown(std::shared_ptr<KeyEvent> keyEvent, int32_t shortcutId, const KeyShortcut &shortcut); 154c29fa5a6Sopenharmony_ci void RunShortcut(std::shared_ptr<KeyEvent> keyEvent, int32_t shortcutId); 155c29fa5a6Sopenharmony_ci void TriggerUp(std::shared_ptr<KeyEvent> keyEvent, int32_t shortcutId, const KeyShortcut &shortcut); 156c29fa5a6Sopenharmony_ci void ResetTriggering(std::shared_ptr<KeyEvent> keyEvent); 157c29fa5a6Sopenharmony_ci bool WillResetOnKeyDown(int32_t keyCode, const KeyShortcut &shortcut) const; 158c29fa5a6Sopenharmony_ci bool WillResetOnKeyUp(int32_t keyCode, const KeyShortcut &shortcut) const; 159c29fa5a6Sopenharmony_ci void ResetTriggering(int32_t shortcutId); 160c29fa5a6Sopenharmony_ci void LoadHotkeys(); 161c29fa5a6Sopenharmony_ci void ReadHotkeys(const std::string &cfgPath); 162c29fa5a6Sopenharmony_ci int32_t ReadHotkey(cJSON *jsonSysKey); 163c29fa5a6Sopenharmony_ci int32_t AddHotkey(const std::set<int32_t> &preKeys, int32_t finalKey); 164c29fa5a6Sopenharmony_ci 165c29fa5a6Sopenharmony_ci std::set<int32_t> shortcutConsumed_; 166c29fa5a6Sopenharmony_ci std::set<SystemKey> systemKeys_; 167c29fa5a6Sopenharmony_ci std::set<ExceptionalSystemKey> exceptSysKeys_; 168c29fa5a6Sopenharmony_ci std::map<int32_t, KeyShortcut> shortcuts_; 169c29fa5a6Sopenharmony_ci std::map<int32_t, int32_t> triggering_; 170c29fa5a6Sopenharmony_ci static const std::map<int32_t, uint32_t> modifiers_; 171c29fa5a6Sopenharmony_ci static std::mutex mutex_; 172c29fa5a6Sopenharmony_ci static std::shared_ptr<KeyShortcutManager> instance_; 173c29fa5a6Sopenharmony_ci std::set<SystemHotkey> hotkeys_; 174c29fa5a6Sopenharmony_ci bool isCheckShortcut_ { true }; 175c29fa5a6Sopenharmony_ci}; 176c29fa5a6Sopenharmony_ci 177c29fa5a6Sopenharmony_ci#define KEY_SHORTCUT_MGR KeyShortcutManager::GetInstance() 178c29fa5a6Sopenharmony_ci} // namespace MMI 179c29fa5a6Sopenharmony_ci} // namespace OHOS 180c29fa5a6Sopenharmony_ci#endif // KEY_SHORTCUT_MANAGER_H 181