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