• 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 
195     class JsMessageHandler : public MsgHandlerCallbackInterface {
196     public:
JsMessageHandler(napi_env env,napi_value onTerminated,napi_value onMessage)197         explicit JsMessageHandler(napi_env env, napi_value onTerminated, napi_value onMessage)
198             : jsMessageHandler_(std::make_shared<JSMsgHandlerCallbackObject>(env, onTerminated, onMessage)) {};
~JsMessageHandler()199         virtual ~JsMessageHandler() {};
200         int32_t OnTerminated() override;
201         int32_t OnMessage(const ArrayBuffer &arrayBuffer) override;
202     private:
203         std::mutex callbackObjectMutex_;
204         std::shared_ptr<JSMsgHandlerCallbackObject> jsMessageHandler_ = nullptr;
205     };
206 private:
207     static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo);
208     static napi_value GetIMController(napi_env env, napi_callback_info cbInfo, bool needThrowException);
209     static napi_value CreateSelectRange(napi_env env, int32_t start, int32_t end);
210     static napi_value CreateSelectMovement(napi_env env, int32_t direction);
211     static napi_value CreateSendFunctionKey(napi_env env, int32_t functionKey);
212     void RegisterListener(napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj);
213     void UnRegisterListener(napi_value callback, std::string type);
214     static bool GetValue(napi_env env, napi_value in, CursorInfo &out);
215     static bool GetValue(napi_env env, napi_value in, InputAttribute &out);
216     static bool GetValue(napi_env env, napi_value in, TextConfig &out);
217     static bool GetValue(napi_env env, napi_value in, Range &out);
218     static napi_value GetAttachOptionsValue(napi_env env, napi_callback_info cbinfo, AttachOptions &attachOptions);
219     static napi_value GetJsKeyboardStatusProperty(napi_env env);
220     static napi_value GetJsEnterKeyTypeProperty(napi_env env);
221     static napi_value GetJsTextInputTypeProperty(napi_env env);
222     static napi_value GetJsDirectionProperty(napi_env env);
223     static napi_value GetJsExtendActionProperty(napi_env env);
224     static napi_value GetJsEnabledStateProperty(napi_env env);
225     static napi_value GetJsRequestKeyboardReasonProperty(napi_env env);
226     static std::shared_ptr<AppExecFwk::EventHandler> GetEventHandler();
227     static const std::set<std::string> TEXT_EVENT_TYPE;
228     static constexpr int32_t MAX_TIMEOUT = 2500;
229     struct UvEntry {
230         std::vector<std::shared_ptr<JSCallbackObject>> vecCopy;
231         std::string type;
232         std::string text;
233         int32_t start = 0;
234         int32_t end = 0;
235         int32_t direction = 0;
236         int32_t length = 0;
237         int32_t action = 0;
238         int32_t keyboardStatus = 0;
239         int32_t enterKeyType = 0;
240         int32_t number = 0;
241         std::shared_ptr<BlockData<std::string>> textResultHandler;
242         std::shared_ptr<BlockData<std::int32_t>> indexResultHandler;
UvEntryUvEntry243         explicit UvEntry(const std::vector<std::shared_ptr<JSCallbackObject>> &cbVec, const std::string &type)
244             : vecCopy(cbVec), type(type)
245         {
246         }
247     };
248     using EntrySetter = std::function<void(UvEntry &)>;
249     std::shared_ptr<UvEntry> GetEntry(const std::string &type, EntrySetter entrySetter = nullptr);
250     uv_loop_s *loop_ = nullptr;
251     std::recursive_mutex mutex_;
252     std::map<std::string, std::vector<std::shared_ptr<JSCallbackObject>>> jsCbMap_;
253     static std::mutex controllerMutex_;
254     static std::shared_ptr<JsGetInputMethodController> controller_;
255     static const std::string IMC_CLASS_NAME;
256     static thread_local napi_ref IMCRef_;
257     static std::mutex eventHandlerMutex_;
258     static std::shared_ptr<AppExecFwk::EventHandler> handler_;
259     static constexpr size_t PARAM_POS_ZERO = 0;
260     static constexpr size_t PARAM_POS_ONE = 1;
261     static constexpr size_t PARAM_POS_TWO = 2;
262     static constexpr size_t PARAM_POS_THREE = 3;
263     static BlockQueue<MessageHandlerInfo> messageHandlerQueue_;
264 };
265 } // namespace MiscServices
266 } // namespace OHOS
267 #endif // INTERFACE_KITS_JS_GET_INPUT_METHOD_CONTROLLER_H
268