• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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_NAPI_INPUTMETHODENGINE_INCLUDE_JS_TEXT_INPUT_CLIENT_H
16 #define INTERFACE_KITS_JS_NAPI_INPUTMETHODENGINE_INCLUDE_JS_TEXT_INPUT_CLIENT_H
17 
18 #include <unordered_map>
19 #include <mutex>
20 
21 #include "edit_async_call.h"
22 #include "block_queue.h"
23 #include "calling_window_info.h"
24 #include "global.h"
25 #include "js_callback_object.h"
26 #include "js_message_handler_info.h"
27 #include "js_util.h"
28 #include "msg_handler_callback_interface.h"
29 #include "native_engine/native_engine.h"
30 #include "native_engine/native_value.h"
31 #include "wm_common.h"
32 #include "text_input_client_listener.h"
33 #include "input_method_utils.h"
34 
35 namespace OHOS {
36 namespace MiscServices {
37 struct PrivateCommandInfo {
38     std::chrono::system_clock::time_point timestamp{};
39     std::unordered_map<std::string, PrivateDataValue> privateCommand;
40     bool operator==(const PrivateCommandInfo &info) const
41     {
42         return (timestamp == info.timestamp && privateCommand == info.privateCommand);
43     }
44 };
45 
46 struct JsRect {
47     static napi_value Write(napi_env env, const Rosen::Rect &nativeObject);
48     static bool Read(napi_env env, napi_value jsObject, Rosen::Rect &nativeObject);
49 };
50 
51 struct JsCallingWindowInfo {
52     static napi_value Write(napi_env env, const CallingWindowInfo &nativeObject);
53     static bool Read(napi_env env, napi_value object, CallingWindowInfo &nativeObject);
54 };
55 
56 struct JsRange {
57     static napi_value Write(napi_env env, const Range &nativeObject);
58     static bool Read(napi_env env, napi_value jsObject, Range &nativeObject);
59 };
60 
61 struct JsInputAttribute {
62     static napi_value Write(napi_env env, const InputAttribute &nativeObject);
63     static bool Read(napi_env env, napi_value jsObject, InputAttribute &nativeObject);
64 };
65 
66 struct JsAttachOptions {
67     static napi_value Write(napi_env env, const AttachOptions &attachOptions);
68     static bool Read(napi_env env, napi_value jsObject, AttachOptions &attachOptions);
69 };
70 
71 struct SendKeyFunctionContext : public AsyncCall::Context {
72     bool isSendKeyFunction = false;
73     int32_t action = 0;
74     napi_status status = napi_generic_failure;
SendKeyFunctionContextSendKeyFunctionContext75     SendKeyFunctionContext() : Context(nullptr, nullptr){};
SendKeyFunctionContextSendKeyFunctionContext76     SendKeyFunctionContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
77 
operatorSendKeyFunctionContext78     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
79     {
80         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
81         return Context::operator()(env, argc, argv, self);
82     }
83 
operatorSendKeyFunctionContext84     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 MoveCursorContext : public AsyncCall::Context {
95     int32_t num = 0;
96     napi_status status = napi_generic_failure;
MoveCursorContextMoveCursorContext97     MoveCursorContext() : Context(nullptr, nullptr){};
MoveCursorContextMoveCursorContext98     MoveCursorContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
99 
operatorMoveCursorContext100     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
101     {
102         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
103         return Context::operator()(env, argc, argv, self);
104     }
operatorMoveCursorContext105     napi_status operator()(napi_env env, napi_value *result) override
106     {
107         if (status != napi_ok) {
108             output_ = nullptr;
109             return status;
110         }
111         return Context::operator()(env, result);
112     }
113 };
114 
115 struct DeleteForwardContext : public AsyncCall::Context {
116     bool isDeleteForward = false;
117     int32_t length = 0;
118     napi_status status = napi_generic_failure;
DeleteForwardContextDeleteForwardContext119     DeleteForwardContext() : Context(nullptr, nullptr){};
DeleteForwardContextDeleteForwardContext120     DeleteForwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
121 
operatorDeleteForwardContext122     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
123     {
124         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
125         return Context::operator()(env, argc, argv, self);
126     }
operatorDeleteForwardContext127     napi_status operator()(napi_env env, napi_value *result) override
128     {
129         if (status != napi_ok) {
130             output_ = nullptr;
131             return status;
132         }
133         return Context::operator()(env, result);
134     }
135 };
136 
137 struct DeleteBackwardContext : public AsyncCall::Context {
138     bool isDeleteBackward = false;
139     int32_t length = 0;
140     napi_status status = napi_generic_failure;
DeleteBackwardContextDeleteBackwardContext141     DeleteBackwardContext() : Context(nullptr, nullptr){};
DeleteBackwardContextDeleteBackwardContext142     DeleteBackwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
143 
operatorDeleteBackwardContext144     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
145     {
146         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
147         return Context::operator()(env, argc, argv, self);
148     }
operatorDeleteBackwardContext149     napi_status operator()(napi_env env, napi_value *result) override
150     {
151         if (status != napi_ok) {
152             output_ = nullptr;
153             return status;
154         }
155         return Context::operator()(env, result);
156     }
157 };
158 
159 struct InsertTextContext : public AsyncCall::Context {
160     bool isInsertText = false;
161     std::string text;
162     napi_status status = napi_generic_failure;
InsertTextContextInsertTextContext163     InsertTextContext() : Context(nullptr, nullptr){};
InsertTextContextInsertTextContext164     InsertTextContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
165 
operatorInsertTextContext166     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
167     {
168         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
169         return Context::operator()(env, argc, argv, self);
170     }
operatorInsertTextContext171     napi_status operator()(napi_env env, napi_value *result) override
172     {
173         if (status != napi_ok) {
174             output_ = nullptr;
175             return status;
176         }
177         return Context::operator()(env, result);
178     }
179 };
180 
181 struct GetForwardContext : public AsyncCall::Context {
182     int32_t length = 0;
183     std::string text;
184     napi_status status = napi_generic_failure;
GetForwardContextGetForwardContext185     GetForwardContext() : Context(nullptr, nullptr){};
GetForwardContextGetForwardContext186     GetForwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
187 
operatorGetForwardContext188     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
189     {
190         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
191         return Context::operator()(env, argc, argv, self);
192     }
operatorGetForwardContext193     napi_status operator()(napi_env env, napi_value *result) override
194     {
195         if (status != napi_ok) {
196             output_ = nullptr;
197             return status;
198         }
199         return Context::operator()(env, result);
200     }
201 };
202 
203 struct GetBackwardContext : public AsyncCall::Context {
204     int32_t length = 0;
205     std::string text;
206     napi_status status = napi_generic_failure;
GetBackwardContextGetBackwardContext207     GetBackwardContext() : Context(nullptr, nullptr){};
GetBackwardContextGetBackwardContext208     GetBackwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
209 
operatorGetBackwardContext210     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
211     {
212         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
213         return Context::operator()(env, argc, argv, self);
214     }
operatorGetBackwardContext215     napi_status operator()(napi_env env, napi_value *result) override
216     {
217         if (status != napi_ok) {
218             output_ = nullptr;
219             return status;
220         }
221         return Context::operator()(env, result);
222     }
223 };
224 
225 struct GetEditorAttributeContext : public AsyncCall::Context {
226     InputAttribute inputAttribute;
GetEditorAttributeContextGetEditorAttributeContext227     GetEditorAttributeContext() : Context(nullptr, nullptr){};
GetEditorAttributeContextGetEditorAttributeContext228     GetEditorAttributeContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
operatorGetEditorAttributeContext229     napi_status operator()(napi_env env, napi_value *result) override
230     {
231         if (status_ != napi_ok) {
232             output_ = nullptr;
233             return status_;
234         }
235         return Context::operator()(env, result);
236     }
237 };
238 
239 struct SelectContext : public AsyncCall::Context {
240     int32_t start = 0;
241     int32_t end = 0;
242     int32_t direction = 0;
243     napi_status status = napi_generic_failure;
SelectContextSelectContext244     SelectContext() : Context(nullptr, nullptr){};
SelectContextSelectContext245     SelectContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
operatorSelectContext246     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
247     {
248         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
249         return Context::operator()(env, argc, argv, self);
250     }
operatorSelectContext251     napi_status operator()(napi_env env, napi_value *result) override
252     {
253         if (status != napi_ok) {
254             output_ = nullptr;
255             return status;
256         }
257         return Context::operator()(env, result);
258     }
259 };
260 
261 struct GetTextIndexAtCursorContext : public AsyncCall::Context {
262     int32_t index = 0;
263     napi_status status = napi_generic_failure;
GetTextIndexAtCursorContextGetTextIndexAtCursorContext264     GetTextIndexAtCursorContext() : Context(nullptr, nullptr){};
GetTextIndexAtCursorContextGetTextIndexAtCursorContext265     GetTextIndexAtCursorContext(InputAction input, OutputAction output)
266         : Context(std::move(input), std::move(output)){};
267 
operatorGetTextIndexAtCursorContext268     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
269     {
270         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
271         return Context::operator()(env, argc, argv, self);
272     }
operatorGetTextIndexAtCursorContext273     napi_status operator()(napi_env env, napi_value *result) override
274     {
275         if (status != napi_ok) {
276             output_ = nullptr;
277             return status;
278         }
279         return Context::operator()(env, result);
280     }
281 };
282 
283 struct SendExtendActionContext : public AsyncCall::Context {
284     int32_t action = 0;
SendExtendActionContextSendExtendActionContext285     SendExtendActionContext() : Context(nullptr, nullptr){};
SendExtendActionContextSendExtendActionContext286     SendExtendActionContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
287 
operatorSendExtendActionContext288     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
289     {
290         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
291         return Context::operator()(env, argc, argv, self);
292     }
operatorSendExtendActionContext293     napi_status operator()(napi_env env, napi_value *result) override
294     {
295         if (status_ != napi_ok) {
296             output_ = nullptr;
297             return status_;
298         }
299         return Context::operator()(env, result);
300     }
301 };
302 
303 struct SendPrivateCommandContext : public AsyncCall::Context {
304     std::unordered_map<std::string, PrivateDataValue> privateCommand;
305     PrivateCommandInfo info;
306     napi_status status = napi_generic_failure;
SendPrivateCommandContextSendPrivateCommandContext307     SendPrivateCommandContext() : Context(nullptr, nullptr){};
308 
operatorSendPrivateCommandContext309     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
310     {
311         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
312         return Context::operator()(env, argc, argv, self);
313     }
314 
operatorSendPrivateCommandContext315     napi_status operator()(napi_env env, napi_value *result) override
316     {
317         if (status != napi_ok) {
318             output_ = nullptr;
319             return status;
320         }
321         return Context::operator()(env, result);
322     }
323 };
324 
325 struct GetCallingWindowInfoContext : public AsyncCall::Context {
326     CallingWindowInfo windowInfo{};
GetCallingWindowInfoContextGetCallingWindowInfoContext327     GetCallingWindowInfoContext() : Context(nullptr, nullptr){};
operatorGetCallingWindowInfoContext328     napi_status operator()(napi_env env, napi_value *result) override
329     {
330         if (status_ != napi_ok) {
331             output_ = nullptr;
332             return status_;
333         }
334         return Context::operator()(env, result);
335     }
336 };
337 
338 struct SetPreviewTextContext : public AsyncCall::Context {
339     std::string text;
340     Range range;
SetPreviewTextContextSetPreviewTextContext341     SetPreviewTextContext() : Context(nullptr, nullptr){};
operatorSetPreviewTextContext342     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
343     {
344         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
345         return Context::operator()(env, argc, argv, self);
346     }
operatorSetPreviewTextContext347     napi_status operator()(napi_env env, napi_value *result) override
348     {
349         if (status_ != napi_ok) {
350             output_ = nullptr;
351             return status_;
352         }
353         return Context::operator()(env, result);
354     }
355 };
356 
357 struct FinishTextPreviewContext : public AsyncCall::Context {
FinishTextPreviewContextFinishTextPreviewContext358     FinishTextPreviewContext() : Context(nullptr, nullptr){};
operatorFinishTextPreviewContext359     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
360     {
361         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
362         return Context::operator()(env, argc, argv, self);
363     }
operatorFinishTextPreviewContext364     napi_status operator()(napi_env env, napi_value *result) override
365     {
366         if (status_ != napi_ok) {
367             output_ = nullptr;
368             return status_;
369         }
370         return Context::operator()(env, result);
371     }
372 };
373 
374 class JsTextInputClientEngine : public TextInputClientListener {
375 public:
376     JsTextInputClientEngine() = default;
377     ~JsTextInputClientEngine() = default;
378     static napi_value Init(napi_env env, napi_value info);
379     static napi_value SendKeyFunction(napi_env env, napi_callback_info info);
380     static napi_value DeleteForward(napi_env env, napi_callback_info info);
381     static napi_value DeleteBackward(napi_env env, napi_callback_info info);
382     static napi_value InsertText(napi_env env, napi_callback_info info);
383     static napi_value GetForward(napi_env env, napi_callback_info info);
384     static napi_value GetBackward(napi_env env, napi_callback_info info);
385     static napi_value MoveCursor(napi_env env, napi_callback_info info);
386     static napi_value GetEditorAttribute(napi_env env, napi_callback_info info);
387     static napi_value GetTextIndexAtCursor(napi_env env, napi_callback_info info);
388     static napi_value GetTextInputClientInstance(napi_env env);
389     static napi_value SelectByRange(napi_env env, napi_callback_info info);
390     static napi_value SelectByMovement(napi_env env, napi_callback_info info);
391     static napi_value SendExtendAction(napi_env env, napi_callback_info info);
392     static napi_value InsertTextSync(napi_env env, napi_callback_info info);
393     static napi_value MoveCursorSync(napi_env env, napi_callback_info info);
394     static napi_value GetEditorAttributeSync(napi_env env, napi_callback_info info);
395     static napi_value SelectByRangeSync(napi_env env, napi_callback_info info);
396     static napi_value SelectByMovementSync(napi_env env, napi_callback_info info);
397     static napi_value GetTextIndexAtCursorSync(napi_env env, napi_callback_info info);
398     static napi_value DeleteForwardSync(napi_env env, napi_callback_info info);
399     static napi_value DeleteBackwardSync(napi_env env, napi_callback_info info);
400     static napi_value GetForwardSync(napi_env env, napi_callback_info info);
401     static napi_value GetBackwardSync(napi_env env, napi_callback_info info);
402     static napi_value GetCallingWindowInfo(napi_env env, napi_callback_info info);
403     static napi_value SendPrivateCommand(napi_env env, napi_callback_info info);
404     static napi_value SetPreviewText(napi_env env, napi_callback_info info);
405     static napi_value SetPreviewTextSync(napi_env env, napi_callback_info info);
406     static napi_value FinishTextPreview(napi_env env, napi_callback_info info);
407     static napi_value FinishTextPreviewSync(napi_env env, napi_callback_info info);
408     static napi_value SendMessage(napi_env env, napi_callback_info info);
409     static napi_value RecvMessage(napi_env env, napi_callback_info info);
410     static napi_value GetAttachOptions(napi_env env, napi_callback_info info);
411     static napi_value Subscribe(napi_env env, napi_callback_info info);
412     static napi_value UnSubscribe(napi_env env, napi_callback_info info);
413     void OnAttachOptionsChanged(const AttachOptions &attachOptions) override;
414     class JsMessageHandler : public MsgHandlerCallbackInterface {
415     public:
JsMessageHandler(napi_env env,napi_value onTerminated,napi_value onMessage)416         explicit JsMessageHandler(napi_env env, napi_value onTerminated, napi_value onMessage)
417             : jsMessageHandler_(std::make_shared<JSMsgHandlerCallbackObject>(env, onTerminated, onMessage)) {};
~JsMessageHandler()418         virtual ~JsMessageHandler() {};
419         int32_t OnTerminated() override;
420         int32_t OnMessage(const ArrayBuffer &arrayBuffer) override;
421 
422     private:
423         std::mutex callbackObjectMutex_;
424         std::shared_ptr<JSMsgHandlerCallbackObject> jsMessageHandler_ = nullptr;
425     };
426 private:
427     static napi_status GetSelectRange(napi_env env, napi_value argv, std::shared_ptr<SelectContext> ctxt);
428     static napi_status GetSelectMovement(napi_env env, napi_value argv, std::shared_ptr<SelectContext> ctxt);
429 
430     static napi_value JsConstructor(napi_env env, napi_callback_info info);
431     static std::shared_ptr<JsTextInputClientEngine> GetTextInputClientEngine();
432     static bool InitTextInputClientEngine();
433     static napi_value GetResult(napi_env env, std::string &text);
434     static napi_value GetResultEditorAttribute(napi_env env,
435         std::shared_ptr<GetEditorAttributeContext> getEditorAttribute);
436     static napi_value HandleParamCheckFailure(napi_env env);
437     static napi_status GetPreviewTextParam(napi_env env, size_t argc, napi_value *argv, std::string &text,
438         Range &range);
439     static bool IsTargetDeviceType(int32_t resDeviceType);
440     void RegisterListener(napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj);
441     void UnRegisterListener(napi_value callback, std::string type);
442 
443     struct UvEntry {
444         std::vector<std::shared_ptr<JSCallbackObject>> vecCopy;
445         std::string type;
446         AttachOptions attachOptions;
UvEntryUvEntry447         explicit UvEntry(const std::vector<std::shared_ptr<JSCallbackObject>> &cbVec, const std::string &type)
448             : vecCopy(cbVec), type(type)
449         {
450         }
451     };
452     using EntrySetter = std::function<void(UvEntry &)>;
453     static std::shared_ptr<AppExecFwk::EventHandler> GetEventHandler();
454     std::shared_ptr<UvEntry> GetEntry(const std::string &type, EntrySetter entrySetter = nullptr);
455     std::recursive_mutex mutex_;
456     std::map<std::string, std::vector<std::shared_ptr<JSCallbackObject>>> jsCbMap_;
457 
458     static const std::string TIC_CLASS_NAME;
459     static thread_local napi_ref TICRef_;
460     static std::shared_ptr<AsyncCall::TaskQueue> taskQueue_;
461     static BlockQueue<PrivateCommandInfo> privateCommandQueue_;
GenerateTraceId()462     static std::string GenerateTraceId()
463     {
464         auto traceId = traceId_++;
465         return std::to_string(traceId);
466     }
467     static uint32_t traceId_;
468 
469     static BlockQueue<MessageHandlerInfo> messageHandlerQueue_;
470     static std::mutex engineMutex_;
471     static std::shared_ptr<JsTextInputClientEngine> textInputClientEngine_;
472     static std::mutex eventHandlerMutex_;
473     static std::shared_ptr<AppExecFwk::EventHandler> handler_;
474     static int32_t deviceTypeCache_;
475 };
476 } // namespace MiscServices
477 } // namespace OHOS
478 #endif // INTERFACE_KITS_JS_NAPI_INPUTMETHODENGINE_INCLUDE_JS_TEXT_INPUT_CLIENT_H