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 }