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_util.h" 25 #include "native_engine/native_engine.h" 26 #include "native_engine/native_value.h" 27 #include "wm_common.h" 28 29 namespace OHOS { 30 namespace MiscServices { 31 struct PrivateCommandInfo { 32 std::chrono::system_clock::time_point timestamp{}; 33 std::unordered_map<std::string, PrivateDataValue> privateCommand; 34 bool operator==(const PrivateCommandInfo &info) const 35 { 36 return (timestamp == info.timestamp && privateCommand == info.privateCommand); 37 } 38 }; 39 40 struct JsRect { 41 static napi_value Write(napi_env env, const Rosen::Rect &nativeObject); 42 static bool Read(napi_env env, napi_value jsObject, Rosen::Rect &nativeObject); 43 }; 44 45 struct JsCallingWindowInfo { 46 static napi_value Write(napi_env env, const CallingWindowInfo &nativeObject); 47 static bool Read(napi_env env, napi_value object, CallingWindowInfo &nativeObject); 48 }; 49 50 struct JsRange { 51 static napi_value Write(napi_env env, const Range &nativeObject); 52 static bool Read(napi_env env, napi_value jsObject, Range &nativeObject); 53 }; 54 55 struct JsInputAttribute { 56 static napi_value Write(napi_env env, const InputAttribute &nativeObject); 57 static bool Read(napi_env env, napi_value jsObject, InputAttribute &nativeObject); 58 }; 59 60 struct SendKeyFunctionContext : public AsyncCall::Context { 61 bool isSendKeyFunction = false; 62 int32_t action = 0; 63 napi_status status = napi_generic_failure; SendKeyFunctionContextSendKeyFunctionContext64 SendKeyFunctionContext() : Context(nullptr, nullptr){}; SendKeyFunctionContextSendKeyFunctionContext65 SendKeyFunctionContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 66 operatorSendKeyFunctionContext67 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 68 { 69 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 70 return Context::operator()(env, argc, argv, self); 71 } 72 operatorSendKeyFunctionContext73 napi_status operator()(napi_env env, napi_value *result) override 74 { 75 if (status != napi_ok) { 76 output_ = nullptr; 77 return status; 78 } 79 return Context::operator()(env, result); 80 } 81 }; 82 83 struct MoveCursorContext : public AsyncCall::Context { 84 int32_t num = 0; 85 napi_status status = napi_generic_failure; MoveCursorContextMoveCursorContext86 MoveCursorContext() : Context(nullptr, nullptr){}; MoveCursorContextMoveCursorContext87 MoveCursorContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 88 operatorMoveCursorContext89 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 90 { 91 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 92 return Context::operator()(env, argc, argv, self); 93 } operatorMoveCursorContext94 napi_status operator()(napi_env env, napi_value *result) override 95 { 96 if (status != napi_ok) { 97 output_ = nullptr; 98 return status; 99 } 100 return Context::operator()(env, result); 101 } 102 }; 103 104 struct DeleteForwardContext : public AsyncCall::Context { 105 bool isDeleteForward = false; 106 int32_t length = 0; 107 napi_status status = napi_generic_failure; DeleteForwardContextDeleteForwardContext108 DeleteForwardContext() : Context(nullptr, nullptr){}; DeleteForwardContextDeleteForwardContext109 DeleteForwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 110 operatorDeleteForwardContext111 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 112 { 113 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 114 return Context::operator()(env, argc, argv, self); 115 } operatorDeleteForwardContext116 napi_status operator()(napi_env env, napi_value *result) override 117 { 118 if (status != napi_ok) { 119 output_ = nullptr; 120 return status; 121 } 122 return Context::operator()(env, result); 123 } 124 }; 125 126 struct DeleteBackwardContext : public AsyncCall::Context { 127 bool isDeleteBackward = false; 128 int32_t length = 0; 129 napi_status status = napi_generic_failure; DeleteBackwardContextDeleteBackwardContext130 DeleteBackwardContext() : Context(nullptr, nullptr){}; DeleteBackwardContextDeleteBackwardContext131 DeleteBackwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 132 operatorDeleteBackwardContext133 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 134 { 135 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 136 return Context::operator()(env, argc, argv, self); 137 } operatorDeleteBackwardContext138 napi_status operator()(napi_env env, napi_value *result) override 139 { 140 if (status != napi_ok) { 141 output_ = nullptr; 142 return status; 143 } 144 return Context::operator()(env, result); 145 } 146 }; 147 148 struct InsertTextContext : public AsyncCall::Context { 149 bool isInsertText = false; 150 std::string text; 151 napi_status status = napi_generic_failure; InsertTextContextInsertTextContext152 InsertTextContext() : Context(nullptr, nullptr){}; InsertTextContextInsertTextContext153 InsertTextContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 154 operatorInsertTextContext155 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 156 { 157 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 158 return Context::operator()(env, argc, argv, self); 159 } operatorInsertTextContext160 napi_status operator()(napi_env env, napi_value *result) override 161 { 162 if (status != napi_ok) { 163 output_ = nullptr; 164 return status; 165 } 166 return Context::operator()(env, result); 167 } 168 }; 169 170 struct GetForwardContext : public AsyncCall::Context { 171 int32_t length = 0; 172 std::string text; 173 napi_status status = napi_generic_failure; GetForwardContextGetForwardContext174 GetForwardContext() : Context(nullptr, nullptr){}; GetForwardContextGetForwardContext175 GetForwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 176 operatorGetForwardContext177 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 178 { 179 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 180 return Context::operator()(env, argc, argv, self); 181 } operatorGetForwardContext182 napi_status operator()(napi_env env, napi_value *result) override 183 { 184 if (status != napi_ok) { 185 output_ = nullptr; 186 return status; 187 } 188 return Context::operator()(env, result); 189 } 190 }; 191 192 struct GetBackwardContext : public AsyncCall::Context { 193 int32_t length = 0; 194 std::string text; 195 napi_status status = napi_generic_failure; GetBackwardContextGetBackwardContext196 GetBackwardContext() : Context(nullptr, nullptr){}; GetBackwardContextGetBackwardContext197 GetBackwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 198 operatorGetBackwardContext199 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 200 { 201 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 202 return Context::operator()(env, argc, argv, self); 203 } operatorGetBackwardContext204 napi_status operator()(napi_env env, napi_value *result) override 205 { 206 if (status != napi_ok) { 207 output_ = nullptr; 208 return status; 209 } 210 return Context::operator()(env, result); 211 } 212 }; 213 214 struct GetEditorAttributeContext : public AsyncCall::Context { 215 InputAttribute inputAttribute; GetEditorAttributeContextGetEditorAttributeContext216 GetEditorAttributeContext() : Context(nullptr, nullptr){}; GetEditorAttributeContextGetEditorAttributeContext217 GetEditorAttributeContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; operatorGetEditorAttributeContext218 napi_status operator()(napi_env env, napi_value *result) override 219 { 220 if (status_ != napi_ok) { 221 output_ = nullptr; 222 return status_; 223 } 224 return Context::operator()(env, result); 225 } 226 }; 227 228 struct SelectContext : public AsyncCall::Context { 229 int32_t start = 0; 230 int32_t end = 0; 231 int32_t direction = 0; 232 napi_status status = napi_generic_failure; SelectContextSelectContext233 SelectContext() : Context(nullptr, nullptr){}; SelectContextSelectContext234 SelectContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; operatorSelectContext235 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 236 { 237 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 238 return Context::operator()(env, argc, argv, self); 239 } operatorSelectContext240 napi_status operator()(napi_env env, napi_value *result) override 241 { 242 if (status != napi_ok) { 243 output_ = nullptr; 244 return status; 245 } 246 return Context::operator()(env, result); 247 } 248 }; 249 250 struct GetTextIndexAtCursorContext : public AsyncCall::Context { 251 int32_t index = 0; 252 napi_status status = napi_generic_failure; GetTextIndexAtCursorContextGetTextIndexAtCursorContext253 GetTextIndexAtCursorContext() : Context(nullptr, nullptr){}; GetTextIndexAtCursorContextGetTextIndexAtCursorContext254 GetTextIndexAtCursorContext(InputAction input, OutputAction output) 255 : Context(std::move(input), std::move(output)){}; 256 operatorGetTextIndexAtCursorContext257 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 258 { 259 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 260 return Context::operator()(env, argc, argv, self); 261 } operatorGetTextIndexAtCursorContext262 napi_status operator()(napi_env env, napi_value *result) override 263 { 264 if (status != napi_ok) { 265 output_ = nullptr; 266 return status; 267 } 268 return Context::operator()(env, result); 269 } 270 }; 271 272 struct SendExtendActionContext : public AsyncCall::Context { 273 int32_t action = 0; SendExtendActionContextSendExtendActionContext274 SendExtendActionContext() : Context(nullptr, nullptr){}; SendExtendActionContextSendExtendActionContext275 SendExtendActionContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; 276 operatorSendExtendActionContext277 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 278 { 279 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 280 return Context::operator()(env, argc, argv, self); 281 } operatorSendExtendActionContext282 napi_status operator()(napi_env env, napi_value *result) override 283 { 284 if (status_ != napi_ok) { 285 output_ = nullptr; 286 return status_; 287 } 288 return Context::operator()(env, result); 289 } 290 }; 291 292 struct SendPrivateCommandContext : public AsyncCall::Context { 293 std::unordered_map<std::string, PrivateDataValue> privateCommand; 294 PrivateCommandInfo info; 295 napi_status status = napi_generic_failure; SendPrivateCommandContextSendPrivateCommandContext296 SendPrivateCommandContext() : Context(nullptr, nullptr){}; 297 operatorSendPrivateCommandContext298 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 299 { 300 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 301 return Context::operator()(env, argc, argv, self); 302 } 303 operatorSendPrivateCommandContext304 napi_status operator()(napi_env env, napi_value *result) override 305 { 306 if (status != napi_ok) { 307 output_ = nullptr; 308 return status; 309 } 310 return Context::operator()(env, result); 311 } 312 }; 313 314 struct GetCallingWindowInfoContext : public AsyncCall::Context { 315 CallingWindowInfo windowInfo{}; GetCallingWindowInfoContextGetCallingWindowInfoContext316 GetCallingWindowInfoContext() : Context(nullptr, nullptr){}; operatorGetCallingWindowInfoContext317 napi_status operator()(napi_env env, napi_value *result) override 318 { 319 if (status_ != napi_ok) { 320 output_ = nullptr; 321 return status_; 322 } 323 return Context::operator()(env, result); 324 } 325 }; 326 327 struct SetPreviewTextContext : public AsyncCall::Context { 328 std::string text; 329 Range range; SetPreviewTextContextSetPreviewTextContext330 SetPreviewTextContext() : Context(nullptr, nullptr){}; operatorSetPreviewTextContext331 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 332 { 333 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 334 return Context::operator()(env, argc, argv, self); 335 } operatorSetPreviewTextContext336 napi_status operator()(napi_env env, napi_value *result) override 337 { 338 if (status_ != napi_ok) { 339 output_ = nullptr; 340 return status_; 341 } 342 return Context::operator()(env, result); 343 } 344 }; 345 346 struct FinishTextPreviewContext : public AsyncCall::Context { FinishTextPreviewContextFinishTextPreviewContext347 FinishTextPreviewContext() : Context(nullptr, nullptr){}; operatorFinishTextPreviewContext348 napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override 349 { 350 CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); 351 return Context::operator()(env, argc, argv, self); 352 } operatorFinishTextPreviewContext353 napi_status operator()(napi_env env, napi_value *result) override 354 { 355 if (status_ != napi_ok) { 356 output_ = nullptr; 357 return status_; 358 } 359 return Context::operator()(env, result); 360 } 361 }; 362 363 class JsTextInputClientEngine { 364 public: 365 JsTextInputClientEngine() = default; 366 ~JsTextInputClientEngine() = default; 367 static napi_value Init(napi_env env, napi_value info); 368 static napi_value SendKeyFunction(napi_env env, napi_callback_info info); 369 static napi_value DeleteForward(napi_env env, napi_callback_info info); 370 static napi_value DeleteBackward(napi_env env, napi_callback_info info); 371 static napi_value InsertText(napi_env env, napi_callback_info info); 372 static napi_value GetForward(napi_env env, napi_callback_info info); 373 static napi_value GetBackward(napi_env env, napi_callback_info info); 374 static napi_value MoveCursor(napi_env env, napi_callback_info info); 375 static napi_value GetEditorAttribute(napi_env env, napi_callback_info info); 376 static napi_value GetTextIndexAtCursor(napi_env env, napi_callback_info info); 377 static napi_value GetTextInputClientInstance(napi_env env); 378 static napi_value SelectByRange(napi_env env, napi_callback_info info); 379 static napi_value SelectByMovement(napi_env env, napi_callback_info info); 380 static napi_value SendExtendAction(napi_env env, napi_callback_info info); 381 static napi_value InsertTextSync(napi_env env, napi_callback_info info); 382 static napi_value MoveCursorSync(napi_env env, napi_callback_info info); 383 static napi_value GetEditorAttributeSync(napi_env env, napi_callback_info info); 384 static napi_value SelectByRangeSync(napi_env env, napi_callback_info info); 385 static napi_value SelectByMovementSync(napi_env env, napi_callback_info info); 386 static napi_value GetTextIndexAtCursorSync(napi_env env, napi_callback_info info); 387 static napi_value DeleteForwardSync(napi_env env, napi_callback_info info); 388 static napi_value DeleteBackwardSync(napi_env env, napi_callback_info info); 389 static napi_value GetForwardSync(napi_env env, napi_callback_info info); 390 static napi_value GetBackwardSync(napi_env env, napi_callback_info info); 391 static napi_value GetCallingWindowInfo(napi_env env, napi_callback_info info); 392 static napi_value SendPrivateCommand(napi_env env, napi_callback_info info); 393 static napi_value SetPreviewText(napi_env env, napi_callback_info info); 394 static napi_value SetPreviewTextSync(napi_env env, napi_callback_info info); 395 static napi_value FinishTextPreview(napi_env env, napi_callback_info info); 396 static napi_value FinishTextPreviewSync(napi_env env, napi_callback_info info); 397 398 private: 399 static napi_status GetSelectRange(napi_env env, napi_value argv, std::shared_ptr<SelectContext> ctxt); 400 static napi_status GetSelectMovement(napi_env env, napi_value argv, std::shared_ptr<SelectContext> ctxt); 401 402 static napi_value JsConstructor(napi_env env, napi_callback_info info); 403 static napi_value GetResult(napi_env env, std::string &text); 404 static napi_value GetResultEditorAttribute( 405 napi_env env, std::shared_ptr<GetEditorAttributeContext> getEditorAttribute); 406 static napi_value HandleParamCheckFailure(napi_env env); 407 static napi_status GetPreviewTextParam(napi_env env, size_t argc, napi_value *argv, std::string &text, 408 Range &range); 409 410 static const std::string TIC_CLASS_NAME; 411 static thread_local napi_ref TICRef_; 412 static std::shared_ptr<AsyncCall::TaskQueue> taskQueue_; 413 static BlockQueue<PrivateCommandInfo> privateCommandQueue_; GenerateTraceId()414 static std::string GenerateTraceId() 415 { 416 auto traceId = traceId_++; 417 return std::to_string(traceId); 418 } 419 static uint32_t traceId_; 420 }; 421 } // namespace MiscServices 422 } // namespace OHOS 423 #endif // INTERFACE_KITS_JS_NAPI_INPUTMETHODENGINE_INCLUDE_JS_TEXT_INPUT_CLIENT_H