1 /*
2 * Copyright (c) 2024 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 #include "input_method_controller.h"
16 #include "native_message_handler_callback.h"
17 #include "native_inputmethod_types.h"
18 #include "native_inputmethod_utils.h"
19 #include "string_ex.h"
20 #ifdef __cplusplus
21 extern "C" {
22 #endif /* __cplusplus */
23 using namespace OHOS;
24 using namespace OHOS::MiscServices;
25 constexpr size_t INVALID_MSG_ID_SIZE = 256; // 256B
26 constexpr size_t INVALID_MSG_PARAM_SIZE = 128 * 1024; // 128KB
IsValidMessageHandlerProxy(InputMethod_MessageHandlerProxy * messageHandler)27 static int32_t IsValidMessageHandlerProxy(InputMethod_MessageHandlerProxy *messageHandler)
28 {
29 if (messageHandler == nullptr) {
30 IMSA_HILOGE("messageHandler is nullptr");
31 return IME_ERR_OK;
32 }
33 if (messageHandler->onTerminatedFunc == nullptr) {
34 IMSA_HILOGE("onTerminatedFunc is nullptr");
35 return IME_ERR_NULL_POINTER;
36 }
37 if (messageHandler->onMessageFunc == nullptr) {
38 IMSA_HILOGE("onMessageFunc is nullptr");
39 return IME_ERR_NULL_POINTER;
40 }
41 return IME_ERR_OK;
42 }
43
OH_InputMethodProxy_ShowKeyboard(InputMethod_InputMethodProxy * inputMethodProxy)44 InputMethod_ErrorCode OH_InputMethodProxy_ShowKeyboard(InputMethod_InputMethodProxy *inputMethodProxy)
45 {
46 auto errCode = IsValidInputMethodProxy(inputMethodProxy);
47 if (errCode != IME_ERR_OK) {
48 IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
49 return errCode;
50 }
51 return ErrorCodeConvert(InputMethodController::GetInstance()->ShowCurrentInput());
52 }
53
OH_InputMethodProxy_ShowTextInput(InputMethod_InputMethodProxy * inputMethodProxy,InputMethod_AttachOptions * options)54 InputMethod_ErrorCode OH_InputMethodProxy_ShowTextInput(
55 InputMethod_InputMethodProxy *inputMethodProxy, InputMethod_AttachOptions *options)
56 {
57 auto errCode = IsValidInputMethodProxy(inputMethodProxy);
58 if (errCode != IME_ERR_OK || options == nullptr) {
59 IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
60 return errCode;
61 }
62 AttachOptions attachOptions;
63 attachOptions.isShowKeyboard = options->showKeyboard;
64 attachOptions.requestKeyboardReason =
65 static_cast<RequestKeyboardReason>(static_cast<int32_t>(options->requestKeyboardReason));
66 return ErrorCodeConvert(InputMethodController::GetInstance()->ShowTextInput(attachOptions));
67 }
68
OH_InputMethodProxy_HideKeyboard(InputMethod_InputMethodProxy * inputMethodProxy)69 InputMethod_ErrorCode OH_InputMethodProxy_HideKeyboard(InputMethod_InputMethodProxy *inputMethodProxy)
70 {
71 auto errCode = IsValidInputMethodProxy(inputMethodProxy);
72 if (errCode != IME_ERR_OK) {
73 IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
74 return errCode;
75 }
76 return ErrorCodeConvert(InputMethodController::GetInstance()->HideCurrentInput());
77 }
OH_InputMethodProxy_NotifySelectionChange(InputMethod_InputMethodProxy * inputMethodProxy,char16_t text[],size_t length,int start,int end)78 InputMethod_ErrorCode OH_InputMethodProxy_NotifySelectionChange(
79 InputMethod_InputMethodProxy *inputMethodProxy, char16_t text[], size_t length, int start, int end)
80 {
81 auto errCode = IsValidInputMethodProxy(inputMethodProxy);
82 if (errCode != IME_ERR_OK) {
83 IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
84 return errCode;
85 }
86 if (text == nullptr) {
87 IMSA_HILOGE("text is nullptr");
88 return IME_ERR_NULL_POINTER;
89 }
90
91 if (length > MAX_TEXT_LENGTH) {
92 IMSA_HILOGE("text length is too long length=%{public}zu", length);
93 return IME_ERR_PARAMCHECK;
94 }
95 return ErrorCodeConvert(
96 InputMethodController::GetInstance()->OnSelectionChange(std::u16string(text, length), start, end));
97 }
OH_InputMethodProxy_NotifyConfigurationChange(InputMethod_InputMethodProxy * inputMethodProxy,InputMethod_EnterKeyType enterKey,InputMethod_TextInputType textType)98 InputMethod_ErrorCode OH_InputMethodProxy_NotifyConfigurationChange(InputMethod_InputMethodProxy *inputMethodProxy,
99 InputMethod_EnterKeyType enterKey, InputMethod_TextInputType textType)
100 {
101 auto errCode = IsValidInputMethodProxy(inputMethodProxy);
102 if (errCode != IME_ERR_OK) {
103 IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
104 return errCode;
105 }
106 Configuration info;
107 info.SetEnterKeyType(static_cast<EnterKeyType>(enterKey));
108 info.SetTextInputType(static_cast<TextInputType>(textType));
109 return ErrorCodeConvert(InputMethodController::GetInstance()->OnConfigurationChange(info));
110 }
111
OH_InputMethodProxy_NotifyCursorUpdate(InputMethod_InputMethodProxy * inputMethodProxy,InputMethod_CursorInfo * cursorInfo)112 InputMethod_ErrorCode OH_InputMethodProxy_NotifyCursorUpdate(
113 InputMethod_InputMethodProxy *inputMethodProxy, InputMethod_CursorInfo *cursorInfo)
114 {
115 auto errCode = IsValidInputMethodProxy(inputMethodProxy);
116 if (errCode != IME_ERR_OK) {
117 IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
118 return errCode;
119 }
120 if (cursorInfo == nullptr) {
121 IMSA_HILOGE("cursorInfo is nullptr");
122 return IME_ERR_NULL_POINTER;
123 }
124 return ErrorCodeConvert(InputMethodController::GetInstance()->OnCursorUpdate(
125 CursorInfo({ cursorInfo->left, cursorInfo->top, cursorInfo->width, cursorInfo->height })));
126 }
127
OH_InputMethodProxy_SendPrivateCommand(InputMethod_InputMethodProxy * inputMethodProxy,InputMethod_PrivateCommand * privateCommand[],size_t size)128 InputMethod_ErrorCode OH_InputMethodProxy_SendPrivateCommand(
129 InputMethod_InputMethodProxy *inputMethodProxy, InputMethod_PrivateCommand *privateCommand[], size_t size)
130 {
131 auto errCode = IsValidInputMethodProxy(inputMethodProxy);
132 if (errCode != IME_ERR_OK) {
133 IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
134 return errCode;
135 }
136 if (privateCommand == nullptr) {
137 IMSA_HILOGE("privateCommand is nullptr");
138 return IME_ERR_NULL_POINTER;
139 }
140
141 std::unordered_map<std::string, PrivateDataValue> command;
142
143 for (size_t i = 0; i < size; i++) {
144 if (privateCommand[i] == nullptr) {
145 IMSA_HILOGE("privateCommand[%zu] is nullptr", i);
146 return IME_ERR_NULL_POINTER;
147 }
148 command.emplace(privateCommand[i]->key, privateCommand[i]->value);
149 }
150 return ErrorCodeConvert(InputMethodController::GetInstance()->SendPrivateCommand(command));
151 }
152
OH_InputMethodProxy_SendMessage(InputMethod_InputMethodProxy * inputMethodProxy,const char16_t * msgId,size_t msgIdLength,const uint8_t * msgParam,size_t msgParamLength)153 InputMethod_ErrorCode OH_InputMethodProxy_SendMessage(InputMethod_InputMethodProxy *inputMethodProxy,
154 const char16_t *msgId, size_t msgIdLength, const uint8_t *msgParam, size_t msgParamLength)
155 {
156 auto errCode = IsValidInputMethodProxy(inputMethodProxy);
157 if (errCode != IME_ERR_OK) {
158 IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
159 return errCode;
160 }
161 if (msgId == nullptr || msgParam == nullptr) {
162 IMSA_HILOGE("msgId or msgParam is nullptr");
163 return IME_ERR_NULL_POINTER;
164 }
165 if (msgIdLength > INVALID_MSG_ID_SIZE || msgParamLength > INVALID_MSG_PARAM_SIZE) {
166 IMSA_HILOGE("ArrayBuffer size is invalid, msgIdLength: %{public}zu, msgParamLength: %{public}zu",
167 msgIdLength, msgParamLength);
168 return IME_ERR_PARAMCHECK;
169 }
170 ArrayBuffer arrayBuffer;
171 std::u16string msgIdStr(msgId, msgIdLength);
172 arrayBuffer.msgId = Str16ToStr8(msgIdStr);
173 arrayBuffer.msgParam.assign(msgParam, msgParam + msgParamLength);
174 return ErrorCodeConvert(InputMethodController::GetInstance()->SendMessage(arrayBuffer));
175 }
176
OH_InputMethodProxy_RecvMessage(InputMethod_InputMethodProxy * inputMethodProxy,InputMethod_MessageHandlerProxy * messageHandler)177 InputMethod_ErrorCode OH_InputMethodProxy_RecvMessage(
178 InputMethod_InputMethodProxy *inputMethodProxy, InputMethod_MessageHandlerProxy *messageHandler)
179 {
180 auto errCode = IsValidInputMethodProxy(inputMethodProxy);
181 if (errCode != IME_ERR_OK) {
182 IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
183 return errCode;
184 }
185 if (IsValidMessageHandlerProxy(messageHandler) != IME_ERR_OK) {
186 IMSA_HILOGE("invalid messageHandler");
187 return IME_ERR_NULL_POINTER;
188 }
189 if (messageHandler == nullptr) {
190 IMSA_HILOGI("UnRegister message handler.");
191 return ErrorCodeConvert(InputMethodController::GetInstance()->RegisterMsgHandler(nullptr));
192 }
193 IMSA_HILOGI("Register message handler.");
194 std::shared_ptr<MsgHandlerCallbackInterface> msgHandler =
195 std::make_shared<NativeMessageHandlerCallback>(messageHandler);
196 return ErrorCodeConvert(InputMethodController::GetInstance()->RegisterMsgHandler(msgHandler));
197 }
198 #ifdef __cplusplus
199 }
200 #endif /* __cplusplus */