• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "js_get_input_method_controller.h"
16 
17 #include "input_method_controller.h"
18 #include "napi/native_api.h"
19 #include "napi/native_node_api.h"
20 #include "string_ex.h"
21 
22 namespace OHOS {
23 namespace MiscServices {
24 thread_local napi_ref JsGetInputMethodController::IMCRef_ = nullptr;
25 const std::string JsGetInputMethodController::IMC_CLASS_NAME = "InputMethodController";
Init(napi_env env,napi_value info)26 napi_value JsGetInputMethodController::Init(napi_env env, napi_value info)
27 {
28     napi_property_descriptor descriptor[] = {
29         DECLARE_NAPI_FUNCTION("getInputMethodController", GetInputMethodController),
30         DECLARE_NAPI_FUNCTION("getController", GetController),
31     };
32     NAPI_CALL(
33         env, napi_define_properties(env, info, sizeof(descriptor) / sizeof(napi_property_descriptor), descriptor));
34 
35     napi_property_descriptor properties[] = {
36         DECLARE_NAPI_FUNCTION("stopInput", StopInput),
37         DECLARE_NAPI_FUNCTION("stopInputSession", StopInputSession),
38         DECLARE_NAPI_FUNCTION("hideSoftKeyboard", HideSoftKeyboard),
39         DECLARE_NAPI_FUNCTION("showSoftKeyboard", ShowSoftKeyboard),
40     };
41     napi_value cons = nullptr;
42     NAPI_CALL(env, napi_define_class(env, IMC_CLASS_NAME.c_str(), IMC_CLASS_NAME.size(),
43         JsConstructor, nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &cons));
44     NAPI_CALL(env, napi_create_reference(env, cons, 1, &IMCRef_));
45     NAPI_CALL(env, napi_set_named_property(env, info, IMC_CLASS_NAME.c_str(), cons));
46 
47     return info;
48 }
49 
JsConstructor(napi_env env,napi_callback_info cbinfo)50 napi_value JsGetInputMethodController::JsConstructor(napi_env env, napi_callback_info cbinfo)
51 {
52     napi_value thisVar = nullptr;
53     NAPI_CALL(env, napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, nullptr));
54 
55     JsGetInputMethodController *controllerObject = new (std::nothrow) JsGetInputMethodController();
56     if (controllerObject == nullptr) {
57         IMSA_HILOGE("controllerObject is nullptr");
58         napi_value result = nullptr;
59         napi_get_null(env, &result);
60         return result;
61     }
62     auto finalize = [](napi_env env, void *data, void *hint) {
63         IMSA_HILOGE("JsGetInputMethodController finalize");
64         auto *objInfo = reinterpret_cast<JsGetInputMethodController *>(data);
65         if (objInfo != nullptr) {
66             IMSA_HILOGE("objInfo is nullptr");
67             delete objInfo;
68         }
69     };
70     napi_status status = napi_wrap(env, thisVar, controllerObject, finalize, nullptr, nullptr);
71     if (status != napi_ok) {
72         IMSA_HILOGE("JsGetInputMethodController napi_wrap failed:%{public}d", status);
73         delete controllerObject;
74         return nullptr;
75     }
76 
77     return thisVar;
78 }
79 
GetInputMethodController(napi_env env,napi_callback_info cbInfo)80 napi_value JsGetInputMethodController::GetInputMethodController(napi_env env, napi_callback_info cbInfo)
81 {
82     return GetIMController(env, cbInfo, false);
83 }
84 
GetController(napi_env env,napi_callback_info cbInfo)85 napi_value JsGetInputMethodController::GetController(napi_env env, napi_callback_info cbInfo)
86 {
87     return GetIMController(env, cbInfo, true);
88 }
89 
GetIMController(napi_env env,napi_callback_info cbInfo,bool needThrowException)90 napi_value JsGetInputMethodController::GetIMController(napi_env env, napi_callback_info cbInfo, bool needThrowException)
91 {
92     napi_value instance = nullptr;
93     napi_value cons = nullptr;
94     if (napi_get_reference_value(env, IMCRef_, &cons) != napi_ok) {
95         IMSA_HILOGE("GetInputMethodSetting::napi_get_reference_value not ok");
96         if (needThrowException) {
97             JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_CONTROLLER, "", TYPE_OBJECT);
98         }
99         return nullptr;
100     }
101 
102     if (napi_new_instance(env, cons, 0, nullptr, &instance) != napi_ok) {
103         IMSA_HILOGE("GetInputMethodSetting::napi_new_instance not ok");
104         if (needThrowException) {
105             JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_CONTROLLER, "", TYPE_OBJECT);
106         }
107         return nullptr;
108     }
109     return instance;
110 }
111 
HandleSoftKeyboard(napi_env env,napi_callback_info info,std::function<int32_t ()> callback,bool isOutput,bool needThrowException)112 napi_value JsGetInputMethodController::HandleSoftKeyboard(
113     napi_env env, napi_callback_info info, std::function<int32_t()> callback, bool isOutput, bool needThrowException)
114 {
115     auto ctxt = std::make_shared<HandleContext>();
116     auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
117         return napi_ok;
118     };
119     auto output = [ctxt, isOutput](napi_env env, napi_value *result) -> napi_status {
120         if (!isOutput) {
121             return napi_ok;
122         }
123         napi_status status = napi_get_boolean(env, ctxt->isHandle, result);
124         IMSA_HILOGE("output napi_get_boolean != nullptr[%{public}d]", result != nullptr);
125         return status;
126     };
127     auto exec = [ctxt, callback, needThrowException](AsyncCall::Context *ctx) {
128         int errCode = callback();
129         if (errCode == ErrorCode::NO_ERROR) {
130             IMSA_HILOGI("exec success");
131             ctxt->status = napi_ok;
132             ctxt->isHandle = true;
133             ctxt->SetState(ctxt->status);
134             return;
135         }
136         IMSA_HILOGI("exec %{public}d", errCode);
137         if (needThrowException) {
138             ctxt->SetErrorCode(errCode);
139         }
140     };
141     ctxt->SetAction(std::move(input), std::move(output));
142     AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(ctxt), 0);
143     return asyncCall.Call(env, exec);
144 }
145 
ShowSoftKeyboard(napi_env env,napi_callback_info info)146 napi_value JsGetInputMethodController::ShowSoftKeyboard(napi_env env, napi_callback_info info)
147 {
148     return HandleSoftKeyboard(
149         env, info, [] { return InputMethodController::GetInstance()->ShowSoftKeyboard(); }, false, true);
150 }
151 
HideSoftKeyboard(napi_env env,napi_callback_info info)152 napi_value JsGetInputMethodController::HideSoftKeyboard(napi_env env, napi_callback_info info)
153 {
154     return HandleSoftKeyboard(
155         env, info, [] { return InputMethodController::GetInstance()->HideSoftKeyboard(); }, false, true);
156 }
157 
StopInputSession(napi_env env,napi_callback_info info)158 napi_value JsGetInputMethodController::StopInputSession(napi_env env, napi_callback_info info)
159 {
160     return HandleSoftKeyboard(
161         env, info, [] { return InputMethodController::GetInstance()->StopInputSession(); }, true, true);
162 }
163 
StopInput(napi_env env,napi_callback_info info)164 napi_value JsGetInputMethodController::StopInput(napi_env env, napi_callback_info info)
165 {
166     return HandleSoftKeyboard(
167         env, info, [] { return InputMethodController::GetInstance()->HideCurrentInput(); }, true, false);
168 }
169 } // namespace MiscServices
170 } // namespace OHOS