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