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