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 20 #include "async_call.h" 21 #include "block_queue.h" 22 #include "calling_window_info.h" 23 #include "global.h" 24 #include "js_message_handler_info.h" 25 #include "js_util.h" 26 #include "msg_handler_callback_interface.h" 27 #include "native_engine/native_engine.h" 28 #include "native_engine/native_value.h" 29 #include "wm_common.h" 30 31 namespace OHOS { 32 namespace MiscServices { 33 struct PrivateCommandInfo { 34 std::chrono::system_clock::time_point timestamp{}; 35 std::unordered_map<std::string, PrivateDataValue> privateCommand; 36 bool operator==(const PrivateCommandInfo &info) const 37 { 38 return (timestamp == info.timestamp && privateCommand == info.privateCommand); 39 } 40 }; 41 42 struct JsRect { 43 static napi_value Write(napi_env env, const Rosen::Rect &nativeObject); 44 static bool Read(napi_env env, napi_value jsObject, Rosen::Rect &nativeObject); 45 }; 46 47 struct JsCallingWindowInfo { 48 static napi_value Write(napi_env env, const CallingWindowInfo &nativeObject); 49 static bool Read(napi_env env, napi_value object, CallingWindowInfo &nativeObject); 50 }; 51 52 struct JsRange { 53 static napi_value Write(napi_env env, const Range &nativeObject); 54 static bool Read(napi_env env, napi_value jsObject, Range &nativeObject); 55 }; 56 57 struct JsInputAttribute { 58 static napi_value Write(napi_env env, const InputAttribute &nativeObject); 59 static bool Read(napi_env env, napi_value jsObject, InputAttribute &nativeObject); 60 }; 61 62 struct SendKeyFunctionContext : public AsyncCall::Context { 63 bool isSendKeyFunction = false; 64 int32_t action = 0; 65 napi_status status = napi_generic_failure; SendKeyFunctionContextSendKeyFunctionContext66 SendKeyFunctionContext() : Context(nullptr, nullptr){}; SendKeyFunctionContextSendKeyFunctionContext67 SendKeyFunctionContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 68 operatorSendKeyFunctionContext69 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 70 { 71 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 72 return Context::operator()(env, argc, argv, self); 73 } 74 operatorSendKeyFunctionContext75 napi_status operator()(napi_env env, napi_value *result) override 76 { 77 if (status != napi_ok) { 78 output_ = nullptr; 79 return status; 80 } 81 return Context::operator()(env, result); 82 } 83 }; 84 85 struct MoveCursorContext : public AsyncCall::Context { 86 int32_t num = 0; 87 napi_status status = napi_generic_failure; MoveCursorContextMoveCursorContext88 MoveCursorContext() : Context(nullptr, nullptr){}; MoveCursorContextMoveCursorContext89 MoveCursorContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 90 operatorMoveCursorContext91 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 92 { 93 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 94 return Context::operator()(env, argc, argv, self); 95 } operatorMoveCursorContext96 napi_status operator()(napi_env env, napi_value *result) override 97 { 98 if (status != napi_ok) { 99 output_ = nullptr; 100 return status; 101 } 102 return Context::operator()(env, result); 103 } 104 }; 105 106 struct DeleteForwardContext : public AsyncCall::Context { 107 bool isDeleteForward = false; 108 int32_t length = 0; 109 napi_status status = napi_generic_failure; DeleteForwardContextDeleteForwardContext110 DeleteForwardContext() : Context(nullptr, nullptr){}; DeleteForwardContextDeleteForwardContext111 DeleteForwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 112 operatorDeleteForwardContext113 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 114 { 115 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 116 return Context::operator()(env, argc, argv, self); 117 } operatorDeleteForwardContext118 napi_status operator()(napi_env env, napi_value *result) override 119 { 120 if (status != napi_ok) { 121 output_ = nullptr; 122 return status; 123 } 124 return Context::operator()(env, result); 125 } 126 }; 127 128 struct DeleteBackwardContext : public AsyncCall::Context { 129 bool isDeleteBackward = false; 130 int32_t length = 0; 131 napi_status status = napi_generic_failure; DeleteBackwardContextDeleteBackwardContext132 DeleteBackwardContext() : Context(nullptr, nullptr){}; DeleteBackwardContextDeleteBackwardContext133 DeleteBackwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 134 operatorDeleteBackwardContext135 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 136 { 137 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 138 return Context::operator()(env, argc, argv, self); 139 } operatorDeleteBackwardContext140 napi_status operator()(napi_env env, napi_value *result) override 141 { 142 if (status != napi_ok) { 143 output_ = nullptr; 144 return status; 145 } 146 return Context::operator()(env, result); 147 } 148 }; 149 150 struct InsertTextContext : public AsyncCall::Context { 151 bool isInsertText = false; 152 std::string text; 153 napi_status status = napi_generic_failure; InsertTextContextInsertTextContext154 InsertTextContext() : Context(nullptr, nullptr){}; InsertTextContextInsertTextContext155 InsertTextContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 156 operatorInsertTextContext157 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 158 { 159 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 160 return Context::operator()(env, argc, argv, self); 161 } operatorInsertTextContext162 napi_status operator()(napi_env env, napi_value *result) override 163 { 164 if (status != napi_ok) { 165 output_ = nullptr; 166 return status; 167 } 168 return Context::operator()(env, result); 169 } 170 }; 171 172 struct GetForwardContext : public AsyncCall::Context { 173 int32_t length = 0; 174 std::string text; 175 napi_status status = napi_generic_failure; GetForwardContextGetForwardContext176 GetForwardContext() : Context(nullptr, nullptr){}; GetForwardContextGetForwardContext177 GetForwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 178 operatorGetForwardContext179 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 180 { 181 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 182 return Context::operator()(env, argc, argv, self); 183 } operatorGetForwardContext184 napi_status operator()(napi_env env, napi_value *result) override 185 { 186 if (status != napi_ok) { 187 output_ = nullptr; 188 return status; 189 } 190 return Context::operator()(env, result); 191 } 192 }; 193 194 struct GetBackwardContext : public AsyncCall::Context { 195 int32_t length = 0; 196 std::string text; 197 napi_status status = napi_generic_failure; GetBackwardContextGetBackwardContext198 GetBackwardContext() : Context(nullptr, nullptr){}; GetBackwardContextGetBackwardContext199 GetBackwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 200 operatorGetBackwardContext201 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 202 { 203 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 204 return Context::operator()(env, argc, argv, self); 205 } operatorGetBackwardContext206 napi_status operator()(napi_env env, napi_value *result) override 207 { 208 if (status != napi_ok) { 209 output_ = nullptr; 210 return status; 211 } 212 return Context::operator()(env, result); 213 } 214 }; 215 216 struct GetEditorAttributeContext : public AsyncCall::Context { 217 InputAttribute inputAttribute; GetEditorAttributeContextGetEditorAttributeContext218 GetEditorAttributeContext() : Context(nullptr, nullptr){}; GetEditorAttributeContextGetEditorAttributeContext219 GetEditorAttributeContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; operatorGetEditorAttributeContext220 napi_status operator()(napi_env env, napi_value *result) override 221 { 222 if (status_ != napi_ok) { 223 output_ = nullptr; 224 return status_; 225 } 226 return Context::operator()(env, result); 227 } 228 }; 229 230 struct SelectContext : public AsyncCall::Context { 231 int32_t start = 0; 232 int32_t end = 0; 233 int32_t direction = 0; 234 napi_status status = napi_generic_failure; SelectContextSelectContext235 SelectContext() : Context(nullptr, nullptr){}; SelectContextSelectContext236 SelectContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; operatorSelectContext237 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 238 { 239 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 240 return Context::operator()(env, argc, argv, self); 241 } operatorSelectContext242 napi_status operator()(napi_env env, napi_value *result) override 243 { 244 if (status != napi_ok) { 245 output_ = nullptr; 246 return status; 247 } 248 return Context::operator()(env, result); 249 } 250 }; 251 252 struct GetTextIndexAtCursorContext : public AsyncCall::Context { 253 int32_t index = 0; 254 napi_status status = napi_generic_failure; GetTextIndexAtCursorContextGetTextIndexAtCursorContext255 GetTextIndexAtCursorContext() : Context(nullptr, nullptr){}; GetTextIndexAtCursorContextGetTextIndexAtCursorContext256 GetTextIndexAtCursorContext(InputAction input, OutputAction output) 257 : Context(std::move(input), std::move(output)){}; 258 operatorGetTextIndexAtCursorContext259 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 260 { 261 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 262 return Context::operator()(env, argc, argv, self); 263 } operatorGetTextIndexAtCursorContext264 napi_status operator()(napi_env env, napi_value *result) override 265 { 266 if (status != napi_ok) { 267 output_ = nullptr; 268 return status; 269 } 270 return Context::operator()(env, result); 271 } 272 }; 273 274 struct SendExtendActionContext : public AsyncCall::Context { 275 int32_t action = 0; SendExtendActionContextSendExtendActionContext276 SendExtendActionContext() : Context(nullptr, nullptr){}; SendExtendActionContextSendExtendActionContext277 SendExtendActionContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 278 operatorSendExtendActionContext279 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 280 { 281 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 282 return Context::operator()(env, argc, argv, self); 283 } operatorSendExtendActionContext284 napi_status operator()(napi_env env, napi_value *result) override 285 { 286 if (status_ != napi_ok) { 287 output_ = nullptr; 288 return status_; 289 } 290 return Context::operator()(env, result); 291 } 292 }; 293 294 struct SendPrivateCommandContext : public AsyncCall::Context { 295 std::unordered_map<std::string, PrivateDataValue> privateCommand; 296 PrivateCommandInfo info; 297 napi_status status = napi_generic_failure; SendPrivateCommandContextSendPrivateCommandContext298 SendPrivateCommandContext() : Context(nullptr, nullptr){}; 299 operatorSendPrivateCommandContext300 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 301 { 302 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 303 return Context::operator()(env, argc, argv, self); 304 } 305 operatorSendPrivateCommandContext306 napi_status operator()(napi_env env, napi_value *result) override 307 { 308 if (status != napi_ok) { 309 output_ = nullptr; 310 return status; 311 } 312 return Context::operator()(env, result); 313 } 314 }; 315 316 struct GetCallingWindowInfoContext : public AsyncCall::Context { 317 CallingWindowInfo windowInfo{}; GetCallingWindowInfoContextGetCallingWindowInfoContext318 GetCallingWindowInfoContext() : Context(nullptr, nullptr){}; operatorGetCallingWindowInfoContext319 napi_status operator()(napi_env env, napi_value *result) override 320 { 321 if (status_ != napi_ok) { 322 output_ = nullptr; 323 return status_; 324 } 325 return Context::operator()(env, result); 326 } 327 }; 328 329 struct SetPreviewTextContext : public AsyncCall::Context { 330 std::string text; 331 Range range; SetPreviewTextContextSetPreviewTextContext332 SetPreviewTextContext() : Context(nullptr, nullptr){}; operatorSetPreviewTextContext333 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 334 { 335 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 336 return Context::operator()(env, argc, argv, self); 337 } operatorSetPreviewTextContext338 napi_status operator()(napi_env env, napi_value *result) override 339 { 340 if (status_ != napi_ok) { 341 output_ = nullptr; 342 return status_; 343 } 344 return Context::operator()(env, result); 345 } 346 }; 347 348 struct FinishTextPreviewContext : public AsyncCall::Context { FinishTextPreviewContextFinishTextPreviewContext349 FinishTextPreviewContext() : Context(nullptr, nullptr){}; operatorFinishTextPreviewContext350 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 351 { 352 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 353 return Context::operator()(env, argc, argv, self); 354 } operatorFinishTextPreviewContext355 napi_status operator()(napi_env env, napi_value *result) override 356 { 357 if (status_ != napi_ok) { 358 output_ = nullptr; 359 return status_; 360 } 361 return Context::operator()(env, result); 362 } 363 }; 364 365 class JsTextInputClientEngine { 366 public: 367 JsTextInputClientEngine() = default; 368 ~JsTextInputClientEngine() = default; 369 static napi_value Init(napi_env env, napi_value info); 370 static napi_value SendKeyFunction(napi_env env, napi_callback_info info); 371 static napi_value DeleteForward(napi_env env, napi_callback_info info); 372 static napi_value DeleteBackward(napi_env env, napi_callback_info info); 373 static napi_value InsertText(napi_env env, napi_callback_info info); 374 static napi_value GetForward(napi_env env, napi_callback_info info); 375 static napi_value GetBackward(napi_env env, napi_callback_info info); 376 static napi_value MoveCursor(napi_env env, napi_callback_info info); 377 static napi_value GetEditorAttribute(napi_env env, napi_callback_info info); 378 static napi_value GetTextIndexAtCursor(napi_env env, napi_callback_info info); 379 static napi_value GetTextInputClientInstance(napi_env env); 380 static napi_value SelectByRange(napi_env env, napi_callback_info info); 381 static napi_value SelectByMovement(napi_env env, napi_callback_info info); 382 static napi_value SendExtendAction(napi_env env, napi_callback_info info); 383 static napi_value InsertTextSync(napi_env env, napi_callback_info info); 384 static napi_value MoveCursorSync(napi_env env, napi_callback_info info); 385 static napi_value GetEditorAttributeSync(napi_env env, napi_callback_info info); 386 static napi_value SelectByRangeSync(napi_env env, napi_callback_info info); 387 static napi_value SelectByMovementSync(napi_env env, napi_callback_info info); 388 static napi_value GetTextIndexAtCursorSync(napi_env env, napi_callback_info info); 389 static napi_value DeleteForwardSync(napi_env env, napi_callback_info info); 390 static napi_value DeleteBackwardSync(napi_env env, napi_callback_info info); 391 static napi_value GetForwardSync(napi_env env, napi_callback_info info); 392 static napi_value GetBackwardSync(napi_env env, napi_callback_info info); 393 static napi_value GetCallingWindowInfo(napi_env env, napi_callback_info info); 394 static napi_value SendPrivateCommand(napi_env env, napi_callback_info info); 395 static napi_value SetPreviewText(napi_env env, napi_callback_info info); 396 static napi_value SetPreviewTextSync(napi_env env, napi_callback_info info); 397 static napi_value FinishTextPreview(napi_env env, napi_callback_info info); 398 static napi_value FinishTextPreviewSync(napi_env env, napi_callback_info info); 399 static napi_value SendMessage(napi_env env, napi_callback_info info); 400 static napi_value RecvMessage(napi_env env, napi_callback_info info); 401 class JsMessageHandler : public MsgHandlerCallbackInterface { 402 public: JsMessageHandler(napi_env env,napi_value onTerminated,napi_value onMessage)403 explicit JsMessageHandler(napi_env env, napi_value onTerminated, napi_value onMessage) 404 : jsMessageHandler_(std::make_shared<JSMsgHandlerCallbackObject>(env, onTerminated, onMessage)) {}; ~JsMessageHandler()405 virtual ~JsMessageHandler() {}; 406 int32_t OnTerminated() override; 407 int32_t OnMessage(const ArrayBuffer &arrayBuffer) override; 408 409 private: 410 std::mutex callbackObjectMutex_; 411 std::shared_ptr<JSMsgHandlerCallbackObject> jsMessageHandler_ = nullptr; 412 }; 413 private: 414 static napi_status GetSelectRange(napi_env env, napi_value argv, std::shared_ptr<SelectContext> ctxt); 415 static napi_status GetSelectMovement(napi_env env, napi_value argv, std::shared_ptr<SelectContext> ctxt); 416 417 static napi_value JsConstructor(napi_env env, napi_callback_info info); 418 static napi_value GetResult(napi_env env, std::string &text); 419 static napi_value GetResultEditorAttribute( 420 napi_env env, std::shared_ptr<GetEditorAttributeContext> getEditorAttribute); 421 static napi_value HandleParamCheckFailure(napi_env env); 422 static napi_status GetPreviewTextParam(napi_env env, size_t argc, napi_value *argv, std::string &text, 423 Range &range); 424 425 static const std::string TIC_CLASS_NAME; 426 static thread_local napi_ref TICRef_; 427 static std::shared_ptr<AsyncCall::TaskQueue> taskQueue_; 428 static BlockQueue<PrivateCommandInfo> privateCommandQueue_; GenerateTraceId()429 static std::string GenerateTraceId() 430 { 431 auto traceId = traceId_++; 432 return std::to_string(traceId); 433 } 434 static uint32_t traceId_; 435 436 static BlockQueue<MessageHandlerInfo> messageHandlerQueue_; 437 }; 438 } // namespace MiscServices 439 } // namespace OHOS 440 #endif // INTERFACE_KITS_JS_NAPI_INPUTMETHODENGINE_INCLUDE_JS_TEXT_INPUT_CLIENT_H