• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 #ifndef INTERFACE_KITS_JS_GET_INPUT_METHOD_CONTROLLER_H
16 #define INTERFACE_KITS_JS_GET_INPUT_METHOD_CONTROLLER_H
17 
18 #include "async_call.h"
19 #include "controller_listener.h"
20 #include "global.h"
21 #include "js_callback_object.h"
22 #include "js_input_method.h"
23 
24 namespace OHOS {
25 namespace MiscServices {
26 struct HandleContext : public AsyncCall::Context {
27     bool isHandle = false;
28     napi_status status = napi_generic_failure;
HandleContextHandleContext29     HandleContext() : Context(nullptr, nullptr){};
HandleContextHandleContext30     HandleContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
31 
operatorHandleContext32     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
33     {
34         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
35         return Context::operator()(env, argc, argv, self);
36     }
operatorHandleContext37     napi_status operator()(napi_env env, napi_value *result) override
38     {
39         if (status != napi_ok) {
40             output_ = nullptr;
41             return status;
42         }
43         return Context::operator()(env, result);
44     }
45 };
46 
47 struct AttachContext : public AsyncCall::Context {
48     sptr<OnTextChangedListener> textListener;
49     InputAttribute attribute;
50     bool showKeyboard = false;
51     TextConfig textConfig;
AttachContextAttachContext52     AttachContext() : Context(nullptr, nullptr) {};
AttachContextAttachContext53     AttachContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)) {};
54 
operatorAttachContext55     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
56     {
57         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
58         return Context::operator()(env, argc, argv, self);
59     }
operatorAttachContext60     napi_status operator()(napi_env env, napi_value *result) override
61     {
62         if (status_ != napi_ok) {
63             output_ = nullptr;
64             return status_;
65         }
66         return Context::operator()(env, result);
67     }
68 };
69 
70 struct SetCallingWindowContext : public AsyncCall::Context {
71     int32_t windID = 0;
SetCallingWindowContextSetCallingWindowContext72     SetCallingWindowContext() : Context(nullptr, nullptr) {};
SetCallingWindowContextSetCallingWindowContext73     SetCallingWindowContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)) {};
74 
operatorSetCallingWindowContext75     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
76     {
77         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
78         return Context::operator()(env, argc, argv, self);
79     }
operatorSetCallingWindowContext80     napi_status operator()(napi_env env, napi_value *result) override
81     {
82         if (status_ != napi_ok) {
83             output_ = nullptr;
84             return status_;
85         }
86         return Context::operator()(env, result);
87     }
88 };
89 
90 struct UpdateCursorContext : public AsyncCall::Context {
91     CursorInfo cursorInfo;
UpdateCursorContextUpdateCursorContext92     UpdateCursorContext() : Context(nullptr, nullptr) {};
UpdateCursorContextUpdateCursorContext93     UpdateCursorContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)) {};
94 
operatorUpdateCursorContext95     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
96     {
97         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
98         return Context::operator()(env, argc, argv, self);
99     }
operatorUpdateCursorContext100     napi_status operator()(napi_env env, napi_value *result) override
101     {
102         if (status_ != napi_ok) {
103             output_ = nullptr;
104             return status_;
105         }
106         return Context::operator()(env, result);
107     }
108 };
109 
110 struct ChangeSelectionContext : public AsyncCall::Context {
111     std::u16string text;
112     int32_t start = 0;
113     int32_t end = 0;
ChangeSelectionContextChangeSelectionContext114     ChangeSelectionContext() : Context(nullptr, nullptr) {};
ChangeSelectionContextChangeSelectionContext115     ChangeSelectionContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)) {};
116 
operatorChangeSelectionContext117     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
118     {
119         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
120         return Context::operator()(env, argc, argv, self);
121     }
operatorChangeSelectionContext122     napi_status operator()(napi_env env, napi_value *result) override
123     {
124         if (status_ != napi_ok) {
125             output_ = nullptr;
126             return status_;
127         }
128         return Context::operator()(env, result);
129     }
130 };
131 
132 struct UpdateAttributeContext : public AsyncCall::Context {
133     InputAttribute attribute;
134     Configuration configuration;
UpdateAttributeContextUpdateAttributeContext135     UpdateAttributeContext() : Context(nullptr, nullptr) {};
UpdateAttributeContextUpdateAttributeContext136     UpdateAttributeContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)) {};
137 
operatorUpdateAttributeContext138     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
139     {
140         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
141         return Context::operator()(env, argc, argv, self);
142     }
operatorUpdateAttributeContext143     napi_status operator()(napi_env env, napi_value *result) override
144     {
145         if (status_ != napi_ok) {
146             output_ = nullptr;
147             return status_;
148         }
149         return Context::operator()(env, result);
150     }
151 };
152 
153 class JsGetInputMethodController : public ControllerListener {
154 public:
155     JsGetInputMethodController() = default;
156     ~JsGetInputMethodController() = default;
157     static napi_value Init(napi_env env, napi_value info);
158     static napi_value GetController(napi_env env, napi_callback_info cbInfo);
159     static napi_value GetInputMethodController(napi_env env, napi_callback_info cbInfo);
160     static std::shared_ptr<JsGetInputMethodController> GetInstance();
161     static napi_value HandleSoftKeyboard(napi_env env, napi_callback_info info, std::function<int32_t()> callback,
162         bool isOutput, bool needThrowException);
163     static napi_value Attach(napi_env env, napi_callback_info info);
164     static napi_value Detach(napi_env env, napi_callback_info info);
165     static napi_value ShowTextInput(napi_env env, napi_callback_info info);
166     static napi_value HideTextInput(napi_env env, napi_callback_info info);
167     static napi_value SetCallingWindow(napi_env env, napi_callback_info info);
168     static napi_value UpdateCursor(napi_env env, napi_callback_info info);
169     static napi_value ChangeSelection(napi_env env, napi_callback_info info);
170     static napi_value UpdateAttribute(napi_env env, napi_callback_info info);
171     static napi_value HideSoftKeyboard(napi_env env, napi_callback_info info);
172     static napi_value ShowSoftKeyboard(napi_env env, napi_callback_info info);
173     static napi_value StopInputSession(napi_env env, napi_callback_info info);
174     static napi_value StopInput(napi_env env, napi_callback_info info);
175     static napi_value Subscribe(napi_env env, napi_callback_info info);
176     static napi_value UnSubscribe(napi_env env, napi_callback_info info);
177     void OnSelectByRange(int32_t start, int32_t end) override;
178     void OnSelectByMovement(int32_t direction) override;
179     void InsertText(const std::u16string &text);
180     void DeleteRight(int32_t length);
181     void DeleteLeft(int32_t length);
182     void SendKeyboardStatus(const KeyboardStatus &status);
183     void SendFunctionKey(const FunctionKey &functionKey);
184     void MoveCursor(const Direction direction);
185     void HandleExtendAction(int32_t action);
186     std::u16string GetText(const std::string &type, int32_t number);
187     int32_t GetTextIndexAtCursor();
188 
189 private:
190     static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo);
191     static napi_value GetIMController(napi_env env, napi_callback_info cbInfo, bool needThrowException);
192     static napi_value CreateSelectRange(napi_env env, int32_t start, int32_t end);
193     static napi_value CreateSelectMovement(napi_env env, int32_t direction);
194     static napi_value CreateSendFunctionKey(napi_env env, int32_t functionKey);
195     void RegisterListener(napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj);
196     void UnRegisterListener(napi_value callback, std::string type);
197     static bool ParseAttachInput(
198         napi_env env, size_t argc, napi_value *argv, const std::shared_ptr<AttachContext> &ctxt);
199     static bool GetValue(napi_env env, napi_value in, CursorInfo &out);
200     static bool GetValue(napi_env env, napi_value in, InputAttribute &out);
201     static bool GetValue(napi_env env, napi_value in, TextConfig &out);
202     static bool GetValue(napi_env env, napi_value in, SelectionRange &out);
203     static napi_value GetJsKeyboardStatusProperty(napi_env env);
204     static napi_value GetJsEnterKeyTypeProperty(napi_env env);
205     static napi_value GetJsTextInputTypeProperty(napi_env env);
206     static napi_value GetJsDirectionProperty(napi_env env);
207     static napi_value GetJsExtendActionProperty(napi_env env);
208     static const std::set<std::string> TEXT_EVENT_TYPE;
209     static constexpr int32_t MAX_TIMEOUT = 2500;
210     struct UvEntry {
211         std::vector<std::shared_ptr<JSCallbackObject>> vecCopy;
212         std::string type;
213         std::string text;
214         int32_t start = 0;
215         int32_t end = 0;
216         int32_t direction = 0;
217         int32_t length = 0;
218         int32_t action = 0;
219         int32_t keyboardStatus = 0;
220         int32_t enterKeyType = 0;
221         int32_t number = 0;
222         std::shared_ptr<BlockData<std::string>> textResultHandler;
223         std::shared_ptr<BlockData<std::int32_t>> indexResultHandler;
UvEntryUvEntry224         explicit UvEntry(const std::vector<std::shared_ptr<JSCallbackObject>> &cbVec, const std::string &type)
225             : vecCopy(cbVec), type(type)
226         {
227         }
228     };
229     using EntrySetter = std::function<void(UvEntry &)>;
230     uv_work_t *GetUVwork(const std::string &type, EntrySetter entrySetter = nullptr);
231     void FreeWorkIfFail(int ret, uv_work_t *work);
232     uv_loop_s *loop_ = nullptr;
233     std::recursive_mutex mutex_;
234     std::map<std::string, std::vector<std::shared_ptr<JSCallbackObject>>> jsCbMap_;
235     static std::mutex controllerMutex_;
236     static std::shared_ptr<JsGetInputMethodController> controller_;
237     static const std::string IMC_CLASS_NAME;
238     static thread_local napi_ref IMCRef_;
239     static constexpr size_t PARAM_POS_ZERO = 0;
240     static constexpr size_t PARAM_POS_ONE = 1;
241     static constexpr size_t PARAM_POS_TWO = 2;
242     static constexpr size_t PARAM_POS_THREE = 3;
243 };
244 } // namespace MiscServices
245 } // namespace OHOS
246 #endif // INTERFACE_KITS_JS_GET_INPUT_METHOD_CONTROLLER_H
247