1 /* 2 * Copyright (c) 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 16 #ifndef INPUTMETHOD_IMF_JSPANEL_H 17 #define INPUTMETHOD_IMF_JSPANEL_H 18 19 #include <mutex> 20 #include <uv.h> 21 22 #include "async_call.h" 23 #include "ffrt_block_queue.h" 24 #include "input_method_panel.h" 25 #include "js_callback_object.h" 26 #include "napi/native_api.h" 27 #include "napi/native_common.h" 28 #include "napi/native_node_api.h" 29 #include "native_engine/native_engine.h" 30 #include "native_engine/native_value.h" 31 32 namespace OHOS { 33 namespace MiscServices { 34 35 enum class JsEvent : uint32_t { 36 RESIZE = 0, 37 MOVE_TO, 38 ADJUST_PANEL_RECT, 39 UPDATE_REGION, 40 SHOW, 41 HIDE, 42 SET_UI_CONTENT, 43 GET_DISPLAYID, 44 SET_IMMERSIVE_MODE, 45 GET_IMMERSIVE_MODE, 46 EVENT_END, 47 }; 48 49 struct JsEventInfo { 50 std::chrono::system_clock::time_point timestamp{}; 51 JsEvent event{ JsEvent::EVENT_END }; 52 bool operator==(const JsEventInfo &info) const 53 { 54 return (timestamp == info.timestamp && event == info.event); 55 } 56 }; 57 58 struct JsPanelRect { 59 static napi_value Write(napi_env env, const LayoutParams &layoutParams); 60 static bool Read(napi_env env, napi_value object, LayoutParams &layoutParams); 61 }; 62 63 struct JsEnhancedPanelRect { 64 static bool Read(napi_env env, napi_value object, EnhancedLayoutParams &layoutParams); 65 }; 66 67 struct JsHotArea { 68 static bool Read(napi_env env, napi_value object, std::vector<Rosen::Rect> &hotAreas); 69 }; 70 71 class JsPanel { 72 public: 73 JsPanel() = default; 74 ~JsPanel(); 75 static napi_value Init(napi_env env); 76 static napi_value SetUiContent(napi_env env, napi_callback_info info); 77 static napi_value Resize(napi_env env, napi_callback_info info); 78 static napi_value MoveTo(napi_env env, napi_callback_info info); 79 static napi_value Show(napi_env env, napi_callback_info info); 80 static napi_value Hide(napi_env env, napi_callback_info info); 81 static napi_value ChangeFlag(napi_env env, napi_callback_info info); 82 static napi_value SetPrivacyMode(napi_env env, napi_callback_info info); 83 static napi_value Subscribe(napi_env env, napi_callback_info info); 84 static napi_value UnSubscribe(napi_env env, napi_callback_info info); 85 static napi_value AdjustPanelRect(napi_env env, napi_callback_info info); 86 static napi_value UpdateRegion(napi_env env, napi_callback_info info); 87 static napi_value StartMoving(napi_env env, napi_callback_info info); 88 static napi_value GetDisplayId(napi_env env, napi_callback_info info); 89 void SetNative(const std::shared_ptr<InputMethodPanel> &panel); 90 std::shared_ptr<InputMethodPanel> GetNative(); 91 static napi_value SetImmersiveMode(napi_env env, napi_callback_info info); 92 static napi_value GetImmersiveMode(napi_env env, napi_callback_info info); 93 94 private: 95 struct PanelContentContext : public AsyncCall::Context { 96 LayoutParams layoutParams = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; 97 EnhancedLayoutParams enhancedLayoutParams; 98 HotAreas hotAreas; 99 std::vector<Rosen::Rect> hotArea; 100 bool isEnhancedCall{ false }; 101 PanelFlag panelFlag = PanelFlag::FLG_FIXED; 102 std::string path = ""; 103 uint32_t width = 0; 104 uint32_t height = 0; 105 int32_t x = 0; 106 int32_t y = 0; 107 uint64_t displayId = 0; 108 std::shared_ptr<InputMethodPanel> inputMethodPanel = nullptr; 109 std::shared_ptr<NativeReference> contentStorage = nullptr; 110 JsEventInfo info; PanelContentContextPanelContentContext111 PanelContentContext(napi_env env, napi_callback_info info) : Context(nullptr, nullptr) 112 { 113 napi_value self = nullptr; 114 napi_status status = napi_get_cb_info(env, info, 0, nullptr, &self, nullptr); 115 CHECK_RETURN_VOID((status == napi_ok) && (self != nullptr), "get callback info failed."); 116 void *native = nullptr; 117 status = napi_unwrap(env, self, &native); 118 CHECK_RETURN_VOID((status == napi_ok) && (native != nullptr), "get jsPanel failed."); 119 inputMethodPanel = reinterpret_cast<JsPanel *>(native)->GetNative(); 120 }; PanelContentContextPanelContentContext121 PanelContentContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; operatorPanelContentContext122 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 } operatorPanelContentContext127 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 static napi_value JsNew(napi_env env, napi_callback_info info); 137 static std::shared_ptr<InputMethodPanel> UnwrapPanel(napi_env env, napi_value thisVar); 138 static void PrintEditorQueueInfoIfTimeout(int64_t start, const JsEventInfo ¤tInfo); 139 140 static bool IsEnhancedAdjust(napi_env env, napi_value *argv); 141 static bool IsPanelFlagValid(napi_env env, PanelFlag panelFlag, bool isEnhancedCalled); 142 static napi_status ParsePanelFlag(napi_env env, napi_value *argv, PanelFlag &panelFlag, bool isEnhancedCalled); 143 static napi_status CheckParam( 144 napi_env env, size_t argc, napi_value *argv, std::shared_ptr<PanelContentContext> ctxt); 145 static napi_status CheckEnhancedParam( 146 napi_env env, size_t argc, napi_value *argv, std::shared_ptr<PanelContentContext> ctxt); 147 static void AdjustLayoutParam(std::shared_ptr<PanelContentContext> ctxt); 148 static void AdjustEnhancedLayoutParam(std::shared_ptr<PanelContentContext> ctxt); 149 150 static const std::string CLASS_NAME; 151 static constexpr size_t ARGC_MAX = 6; 152 std::shared_ptr<InputMethodPanel> inputMethodPanel_ = nullptr; 153 154 static std::mutex panelConstructorMutex_; 155 static thread_local napi_ref panelConstructorRef_; 156 157 static FFRTBlockQueue<JsEventInfo> jsQueue_; 158 }; 159 } // namespace MiscServices 160 } // namespace OHOS 161 162 #endif //INPUTMETHOD_IMF_JSPANEL_H 163