• 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     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 */