• 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 "iremote_object.h"
25 #include "panel_info.h"
26 #include "key_event.h"
27 
28 namespace OHOS {
29 namespace MiscServices {
30 constexpr uint32_t INVALID_WINDOW_ID = 0;
31 constexpr int32_t INVALID_VALUE = -1;
32 constexpr size_t MAX_PRIVATE_COMMAND_SIZE = 32 * 1024; // 32K
33 constexpr size_t MAX_PRIVATE_COMMAND_COUNT = 5;
34 constexpr size_t MAX_SYS_PRIVATE_COMMAND_COUNT = MAX_PRIVATE_COMMAND_COUNT + 1;
35 constexpr size_t MAX_VALUE_MAP_COUNT = 256;
36 constexpr size_t MAX_ARRAY_BUFFER_MSG_ID_SIZE = 256; // 256B
37 constexpr size_t MAX_ARRAY_BUFFER_MSG_PARAM_SIZE = 128 * 1024; // 128KB
38 static constexpr uint64_t INVALID_DISPLAY_ID = -1ULL;
39 const constexpr char *SYSTEM_CMD_KEY = "sys_cmd";
40 enum class EnterKeyType {
41     UNSPECIFIED = 0,
42     NONE,
43     GO,
44     SEARCH,
45     SEND,
46     NEXT,
47     DONE,
48     PREVIOUS,
49     NEW_LINE,
50 };
51 
52 enum class TextInputType {
53     NONE = -1,
54     TEXT = 0,
55     MULTILINE,
56     NUMBER,
57     PHONE,
58     DATETIME,
59     EMAIL_ADDRESS,
60     URL,
61     VISIBLE_PASSWORD,
62     NUMBER_PASSWORD,
63     SCREEN_LOCK_PASSWORD,
64     USER_NAME,
65     NEW_PASSWORD,
66     NUMBER_DECIMAL,
67     ONE_TIME_CODE,
68 };
69 
70 enum class Direction {
71     NONE = 0,
72     UP = 1,
73     DOWN,
74     LEFT,
75     RIGHT,
76 };
77 
78 enum class SecurityMode : int32_t {
79     BASIC = 0,
80     FULL = 1,
81 };
82 
83 enum class ExtendAction {
84     SELECT_ALL = 0,
85     CUT = 3,
86     COPY,
87     PASTE,
88 };
89 
90 enum class CapacityType: int32_t {
91     IMMERSIVE_EFFECT,
92     END,
93 };
94 
95 class Configuration {
96 public:
GetEnterKeyType()97     EnterKeyType GetEnterKeyType() const
98     {
99         return enterKeyType;
100     }
101 
SetEnterKeyType(EnterKeyType keyType)102     void SetEnterKeyType(EnterKeyType keyType)
103     {
104         enterKeyType = keyType;
105     }
106 
GetTextInputType()107     TextInputType GetTextInputType() const
108     {
109         return textInputType;
110     }
111 
SetTextInputType(TextInputType textType)112     void SetTextInputType(TextInputType textType)
113     {
114         textInputType = textType;
115     }
116 
117 private:
118     EnterKeyType enterKeyType = EnterKeyType::UNSPECIFIED;
119     TextInputType textInputType = TextInputType::TEXT;
120 };
121 
122 struct CursorInfo {
123     double left = -1.0;
124     double top = -1.0;
125     double width = -1.0;
126     double height = -1.0;
127     bool operator==(const CursorInfo &info) const
128     {
129         return (left == info.left && top == info.top && width == info.width && height == info.height);
130     }
131 };
132 
133 struct CursorInfoInner : public Parcelable {
134     double left = -1.0;
135     double top = -1.0;
136     double width = -1.0;
137     double height = -1.0;
138     bool operator==(const CursorInfoInner &info) const
139     {
140         return (left == info.left && top == info.top && width == info.width && height == info.height);
141     }
142 
ReadFromParcelCursorInfoInner143     bool ReadFromParcel(Parcel &in)
144     {
145         left = in.ReadDouble();
146         top = in.ReadDouble();
147         width = in.ReadDouble();
148         height = in.ReadDouble();
149         return true;
150     }
151 
MarshallingCursorInfoInner152     bool Marshalling(Parcel &out) const
153     {
154         if (!out.WriteDouble(left)) {
155             return false;
156         }
157 
158         if (!out.WriteDouble(top)) {
159             return false;
160         }
161 
162         if (!out.WriteDouble(width)) {
163             return false;
164         }
165 
166         if (!out.WriteDouble(height)) {
167             return false;
168         }
169         return true;
170     }
171 
UnmarshallingCursorInfoInner172     static CursorInfoInner *Unmarshalling(Parcel &in)
173     {
174         CursorInfoInner *data = new (std::nothrow) CursorInfoInner();
175         if (data && !data->ReadFromParcel(in)) {
176             delete data;
177             data = nullptr;
178         }
179         return data;
180     }
181 };
182 
183 class KeyEvent { };
184 
185 enum class KeyboardStatus : int32_t {
186     NONE = 0,
187     HIDE,
188     SHOW
189 }; // soft keyboard
190 
191 enum Trigger : int32_t {
192     IME_APP,
193     IMF,
194     END
195 };
196 struct PanelStatusInfo {
197     PanelInfo panelInfo;
198     bool visible { false };
199     Trigger trigger { END };
200     uint32_t sessionId { 0 };
201     bool operator==(const PanelStatusInfo &info) const
202     {
203         return info.panelInfo.panelFlag == panelInfo.panelFlag && info.panelInfo.panelType == panelInfo.panelType &&
204             info.visible == visible && info.trigger == trigger;
205     }
206 };
207 
208 struct PanelStatusInfoInner : public Parcelable {
209     PanelInfo panelInfo;
210     bool visible { false };
211     Trigger trigger { END };
212     uint32_t sessionId { 0 };
213     bool operator==(const PanelStatusInfoInner &info) const
214     {
215         return info.panelInfo.panelFlag == panelInfo.panelFlag && info.panelInfo.panelType == panelInfo.panelType &&
216             info.visible == visible && info.trigger == trigger;
217     }
218 
219     bool ReadFromParcel(Parcel &in);
220     bool Marshalling(Parcel &out) const;
221     static PanelStatusInfoInner *Unmarshalling(Parcel &in);
222 };
223 
224 class FunctionKey {
225 public:
GetEnterKeyType()226     EnterKeyType GetEnterKeyType() const
227     {
228         return enterKeyType;
229     }
230 
SetEnterKeyType(EnterKeyType keyType)231     void SetEnterKeyType(EnterKeyType keyType)
232     {
233         enterKeyType = keyType;
234     }
235 
236 private:
237     EnterKeyType enterKeyType = EnterKeyType::UNSPECIFIED;
238 };
239 
240 struct Range {
241     int32_t start = INVALID_VALUE;
242     int32_t end = INVALID_VALUE;
243     bool operator==(const Range &range) const
244     {
245         return start == range.start && end == range.end;
246     }
247 };
248 
249 struct RangeInner : public Parcelable {
250     int32_t start = INVALID_VALUE;
251     int32_t end = INVALID_VALUE;
252     bool operator==(const RangeInner &range) const
253     {
254         return start == range.start && end == range.end;
255     }
ReadFromParcelRangeInner256     bool ReadFromParcel(Parcel &in)
257     {
258         start = in.ReadInt32();
259         end = in.ReadInt32();
260         return true;
261     }
MarshallingRangeInner262     bool Marshalling(Parcel &out) const
263     {
264         if (!out.WriteInt32(start)) {
265             return false;
266         }
267 
268         if (!out.WriteInt32(end)) {
269             return false;
270         }
271         return true;
272     }
UnmarshallingRangeInner273     static RangeInner *Unmarshalling(Parcel &in)
274     {
275         RangeInner *data = new (std::nothrow) RangeInner();
276         if (data && !data->ReadFromParcel(in)) {
277             delete data;
278             data = nullptr;
279         }
280         return data;
281     }
282 };
283 
284 struct TextSelection {
285     int32_t oldBegin = INVALID_VALUE;
286     int32_t oldEnd = INVALID_VALUE;
287     int32_t newBegin = INVALID_VALUE;
288     int32_t newEnd = INVALID_VALUE;
289 };
290 
291 struct TextSelectionInner : public Parcelable {
292     int32_t oldBegin = INVALID_VALUE;
293     int32_t oldEnd = INVALID_VALUE;
294     int32_t newBegin = INVALID_VALUE;
295     int32_t newEnd = INVALID_VALUE;
296 
297     bool ReadFromParcel(Parcel &in);
298     bool Marshalling(Parcel &out) const;
299     static TextSelectionInner *Unmarshalling(Parcel &in);
300 };
301 
302 enum PrivateDataValueType : int32_t {
303     VALUE_TYPE_STRING = 0,
304     VALUE_TYPE_BOOL,
305     VALUE_TYPE_NUMBER
306 };
307 using PrivateDataValue = std::variant<std::string, bool, int32_t>;
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 using ValueMap = std::unordered_map<std::string, PrivateDataValue>;
317 
318 struct Value : public Parcelable {
ValueValue319     Value(const std::unordered_map<std::string, PrivateDataValue>& map) : valueMap(map) {}
320     Value() = default;
321     bool ReadFromParcel(Parcel &in);
322     bool Marshalling(Parcel &out) const override;
323     static Value *Unmarshalling(Parcel &in);
324 
325     ValueMap valueMap;
326 };
327 
328 struct KeyEventValue : public Parcelable {
329     bool ReadFromParcel(Parcel &in);
330     bool Marshalling(Parcel &out) const override;
331     static KeyEventValue *Unmarshalling(Parcel &in);
332 
333     std::shared_ptr<MMI::KeyEvent> event;
334 };
335 struct TextTotalConfig {
336 public:
337     InputAttribute inputAttribute = {};
338     CursorInfo cursorInfo = {};
339     TextSelection textSelection = {};
340     uint32_t windowId = INVALID_WINDOW_ID;
341     double positionY = 0;
342     double height = 0;
343     std::unordered_map<std::string, PrivateDataValue> privateCommand = {};
344     RequestKeyboardReason requestKeyboardReason = RequestKeyboardReason::NONE;
345     sptr<IRemoteObject> abilityToken { nullptr };
346     bool isSimpleKeyboardEnabled { false }; // indicates enable basic keyboard or not
347 
ToStringTextTotalConfig348     std::string ToString() const
349     {
350         std::string config;
351         config.append("pattern/enterKey/preview: " + std::to_string(inputAttribute.inputPattern) + "/" +
352             std::to_string(inputAttribute.enterKeyType) + "/" + std::to_string(inputAttribute.isTextPreviewSupported));
353         config.append(" windowId/y/height: " + std::to_string(windowId) + "/" + std::to_string(positionY) + "/" +
354             std::to_string(height));
355         config.append(
356             " oldRange: " + std::to_string(textSelection.oldBegin) + "/" + std::to_string(textSelection.oldEnd));
357         config.append(
358             " newRange: " + std::to_string(textSelection.newBegin) + "/" + std::to_string(textSelection.newEnd));
359         config.append(" cursor: " + std::to_string(cursorInfo.left) + "/" + std::to_string(cursorInfo.top) + "/" +
360             std::to_string(cursorInfo.width) + "/" + std::to_string(cursorInfo.height));
361         return config;
362     }
363 };
364 
365 struct TextTotalConfigInner : public Parcelable  {
366 public:
367     InputAttributeInner inputAttribute = {};
368     CursorInfoInner cursorInfo = {};
369     TextSelectionInner textSelection = {};
370     uint32_t windowId = INVALID_WINDOW_ID;
371     double positionY = 0;
372     double height = 0;
373     Value commandValue;
374     RequestKeyboardReason requestKeyboardReason = RequestKeyboardReason::NONE;
375     bool isSimpleKeyboardEnabled = false;
376     sptr<IRemoteObject> abilityToken { nullptr };
377 
378     bool ReadFromParcel(Parcel &parcel);
379     bool Marshalling(Parcel &parcel) const override;
380     static TextTotalConfigInner *Unmarshalling(Parcel &parcel);
381 
ToStringTextTotalConfigInner382     std::string ToString() const
383     {
384         std::string config;
385         config.append("pattern/enterKey/preview: " + std::to_string(inputAttribute.inputPattern) + "/" +
386             std::to_string(inputAttribute.enterKeyType) + "/" + std::to_string(inputAttribute.isTextPreviewSupported));
387         config.append(" windowId/y/height: " + std::to_string(windowId) + "/" + std::to_string(positionY) + "/" +
388             std::to_string(height));
389         config.append(
390             " oldRange: " + std::to_string(textSelection.oldBegin) + "/" + std::to_string(textSelection.oldEnd));
391         config.append(
392             " newRange: " + std::to_string(textSelection.newBegin) + "/" + std::to_string(textSelection.newEnd));
393         config.append(" cursor: " + std::to_string(cursorInfo.left) + "/" + std::to_string(cursorInfo.top) + "/" +
394             std::to_string(cursorInfo.width) + "/" + std::to_string(cursorInfo.height));
395         return config;
396     }
397 };
398 struct TextConfig {
399     InputAttribute inputAttribute = {};
400     CursorInfo cursorInfo = {};
401     Range range = {};
402     uint32_t windowId = INVALID_WINDOW_ID;
403     double positionY = 0;
404     double height = 0;
405     bool newEditBox = false;
406     std::unordered_map<std::string, PrivateDataValue> privateCommand = {};
407     sptr<IRemoteObject> abilityToken { nullptr };
408 
ToStringTextConfig409     std::string ToString() const
410     {
411         std::string config;
412         config.append("pattern/enterKey/preview: " + std::to_string(inputAttribute.inputPattern) + "/" +
413             std::to_string(inputAttribute.enterKeyType) + "/" + std::to_string(inputAttribute.isTextPreviewSupported));
414         config.append(" windowId/y/height: " + std::to_string(windowId) + "/" + std::to_string(positionY) + "/" +
415             std::to_string(height));
416         config.append(" range: " + std::to_string(range.start) + "/" + std::to_string(range.end));
417         config.append(" cursor: " + std::to_string(cursorInfo.left) + "/" + std::to_string(cursorInfo.top) + "/" +
418             std::to_string(cursorInfo.width) + "/" + std::to_string(cursorInfo.height));
419         return config;
420     }
421 
IsPrivateCommandValidTextConfig422     static bool IsPrivateCommandValid(const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
423     {
424         size_t privateCommandSize = privateCommand.size();
425         size_t maxSize =
426             IsSystemPrivateCommand(privateCommand) ? MAX_SYS_PRIVATE_COMMAND_COUNT : MAX_PRIVATE_COMMAND_COUNT;
427         if (privateCommandSize == 0 || privateCommandSize > maxSize) {
428             IMSA_HILOGE("privateCommand size must more than 0 and less than 5.");
429             return false;
430         }
431         size_t totalSize = 0;
432         for (const auto &iter : privateCommand) {
433             size_t keySize = iter.first.size();
434             size_t idx = iter.second.index();
435             size_t valueSize = 0;
436 
437             if (idx == static_cast<size_t>(PrivateDataValueType::VALUE_TYPE_STRING)) {
438                 auto stringValue = std::get_if<std::string>(&iter.second);
439                 if (stringValue == nullptr) {
440                     IMSA_HILOGE("get stringValue failed.");
441                     return false;
442                 }
443                 valueSize = (*stringValue).size();
444             } else if (idx == static_cast<size_t>(PrivateDataValueType::VALUE_TYPE_BOOL)) {
445                 valueSize = sizeof(bool);
446             } else if (idx == static_cast<size_t>(PrivateDataValueType::VALUE_TYPE_NUMBER)) {
447                 valueSize = sizeof(int32_t);
448             }
449             totalSize = totalSize + keySize + valueSize;
450         }
451         if (totalSize > MAX_PRIVATE_COMMAND_SIZE) {
452             IMSA_HILOGE("totalSize : %{public}zu", totalSize);
453             return false;
454         }
455         return true;
456     }
IsSystemPrivateCommandTextConfig457     static bool IsSystemPrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
458     {
459         IMSA_HILOGD("in.");
460         size_t privateCommandSize = privateCommand.size();
461         if (privateCommandSize == 0 || privateCommandSize > MAX_PRIVATE_COMMAND_COUNT) {
462             IMSA_HILOGE("privateCommand size must more than 0 and less than 5.");
463             return false;
464         }
465         auto it = privateCommand.find(SYSTEM_CMD_KEY);
466         if (it != privateCommand.end()) {
467             // if privateCommand has the key system_cmd and value is 1, it's a system privateCommand.
468             if (it->second.index() == static_cast<size_t>(PrivateDataValueType::VALUE_TYPE_NUMBER)) {
469                 auto numberValue = std::get_if<int32_t>(&it->second);
470                 if (numberValue == nullptr) {
471                     IMSA_HILOGE("get stringValue failed.");
472                     return false;
473                 }
474                 return *numberValue == 1;
475             }
476         }
477         return false;
478     }
479 };
480 
481 enum class InputType : int32_t {
482     NONE = -1,
483     CAMERA_INPUT = 0,
484     SECURITY_INPUT,
485     VOICE_INPUT,
486     VOICEKB_INPUT,
487     END
488 };
489 
490 enum class SwitchTrigger : uint32_t {
491     CURRENT_IME = 0,
492     SYSTEM_APP,
493     IMSA,
494     NATIVE_SA
495 };
496 
497 struct ArrayBuffer : public Parcelable {
498     size_t jsArgc = 0;
499     std::string msgId;
500     std::vector<uint8_t> msgParam;
IsSizeValidArrayBuffer501     static bool IsSizeValid(const ArrayBuffer &arrayBuffer)
502     {
503         if (arrayBuffer.msgId.size() > MAX_ARRAY_BUFFER_MSG_ID_SIZE) {
504             IMSA_HILOGE("Invalid msgId size: %{public}zu.", arrayBuffer.msgId.size());
505             return false;
506         }
507         if (arrayBuffer.msgParam.size() > MAX_ARRAY_BUFFER_MSG_PARAM_SIZE) {
508             IMSA_HILOGE("Invalid msgParam size: %{public}zu.", arrayBuffer.msgParam.size());
509             return false;
510         }
511         return true;
512     }
513     bool operator==(const ArrayBuffer &arrayBuffer) const
514     {
515         return jsArgc == arrayBuffer.jsArgc && msgId == arrayBuffer.msgId && msgParam == arrayBuffer.msgParam;
516     }
517     bool ReadFromParcel(Parcel &in);
518     bool Marshalling(Parcel &out) const;
519     static ArrayBuffer *Unmarshalling(Parcel &in);
520 };
521 
522 struct AttachOptions {
523     bool isShowKeyboard = false;
524     bool isSimpleKeyboardEnabled = false;
525     RequestKeyboardReason requestKeyboardReason { RequestKeyboardReason::NONE };
526 };
527 struct ImfCallingWindowInfo {
528     uint32_t windowId = INVALID_WINDOW_ID;
529     uint64_t displayId = 0;
530 };
531 
532 struct DetachOptions {
533     uint32_t sessionId{ 0 };
534     bool isUnbindFromClient{ false };
535     bool isInactiveClient{ false };
536     bool isNotifyClientAsync{ false };
537 };
538 
539 enum class ResponseDataType : uint64_t { NONE_TYPE = 0, STRING_TYPE, INT32_TYPE };
540 
541 using ResponseData = std::variant<std::monostate, std::string, int32_t>;
542 
543 struct ResponseDataInner : public Parcelable {
544     bool ReadFromParcel(Parcel &in);
545     bool Marshalling(Parcel &out) const override;
UnmarshallingResponseDataInner546     static ResponseDataInner *Unmarshalling(Parcel &in)
547     {
548         ResponseDataInner *data = new (std::nothrow) ResponseDataInner();
549         if (data != nullptr && !data->ReadFromParcel(in)) {
550             delete data;
551             data = nullptr;
552         }
553         return data;
554     }
555     ResponseData rspData = std::monostate{};
556 };
557 } // namespace MiscServices
558 } // namespace OHOS
559 #endif // FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_INPUT_METHOD_UTILS_H
560