• 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 #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