• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     auto instance = InputMethodController::GetInstance();
52     if (instance == nullptr) {
53         IMSA_HILOGE("InputMethodController is nullptr");
54         return IME_ERR_NULL_POINTER;
55     }
56     return ErrorCodeConvert(instance->ShowCurrentInput());
57 }
58 
OH_InputMethodProxy_ShowTextInput(InputMethod_InputMethodProxy * inputMethodProxy,InputMethod_AttachOptions * options)59 InputMethod_ErrorCode OH_InputMethodProxy_ShowTextInput(
60     InputMethod_InputMethodProxy *inputMethodProxy, InputMethod_AttachOptions *options)
61 {
62     auto errCode = IsValidInputMethodProxy(inputMethodProxy);
63     if (errCode != IME_ERR_OK || options == nullptr) {
64         IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
65         return errCode;
66     }
67     AttachOptions attachOptions;
68     attachOptions.isShowKeyboard = options->showKeyboard;
69     attachOptions.requestKeyboardReason =
70         static_cast<RequestKeyboardReason>(static_cast<int32_t>(options->requestKeyboardReason));
71     auto instance = InputMethodController::GetInstance();
72     if (instance == nullptr) {
73         IMSA_HILOGE("InputMethodController is nullptr");
74         return IME_ERR_NULL_POINTER;
75     }
76     return ErrorCodeConvert(instance->ShowTextInput(attachOptions));
77 }
78 
OH_InputMethodProxy_HideKeyboard(InputMethod_InputMethodProxy * inputMethodProxy)79 InputMethod_ErrorCode OH_InputMethodProxy_HideKeyboard(InputMethod_InputMethodProxy *inputMethodProxy)
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     auto instance = InputMethodController::GetInstance();
87     if (instance == nullptr) {
88         IMSA_HILOGE("InputMethodController is nullptr");
89         return IME_ERR_NULL_POINTER;
90     }
91     return ErrorCodeConvert(instance->HideCurrentInput());
92 }
OH_InputMethodProxy_NotifySelectionChange(InputMethod_InputMethodProxy * inputMethodProxy,char16_t text[],size_t length,int start,int end)93 InputMethod_ErrorCode OH_InputMethodProxy_NotifySelectionChange(
94     InputMethod_InputMethodProxy *inputMethodProxy, char16_t text[], size_t length, int start, int end)
95 {
96     auto errCode = IsValidInputMethodProxy(inputMethodProxy);
97     if (errCode != IME_ERR_OK) {
98         IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
99         return errCode;
100     }
101     if (text == nullptr) {
102         IMSA_HILOGE("text is nullptr");
103         return IME_ERR_NULL_POINTER;
104     }
105 
106     if (length > MAX_TEXT_LENGTH) {
107         IMSA_HILOGE("text length is too long length=%{public}zu", length);
108         return IME_ERR_PARAMCHECK;
109     }
110     auto instance = InputMethodController::GetInstance();
111     if (instance == nullptr) {
112         IMSA_HILOGE("InputMethodController is nullptr");
113         return IME_ERR_NULL_POINTER;
114     }
115     return ErrorCodeConvert(instance->OnSelectionChange(std::u16string(text, length), start, end));
116 }
OH_InputMethodProxy_NotifyConfigurationChange(InputMethod_InputMethodProxy * inputMethodProxy,InputMethod_EnterKeyType enterKey,InputMethod_TextInputType textType)117 InputMethod_ErrorCode OH_InputMethodProxy_NotifyConfigurationChange(InputMethod_InputMethodProxy *inputMethodProxy,
118     InputMethod_EnterKeyType enterKey, InputMethod_TextInputType textType)
119 {
120     auto errCode = IsValidInputMethodProxy(inputMethodProxy);
121     if (errCode != IME_ERR_OK) {
122         IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
123         return errCode;
124     }
125     Configuration info;
126     info.SetEnterKeyType(static_cast<EnterKeyType>(enterKey));
127     info.SetTextInputType(static_cast<TextInputType>(textType));
128     auto instance = InputMethodController::GetInstance();
129     if (instance == nullptr) {
130         IMSA_HILOGE("InputMethodController is nullptr");
131         return IME_ERR_NULL_POINTER;
132     }
133     return ErrorCodeConvert(instance->OnConfigurationChange(info));
134 }
135 
OH_InputMethodProxy_NotifyCursorUpdate(InputMethod_InputMethodProxy * inputMethodProxy,InputMethod_CursorInfo * cursorInfo)136 InputMethod_ErrorCode OH_InputMethodProxy_NotifyCursorUpdate(
137     InputMethod_InputMethodProxy *inputMethodProxy, InputMethod_CursorInfo *cursorInfo)
138 {
139     auto errCode = IsValidInputMethodProxy(inputMethodProxy);
140     if (errCode != IME_ERR_OK) {
141         IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
142         return errCode;
143     }
144     if (cursorInfo == nullptr) {
145         IMSA_HILOGE("cursorInfo is nullptr");
146         return IME_ERR_NULL_POINTER;
147     }
148     CursorInfo info;
149     info.left = cursorInfo->left;
150     info.top = cursorInfo->top;
151     info.width = cursorInfo->width;
152     info.height = cursorInfo->height;
153     auto instance = InputMethodController::GetInstance();
154     if (instance == nullptr) {
155         IMSA_HILOGE("InputMethodController is nullptr");
156         return IME_ERR_NULL_POINTER;
157     }
158     return ErrorCodeConvert(instance->OnCursorUpdate(info));
159 }
160 
OH_InputMethodProxy_SendPrivateCommand(InputMethod_InputMethodProxy * inputMethodProxy,InputMethod_PrivateCommand * privateCommand[],size_t size)161 InputMethod_ErrorCode OH_InputMethodProxy_SendPrivateCommand(
162     InputMethod_InputMethodProxy *inputMethodProxy, InputMethod_PrivateCommand *privateCommand[], size_t size)
163 {
164     auto errCode = IsValidInputMethodProxy(inputMethodProxy);
165     if (errCode != IME_ERR_OK) {
166         IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
167         return errCode;
168     }
169     if (privateCommand == nullptr) {
170         IMSA_HILOGE("privateCommand is nullptr");
171         return IME_ERR_NULL_POINTER;
172     }
173 
174     if (size > MAX_SYS_PRIVATE_COMMAND_COUNT) {
175         IMSA_HILOGE("privateCommand size is too large: %{public}zu", size);
176         return IME_ERR_PARAMCHECK;
177     }
178 
179     std::unordered_map<std::string, PrivateDataValue> command;
180     for (size_t i = 0; i < size; i++) {
181         if (privateCommand[i] == nullptr) {
182             IMSA_HILOGE("privateCommand[%zu] is nullptr", i);
183             return IME_ERR_NULL_POINTER;
184         }
185         command.emplace(privateCommand[i]->key, privateCommand[i]->value);
186     }
187     auto instance = InputMethodController::GetInstance();
188     if (instance == nullptr) {
189         IMSA_HILOGE("InputMethodController is nullptr");
190         return IME_ERR_NULL_POINTER;
191     }
192     return ErrorCodeConvert(instance->SendPrivateCommand(command));
193 }
194 
OH_InputMethodProxy_SendMessage(InputMethod_InputMethodProxy * inputMethodProxy,const char16_t * msgId,size_t msgIdLength,const uint8_t * msgParam,size_t msgParamLength)195 InputMethod_ErrorCode OH_InputMethodProxy_SendMessage(InputMethod_InputMethodProxy *inputMethodProxy,
196     const char16_t *msgId, size_t msgIdLength, const uint8_t *msgParam, size_t msgParamLength)
197 {
198     auto errCode = IsValidInputMethodProxy(inputMethodProxy);
199     if (errCode != IME_ERR_OK) {
200         IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
201         return errCode;
202     }
203     if (msgId == nullptr || msgParam == nullptr) {
204         IMSA_HILOGE("msgId or msgParam is nullptr");
205         return IME_ERR_NULL_POINTER;
206     }
207     if (msgIdLength > INVALID_MSG_ID_SIZE || msgParamLength > INVALID_MSG_PARAM_SIZE) {
208         IMSA_HILOGE("ArrayBuffer size is invalid, msgIdLength: %{public}zu, msgParamLength: %{public}zu",
209             msgIdLength, msgParamLength);
210         return IME_ERR_PARAMCHECK;
211     }
212     ArrayBuffer arrayBuffer;
213     std::u16string msgIdStr(msgId, msgIdLength);
214     arrayBuffer.msgId = Str16ToStr8(msgIdStr);
215     arrayBuffer.msgParam.assign(msgParam, msgParam + msgParamLength);
216     auto instance = InputMethodController::GetInstance();
217     if (instance == nullptr) {
218         IMSA_HILOGE("InputMethodController is nullptr");
219         return IME_ERR_NULL_POINTER;
220     }
221     return ErrorCodeConvert(instance->SendMessage(arrayBuffer));
222 }
223 
OH_InputMethodProxy_RecvMessage(InputMethod_InputMethodProxy * inputMethodProxy,InputMethod_MessageHandlerProxy * messageHandler)224 InputMethod_ErrorCode OH_InputMethodProxy_RecvMessage(
225     InputMethod_InputMethodProxy *inputMethodProxy, InputMethod_MessageHandlerProxy *messageHandler)
226 {
227     auto errCode = IsValidInputMethodProxy(inputMethodProxy);
228     if (errCode != IME_ERR_OK) {
229         IMSA_HILOGE("invalid state, errCode=%{public}d", errCode);
230         return errCode;
231     }
232     if (IsValidMessageHandlerProxy(messageHandler) != IME_ERR_OK) {
233         IMSA_HILOGE("invalid messageHandler");
234         return IME_ERR_NULL_POINTER;
235     }
236     auto instance = InputMethodController::GetInstance();
237     if (instance == nullptr) {
238         IMSA_HILOGE("InputMethodController is nullptr");
239         return IME_ERR_NULL_POINTER;
240     }
241     if (messageHandler == nullptr) {
242         IMSA_HILOGI("UnRegister message handler.");
243         return ErrorCodeConvert(instance->RegisterMsgHandler(nullptr));
244     }
245     IMSA_HILOGI("Register message handler.");
246     std::shared_ptr<MsgHandlerCallbackInterface> msgHandler =
247         std::make_shared<NativeMessageHandlerCallback>(messageHandler);
248     return ErrorCodeConvert(instance->RegisterMsgHandler(msgHandler));
249 }
250 #ifdef __cplusplus
251 }
252 #endif /* __cplusplus */