• 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 "event_handler.h"
21 #include "global.h"
22 #include "js_callback_object.h"
23 #include "js_input_method.h"
24 #include "js_message_handler_info.h"
25 #include "msg_handler_callback_interface.h"
26 
27 namespace OHOS {
28 namespace MiscServices {
29 struct HandleContext : public AsyncCall::Context {
30     bool isHandle = false;
31     napi_status status = napi_generic_failure;
HandleContextHandleContext32     HandleContext() : Context(nullptr, nullptr){};
HandleContextHandleContext33     HandleContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
34 
operatorHandleContext35     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
36     {
37         CHECK_RETURN(self != nullptr, "self is nullptr!", napi_invalid_arg);
38         return Context::operator()(env, argc, argv, self);
39     }
operatorHandleContext40     napi_status operator()(napi_env env, napi_value *result) override
41     {
42         if (status != napi_ok) {
43             output_ = nullptr;
44             return status;
45         }
46         return Context::operator()(env, result);
47     }
48 };
49 
50 struct AttachContext : public AsyncCall::Context {
51     sptr<OnTextChangedListener> textListener;
52     InputAttribute attribute;
53     bool showKeyboard = false;
54     int32_t requestKeyboardReason = 0;
55     TextConfig textConfig;
AttachContextAttachContext56     AttachContext() : Context(nullptr, nullptr){};
AttachContextAttachContext57     AttachContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
58 
operatorAttachContext59     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
60     {
61         CHECK_RETURN(self != nullptr, "self is nullptr!", napi_invalid_arg);
62         return Context::operator()(env, argc, argv, self);
63     }
operatorAttachContext64     napi_status operator()(napi_env env, napi_value *result) override
65     {
66         if (status_ != napi_ok) {
67             output_ = nullptr;
68             return status_;
69         }
70         return Context::operator()(env, result);
71     }
72 };
73 
74 struct SetCallingWindowContext : public AsyncCall::Context {
75     int32_t windID = 0;
SetCallingWindowContextSetCallingWindowContext76     SetCallingWindowContext() : Context(nullptr, nullptr){};
SetCallingWindowContextSetCallingWindowContext77     SetCallingWindowContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
78 
operatorSetCallingWindowContext79     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
80     {
81         CHECK_RETURN(self != nullptr, "self is nullptr!", napi_invalid_arg);
82         return Context::operator()(env, argc, argv, self);
83     }
operatorSetCallingWindowContext84     napi_status operator()(napi_env env, napi_value *result) override
85     {
86         if (status_ != napi_ok) {
87             output_ = nullptr;
88             return status_;
89         }
90         return Context::operator()(env, result);
91     }
92 };
93 
94 struct UpdateCursorContext : public AsyncCall::Context {
95     CursorInfo cursorInfo;
UpdateCursorContextUpdateCursorContext96     UpdateCursorContext() : Context(nullptr, nullptr){};
UpdateCursorContextUpdateCursorContext97     UpdateCursorContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
98 
operatorUpdateCursorContext99     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
100     {
101         CHECK_RETURN(self != nullptr, "self is nullptr!", napi_invalid_arg);
102         return Context::operator()(env, argc, argv, self);
103     }
operatorUpdateCursorContext104     napi_status operator()(napi_env env, napi_value *result) override
105     {
106         if (status_ != napi_ok) {
107             output_ = nullptr;
108             return status_;
109         }
110         return Context::operator()(env, result);
111     }
112 };
113 
114 struct ChangeSelectionContext : public AsyncCall::Context {
115     std::u16string text;
116     int32_t start = 0;
117     int32_t end = 0;
ChangeSelectionContextChangeSelectionContext118     ChangeSelectionContext() : Context(nullptr, nullptr){};
ChangeSelectionContextChangeSelectionContext119     ChangeSelectionContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
120 
operatorChangeSelectionContext121     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
122     {
123         CHECK_RETURN(self != nullptr, "self is nullptr!", napi_invalid_arg);
124         return Context::operator()(env, argc, argv, self);
125     }
operatorChangeSelectionContext126     napi_status operator()(napi_env env, napi_value *result) override
127     {
128         if (status_ != napi_ok) {
129             output_ = nullptr;
130             return status_;
131         }
132         return Context::operator()(env, result);
133     }
134 };
135 
136 struct UpdateAttributeContext : public AsyncCall::Context {
137     InputAttribute attribute;
138     Configuration configuration;
UpdateAttributeContextUpdateAttributeContext139     UpdateAttributeContext() : Context(nullptr, nullptr){};
UpdateAttributeContextUpdateAttributeContext140     UpdateAttributeContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
141 
operatorUpdateAttributeContext142     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
143     {
144         CHECK_RETURN(self != nullptr, "self is nullptr!", napi_invalid_arg);
145         return Context::operator()(env, argc, argv, self);
146     }
operatorUpdateAttributeContext147     napi_status operator()(napi_env env, napi_value *result) override
148     {
149         if (status_ != napi_ok) {
150             output_ = nullptr;
151             return status_;
152         }
153         return Context::operator()(env, result);
154     }
155 };
156 
157 class JsGetInputMethodController : public ControllerListener {
158 public:
159     JsGetInputMethodController() = default;
160     ~JsGetInputMethodController() = default;
161     static napi_value Init(napi_env env, napi_value info);
162     static napi_value GetController(napi_env env, napi_callback_info cbInfo);
163     static napi_value GetInputMethodController(napi_env env, napi_callback_info cbInfo);
164     static std::shared_ptr<JsGetInputMethodController> GetInstance();
165     static napi_value HandleSoftKeyboard(napi_env env, napi_callback_info info, std::function<int32_t()> callback,
166         bool isOutput, bool needThrowException);
167     static napi_value Attach(napi_env env, napi_callback_info info);
168     static napi_value Detach(napi_env env, napi_callback_info info);
169     static napi_value ShowTextInput(napi_env env, napi_callback_info info);
170     static napi_value HideTextInput(napi_env env, napi_callback_info info);
171     static napi_value SetCallingWindow(napi_env env, napi_callback_info info);
172     static napi_value UpdateCursor(napi_env env, napi_callback_info info);
173     static napi_value ChangeSelection(napi_env env, napi_callback_info info);
174     static napi_value UpdateAttribute(napi_env env, napi_callback_info info);
175     static napi_value HideSoftKeyboard(napi_env env, napi_callback_info info);
176     static napi_value ShowSoftKeyboard(napi_env env, napi_callback_info info);
177     static napi_value StopInputSession(napi_env env, napi_callback_info info);
178     static napi_value StopInput(napi_env env, napi_callback_info info);
179     static napi_value Subscribe(napi_env env, napi_callback_info info);
180     static napi_value UnSubscribe(napi_env env, napi_callback_info info);
181     static napi_value SendMessage(napi_env env, napi_callback_info info);
182     static napi_value RecvMessage(napi_env env, napi_callback_info info);
183     void OnSelectByRange(int32_t start, int32_t end) override;
184     void OnSelectByMovement(int32_t direction) override;
185     void InsertText(const std::u16string &text);
186     void DeleteRight(int32_t length);
187     void DeleteLeft(int32_t length);
188     void SendKeyboardStatus(const KeyboardStatus &status);
189     void SendFunctionKey(const FunctionKey &functionKey);
190     void MoveCursor(const Direction direction);
191     void HandleExtendAction(int32_t action);
192     std::u16string GetText(const std::string &type, int32_t number);
193     int32_t GetTextIndexAtCursor();
194     int32_t SetPreviewText(const std::u16string &text, const Range &range);
195     void FinishTextPreview();
196 
197     class JsMessageHandler : public MsgHandlerCallbackInterface {
198     public:
JsMessageHandler(napi_env env,napi_value onTerminated,napi_value onMessage)199         explicit JsMessageHandler(napi_env env, napi_value onTerminated, napi_value onMessage)
200             : jsMessageHandler_(std::make_shared<JSMsgHandlerCallbackObject>(env, onTerminated, onMessage)) {};
~JsMessageHandler()201         virtual ~JsMessageHandler() {};
202         int32_t OnTerminated() override;
203         int32_t OnMessage(const ArrayBuffer &arrayBuffer) override;
204     private:
205         std::mutex callbackObjectMutex_;
206         std::shared_ptr<JSMsgHandlerCallbackObject> jsMessageHandler_ = nullptr;
207     };
208 private:
209     static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo);
210     static napi_value GetIMController(napi_env env, napi_callback_info cbInfo, bool needThrowException);
211     static napi_value CreateSelectRange(napi_env env, int32_t start, int32_t end);
212     static napi_value CreateSelectMovement(napi_env env, int32_t direction);
213     static napi_value CreateSendFunctionKey(napi_env env, int32_t functionKey);
214     void RegisterListener(napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj);
215     void UnRegisterListener(napi_value callback, std::string type);
216     bool IsRegister(const std::string &type);
217     void UpdateTextPreviewState(const std::string &type);
218     static bool GetValue(napi_env env, napi_value in, CursorInfo &out);
219     static bool GetValue(napi_env env, napi_value in, InputAttribute &out);
220     static bool GetValue(napi_env env, napi_value in, TextConfig &out);
221     static bool GetValue(napi_env env, napi_value in, Range &out);
222     static napi_value GetAttachOptionsValue(napi_env env, napi_callback_info cbinfo, AttachOptions &attachOptions);
223     static napi_value GetJsKeyboardStatusProperty(napi_env env);
224     static napi_value GetJsEnterKeyTypeProperty(napi_env env);
225     static napi_value GetJsTextInputTypeProperty(napi_env env);
226     static napi_value GetJsDirectionProperty(napi_env env);
227     static napi_value GetJsExtendActionProperty(napi_env env);
228     static napi_value GetJsEnabledStateProperty(napi_env env);
229     static napi_value GetJsRequestKeyboardReasonProperty(napi_env env);
230     static std::shared_ptr<AppExecFwk::EventHandler> GetEventHandler();
231     static bool IsTextPreviewSupported();
232     static const std::set<std::string> TEXT_EVENT_TYPE;
233     static constexpr int32_t MAX_TIMEOUT = 2500;
234     struct UvEntry {
235         std::vector<std::shared_ptr<JSCallbackObject>> vecCopy;
236         std::string type;
237         std::string text;
238         int32_t start = 0;
239         int32_t end = 0;
240         int32_t direction = 0;
241         int32_t length = 0;
242         int32_t action = 0;
243         int32_t keyboardStatus = 0;
244         int32_t enterKeyType = 0;
245         int32_t number = 0;
246         std::shared_ptr<BlockData<std::string>> textResultHandler;
247         std::shared_ptr<BlockData<std::int32_t>> indexResultHandler;
UvEntryUvEntry248         explicit UvEntry(const std::vector<std::shared_ptr<JSCallbackObject>> &cbVec, const std::string &type)
249             : vecCopy(cbVec), type(type)
250         {
251         }
252     };
253     using EntrySetter = std::function<void(UvEntry &)>;
254     std::shared_ptr<UvEntry> GetEntry(const std::string &type, EntrySetter entrySetter = nullptr);
255     uv_loop_s *loop_ = nullptr;
256     std::recursive_mutex mutex_;
257     std::map<std::string, std::vector<std::shared_ptr<JSCallbackObject>>> jsCbMap_;
258     static std::mutex controllerMutex_;
259     static std::shared_ptr<JsGetInputMethodController> controller_;
260     static const std::string IMC_CLASS_NAME;
261     static thread_local napi_ref IMCRef_;
262     static std::mutex eventHandlerMutex_;
263     static std::shared_ptr<AppExecFwk::EventHandler> handler_;
264     static constexpr size_t PARAM_POS_ZERO = 0;
265     static constexpr size_t PARAM_POS_ONE = 1;
266     static constexpr size_t PARAM_POS_TWO = 2;
267     static constexpr size_t PARAM_POS_THREE = 3;
268     static BlockQueue<MessageHandlerInfo> messageHandlerQueue_;
269 };
270 } // namespace MiscServices
271 } // namespace OHOS
272 #endif // INTERFACE_KITS_JS_GET_INPUT_METHOD_CONTROLLER_H