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