1 /* 2 * Copyright (C) 2021-2023 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 FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_INPUT_METHOD_UTILS_H 17 #define FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_INPUT_METHOD_UTILS_H 18 19 #include <stdint.h> 20 21 #include <variant> 22 23 #include "global.h" 24 #include "input_attribute.h" 25 #include "panel_info.h" 26 27 namespace OHOS { 28 namespace MiscServices { 29 constexpr uint32_t INVALID_WINDOW_ID = 0; 30 constexpr int32_t INVALID_VALUE = -1; 31 constexpr size_t MAX_PRIVATE_COMMAND_SIZE = 32 * 1024; // 32K 32 constexpr size_t MAX_PRIVATE_COMMAND_COUNT = 5; 33 const constexpr char* SYSTEM_CMD_KEY = "sys_cmd"; 34 enum class EnterKeyType { 35 UNSPECIFIED = 0, 36 NONE, 37 GO, 38 SEARCH, 39 SEND, 40 NEXT, 41 DONE, 42 PREVIOUS, 43 NEW_LINE, 44 }; 45 46 enum class TextInputType { 47 NONE = -1, 48 TEXT = 0, 49 MULTILINE, 50 NUMBER, 51 PHONE, 52 DATETIME, 53 EMAIL_ADDRESS, 54 URL, 55 VISIBLE_PASSWORD, 56 NUMBER_PASSWORD, 57 SCREEN_LOCK_PASSWORD, 58 USER_NAME, 59 NEW_PASSWORD, 60 NUMBER_DECIMAL, 61 }; 62 63 enum class Direction { 64 NONE = 0, 65 UP = 1, 66 DOWN, 67 LEFT, 68 RIGHT, 69 }; 70 71 enum class SecurityMode : int32_t { 72 BASIC = 0, 73 FULL = 1, 74 }; 75 76 enum class ExtendAction { 77 SELECT_ALL = 0, 78 CUT = 3, 79 COPY, 80 PASTE, 81 }; 82 83 class Configuration { 84 public: GetEnterKeyType()85 EnterKeyType GetEnterKeyType() const 86 { 87 return enterKeyType; 88 } 89 SetEnterKeyType(EnterKeyType keyType)90 void SetEnterKeyType(EnterKeyType keyType) 91 { 92 enterKeyType = keyType; 93 } 94 GetTextInputType()95 TextInputType GetTextInputType() const 96 { 97 return textInputType; 98 } 99 SetTextInputType(TextInputType textType)100 void SetTextInputType(TextInputType textType) 101 { 102 textInputType = textType; 103 } 104 105 private: 106 EnterKeyType enterKeyType = EnterKeyType::UNSPECIFIED; 107 TextInputType textInputType = TextInputType::TEXT; 108 }; 109 110 struct CursorInfo { 111 double left = -1.0; 112 double top = -1.0; 113 double width = -1.0; 114 double height = -1.0; 115 bool operator==(const CursorInfo &info) const 116 { 117 return (left == info.left && top == info.top && width == info.width && height == info.height); 118 } 119 }; 120 121 class KeyEvent {}; 122 123 enum class KeyboardStatus : int32_t { NONE = 0, HIDE, SHOW }; // soft keyboard 124 125 enum Trigger : int32_t { IME_APP, IMF, END }; 126 struct PanelStatusInfo { 127 PanelInfo panelInfo; 128 bool visible{ false }; 129 Trigger trigger{ END }; 130 bool operator==(const PanelStatusInfo &info) const 131 { 132 return info.panelInfo.panelFlag == panelInfo.panelFlag && info.panelInfo.panelType == panelInfo.panelType 133 && info.visible == visible && info.trigger == trigger; 134 } 135 }; 136 137 class FunctionKey { 138 public: GetEnterKeyType()139 EnterKeyType GetEnterKeyType() const 140 { 141 return enterKeyType; 142 } 143 SetEnterKeyType(EnterKeyType keyType)144 void SetEnterKeyType(EnterKeyType keyType) 145 { 146 enterKeyType = keyType; 147 } 148 149 private: 150 EnterKeyType enterKeyType = EnterKeyType::UNSPECIFIED; 151 }; 152 153 struct Range { 154 int32_t start = INVALID_VALUE; 155 int32_t end = INVALID_VALUE; 156 bool operator==(const Range &range) const 157 { 158 return start == range.start && end == range.end; 159 } 160 }; 161 162 struct TextSelection { 163 int32_t oldBegin = INVALID_VALUE; 164 int32_t oldEnd = INVALID_VALUE; 165 int32_t newBegin = INVALID_VALUE; 166 int32_t newEnd = INVALID_VALUE; 167 }; 168 169 enum PrivateDataValueType : int32_t { VALUE_TYPE_STRING = 0, VALUE_TYPE_BOOL, VALUE_TYPE_NUMBER }; 170 using PrivateDataValue = std::variant<std::string, bool, int32_t>; 171 172 struct TextTotalConfig { 173 public: 174 InputAttribute inputAttribute = {}; 175 CursorInfo cursorInfo = {}; 176 TextSelection textSelection = {}; 177 uint32_t windowId = INVALID_WINDOW_ID; 178 double positionY = 0; 179 double height = 0; 180 std::unordered_map<std::string, PrivateDataValue> privateCommand = {}; 181 ToStringTextTotalConfig182 std::string ToString() const 183 { 184 std::string config; 185 config.append("pattern/enterKey/preview: " + std::to_string(inputAttribute.inputPattern) + "/" 186 + std::to_string(inputAttribute.enterKeyType) + "/" 187 + std::to_string(inputAttribute.isTextPreviewSupported)); 188 config.append(" windowId/y/height: " + std::to_string(windowId) + "/" + std::to_string(positionY) + "/" 189 + std::to_string(height)); 190 config.append( 191 " oldRange: " + std::to_string(textSelection.oldBegin) + "/" + std::to_string(textSelection.oldEnd)); 192 config.append( 193 " newRange: " + std::to_string(textSelection.newBegin) + "/" + std::to_string(textSelection.newEnd)); 194 config.append(" cursor: " + std::to_string(cursorInfo.left) + "/" + std::to_string(cursorInfo.top) + "/" 195 + std::to_string(cursorInfo.width) + "/" + std::to_string(cursorInfo.height)); 196 return config; 197 } 198 }; 199 struct TextConfig { 200 InputAttribute inputAttribute = {}; 201 CursorInfo cursorInfo = {}; 202 Range range = {}; 203 uint32_t windowId = INVALID_WINDOW_ID; 204 double positionY = 0; 205 double height = 0; 206 std::unordered_map<std::string, PrivateDataValue> privateCommand = {}; 207 ToStringTextConfig208 std::string ToString() const 209 { 210 std::string config; 211 config.append("pattern/enterKey/preview: " + std::to_string(inputAttribute.inputPattern) + "/" 212 + std::to_string(inputAttribute.enterKeyType) + "/" 213 + std::to_string(inputAttribute.isTextPreviewSupported)); 214 config.append(" windowId/y/height: " + std::to_string(windowId) + "/" + std::to_string(positionY) + "/" 215 + std::to_string(height)); 216 config.append(" range: " + std::to_string(range.start) + "/" + std::to_string(range.end)); 217 config.append(" cursor: " + std::to_string(cursorInfo.left) + "/" + std::to_string(cursorInfo.top) + "/" 218 + std::to_string(cursorInfo.width) + "/" + std::to_string(cursorInfo.height)); 219 return config; 220 } 221 IsPrivateCommandValidTextConfig222 static bool IsPrivateCommandValid(const std::unordered_map<std::string, PrivateDataValue> &privateCommand) 223 { 224 size_t privateCommandSize = privateCommand.size(); 225 size_t maxSize = IsSystemPrivateCommand(privateCommand) ? (MAX_PRIVATE_COMMAND_COUNT + 1) 226 : MAX_PRIVATE_COMMAND_COUNT; 227 if (privateCommandSize == 0 || privateCommandSize > maxSize) { 228 IMSA_HILOGE("privateCommand size must more than 0 and less than 5."); 229 return false; 230 } 231 size_t totalSize = 0; 232 for (const auto &iter : privateCommand) { 233 size_t keySize = iter.first.size(); 234 size_t idx = iter.second.index(); 235 size_t valueSize = 0; 236 237 if (idx == static_cast<size_t>(PrivateDataValueType::VALUE_TYPE_STRING)) { 238 auto stringValue = std::get_if<std::string>(&iter.second); 239 if (stringValue == nullptr) { 240 IMSA_HILOGE("get stringValue failed."); 241 return false; 242 } 243 valueSize = (*stringValue).size(); 244 } else if (idx == static_cast<size_t>(PrivateDataValueType::VALUE_TYPE_BOOL)) { 245 valueSize = sizeof(bool); 246 } else if (idx == static_cast<size_t>(PrivateDataValueType::VALUE_TYPE_NUMBER)) { 247 valueSize = sizeof(int32_t); 248 } 249 totalSize = totalSize + keySize + valueSize; 250 } 251 if (totalSize > MAX_PRIVATE_COMMAND_SIZE) { 252 IMSA_HILOGE("totalSize : %{public}zu", totalSize); 253 return false; 254 } 255 return true; 256 } IsSystemPrivateCommandTextConfig257 static bool IsSystemPrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand) 258 { 259 IMSA_HILOGD("in."); 260 size_t privateCommandSize = privateCommand.size(); 261 if (privateCommandSize == 0 || privateCommandSize > MAX_PRIVATE_COMMAND_COUNT) { 262 IMSA_HILOGE("privateCommand size must more than 0 and less than 5."); 263 return false; 264 } 265 auto it = privateCommand.find(SYSTEM_CMD_KEY); 266 if (it != privateCommand.end()) { 267 // if privateCommand has the key system_cmd and value is 1, it's a system privateCommand. 268 if (it->second.index() == static_cast<size_t>(PrivateDataValueType::VALUE_TYPE_NUMBER)) { 269 auto numberValue = std::get_if<int32_t>(&it->second); 270 if (numberValue == nullptr) { 271 IMSA_HILOGE("get stringValue failed."); 272 return false; 273 } 274 return *numberValue == 1; 275 } 276 } 277 return false; 278 } 279 }; 280 281 enum class InputType : int32_t { NONE = -1, CAMERA_INPUT = 0, SECURITY_INPUT, VOICE_INPUT, END }; 282 283 enum class SwitchTrigger : uint32_t { CURRENT_IME = 0, SYSTEM_APP, IMSA, NATIVE_SA}; 284 } // namespace MiscServices 285 } // namespace OHOS 286 #endif // FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_INPUT_METHOD_UTILS_H 287