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