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
16 #include "input_method_ffi.h"
17
18 #include "inputmethod_trace.h"
19 #include "cj_input_method_controller.h"
20 #include "input_method_property.h"
21 #include "setting_listeners.h"
22 #include "global.h"
23 #include "utils.h"
24 #include "input_method_utils.h"
25
26 namespace OHOS::MiscServices {
27 extern "C" {
FfiInputMethodGetDefaultInputMethod(CInputMethodProperty * props)28 int32_t FfiInputMethodGetDefaultInputMethod(CInputMethodProperty *props)
29 {
30 auto ctrl = InputMethodController::GetInstance();
31 if (ctrl == nullptr) {
32 return ERR_NO_MEMORY;
33 }
34 std::shared_ptr<Property> property;
35 int32_t ret = Utils::ConvertErrorCode(ctrl->GetDefaultInputMethod(property));
36 if (property == nullptr) {
37 IMSA_HILOGE("default input method is nullptr!");
38 return ret;
39 }
40 Utils::InputMethodProperty2C(props, *property);
41 return ret;
42 }
43
FfiInputMethodGetCurrentInputMethod(CInputMethodProperty * props)44 int32_t FfiInputMethodGetCurrentInputMethod(CInputMethodProperty *props)
45 {
46 auto ctrl = InputMethodController::GetInstance();
47 if (ctrl == nullptr) {
48 return ERR_NO_MEMORY;
49 }
50 std::shared_ptr<Property> property = ctrl->GetCurrentInputMethod();
51 if (property == nullptr) {
52 IMSA_HILOGE("current input method is nullptr!");
53 return ERR_NO_MEMORY;
54 }
55 Utils::InputMethodProperty2C(props, *property);
56 return ErrorCode::NO_ERROR;
57 }
58
FfiInputMethodSwitchInputMethod(bool * result,CInputMethodProperty props)59 int32_t FfiInputMethodSwitchInputMethod(bool *result, CInputMethodProperty props)
60 {
61 InputMethodSyncTrace tracer("CJInputMethod_SwitchInputMethod");
62 auto ctrl = InputMethodController::GetInstance();
63 if (ctrl == nullptr) {
64 return ERR_NO_MEMORY;
65 }
66 int32_t errCode =
67 ctrl->SwitchInputMethod(SwitchTrigger::CURRENT_IME, std::string(props.name), std::string(props.id));
68 if (errCode == ErrorCode::NO_ERROR) {
69 *result = true;
70 }
71 return Utils::ConvertErrorCode(errCode);
72 }
73
FfiInputMethodSwitchCurrentInputMethodSubtype(bool * result,CInputMethodSubtype target)74 int32_t FfiInputMethodSwitchCurrentInputMethodSubtype(bool *result, CInputMethodSubtype target)
75 {
76 InputMethodSyncTrace tracer("CJInputMethod_SwitchCurrentInputMethodSubtype");
77 auto ctrl = InputMethodController::GetInstance();
78 if (ctrl == nullptr) {
79 return ERR_NO_MEMORY;
80 }
81 int32_t errCode =
82 ctrl->SwitchInputMethod(SwitchTrigger::CURRENT_IME, std::string(target.name), std::string(target.id));
83 if (errCode == ErrorCode::NO_ERROR) {
84 *result = true;
85 }
86 return Utils::ConvertErrorCode(errCode);
87 }
88
FfiInputMethodGetCurrentInputMethodSubtype(CInputMethodSubtype * props)89 int32_t FfiInputMethodGetCurrentInputMethodSubtype(CInputMethodSubtype *props)
90 {
91 auto ctrl = InputMethodController::GetInstance();
92 if (ctrl == nullptr) {
93 return ERR_NO_MEMORY;
94 }
95 std::shared_ptr<SubProperty> subProperty = ctrl->GetCurrentInputMethodSubtype();
96 if (subProperty == nullptr) {
97 IMSA_HILOGE("current input method subtype is nullptr!");
98 return ERR_NO_MEMORY;
99 }
100 Utils::InputMethodSubProperty2C(props, *subProperty);
101 return ErrorCode::NO_ERROR;
102 }
103
FfiInputMethodSwitchCurrentInputMethodAndSubtype(bool * result,CInputMethodProperty target,CInputMethodSubtype subtype)104 int32_t FfiInputMethodSwitchCurrentInputMethodAndSubtype(bool *result,
105 CInputMethodProperty target, CInputMethodSubtype subtype)
106 {
107 InputMethodSyncTrace tracer("CJInputMethod_SwitchCurrentInputMethodAndSubtype");
108 auto ctrl = InputMethodController::GetInstance();
109 if (ctrl == nullptr) {
110 return ERR_NO_MEMORY;
111 }
112 int32_t errCode = ctrl->SwitchInputMethod(SwitchTrigger::CURRENT_IME,
113 std::string(subtype.name), std::string(subtype.id));
114 if (errCode == ErrorCode::NO_ERROR) {
115 *result = true;
116 }
117 return Utils::ConvertErrorCode(errCode);
118 }
119
FfiInputMethodGetSystemInputMethodConfigAbility(CElementName * elem)120 int32_t FfiInputMethodGetSystemInputMethodConfigAbility(CElementName *elem)
121 {
122 OHOS::AppExecFwk::ElementName inputMethodConfig;
123 auto ctrl = InputMethodController::GetInstance();
124 if (ctrl == nullptr) {
125 return ERR_NO_MEMORY;
126 }
127 int32_t ret = ctrl->GetInputMethodConfig(inputMethodConfig);
128 if (ret == ErrorCode::NO_ERROR && elem != nullptr) {
129 elem->deviceId = Utils::MallocCString(inputMethodConfig.GetDeviceID());
130 elem->bundleName = Utils::MallocCString(inputMethodConfig.GetBundleName());
131 elem->abilityName = Utils::MallocCString(inputMethodConfig.GetAbilityName());
132 elem->moduleName = Utils::MallocCString(inputMethodConfig.GetModuleName());
133 }
134 return Utils::ConvertErrorCode(ret);
135 }
136
FfiInputMethodSettingListInputMethodSubtype(CInputMethodProperty props)137 RetInputMethodSubtype FfiInputMethodSettingListInputMethodSubtype(CInputMethodProperty props)
138 {
139 IMSA_HILOGD("run in ListInputMethodSubtype");
140 RetInputMethodSubtype ret{};
141 Property property = Utils::C2InputMethodProperty(props);
142 std::vector<SubProperty> subProps;
143 auto ctrl = InputMethodController::GetInstance();
144 if (ctrl == nullptr) {
145 ret.code = ERR_NO_MEMORY;
146 return ret;
147 }
148 int32_t errCode = ctrl->ListInputMethodSubtype(property, subProps);
149 ret.code = Utils::ConvertErrorCode(errCode);
150 if (errCode != ErrorCode::NO_ERROR) {
151 return ret;
152 }
153 IMSA_HILOGI("exec ListInputMethodSubtype success");
154 ret.size = static_cast<int64_t>(subProps.size());
155 if (ret.size > 0) {
156 ret.head = static_cast<CInputMethodSubtype *>(malloc(sizeof(CInputMethodSubtype) * ret.size));
157 }
158 if (ret.head == nullptr) {
159 ret.size = 0;
160 return ret;
161 }
162 for (unsigned int i = 0; i < ret.size; i++) {
163 CInputMethodSubtype subtype;
164 Utils::InputMethodSubProperty2C(&subtype, subProps[i]);
165 ret.head[i] = subtype;
166 }
167 return ret;
168 }
169
FfiInputMethodSettingListCurrentInputMethodSubtype()170 RetInputMethodSubtype FfiInputMethodSettingListCurrentInputMethodSubtype()
171 {
172 IMSA_HILOGD("run in ListCurrentInputMethodSubtype");
173 RetInputMethodSubtype ret{};
174 std::vector<SubProperty> subProps;
175 auto ctrl = InputMethodController::GetInstance();
176 if (ctrl == nullptr) {
177 ret.code = ERR_NO_MEMORY;
178 return ret;
179 }
180 int32_t errCode = ctrl->ListCurrentInputMethodSubtype(subProps);
181 ret.code = Utils::ConvertErrorCode(errCode);
182 if (errCode != ErrorCode::NO_ERROR) {
183 return ret;
184 }
185 IMSA_HILOGI("exec ListCurrentInputMethodSubtype success.");
186 ret.size = static_cast<int64_t>(subProps.size());
187 if (ret.size > 0) {
188 ret.head = static_cast<CInputMethodSubtype *>(malloc(sizeof(CInputMethodSubtype) * ret.size));
189 }
190 if (ret.head == nullptr) {
191 ret.size = 0;
192 return ret;
193 }
194 for (unsigned int i = 0; i < ret.size; i++) {
195 CInputMethodSubtype props;
196 Utils::InputMethodSubProperty2C(&props, subProps[i]);
197 ret.head[i] = props;
198 }
199 return ret;
200 }
201
FfiInputMethodSettingGetInputMethods(bool enable)202 RetInputMethodProperty FfiInputMethodSettingGetInputMethods(bool enable)
203 {
204 IMSA_HILOGD("run in");
205 RetInputMethodProperty ret{};
206 std::vector<Property> properties;
207 auto ctrl = InputMethodController::GetInstance();
208 if (ctrl == nullptr) {
209 ret.code = ERR_NO_MEMORY;
210 return ret;
211 }
212 int32_t errCode = ctrl->ListInputMethod(enable, properties);
213 ret.code = Utils::ConvertErrorCode(errCode);
214 if (errCode != ErrorCode::NO_ERROR) {
215 return ret;
216 }
217 ret.size = static_cast<int64_t>(properties.size());
218 if (ret.size > 0) {
219 ret.head = static_cast<CInputMethodProperty *>(malloc(sizeof(CInputMethodProperty) * ret.size));
220 }
221 if (ret.head == nullptr) {
222 ret.size = 0;
223 return ret;
224 }
225 for (unsigned int i = 0; i < ret.size; i++) {
226 CInputMethodProperty props;
227 Utils::InputMethodProperty2C(&props, properties[i]);
228 ret.head[i] = props;
229 }
230 return ret;
231 }
232
FfiInputMethodSettingGetAllInputMethods()233 RetInputMethodProperty FfiInputMethodSettingGetAllInputMethods()
234 {
235 IMSA_HILOGD("run in");
236 RetInputMethodProperty ret{};
237 std::vector<Property> properties;
238 auto ctrl = InputMethodController::GetInstance();
239 if (ctrl == nullptr) {
240 ret.code = ERR_NO_MEMORY;
241 return ret;
242 }
243 int32_t errCode = ctrl->ListInputMethod(properties);
244 ret.code = Utils::ConvertErrorCode(errCode);
245 if (errCode != ErrorCode::NO_ERROR) {
246 return ret;
247 }
248 ret.size = static_cast<int64_t>(properties.size());
249 if (ret.size > 0) {
250 ret.head = static_cast<CInputMethodProperty *>(malloc(sizeof(CInputMethodProperty) * ret.size));
251 }
252 if (ret.head == nullptr) {
253 ret.size = 0;
254 return ret;
255 }
256 for (unsigned int i = 0; i < ret.size; i++) {
257 CInputMethodProperty props;
258 Utils::InputMethodProperty2C(&props, properties[i]);
259 ret.head[i] = props;
260 }
261 return ret;
262 }
263
FfiInputMethodSettingOn(uint32_t type,void (* func)(CInputMethodProperty,CInputMethodSubtype))264 int32_t FfiInputMethodSettingOn(uint32_t type, void (*func)(CInputMethodProperty, CInputMethodSubtype))
265 {
266 auto setting = CJGetInputMethodSetting::GetIMSInstance();
267 if (setting == nullptr) {
268 return ERR_NO_MEMORY;
269 }
270 return Utils::ConvertErrorCode(setting->Subscribe(type, func));
271 }
272
FfiInputMethodSettingOff(uint32_t type)273 int32_t FfiInputMethodSettingOff(uint32_t type)
274 {
275 auto setting = CJGetInputMethodSetting::GetIMSInstance();
276 if (setting == nullptr) {
277 return ERR_NO_MEMORY;
278 }
279 return Utils::ConvertErrorCode(setting->UnSubscribe(type));
280 }
281
FfiInputMethodSettingShowOptionalInputMethods(bool * result)282 int32_t FfiInputMethodSettingShowOptionalInputMethods(bool *result)
283 {
284 IMSA_HILOGD("start JsGetInputMethodSetting.");
285 auto ctrl = InputMethodController::GetInstance();
286 if (ctrl == nullptr) {
287 return ERR_NO_MEMORY;
288 }
289 int32_t errCode = ctrl->DisplayOptionalInputMethod();
290 if (errCode == ErrorCode::NO_ERROR) {
291 IMSA_HILOGI("exec DisplayOptionalInputMethod success");
292 *result = true;
293 }
294 return Utils::ConvertErrorCode(errCode);
295 }
296
FfiInputMethodControllerOn(int8_t type,int64_t id)297 int32_t FfiInputMethodControllerOn(int8_t type, int64_t id)
298 {
299 return Utils::ConvertErrorCode(CjInputMethodController::Subscribe(type, id));
300 }
301
FfiInputMethodControllerOff(int8_t type)302 int32_t FfiInputMethodControllerOff(int8_t type)
303 {
304 return Utils::ConvertErrorCode(CjInputMethodController::Unsubscribe(type));
305 }
306
FfiInputMethodControllerAttach(bool showKeyboard,CTextConfig txtCfg)307 int32_t FfiInputMethodControllerAttach(bool showKeyboard, CTextConfig txtCfg)
308 {
309 AttachOptions attachOptions;
310 attachOptions.isShowKeyboard = showKeyboard;
311 attachOptions.requestKeyboardReason = RequestKeyboardReason::NONE;
312 return Utils::ConvertErrorCode(CjInputMethodController::Attach(txtCfg, attachOptions));
313 }
314
FfiInputMethodControllerAttachWithReason(bool showKeyboard,CTextConfig txtCfg,int32_t reason)315 int32_t FfiInputMethodControllerAttachWithReason(bool showKeyboard, CTextConfig txtCfg, int32_t reason)
316 {
317 AttachOptions attachOptions;
318 attachOptions.isShowKeyboard = showKeyboard;
319 attachOptions.requestKeyboardReason = static_cast<RequestKeyboardReason>(reason);
320 return Utils::ConvertErrorCode(CjInputMethodController::Attach(txtCfg, attachOptions));
321 }
322
FfiInputMethodControllerDetach()323 int32_t FfiInputMethodControllerDetach()
324 {
325 return Utils::ConvertErrorCode(CjInputMethodController::Detach());
326 }
327
FfiInputMethodControllerShowTextInput()328 int32_t FfiInputMethodControllerShowTextInput()
329 {
330 AttachOptions attachOptions;
331 attachOptions.isShowKeyboard = false;
332 attachOptions.requestKeyboardReason = RequestKeyboardReason::NONE;
333 return Utils::ConvertErrorCode(CjInputMethodController::ShowTextInput(attachOptions));
334 }
335
FfiInputMethodControllerShowTextInputWithReason(int32_t reason)336 int32_t FfiInputMethodControllerShowTextInputWithReason(int32_t reason)
337 {
338 AttachOptions attachOptions;
339 attachOptions.isShowKeyboard = false;
340 attachOptions.requestKeyboardReason = static_cast<RequestKeyboardReason>(reason);
341 return Utils::ConvertErrorCode(CjInputMethodController::ShowTextInput(attachOptions));
342 }
343
FfiInputMethodControllerHideTextInput()344 int32_t FfiInputMethodControllerHideTextInput()
345 {
346 return Utils::ConvertErrorCode(CjInputMethodController::HideTextInput());
347 }
348
FfiInputMethodControllerSetCallingWindow(uint32_t windowId)349 int32_t FfiInputMethodControllerSetCallingWindow(uint32_t windowId)
350 {
351 return Utils::ConvertErrorCode(CjInputMethodController::SetCallingWindow(windowId));
352 }
353
FfiInputMethodControllerUpdateCursor(CCursorInfo cursor)354 int32_t FfiInputMethodControllerUpdateCursor(CCursorInfo cursor)
355 {
356 return Utils::ConvertErrorCode(CjInputMethodController::UpdateCursor(cursor));
357 }
358
FfiInputMethodControllerChangeSelection(char * text,int32_t start,int32_t end)359 int32_t FfiInputMethodControllerChangeSelection(char *text, int32_t start, int32_t end)
360 {
361 return Utils::ConvertErrorCode(CjInputMethodController::ChangeSelection(std::string(text), start, end));
362 }
363
FfiInputMethodControllerUpdateAttribute(CInputAttribute inputAttribute)364 int32_t FfiInputMethodControllerUpdateAttribute(CInputAttribute inputAttribute)
365 {
366 return Utils::ConvertErrorCode(CjInputMethodController::UpdateAttribute(inputAttribute));
367 }
368
FfiInputMethodControllerShowSoftKeyboard()369 int32_t FfiInputMethodControllerShowSoftKeyboard()
370 {
371 return Utils::ConvertErrorCode(CjInputMethodController::ShowSoftKeyboard());
372 }
373
FfiInputMethodControllerHideSoftKeyboard()374 int32_t FfiInputMethodControllerHideSoftKeyboard()
375 {
376 return Utils::ConvertErrorCode(CjInputMethodController::HideSoftKeyboard());
377 }
378
FfiInputMethodControllerStopInputSession()379 int32_t FfiInputMethodControllerStopInputSession()
380 {
381 return Utils::ConvertErrorCode(CjInputMethodController::StopInputSession());
382 }
383 }
384 }