diff --git a/ace_config.gni b/ace_config.gni index 250bb8cf051..8e805b203b2 100644 --- a/ace_config.gni +++ b/ace_config.gni @@ -18,8 +18,7 @@ ace_flutter_engine_root = "//third_party/flutter" ace_test_output_root = "ace_engine_standard" -objcopy_arm = "//prebuilts/gcc/linux-x86/arm/gcc-linaro-7.5.0-arm-linux-gnueabi/arm-linux-gnueabi/bin/objcopy" -objcopy_aarch64 = "//prebuilts/gcc/linux-x86/aarch64/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/bin/objcopy" +objcopy_aarch64 = "//prebuilts/gcc/linux-x86/arm/gcc-linaro-7.5.0-arm-linux-gnueabi/arm-linux-gnueabi/bin/objcopy" objcopy_x86_64 = "" ark_tools_root = "//prebuilts/ace-toolkit/ace-loader/panda" node_js_path = "//prebuilts/ace-toolkit/nodejs/node-v12.18.4-linux-x64/bin/" diff --git a/adapter/ohos/cpp/ace_ability.cpp b/adapter/ohos/cpp/ace_ability.cpp index 50d6d12fb7e..032584263fc 100644 --- a/adapter/ohos/cpp/ace_ability.cpp +++ b/adapter/ohos/cpp/ace_ability.cpp @@ -164,12 +164,93 @@ const std::string AceAbility::PAGE_URI = "url"; const std::string AceAbility::CONTINUE_PARAMS_KEY = "__remoteData"; REGISTER_AA(AceAbility) + +int32_t g_dialogId = 1; +const std::string WINDOW_DIALOG_DOUBLE_BUTTON = "pages/dialog/dialog.js"; + +void showDialog(OHOS::sptr window, std::string jsBoudle, std::string param, DialogCallback callback) +{ + LOGI("showDialog"); + + SetHwIcuDirectory(); + // create container + Platform::AceContainer::CreateContainer( + g_dialogId, FrontendType::JS, false, nullptr, + std::make_unique([]() { + //TerminateAbility(); + })); + Platform::AceContainer::SetDialogCallback(g_dialogId, callback); + // create view. + auto flutterAceView = Platform::FlutterAceView::CreateView(g_dialogId); + // window->Resize(460, 700); + auto&& touchEventCallback = [aceView = flutterAceView](OHOS::TouchEvent event) -> bool { + LOGD("RegistOnTouchCb touchEventCallback called"); + return aceView->DispatchTouchEvent(aceView, event); + }; + window->OnTouch(touchEventCallback); + + // register surface change callback + auto&& surfaceChangedCallBack = [flutterAceView](uint32_t width, uint32_t height) { + LOGD("RegistWindowInfoChangeCb surfaceChangedCallBack called"); + flutter::ViewportMetrics metrics; + metrics.physical_width = width; + metrics.physical_height = height; + Platform::FlutterAceView::SetViewportMetrics(flutterAceView, metrics); + Platform::FlutterAceView::SurfaceChanged(flutterAceView, width, height, 0); + }; + window->OnSizeChange(surfaceChangedCallBack); + Platform::FlutterAceView::SurfaceCreated(flutterAceView, window); + + // set metrics + BufferRequestConfig windowConfig = { + .width = window->GetSurface()->GetDefaultWidth(), + .height = window->GetSurface()->GetDefaultHeight(), + .strideAlignment = 0x8, + .format = PIXEL_FMT_RGBA_8888, + .usage = window->GetSurface()->GetDefaultUsage(), + }; + LOGI("AceAbility: windowConfig: width: %{public}d, height: %{public}d", windowConfig.width, windowConfig.height); + + flutter::ViewportMetrics metrics; + metrics.physical_width = windowConfig.width; + metrics.physical_height = windowConfig.height; + Platform::FlutterAceView::SetViewportMetrics(flutterAceView, metrics); + + // add asset path. + auto packagePathStr = "system/dialog/"; + auto assetBasePathStr = { std::string("assets/js/default/"), std::string("assets/js/share/") }; + Platform::AceContainer::AddAssetPath(g_dialogId, packagePathStr, assetBasePathStr); + + // set view + Platform::AceContainer::SetView(flutterAceView, 1.0f, windowConfig.width, windowConfig.height); + Platform::FlutterAceView::SurfaceChanged(flutterAceView, windowConfig.width, windowConfig.height, 0); + + // set window id + auto context = Platform::AceContainer::GetContainer(g_dialogId)->GetPipelineContext(); + if (context != nullptr) { + context->SetWindowId(window->GetID()); + } + + // run page. + Platform::AceContainer::RunPage( + g_dialogId, Platform::AceContainer::GetContainer(g_dialogId)->GeneratePageId(), + jsBoudle, param); + + g_dialogId++; +} + +void DialogHandle1(std::string event, std::string param) +{ + LOGI("DialogHandle1 event=%{public}s, param=%{public}s", event.c_str(), param.c_str()); +} + void AceAbility::OnStart(const Want& want) { Ability::OnStart(want); LOGI("AceAbility::OnStart called"); SetHwIcuDirectory(); + bool isSystemUI = false; std::unique_ptr resConfig(Global::Resource::CreateResConfig()); auto resourceManager = GetResourceManager(); @@ -194,6 +275,10 @@ void AceAbility::OnStart(const Want& want) if (moduleInfo != nullptr) { packagePathStr += "/" + moduleInfo->name + "/"; } + if ((packagePathStr.find("systemui") != -1) || (packagePathStr.find("launcher") != -1)) { + isSystemUI = true; + } + FrontendType frontendType = GetFrontendTypeFromManifest(packagePathStr); bool isArkApp = GetIsArkFromConfig(packagePathStr); @@ -295,6 +380,12 @@ void AceAbility::OnStart(const Want& want) parsedPageUrl, want.GetStringParam(START_PARAMS_KEY)); Platform::AceContainer::OnRestoreData(abilityId_, remoteData_); + if (!isSystemUI && (moduleInfo->name.find("ohos.istone.system.dialog")) != -1) { + std::string dialogParam = "{\"title\":\"Alert!\", \"message\":\"Two button style!\"," \ + "\"button1\":\"Got it!\", \"button2\":\"Cancel!\"}"; + showDialog(Ability::GetWindow(), WINDOW_DIALOG_DOUBLE_BUTTON, dialogParam, DialogHandle1); + return; + } LOGI("AceAbility::OnStart called End"); } diff --git a/adapter/ohos/cpp/ace_ability.h b/adapter/ohos/cpp/ace_ability.h index bdb447b248f..567db094951 100644 --- a/adapter/ohos/cpp/ace_ability.h +++ b/adapter/ohos/cpp/ace_ability.h @@ -23,6 +23,8 @@ #include "want.h" namespace OHOS::Ace { +using DialogCallback = std::function; +void showDialog(OHOS::sptr window, std::string jsBoudle, std::string param, DialogCallback callback); class AceAbility final : public OHOS::AppExecFwk::Ability { public: diff --git a/adapter/ohos/cpp/ace_container.cpp b/adapter/ohos/cpp/ace_container.cpp index 75bed45a25e..752602d3db7 100644 --- a/adapter/ohos/cpp/ace_container.cpp +++ b/adapter/ohos/cpp/ace_container.cpp @@ -666,4 +666,16 @@ void AceContainer::SetWindowStyle(int32_t instanceId, WindowModal windowModal, C container->SetWindowModal(windowModal); container->SetColorScheme(colorScheme); } + +void AceContainer::SetDialogCallback(int32_t instanceId, DialogCallback callback) +{ + auto container = AceEngine::Get().GetContainer(instanceId); + if (!container) { + return; + } + auto front = container->GetFrontend(); + if (front && front->GetType() == FrontendType::JS) { + front->SetDialogCallback(callback); + } +} } // namespace OHOS::Ace::Platform diff --git a/adapter/ohos/cpp/ace_container.h b/adapter/ohos/cpp/ace_container.h index 83e9358ae0b..2b234bdeaac 100644 --- a/adapter/ohos/cpp/ace_container.h +++ b/adapter/ohos/cpp/ace_container.h @@ -25,6 +25,7 @@ #include "base/utils/noncopyable.h" #include "core/common/ace_view.h" #include "core/common/container.h" +#include "core/common/frontend.h" #include "core/common/js_message_dispatcher.h" namespace OHOS::Ace::Platform { @@ -157,7 +158,7 @@ public: static RefPtr GetContainer(int32_t instanceId); static bool UpdatePage(int32_t instanceId, int32_t pageId, const std::string& content); - + static void SetDialogCallback(int32_t instanceId, DialogCallback callback); private: void InitializeFrontend(); void InitializeCallback(); diff --git a/adapter/ohos/cpp/ace_form_ability.cpp b/adapter/ohos/cpp/ace_form_ability.cpp index d7fe813dbd8..2a5f4725a2d 100755 --- a/adapter/ohos/cpp/ace_form_ability.cpp +++ b/adapter/ohos/cpp/ace_form_ability.cpp @@ -51,12 +51,38 @@ private: FormPlatformFinish onFinish_; }; -int64_t AceFormAbility::instanceId_ = 0; -const std::string AceFormAbility::START_PARAMS_KEY = "__startParams"; const std::string AceFormAbility::URI = "url"; REGISTER_AA(AceFormAbility) +void AceFormAbility::OnStart(const OHOS::AAFwk::Want &want) +{ + LOGI("AceFormAbility::OnStart start"); + Ability::OnStart(want); + return; +} + +void AceFormAbility::OnStop() +{ + LOGI("AceFormAbility::OnStop start "); + Ability::OnStop(); + return; +} + +sptr AceFormAbility::OnConnect(const Want &want) +{ + LOGI("AceFormAbility::OnConnect start"); + Ability::OnConnect(want); + return GetFormRemoteObject(); +} + +void AceFormAbility::OnDisconnect(const Want &want) +{ + LOGI("AceFormAbility::OnDisconnect start"); + Ability::OnDisconnect(want); + return; +} + OHOS::AppExecFwk::FormProviderInfo AceFormAbility::OnCreate(const OHOS::AAFwk::Want& want) { LOGI("AceFormAbility::OnCreate called"); @@ -130,32 +156,4 @@ void AceFormAbility::OnAcquireState(const OHOS::AAFwk::Want& want) Platform::PaContainer::OnAcquireState(want); } -void AceFormAbility::OnStart(const OHOS::AAFwk::Want &want) -{ - LOGI("AceFormAbility::OnStart start"); - Ability::OnStart(want); - return; -} - -void AceFormAbility::OnStop() -{ - LOGI("AceFormAbility::OnStop start "); - Ability::OnStop(); - return; -} - -sptr AceFormAbility::OnConnect(const Want &want) -{ - LOGI("AceFormAbility::OnConnect start"); - Ability::OnConnect(want); - return GetFormRemoteObject(); -} - -void AceFormAbility::OnDisconnect(const Want &want) -{ - LOGI("AceFormAbility::OnDisconnect start"); - Ability::OnDisconnect(want); - return; -} - } // namespace OHOS::Ace diff --git a/adapter/ohos/cpp/ace_form_ability.h b/adapter/ohos/cpp/ace_form_ability.h index 7c36995f8fd..9d42a5465a8 100755 --- a/adapter/ohos/cpp/ace_form_ability.h +++ b/adapter/ohos/cpp/ace_form_ability.h @@ -28,8 +28,6 @@ class AceFormAbility final : public OHOS::AppExecFwk::Ability { public: AceFormAbility() { - abilityId_ = instanceId_; - instanceId_++; } virtual ~AceFormAbility() = default; void OnStart(const OHOS::AAFwk::Want& want) override; @@ -37,75 +35,16 @@ public: sptr OnConnect(const OHOS::AAFwk::Want &want) override; void OnDisconnect(const OHOS::AAFwk::Want &want) override; - /** - * @brief Called to return a FormProviderInfo object. - * - *

You must override this method if your ability will serve as a form provider to provide a form for clients. - * The default implementation returns nullptr.

- * - * @param want Indicates the detailed information for creating a FormProviderInfo. - * The Want object must include the form ID, form name of the form, - * which can be obtained from Ability#PARAM_FORM_IDENTITY_KEY, - * Ability#PARAM_FORM_NAME_KEY, and Ability#PARAM_FORM_DIMENSION_KEY, - * respectively. Such form information must be managed as persistent data for further form - * acquisition, update, and deletion. - * - * @return Returns the created FormProviderInfo object. - */ virtual OHOS::AppExecFwk::FormProviderInfo OnCreate(const OHOS::AAFwk::Want &want) override; - - /** - * @brief Called to notify the form provider that a specified form has been deleted. Override this method if - * you want your application, as the form provider, to be notified of form deletion. - * - * @param formId Indicates the ID of the deleted form. - * @return None. - */ virtual void OnDelete(const int64_t formId) override; - - /** - * @brief Called to notify the form provider to update a specified form. - * - * @param formId Indicates the ID of the form to update. - * @param message Form event message. - */ virtual void OnTriggerEvent(const int64_t formId, const std::string &message) override; - - /** - * @brief Called to notify the form provider to update a specified form. - * - * @param formId Indicates the ID of the form to update. - * @return none. - */ virtual void OnUpdate(const int64_t formId) override; - - /** - * @brief Called when the form provider is notified that a temporary form is successfully converted to - * a normal form. - * - * @param formId Indicates the ID of the form. - * @return None. - */ virtual void OnCastTemptoNormal(const int64_t formId) override; - - /** - * @brief Called when the form provider receives form events from the fms. - * - * @param formEventsMap Indicates the form events occurred. The key in the Map object indicates the form ID, - * and the value indicates the event type, which can be either FORM_VISIBLE - * or FORM_INVISIBLE. FORM_VISIBLE means that the form becomes visible, - * and FORM_INVISIBLE means that the form becomes invisible. - * @return none. - */ virtual void OnVisibilityChanged(const std::map& formEventsMap) override; - // Wait for AAfwk support this callback. virtual void OnAcquireState(const OHOS::AAFwk::Want &want); private: - int64_t abilityId_ = 0; - static int64_t instanceId_; - static const std::string START_PARAMS_KEY; static const std::string URI; }; } // namespace OHOS::Ace diff --git a/adapter/ohos/cpp/ace_service_ability.cpp b/adapter/ohos/cpp/ace_service_ability.cpp index 4124ba68fe1..ce8d50b43f9 100644 --- a/adapter/ohos/cpp/ace_service_ability.cpp +++ b/adapter/ohos/cpp/ace_service_ability.cpp @@ -63,11 +63,6 @@ void AceServiceAbility::OnStart(const OHOS::AAFwk::Want &want) Ability::OnStart(want); LOGI("AceServiceAbility::OnStart called"); - if (type_ == BackendType::FORM) { - LOGI("AceServiceAbility::OnStart is form"); - return; - } - // get url std::string parsedUrl; if (want.HasParameter(URI)) { @@ -118,10 +113,6 @@ void AceServiceAbility::OnStop() sptr AceServiceAbility::OnConnect(const Want &want) { LOGI("AceServiceAbility::OnConnect start"); - if (type_ == BackendType::FORM) { - LOGI("AceServiceAbility::OnConnect is form"); - return GetFormRemoteObject(); - } Ability::OnConnect(want); auto ret = Platform::PaContainer::OnConnect(abilityId_, want); if (ret == nullptr) { @@ -140,82 +131,5 @@ void AceServiceAbility::OnDisconnect(const Want &want) LOGI("AceServiceAbility::OnDisconnect end"); } -OHOS::AppExecFwk::FormProviderInfo AceServiceAbility::OnCreate(const OHOS::AAFwk::Want& want) -{ - LOGI("AceServiceAbility::OnCreate called"); - // get url - std::string parsedUrl; - if (want.HasParameter(URI)) { - parsedUrl = want.GetStringParam(URI); - } else { - parsedUrl = "app.js"; - } - - int32_t wantId = abilityId_; - if (want.HasParameter(AppExecFwk::Constants::PARAM_FORM_IDENTITY_KEY)) { - std::string wantIdStr = want.GetStringParam(AppExecFwk::Constants::PARAM_FORM_IDENTITY_KEY); - wantId = atoi(wantIdStr.c_str()); - LOGI("AceServiceAbility:: wantId = %{public}s, %{public}d", wantIdStr.c_str(), wantId); - } else { - LOGE("AceServiceAbility:: has not formId in want"); - } - - // init service - BackendType backendType = BackendType::FORM; - Platform::PaContainer::CreateContainer( - wantId, backendType, this, - std::make_unique([this]() { - TerminateAbility(); - })); - - // get asset - auto packagePathStr = GetBundleCodePath(); - auto moduleInfo = GetHapModuleInfo(); - if (moduleInfo != nullptr) { - packagePathStr += "/" + moduleInfo->name + "/"; - } - auto assetBasePathStr = {std::string("assets/js/default/"), std::string("assets/js/share/")}; - Platform::PaContainer::AddAssetPath(wantId, packagePathStr, assetBasePathStr); - - // run service - Platform::PaContainer::RunPa(wantId, parsedUrl, want); - - OHOS::AppExecFwk::FormProviderInfo formProviderInfo; - formProviderInfo.SetFormData(Platform::PaContainer::GetFormData(wantId)); - std::string formData = formProviderInfo.GetFormData().GetDataString(); - LOGI("AceServiceAbility::OnCreate return ok, formData: %{public}s", formData.c_str()); - return formProviderInfo; -} - -void AceServiceAbility::OnDelete(const int64_t formId) -{ - Platform::PaContainer::OnDelete(formId); -} - -void AceServiceAbility::OnTriggerEvent(const int64_t formId, const std::string& message) -{ - Platform::PaContainer::OnTriggerEvent(formId, message); -} - -void AceServiceAbility::OnUpdate(const int64_t formId) -{ - Platform::PaContainer::OnUpdate(formId); -} - -void AceServiceAbility::OnCastTemptoNormal(const int64_t formId) -{ - Platform::PaContainer::OnCastTemptoNormal(formId); -} - -void AceServiceAbility::OnVisibilityChanged(const std::map& formEventsMap) -{ - Platform::PaContainer::OnVisibilityChanged(formEventsMap); -} - -void AceServiceAbility::OnAcquireState(const OHOS::AAFwk::Want& want) -{ - Platform::PaContainer::OnAcquireState(want); -} - } } // namespace OHOS::Ace diff --git a/adapter/ohos/cpp/ace_service_ability.h b/adapter/ohos/cpp/ace_service_ability.h index 86e4eb121b3..77c31bcc222 100644 --- a/adapter/ohos/cpp/ace_service_ability.h +++ b/adapter/ohos/cpp/ace_service_ability.h @@ -39,21 +39,12 @@ public: sptr OnConnect(const OHOS::AAFwk::Want &want) override; void OnDisconnect(const OHOS::AAFwk::Want &want) override; - virtual OHOS::AppExecFwk::FormProviderInfo OnCreate(const OHOS::AAFwk::Want &want) override; - virtual void OnDelete(const int64_t formId) override; - virtual void OnTriggerEvent(const int64_t formId, const std::string &message) override; - virtual void OnUpdate(const int64_t formId) override; - virtual void OnCastTemptoNormal(const int64_t formId) override; - virtual void OnVisibilityChanged(const std::map& formEventsMap) override; - virtual void OnAcquireState(const OHOS::AAFwk::Want &want); - private: int32_t abilityId_ = 100000; static int32_t instanceId_; static const std::string START_PARAMS_KEY; static const std::string URI; - BackendType type_ = BackendType::FORM; }; } // namespace OHOS::Ace #endif // FOUNDATION_ACE_ACE_ENGINE_ADAPTER_OHOS_CPP_ACE_SERVICE_ABILITY_H diff --git a/adapter/ohos/interfaces/napi/kits/prompt/js_prompt.cpp b/adapter/ohos/interfaces/napi/kits/prompt/js_prompt.cpp index 16600a7b9de..f1fd82a25e9 100644 --- a/adapter/ohos/interfaces/napi/kits/prompt/js_prompt.cpp +++ b/adapter/ohos/interfaces/napi/kits/prompt/js_prompt.cpp @@ -59,6 +59,8 @@ static napi_value JSPromptShowToast(napi_env env, napi_callback_info info) napi_value messageNApi = nullptr; napi_value durationNApi = nullptr; napi_value bottomNApi = nullptr; + std::string messageString; + std::string bottomString; napi_valuetype valueType = napi_undefined; napi_typeof(env, argv, &valueType); @@ -66,20 +68,34 @@ static napi_value JSPromptShowToast(napi_env env, napi_callback_info info) napi_get_named_property(env, argv, "message", &messageNApi); napi_get_named_property(env, argv, "duration", &durationNApi); napi_get_named_property(env, argv, "bottom", &bottomNApi); + } else { + return nullptr; } size_t ret = 0; - size_t messageLen = GetParamLen(messageNApi); - std::unique_ptr message(new char[messageLen] { 0 }); - napi_get_value_string_utf8(env, messageNApi, message.get(), messageLen, &ret); - - size_t bottomLen = GetParamLen(bottomNApi); - std::unique_ptr bottom(new char[messageLen] { 0 }); - napi_get_value_string_utf8(env, bottomNApi, bottom.get(), bottomLen, &ret); + napi_typeof(env, messageNApi, &valueType); + if (valueType == napi_string) { + size_t messageLen = GetParamLen(messageNApi) + 1; + std::unique_ptr message = std::make_unique(messageLen); + napi_get_value_string_utf8(env, messageNApi, message.get(), messageLen, &ret); + messageString = message.get(); + } else { + LOGE("The paramter type is incorrect"); + return nullptr; + } int32_t duration = -1; - napi_get_value_int32(env, bottomNApi, &duration); - std::string messageString = message.get(); - std::string bottomString = bottom.get(); + napi_typeof(env, durationNApi, &valueType); + if (valueType == napi_number) { + napi_get_value_int32(env, durationNApi, &duration); + } + + napi_typeof(env, bottomNApi, &valueType); + if (valueType == napi_string) { + size_t bottomLen = GetParamLen(bottomNApi) + 1; + std::unique_ptr message = std::make_unique(bottomLen); + napi_get_value_string_utf8(env, bottomNApi, message.get(), bottomLen, &ret); + bottomString = message.get(); + } OHOS::Ace::Framework::JsEngine* jsEngine = nullptr; napi_get_jsEngine(env, (void**)&jsEngine); diff --git a/frameworks/bridge/BUILD.gn b/frameworks/bridge/BUILD.gn index 0adcef7be5a..2a705c19d38 100644 --- a/frameworks/bridge/BUILD.gn +++ b/frameworks/bridge/BUILD.gn @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import("//ark/ts2abc/ts2panda/ts2abc_config.gni") import("//build/ohos.gni") import("//foundation/ace/ace_engine/ace_config.gni") @@ -581,22 +582,67 @@ gen_obj("js_enum_style") { snapshot_dep = [] } +# compile stateMgmt.js, jsEnumStyle.js to stateMgmt.abc, jsEnumStyle.abc. +action("gen_stateMgmt_abc") { + visibility = [ ":*" ] + + deps = [ "//ark/ts2abc/ts2panda:ark_ts2abc_build" ] + + script = "//ark/ts2abc/ts2panda/scripts/generate_js_bytecode.py" + + args = [ + "--src-js", + rebase_path( + "//foundation/ace/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js"), + "--dst-file", + rebase_path(base_output_path + "/stateMgmt.abc"), + "--node", + rebase_path("${node_path}"), + "--frontend-tool-path", + rebase_path("${ts2abc_build_path}"), + "--node-modules", + rebase_path("${node_modules}"), + ] + + inputs = [ "//foundation/ace/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js" ] + outputs = [ base_output_path + "/stateMgmt.abc" ] +} + +action("gen_jsEnumStyle_abc") { + visibility = [ ":*" ] + + deps = [ "//ark/ts2abc/ts2panda:ark_ts2abc_build" ] + + script = "//ark/ts2abc/ts2panda/scripts/generate_js_bytecode.py" + + args = [ + "--src-js", + rebase_path( + "//foundation/ace/ace_engine/frameworks/bridge/declarative_frontend/engine/jsEnumStyle.js"), + "--dst-file", + rebase_path(base_output_path + "/jsEnumStyle.abc"), + "--node", + rebase_path("${node_path}"), + "--frontend-tool-path", + rebase_path("${ts2abc_build_path}"), + "--node-modules", + rebase_path("${node_modules}"), + ] + + inputs = [ "//foundation/ace/ace_engine/frameworks/bridge/declarative_frontend/engine/jsEnumStyle.js" ] + outputs = [ base_output_path + "/jsEnumStyle.abc" ] +} + gen_obj("abc_proxyclass") { - input = "declarative_frontend/engine/stateMgmt.abc" - if (use_mac) { - abcproxyclass_obj_path = base_output_path + "/js_proxy_class.c" - } + input = base_output_path + "/stateMgmt.abc" output = abcproxyclass_obj_path - snapshot_dep = [] + snapshot_dep = [ ":gen_stateMgmt_abc" ] } gen_obj("abc_enum_style") { - input = "declarative_frontend/engine/jsEnumStyle.abc" - if (use_mac) { - abcenumstyle_obj_path = base_output_path + "/js_enum_style.c" - } + input = base_output_path + "/jsEnumStyle.abc" output = abcenumstyle_obj_path - snapshot_dep = [] + snapshot_dep = [ ":gen_jsEnumStyle_abc" ] } gen_obj("js_mock_system_plugin") { @@ -775,7 +821,10 @@ template("declarative_js_engine") { defines += [ "APP_USE_ARM" ] } - deps += [ "//ark/js_runtime:libark_jsruntime" ] + deps += [ + "//ark/js_runtime:libark_jsruntime", + "//third_party/jsframework:ark_build", + ] configs += [ "//ark/runtime_core/libpandabase:arkbase_public_config", @@ -928,8 +977,7 @@ template("js_backend_engine") { "appexecfwk_standard:appexecfwk_core", "appexecfwk_standard:libeventhandler", "ipc:ipc_core", - - #"ipc_js:rpc", + "ipc_js:rpc", "napi:ace_napi", "samgr_L2:samgr_proxy", ] diff --git a/frameworks/bridge/declarative_frontend/engine/jsEnumStyle.abc b/frameworks/bridge/declarative_frontend/engine/jsEnumStyle.abc deleted file mode 100644 index d44cd5f4fbe..00000000000 Binary files a/frameworks/bridge/declarative_frontend/engine/jsEnumStyle.abc and /dev/null differ diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_bindings.h b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_bindings.h index 222e0188a06..36f7d054644 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_bindings.h +++ b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_bindings.h @@ -136,6 +136,7 @@ private: static JSGCMarkCallback jsGcMark_; static std::string className_; static panda::Global classFunction_; + static std::vector> functionIds_; }; template diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_bindings.inl b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_bindings.inl index 4a1af8484bc..d351a856e64 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_bindings.inl +++ b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_bindings.inl @@ -43,6 +43,9 @@ std::string JsiClass::className_; template panda::Global JsiClass::classFunction_; +template +std::vector> JsiClass::functionIds_; + template void JsiClass::Declare(const char* name) { @@ -58,6 +61,7 @@ void JsiClass::Method(const char* name, R (Base::*func)(Args...), int id) auto runtime = std::static_pointer_cast(JsiDeclarativeEngineInstance::GetJsRuntime()); auto vm = runtime->GetEcmaVm(); auto funcId = std::make_shared(id); + functionIds_.emplace_back(funcId); customFunctions_.emplace(name, panda::FunctionRef::New(vm, MethodCallback, funcId.get())); } @@ -68,6 +72,7 @@ void JsiClass::CustomMethod(const char* name, MemberFunctionCallback callb auto runtime = std::static_pointer_cast(JsiDeclarativeEngineInstance::GetJsRuntime()); auto vm = runtime->GetEcmaVm(); auto funcId = std::make_shared(id); + functionIds_.emplace_back(funcId); customFunctions_.emplace( name, panda::FunctionRef::New(vm, InternalMemberFunctionCallback, @@ -90,6 +95,7 @@ void JsiClass::CustomMethod(const char* name, JSMemberFunctionCallback cal auto runtime = std::static_pointer_cast(JsiDeclarativeEngineInstance::GetJsRuntime()); auto vm = runtime->GetEcmaVm(); auto funcId = std::make_shared(id); + functionIds_.emplace_back(funcId); customFunctions_.emplace(name, panda::FunctionRef::New(vm, InternalJSMemberFunctionCallback, funcId.get())); } @@ -100,7 +106,8 @@ void JsiClass::StaticMethod(const char* name, R (*func)(Args...), int id) auto runtime = std::static_pointer_cast(JsiDeclarativeEngineInstance::GetJsRuntime()); auto vm = runtime->GetEcmaVm(); auto funcId = std::make_shared(id); - customFunctions_.emplace(name, panda::FunctionRef::New(vm, StaticMethodCallback, funcId.get())); + functionIds_.emplace_back(funcId); + staticFunctions_.emplace(name, panda::FunctionRef::New(vm, StaticMethodCallback, funcId.get())); } template @@ -109,6 +116,7 @@ void JsiClass::StaticMethod(const char* name, JSFunctionCallback func, int id auto runtime = std::static_pointer_cast(JsiDeclarativeEngineInstance::GetJsRuntime()); auto vm = runtime->GetEcmaVm(); auto funcId = std::make_shared(id); + functionIds_.emplace_back(funcId); staticFunctions_.emplace(name, panda::FunctionRef::New(vm, JSStaticMethodCallback, funcId.get())); } @@ -142,6 +150,8 @@ void JsiClass::Bind(BindingTarget t, FunctionCallback ctor) vm, panda::FunctionRef::NewClassFunction(vm, ConstructorInterceptor, nullptr, nullptr)); classFunction_->SetName(vm, StringRef::NewFromUtf8(vm, className_.c_str())); auto prototype = Local(classFunction_->GetFunctionPrototype(vm)); + prototype->Set(vm, panda::StringRef::NewFromUtf8(vm, "constructor"), + panda::Local(classFunction_.ToLocal(vm))); for (const auto& [name, val] : staticFunctions_) { classFunction_->Set(vm, panda::StringRef::NewFromUtf8(vm, name.c_str()), val); } @@ -164,6 +174,8 @@ void JsiClass::Bind( vm, panda::FunctionRef::NewClassFunction(vm, JSConstructorInterceptor, nullptr, nullptr)); classFunction_->SetName(vm, StringRef::NewFromUtf8(vm, className_.c_str())); auto prototype = panda::Local(classFunction_->GetFunctionPrototype(vm)); + prototype->Set(vm, panda::StringRef::NewFromUtf8(vm, "constructor"), + panda::Local(classFunction_.ToLocal(vm))); for (const auto& [name, val] : staticFunctions_) { classFunction_->Set(vm, panda::StringRef::NewFromUtf8(vm, name.c_str()), val); } @@ -186,6 +198,8 @@ void JsiClass::Bind(BindingTarget t, JSDestructorCallback dtor, JSGCMarkCa vm, panda::FunctionRef::NewClassFunction(vm, InternalConstructor, nullptr, nullptr)); classFunction_->SetName(vm, StringRef::NewFromUtf8(vm, className_.c_str())); auto prototype = panda::Local(classFunction_->GetFunctionPrototype(vm)); + prototype->Set(vm, panda::StringRef::NewFromUtf8(vm, "constructor"), + panda::Local(classFunction_.ToLocal(vm))); for (const auto& [name, val] : staticFunctions_) { classFunction_->Set(vm, panda::StringRef::NewFromUtf8(vm, name.c_str()), val); } @@ -200,15 +214,15 @@ template template void JsiClass::Inherit() { - auto& staticFunctions = GetStaticFunctions(); + auto& staticFunctions = JsiClass::GetStaticFunctions(); for (auto& [name, function] : staticFunctions) { if (staticFunctions_.find(name) != staticFunctions_.end()) { continue; } staticFunctions_.emplace(name, function); } - auto& customFunctions_ = GetCustomFunctions(); - for (auto& [name, function] : customFunctions_) { + auto& customFunctions = JsiClass::GetCustomFunctions(); + for (auto& [name, function] : customFunctions) { if (customFunctions_.find(name) != customFunctions_.end()) { continue; } @@ -385,11 +399,17 @@ panda::Local JsiClass::InternalConstructor(panda::EcmaVM* panda::Local thisObj, panda::Local newTarget, const panda::Local argv[], int32_t argc, void* data) { - JsiCallbackInfo info(vm, thisObj, argc, argv); + if (!newTarget->IsFunction()) { + return panda::Local(panda::JSValueRef::Undefined(vm)); + } + auto function = panda::Local(newTarget); + auto proto = function->GetFunctionPrototype(vm); + JsiCallbackInfo info(vm, proto, argc, argv); auto tuple = __detail__::ToTuple...>(argv); C* instance = FunctionUtils::ConstructFromTuple(tuple); + Local(thisObj)->SetNativePointerFieldCount(1); panda::Local(thisObj)->SetNativePointerField(0, static_cast(instance)); - return panda::Local(panda::JSValueRef::Undefined(vm)); + return thisObj; } template @@ -404,7 +424,12 @@ panda::Local JsiClass::ConstructorInterceptor(panda::EcmaV panda::Local thisObj, panda::Local newTarget, const panda::Local argv[], int32_t argc, void* data) { - return constructor_(vm, thisObj, argv, argc, data); + if (!newTarget->IsFunction()) { + return panda::Local(panda::JSValueRef::Undefined(vm)); + } + auto function = panda::Local(newTarget); + auto proto = function->GetFunctionPrototype(vm); + return constructor_(vm, proto, argv, argc, data); } template @@ -412,8 +437,24 @@ panda::Local JsiClass::JSConstructorInterceptor(panda::Ecm panda::Local thisObj, panda::Local newTarget, const panda::Local argv[], int32_t argc, void* data) { - JsiCallbackInfo info(vm, thisObj, argc, argv); - jsConstructor_(info); + if (newTarget->IsFunction()) { + auto function = panda::Local(newTarget); + auto proto = function->GetFunctionPrototype(vm); + JsiCallbackInfo info(vm, proto, argc, argv); + jsConstructor_(info); + auto retVal = info.GetReturnValue(); + if (retVal.valueless_by_exception()) { + LOGE("Constructor of %s must return a value!", ThisJSClass::JSName()); + return panda::Local(panda::JSValueRef::Undefined(vm)); + } + auto instance = std::get_if(&retVal); + if (instance) { + Local(thisObj)->SetNativePointerFieldCount(1); + Local(thisObj)->SetNativePointerField(0, *instance); + LOGD("Constructed %s", ThisJSClass::JSName()); + return thisObj; + } + } return panda::Local(panda::JSValueRef::Undefined(vm)); } diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.cpp b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.cpp index c52e77bdcc5..e99a73be976 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.cpp +++ b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.cpp @@ -458,11 +458,14 @@ void JsiDeclarativeEngineInstance::RootViewHandle(const shared_ptr& r LOGE("jsRuntime is nullptr"); return; } - auto arkRuntime = std::static_pointer_cast(runtime); - panda::Global globalValue = panda::Global(arkRuntime->GetEcmaVm(), value); RefPtr page = JsiDeclarativeEngineInstance::GetStagingPage(runtime); if (page != nullptr) { - rootViewMap_.emplace(page->GetPageId(), globalValue); + auto arkRuntime = std::static_pointer_cast(runtime_); + if (!arkRuntime) { + LOGE("ark engine is null"); + return; + } + rootViewMap_.emplace(page->GetPageId(), panda::Global(arkRuntime->GetEcmaVm(), value)); } } @@ -470,7 +473,12 @@ void JsiDeclarativeEngineInstance::DestroyRootViewHandle(int32_t pageId) { CHECK_RUN_ON(JS); if (rootViewMap_.count(pageId) != 0) { - panda::Global rootView = rootViewMap_[pageId]; + auto arkRuntime = std::static_pointer_cast(runtime_); + if (!arkRuntime) { + LOGE("ark engine is null"); + return; + } + panda::Local rootView = rootViewMap_[pageId].ToLocal(arkRuntime->GetEcmaVm()); JSView* jsView = static_cast(rootView->GetNativePointerField(0)); jsView->Destroy(nullptr); rootViewMap_.erase(pageId); @@ -483,8 +491,13 @@ void JsiDeclarativeEngineInstance::DestroyAllRootViewHandle() if (rootViewMap_.size() > 0) { LOGI("DestroyAllRootViewHandle release left %{private}zu views ", rootViewMap_.size()); } + auto arkRuntime = std::static_pointer_cast(runtime_); + if (!arkRuntime) { + LOGE("ark engine is null"); + return; + } for (const auto& pair : rootViewMap_) { - panda::Global rootView = pair.second; + panda::Local rootView = pair.second.ToLocal(arkRuntime->GetEcmaVm()); JSView* jsView = static_cast(rootView->GetNativePointerField(0)); jsView->Destroy(nullptr); } @@ -635,7 +648,7 @@ bool JsiDeclarativeEngine::Initialize(const RefPtr& delegate) nativeEngine_ = new ArkNativeEngine(const_cast(vm), static_cast(this)); ACE_DCHECK(delegate); delegate->AddTaskObserver([nativeEngine = nativeEngine_](){ - nativeEngine->Loop(LOOP_DEFAULT); + nativeEngine->Loop(LOOP_NOWAIT); }); return result; diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_ref.h b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_ref.h index af86bc956ac..a887ebb8400 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_ref.h +++ b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_ref.h @@ -78,7 +78,8 @@ public: template static JsiRef Make(Args&&... args) { - return JsiRef::Claim(T { std::forward(args)... }); + auto obj = T { args... }; + return JsiRef(obj); } static JsiRef Claim(T&& val) diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.cpp b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.cpp index 1b42557cc0f..347f3caddaa 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.cpp +++ b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.cpp @@ -27,48 +27,83 @@ JsiValue::JsiValue(panda::Local val) : JsiType(val) {} bool JsiValue::IsEmpty() const { - return GetHandle().IsEmpty(); + if (GetHandle().IsEmpty()) { + return true; + } + return GetHandle()->IsUndefined() || GetHandle()->IsNull(); } bool JsiValue::IsFunction() const { - return GetHandle()->IsFunction(); + if (GetHandle().IsEmpty()) { + return false; + } else { + return GetHandle()->IsFunction(); + } } bool JsiValue::IsNumber() const { - return GetHandle()->IsNumber(); + if (GetHandle().IsEmpty()) { + return false; + } else { + return GetHandle()->IsNumber(); + } } bool JsiValue::IsString() const { - return GetHandle()->IsString(); + if (GetHandle().IsEmpty()) { + return false; + } else { + return GetHandle()->IsString(); + } } bool JsiValue::IsBoolean() const { - return GetHandle()->IsBoolean(); + if (GetHandle().IsEmpty()) { + return false; + } else { + return GetHandle()->IsBoolean(); + } } bool JsiValue::IsObject() const { - return GetHandle()->IsObject(); + if (GetHandle().IsEmpty()) { + return false; + } else { + return GetHandle()->IsObject(); + } } bool JsiValue::IsArray() const { auto runtime = std::static_pointer_cast(JsiDeclarativeEngineInstance::GetJsRuntime()); - return GetHandle()->IsArray(runtime->GetEcmaVm()); + if (GetHandle().IsEmpty()) { + return false; + } else { + return GetHandle()->IsArray(runtime->GetEcmaVm()); + } } bool JsiValue::IsUndefined() const { - return GetHandle()->IsUndefined(); + if (GetHandle().IsEmpty()) { + return true; + } else { + return GetHandle()->IsUndefined(); + } } bool JsiValue::IsNull() const { - return GetHandle()->IsNull(); + if (GetHandle().IsEmpty()) { + return true; + } else { + return GetHandle()->IsNull(); + } } std::string JsiValue::ToString() const @@ -124,7 +159,10 @@ JsiRef JsiObject::GetProperty(const char* prop) const { auto runtime = std::static_pointer_cast(JsiDeclarativeEngineInstance::GetJsRuntime()); auto stringRef = panda::StringRef::NewFromUtf8(runtime->GetEcmaVm(), prop); - return JsiRef::Make(GetHandle()->Get(runtime->GetEcmaVm(), stringRef)); + auto value = GetHandle()->Get(runtime->GetEcmaVm(), stringRef); + auto func = JsiValue(value); + auto refValue = JsiRef(func); + return refValue; } void JsiObject::SetPropertyJsonObject(const char* prop, const char* value) const @@ -158,7 +196,6 @@ JsiFunction::JsiFunction(panda::Local val) : JsiType(val) JsiRef JsiFunction::Call(JsiRef thisVal, int argc, JsiRef argv[]) const { - panda::LocalScope scope(vm_); std::vector> arguments; for (int i = 0; i < argc; ++i) { arguments.emplace_back(argv[i].Get().GetHandle()); @@ -211,7 +248,9 @@ JsiRef JsiCallbackInfo::operator[](size_t index) const JsiRef JsiCallbackInfo::This() const { - return JsiRef::Make(thisObj_); + auto obj = JsiObject { thisObj_ }; + auto ref = JsiRef(obj); + return ref; } int JsiCallbackInfo::Length() const diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.inl b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.inl index c25b1fd797a..5f5bbf733e0 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.inl +++ b/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.inl @@ -40,30 +40,40 @@ JsiType::JsiType(panda::Local val) } template -JsiType::JsiType(panda::Global other) : handle_(other) -{} - -template -JsiType::JsiType(const JsiType& rhs) : handle_(rhs.handle_) -{} - -template -JsiType::JsiType(JsiType&& rhs) : handle_(std::move(rhs.handle_)) +JsiType::JsiType(panda::Global other) { + auto runtime = std::static_pointer_cast(JsiDeclarativeEngineInstance::GetJsRuntime()); + handle_ = Global(runtime->GetEcmaVm(), other.ToLocal(runtime->GetEcmaVm())); +} + +template +JsiType::JsiType(const JsiType& rhs) +{ + auto runtime = std::static_pointer_cast(JsiDeclarativeEngineInstance::GetJsRuntime()); + handle_ = Global(runtime->GetEcmaVm(), rhs.handle_.ToLocal(runtime->GetEcmaVm())); +} + +template +JsiType::JsiType(JsiType&& rhs) +{ + auto runtime = std::static_pointer_cast(JsiDeclarativeEngineInstance::GetJsRuntime()); + handle_ = Global(runtime->GetEcmaVm(), rhs.handle_.ToLocal(runtime->GetEcmaVm())); rhs.handle_.FreeGlobalHandleAddr(); } template JsiType& JsiType::operator=(const JsiType& rhs) { - handle_ = rhs.handle_; + auto runtime = std::static_pointer_cast(JsiDeclarativeEngineInstance::GetJsRuntime()); + handle_ = Global(runtime->GetEcmaVm(), rhs.handle_.ToLocal(runtime->GetEcmaVm())); return *this; } template JsiType& JsiType::operator=(JsiType&& rhs) { - handle_ = std::move(rhs.handle_); + auto runtime = std::static_pointer_cast(JsiDeclarativeEngineInstance::GetJsRuntime()); + handle_ = Global(runtime->GetEcmaVm(), rhs.handle_.ToLocal(runtime->GetEcmaVm())); rhs.handle_.FreeGlobalHandleAddr(); return *this; } diff --git a/frameworks/bridge/declarative_frontend/engine/stateMgmt.abc b/frameworks/bridge/declarative_frontend/engine/stateMgmt.abc deleted file mode 100644 index 513149bb20d..00000000000 Binary files a/frameworks/bridge/declarative_frontend/engine/stateMgmt.abc and /dev/null differ diff --git a/frameworks/bridge/declarative_frontend/jsview/js_textarea.cpp b/frameworks/bridge/declarative_frontend/jsview/js_textarea.cpp index 475e1f828bd..66eb8d6d7ab 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_textarea.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_textarea.cpp @@ -18,9 +18,7 @@ #include #include "bridge/declarative_frontend/jsview/js_view_common_def.h" #include "bridge/declarative_frontend/view_stack_processor.h" -#include "core/components/text_field/render_text_field.h" #include "core/components/text_field/text_field_component.h" -#include "core/components/text_field/text_field_element.h" #include "frameworks/bridge/declarative_frontend/engine/functions/js_function.h" #include "frameworks/bridge/declarative_frontend/jsview/js_container_base.h" #include "frameworks/bridge/declarative_frontend/jsview/js_interactable_view.h" @@ -205,4 +203,4 @@ void JSTextArea::SetOnChange(const JSCallbackInfo& info) info.ReturnSelf(); } -} // namespace OHOS::Ace::Framework \ No newline at end of file +} // namespace OHOS::Ace::Framework diff --git a/frameworks/bridge/declarative_frontend/jsview/js_textinput.cpp b/frameworks/bridge/declarative_frontend/jsview/js_textinput.cpp index a61589a0fd4..a6d5e0bd29c 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_textinput.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_textinput.cpp @@ -15,14 +15,12 @@ #include "frameworks/bridge/declarative_frontend/jsview/js_textinput.h" -#include +#include #include "frameworks/bridge/declarative_frontend/engine/functions/js_function.h" #include "frameworks/bridge/declarative_frontend/jsview/js_view_common_def.h" #include "frameworks/bridge/declarative_frontend/view_stack_processor.h" -#include "frameworks/core/components/text_field/render_text_field.h" #include "frameworks/core/components/text_field/text_field_component.h" -#include "frameworks/core/components/text_field/text_field_element.h" #include "frameworks/core/common/ime/text_input_action.h" namespace OHOS::Ace::Framework { @@ -258,4 +256,4 @@ void JSTextInput::SetOnChange(const JSCallbackInfo& info) info.ReturnSelf(); } -} // namespace OHOS::Ace::Framework \ No newline at end of file +} // namespace OHOS::Ace::Framework diff --git a/frameworks/bridge/js_frontend/engine/common/js_engine.h b/frameworks/bridge/js_frontend/engine/common/js_engine.h index b9d39d47e34..d3ac809785f 100644 --- a/frameworks/bridge/js_frontend/engine/common/js_engine.h +++ b/frameworks/bridge/js_frontend/engine/common/js_engine.h @@ -152,6 +152,15 @@ public: instanceName_ = name; } + void SetDialogCallback(const DialogCallback callback) + { + dialogCallback_ = callback; + } + DialogCallback GetDialogCallback() const + { + return dialogCallback_; + } + void AddExtraNativeObject(const std::string& key, void* value) { extraNativeObject_[key] = value; @@ -194,6 +203,7 @@ private: std::string instanceName_; std::unordered_map extraNativeObject_; + DialogCallback dialogCallback_; }; } // namespace OHOS::Ace::Framework diff --git a/frameworks/bridge/js_frontend/engine/quickjs/qjs_engine.cpp b/frameworks/bridge/js_frontend/engine/quickjs/qjs_engine.cpp index 7e109996439..7e86c72589a 100644 --- a/frameworks/bridge/js_frontend/engine/quickjs/qjs_engine.cpp +++ b/frameworks/bridge/js_frontend/engine/quickjs/qjs_engine.cpp @@ -37,6 +37,7 @@ #include "base/utils/utils.h" #include "core/common/ace_application_info.h" #include "core/common/container.h" +#include "core/common/frontend.h" #include "core/event/ace_event_helper.h" #include "core/event/back_end_event_manager.h" #include "frameworks/bridge/common/dom/dom_type.h" @@ -79,6 +80,7 @@ constexpr int32_t ARGS_READ_RESOURCE_LENGTH = 2; constexpr int32_t MAX_READ_TEXT_LENGTH = 4096; const std::regex URI_PARTTEN("^\\/([a-z0-9A-Z_]+\\/)*[a-z0-9A-Z_]+\\.?[a-z0-9A-Z_]*$"); static int32_t globalNodeId = 50000; +const std::string WINDOW_DIALOG_DOUBLE_BUTTON = "pages/dialog/dialog.js"; int32_t CallEvalBuf( JSContext* ctx, const char* buf, size_t bufLen, const char* filename, int32_t evalFlags, int32_t instanceId) @@ -2448,6 +2450,33 @@ JSValue JsLoadLocaleData(JSContext* ctx, JSValueConst value, int32_t argc, JSVal } } +std::map g_JsEngindMap; +JSValue JSWindowCallBack(JSContext* ctx, JSValueConst value, int32_t argc, JSValueConst* argv) +{ + ACE_SCOPED_TRACE("QjsEngine::JSWindowCallBack"); + LOGI("JSWindowCallBack"); + JSValue globalObj = JS_GetGlobalObject(ctx); + JSValue id = JS_GetPropertyStr(ctx, globalObj, "dialogId"); + int32_t global_id; + JS_ToInt32(ctx, &global_id, id); + + for (auto& iter : g_JsEngindMap) { + if (iter.first == id) { + JsEngine* jsEngine = iter.second; + if (jsEngine == nullptr) { + return JS_NULL; + } + + DialogCallback dialogCallback = jsEngine->GetDialogCallback(); + if (dialogCallback) { + dialogCallback("OK", ""); + } + } + } + + return JS_NULL; +} + // Follow definition in quickjs. #define JS_CFUNC_DEF_CPP(name, length, func) \ { \ @@ -2515,6 +2544,7 @@ void InitJsConsoleObject(JSContext* ctx, const JSValue& globalObj) JS_SetPropertyStr(ctx, aceConsole, "warn", JS_NewCFunction(ctx, JsWarnLogPrint, "warn", 1)); JS_SetPropertyStr(ctx, aceConsole, "error", JS_NewCFunction(ctx, JsErrorLogPrint, "error", 1)); JS_SetPropertyStr(ctx, globalObj, "aceConsole", aceConsole); + JS_SetPropertyStr(ctx, globalObj, "dialogCallback", JS_NewCFunction(ctx, JSWindowCallBack, "dialogCallback", 1)); } void InitJsDocumentObject(JSContext* ctx, const JSValue& globalObj) @@ -2910,6 +2940,7 @@ bool QjsEngine::Initialize(const RefPtr& delegate) ACE_SCOPED_TRACE("QjsEngine::Initialize"); LOGI("Initialize"); + g_JsEngindMap[instanceId_] = this; JSRuntime* runtime = nullptr; JSContext* context = nullptr; @@ -3113,6 +3144,9 @@ void QjsEngine::LoadJs(const std::string& url, const RefPtr& page, bo JS_SetContextOpaque(ctx, reinterpret_cast(AceType::RawPtr(engineInstance_))); JSValue globalObj = JS_GetGlobalObject(ctx); + if((url.compare(WINDOW_DIALOG_DOUBLE_BUTTON)) == 0){ + JS_SetPropertyStr(ctx, globalObj, "dialogId", JS_NewInt32(ctx, instanceId_)); + } JSValue createInstanceFunc = QJSUtils::GetPropertyStr(ctx, globalObj, "createInstance"); if (!JS_IsFunction(ctx, createInstanceFunc)) { LOGD("createInstance is not found, cannot load js!"); diff --git a/frameworks/bridge/js_frontend/frontend_delegate_impl.cpp b/frameworks/bridge/js_frontend/frontend_delegate_impl.cpp index bbe94891f33..c594c38c04f 100644 --- a/frameworks/bridge/js_frontend/frontend_delegate_impl.cpp +++ b/frameworks/bridge/js_frontend/frontend_delegate_impl.cpp @@ -157,6 +157,10 @@ void FrontendDelegateImpl::RunPage(const std::string& url, const std::string& pa } else { mainPagePath_ = manifestParser_->GetRouter()->GetEntry(); } + + if ((url.find("pages/dialog/dialog.js")) != -1) { + mainPagePath_ = url; + } LoadPage(GenerateNextPageId(), mainPagePath_, true, params); } @@ -1306,10 +1310,12 @@ void FrontendDelegateImpl::PopPage() return; } auto ability = static_cast(delegate->ability_); - std::shared_ptr info = ability->GetAbilityInfo(); - if (info != nullptr && info->isLauncherAbility) { - LOGW("launcher ability, return"); - return; + if (ability) { + std::shared_ptr info = ability->GetAbilityInfo(); + if (info != nullptr && info->isLauncherAbility) { + LOGW("launcher ability, return"); + return; + } } #if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM) delegate->OnPageHide(); diff --git a/frameworks/bridge/js_frontend/js_frontend.h b/frameworks/bridge/js_frontend/js_frontend.h index 225073e09c2..628cfdac8a6 100644 --- a/frameworks/bridge/js_frontend/js_frontend.h +++ b/frameworks/bridge/js_frontend/js_frontend.h @@ -163,6 +163,12 @@ public: ability_ = ability; } + void SetDialogCallback(DialogCallback callback) override + { + if (jsEngine_) { + jsEngine_->SetDialogCallback(callback); + } + } private: void InitializeFrontendDelegate(const RefPtr& taskExecutor); diff --git a/frameworks/bridge/pa_backend/engine/quickjs/qjs_pa_engine.cpp b/frameworks/bridge/pa_backend/engine/quickjs/qjs_pa_engine.cpp index 6b10cb3b650..56fff8fb737 100644 --- a/frameworks/bridge/pa_backend/engine/quickjs/qjs_pa_engine.cpp +++ b/frameworks/bridge/pa_backend/engine/quickjs/qjs_pa_engine.cpp @@ -21,11 +21,9 @@ #include #include -/* #include "napi/native_node_api.h" #include "napi_common_want.h" #include "napi_remote_object.h" -*/ #include "third_party/quickjs/message_server.h" @@ -525,13 +523,10 @@ void QjsPaEngine::LoadJs(const std::string& url, const OHOS::AAFwk::Want &want) return; } - /* napi_value napiWant = OHOS::AppExecFwk::WrapWant(reinterpret_cast(nativeEngine_), want); NativeValue* nativeWant = reinterpret_cast(napiWant); JSValue jsWant = (JSValue)*nativeWant; JSValueConst argv[] = { jsWant }; - */ - JSValueConst argv[] = {}; JSValue retVal = QJSUtils::Call(ctx, paStartFunc, paObj, countof(argv), argv); if (JS_IsException(retVal)) { LOGE("PA: QjsPaEngine QJSUtils::Call IsException"); @@ -1066,7 +1061,6 @@ Uri QjsPaEngine::DenormalizeUri(const Uri& uri) sptr QjsPaEngine::OnConnectService(const OHOS::AAFwk::Want &want) { -/* LOGI("OnConnectService"); JSContext *ctx = engineInstance_->GetQjsContext(); ACE_DCHECK(ctx); @@ -1103,13 +1097,10 @@ sptr QjsPaEngine::OnConnectService(const OHOS::AAFwk::Want &want) JS_FreeValue(ctx, retVal); return remoteObj; } -*/ - return nullptr; } void QjsPaEngine::OnDisconnectService(const OHOS::AAFwk::Want &want) { -/* LOGI("OnDisconnectService"); JSContext *ctx = engineInstance_->GetQjsContext(); ACE_DCHECK(ctx); @@ -1136,7 +1127,6 @@ void QjsPaEngine::OnDisconnectService(const OHOS::AAFwk::Want &want) LOGE("Qjs OnDisconnectService FAILED!"); } JS_FreeValue(ctx, globalObj); -*/ } void QjsPaEngine::OnDelete(const int64_t formId) @@ -1258,13 +1248,10 @@ void QjsPaEngine::OnAcquireState(const OHOS::AAFwk::Want &want) QJSHandleScope handleScope(ctx); JSValue paFunc = GetPaFunc("onAcquireState"); - /* napi_value napiWant = OHOS::AppExecFwk::WrapWant(reinterpret_cast(nativeEngine_), want); NativeValue* nativeWant = reinterpret_cast(napiWant); JSValue jsWant = (JSValue)*nativeWant; JSValueConst argv[] = { jsWant }; - */ - JSValueConst argv[] = {}; JSValue retVal = QJSUtils::Call(ctx, paFunc, JS_UNDEFINED, countof(argv), argv); if (JS_IsException(retVal)) { LOGE("PA: OnAcquireState FAILED!"); diff --git a/frameworks/core/common/frontend.h b/frameworks/core/common/frontend.h index a7a0d1022b2..30fefff7dea 100644 --- a/frameworks/core/common/frontend.h +++ b/frameworks/core/common/frontend.h @@ -32,6 +32,7 @@ constexpr int32_t DEFAULT_DESIGN_WIDTH = 720; #else constexpr int32_t DEFAULT_DESIGN_WIDTH = 454; #endif +using DialogCallback = std::function; // Window config of frontend. struct WindowConfig { @@ -170,7 +171,7 @@ public: // navigator component call router virtual void NavigatePage(uint8_t type, const PageTarget& target, const std::string& params) {}; - + virtual void SetDialogCallback(DialogCallback callback) {}; virtual void NotifyAppStorage(const std::string& key, const std::string& value) {}; // Disallow pop last page diff --git a/frameworks/core/components/box/BUILD.gn b/frameworks/core/components/box/BUILD.gn index 48a8f1838a8..c74236305cf 100644 --- a/frameworks/core/components/box/BUILD.gn +++ b/frameworks/core/components/box/BUILD.gn @@ -22,4 +22,8 @@ build_component("box") { "render_box.cpp", "render_box_base.cpp", ] + external_deps = [ + "inputmethod_native:inputmethod_ability", + "inputmethod_native:inputmethod_client", + ] } diff --git a/frameworks/core/components/camera/camera.cpp b/frameworks/core/components/camera/camera.cpp index 978359e0b60..7e46cc0f422 100644 --- a/frameworks/core/components/camera/camera.cpp +++ b/frameworks/core/components/camera/camera.cpp @@ -225,7 +225,7 @@ sptr CameraCallback::createSubWindowSurface() void CameraCallback::MarkTreeRender(const RefPtr& root) { root->MarkNeedRender(); - LOGE("Hole: MarkTreeRender %{public}s", AceType::TypeName(Referenced::RawPtr(root))); + LOGI("Hole: MarkTreeRender %{public}s", AceType::TypeName(Referenced::RawPtr(root))); for (auto child: root->GetChildren()){ MarkTreeRender(child); } @@ -248,7 +248,7 @@ void CameraCallback::MarkWholeRender(const WeakPtr& nodeWeak) for(auto child: parent->GetChildren()) { if (child == node){ - LOGE("Hole: MarkWholeRender meet barrier"); + LOGI("Hole: MarkWholeRender meet barrier"); break; } MarkTreeRender(child); @@ -519,13 +519,12 @@ void CameraCallback::Release() LOGI("CameraCallback: Destroy subWindow."); subwindow_ = nullptr; auto context = context_.Upgrade(); - LOGE("Hole: Release x=0, y=0, w=0, h=0"); + LOGI("Hole: Release x=0, y=0, w=0, h=0"); context->SetClipHole(0, 0, 0, 0); auto renderNode = renderNode_.Upgrade(); if (renderNode) { renderNode->SetHasSubWindow(false); } - context->MarkForcedRefresh(); } LOGI("CameraCallback: Release end."); } diff --git a/frameworks/core/components/search/BUILD.gn b/frameworks/core/components/search/BUILD.gn index e63227259be..a5d0addea57 100644 --- a/frameworks/core/components/search/BUILD.gn +++ b/frameworks/core/components/search/BUILD.gn @@ -20,4 +20,9 @@ build_component("search") { "search_component.cpp", "search_element.cpp", ] + + external_deps = [ + "inputmethod_native:inputmethod_ability", + "inputmethod_native:inputmethod_client", + ] } diff --git a/frameworks/core/components/stack/BUILD.gn b/frameworks/core/components/stack/BUILD.gn index af1d1dd185a..3c3ff853ea0 100644 --- a/frameworks/core/components/stack/BUILD.gn +++ b/frameworks/core/components/stack/BUILD.gn @@ -20,4 +20,9 @@ build_component("stack") { "stack_component.cpp", "stack_element.cpp", ] + + external_deps = [ + "inputmethod_native:inputmethod_ability", + "inputmethod_native:inputmethod_client", + ] } diff --git a/frameworks/core/components/text_field/BUILD.gn b/frameworks/core/components/text_field/BUILD.gn index 6fee734b891..e98aa987243 100644 --- a/frameworks/core/components/text_field/BUILD.gn +++ b/frameworks/core/components/text_field/BUILD.gn @@ -21,4 +21,9 @@ build_component("text_field") { "text_field_controller.cpp", "text_field_element.cpp", ] + + external_deps = [ + "inputmethod_native:inputmethod_ability", + "inputmethod_native:inputmethod_client", + ] } diff --git a/frameworks/core/components/text_field/render_text_field.cpp b/frameworks/core/components/text_field/render_text_field.cpp index d44c792e5b0..aab8a061c4e 100644 --- a/frameworks/core/components/text_field/render_text_field.cpp +++ b/frameworks/core/components/text_field/render_text_field.cpp @@ -25,6 +25,7 @@ #include "core/components/text_overlay/text_overlay_component.h" #include "core/components/text_overlay/text_overlay_element.h" #include "core/event/ace_event_helper.h" +#include "unistd.h" namespace OHOS::Ace { namespace { @@ -55,6 +56,65 @@ constexpr Dimension DEFLATE_RADIUS_FOCUS = 3.0_vp; } // namespace +void OnTextChangedListenerImpl::InsertText(const std::u16string& text) { + if (text.length() <= 0) { + LOGE("the text is null"); + return; + } + + auto renderTextField = field_.Upgrade(); + if (!renderTextField) { + return; + } + + auto value = renderTextField->GetEditingValue(); + std::shared_ptr textEditingValue = std::shared_ptr(new TextEditingValue()); + textEditingValue->text = value.GetBeforeSelection() + StringUtils::Str16ToStr8(text) + value.GetAfterSelection(); + textEditingValue->UpdateSelection(std::max(value.selection.GetStart(), 0) + text.length()); + + renderTextField->UpdateEditingValue(textEditingValue, true); +} + +void OnTextChangedListenerImpl::DeleteBackward(int32_t length) { + if (length <= 0) { + LOGE("Delete nothing."); + return; + } + + auto renderTextField = field_.Upgrade(); + if (!renderTextField) { + return; + } + + auto value = renderTextField->GetEditingValue(); + auto start = value.selection.GetStart(); + auto end = value.selection.GetEnd(); + std::shared_ptr textEditingValue = std::shared_ptr(new TextEditingValue()); + textEditingValue->text = value.text; + textEditingValue->UpdateSelection(start, end); + + if (start > 0 && end > 0) { + textEditingValue->Delete(start == end ? start - length : start, end); + } + + renderTextField->UpdateEditingValue(textEditingValue, true); +} + +void OnTextChangedListenerImpl::SetKeyboardStatus(bool status) { + auto renderTextField = field_.Upgrade(); + if (!renderTextField) { + return; + } + + LOGE("aaainputmethod:SetKeyboardStatus, status=%{public}d", status); + if (status) { + renderTextField->SetInputMethodStatus(true); + } else { + MiscServices::InputMethodController::GetInstance()->Close(); + renderTextField->SetInputMethodStatus(false); + } +} + RenderTextField::RenderTextField() : twinklingInterval(TWINKLING_INTERVAL_MS), controller_(AceType::MakeRefPtr()) {} @@ -78,8 +138,7 @@ RenderTextField::~RenderTextField() // If soft keyboard is still exist, close it. if (HasConnection()) { - connection_->Close(GetInstanceId()); - connection_ = nullptr; + MiscServices::InputMethodController::GetInstance()->Close(); } } @@ -685,15 +744,12 @@ bool RenderTextField::RequestKeyboard(bool isFocusViewChanged, bool needStartTwi } if (softKeyboardEnabled_) { - if (!HasConnection()) { - AttachIme(); - if (!HasConnection()) { - LOGE("Get TextInput connection error"); - return false; - } - connection_->SetEditingState(GetEditingValue(), GetInstanceId()); - } - connection_->Show(isFocusViewChanged, GetInstanceId()); + if (!HasConnection()) { + MiscServices::InputMethodController::GetInstance()->Attach(); + sleep(1); + listener_ = new OnTextChangedListenerImpl(WeakClaim(this)); + MiscServices::InputMethodController::GetInstance()->ShowTextInput(listener_); + } } if (keyboard_ != TextInputType::MULTILINE) { resetToStart_ = false; @@ -710,8 +766,7 @@ bool RenderTextField::CloseKeyboard(bool forceClose) if (!isOverlayShowed_ || !isOverlayFocus_ || forceClose) { StopTwinkling(); if (HasConnection()) { - connection_->Close(GetInstanceId()); - connection_ = nullptr; + MiscServices::InputMethodController::GetInstance()->HideTextInput(); } if (onKeyboardClose_) { @@ -733,26 +788,6 @@ bool RenderTextField::CloseKeyboard(bool forceClose) return false; } -void RenderTextField::AttachIme() -{ - auto context = context_.Upgrade(); - if (!context) { - LOGW("No context exists, failed to request keyboard."); - return; - } - - TextInputConfiguration config; - config.type = keyboard_; - config.action = action_; - config.actionLabel = actionLabel_; - config.obscureText = obscure_; - LOGD("Request keyboard configuration: type=%{private}d action=%{private}d actionLabel=%{private}s " - "obscureText=%{private}d", - keyboard_, action_, actionLabel_.c_str(), obscure_); - connection_ = - TextInputProxy::GetInstance().Attach(WeakClaim(this), config, context->GetTaskExecutor(), GetInstanceId()); -} - void RenderTextField::StartTwinkling() { // Ignore the result because all ops are called on this same thread (ACE UI). @@ -1340,7 +1375,6 @@ void RenderTextField::UpdateRemoteEditing(bool needFireChangeEvent) if (!HasConnection()) { return; } - connection_->SetEditingState(GetEditingValue(), GetInstanceId(), needFireChangeEvent); } void RenderTextField::UpdateRemoteEditingIfNeeded(bool needFireChangeEvent) diff --git a/frameworks/core/components/text_field/render_text_field.h b/frameworks/core/components/text_field/render_text_field.h index 61dbeee6118..e5ba3e183ff 100644 --- a/frameworks/core/components/text_field/render_text_field.h +++ b/frameworks/core/components/text_field/render_text_field.h @@ -23,10 +23,9 @@ #include "base/geometry/rect.h" #include "base/geometry/size.h" #include "base/utils/system_properties.h" +#include "input_method_controller.h" #include "core/common/clipboard/clipboard.h" #include "core/common/ime/text_edit_controller.h" -#include "core/common/ime/text_input_client.h" -#include "core/common/ime/text_input_connection.h" #include "core/common/ime/text_input_formatter.h" #include "core/common/ime/text_input_type.h" #include "core/common/ime/text_selection.h" @@ -46,6 +45,7 @@ namespace OHOS::Ace { class ClickRecognizer; class ClickInfo; class TextOverlayComponent; +class RenderTextField; struct TextEditingValue; enum class DirectionStatus : uint8_t { @@ -62,8 +62,19 @@ enum class CursorPositionType { NORMAL, }; -class RenderTextField : public RenderNode, public TextInputClient, public ValueChangeObserver { - DECLARE_ACE_TYPE(RenderTextField, RenderNode, TextInputClient, ValueChangeObserver); + +class OnTextChangedListenerImpl : public MiscServices::OnTextChangedListener { +public: + OnTextChangedListenerImpl(const WeakPtr& field ) : field_(field) {} + void InsertText(const std::u16string& text) override; + void DeleteBackward(int32_t length) override; + void SetKeyboardStatus(bool status) override; +private: + WeakPtr field_; +}; + +class RenderTextField : public RenderNode, public ValueChangeObserver { + DECLARE_ACE_TYPE(RenderTextField, RenderNode, ValueChangeObserver); public: ~RenderTextField() override; @@ -75,8 +86,8 @@ public: void Update(const RefPtr& component) override; void PerformLayout() override; // Override TextInputClient - void UpdateEditingValue(const std::shared_ptr& value, bool needFireChangeEvent = true) override; - void PerformAction(TextInputAction action, bool forceCloseKeyboard = false) override; + void UpdateEditingValue(const std::shared_ptr& value, bool needFireChangeEvent = true); + void PerformAction(TextInputAction action, bool forceCloseKeyboard = false); void OnStatusChanged(RenderStatus renderStatus) override; void OnValueChanged(bool needFireChangeEvent = true, bool needFireSelectChangeEvent = true) override; void OnPaintFinish() override; @@ -208,6 +219,11 @@ public: needNotifyChangeEvent_ = needNotifyChangeEvent; } + void SetInputMethodStatus(bool imeAttached) + { + imeAttached_ = imeAttached; + } + protected: // Describe where caret is and how tall visually. struct CaretMetrics { @@ -262,7 +278,7 @@ protected: bool HasConnection() const { - return connection_; + return imeAttached_; } bool ShowCounter() const; @@ -436,8 +452,6 @@ private: */ void UpdateRemoteEditingIfNeeded(bool needFireChangeEvent = true); - void AttachIme(); - int32_t initIndex_ = 0; bool isOverlayFocus_ = false; bool isShiftDown_ = false; @@ -446,6 +460,7 @@ private: bool isSingleHandle_ = false; bool hasTextOverlayPushed_ = false; bool softKeyboardEnabled_ = true; + bool imeAttached_ = false; Color pressColor_; TextSelection selection_; // Selection from custom. DeviceOrientation deviceOrientation_ = DeviceOrientation::PORTRAIT; @@ -487,6 +502,7 @@ private: RefPtr rawRecognizer_; RefPtr pressController_; RefPtr animator_; + sptr listener_; }; } // namespace OHOS::Ace diff --git a/frameworks/core/components/text_overlay/BUILD.gn b/frameworks/core/components/text_overlay/BUILD.gn index 4fae3629bb5..eac38f00b94 100644 --- a/frameworks/core/components/text_overlay/BUILD.gn +++ b/frameworks/core/components/text_overlay/BUILD.gn @@ -20,4 +20,9 @@ build_component("text_overlay") { "text_overlay_component.cpp", "text_overlay_element.cpp", ] + + external_deps = [ + "inputmethod_native:inputmethod_ability", + "inputmethod_native:inputmethod_client", + ] } diff --git a/frameworks/core/pipeline/base/flutter_render_context.cpp b/frameworks/core/pipeline/base/flutter_render_context.cpp index 6a6bc96a179..4d839c7d628 100644 --- a/frameworks/core/pipeline/base/flutter_render_context.cpp +++ b/frameworks/core/pipeline/base/flutter_render_context.cpp @@ -71,19 +71,12 @@ void FlutterRenderContext::PaintChild(const RefPtr& child, const Off if (child->NeedRender()) { FlutterRenderContext context; auto pipelineContext = child->GetContext().Upgrade(); - LOGE("Hole: child canvas render"); - if (clipHole_.IsValid() && !pipelineContext->GetHasMeetSubWindowNode()) { - auto transparentHole = pipelineContext->GetTransparentHole(); - if (transparentHole.IsValid()) { - Offset childOffset = rect.GetOffset(); - Rect hole = transparentHole - childOffset; - LOGE("Hole: FlutterRenderContext::PaintChild %{public}p: hole:%{public}s, offset:%{public}s", &context, hole.ToString().c_str(), childOffset.ToString().c_str()); - context.SetClipHole(hole); - } else { - LOGE("Hole: FlutterRenderContext::PaintChild:hole is invalid"); - } - } else { - LOGE("Hole: clipHole_ is not valid or has meed subwindownode"); + LOGI("Hole: child canvas render"); + auto transparentHole = pipelineContext->GetTransparentHole(); + if (transparentHole.IsValid()) { + Offset childOffset = rect.GetOffset(); + Rect hole = transparentHole - childOffset; + context.SetClipHole(hole); } context.Repaint(child); } else { @@ -109,7 +102,8 @@ void FlutterRenderContext::StartRecording() if (clipHole_.IsValid()) { canvas_->save(); needRestoreHole_ = true; - canvas_->clipRect(clipHole_.Left(), clipHole_.Top(), clipHole_.Right(), clipHole_.Bottom(), SkClipOp::kDifference); + canvas_->clipRect(clipHole_.Left(), clipHole_.Top(), + clipHole_.Right(), clipHole_.Bottom(), SkClipOp::kDifference); } containerLayer_->AddChildren(currentLayer_); } diff --git a/frameworks/core/pipeline/base/render_node.cpp b/frameworks/core/pipeline/base/render_node.cpp index 20d9e81c5f0..ea171ff3d85 100644 --- a/frameworks/core/pipeline/base/render_node.cpp +++ b/frameworks/core/pipeline/base/render_node.cpp @@ -246,7 +246,7 @@ void RenderNode::RenderWithContext(RenderContext& context, const Offset& offset) } pendingDispatchLayoutReady_ = false; if (GetHasSubWindow()) { - LOGE("Hole: meet subwindow node"); + LOGI("Hole: meet subwindow node"); auto& flutterRenderContext = static_cast(context); if (flutterRenderContext.GetNeedRestoreHole()) { auto canvas = flutterRenderContext.GetCanvas(); @@ -292,6 +292,11 @@ void RenderNode::NotifyPaintFinish() void RenderNode::Paint(RenderContext& context, const Offset& offset) { + auto canvas = static_cast(context).GetCanvas(); + if (!canvas || !canvas->canvas()) { + LOGI("Paint canvas is null"); + return; + } const auto& children = GetChildren(); for (const auto& item : SortChildrenByZIndex(children)) { PaintChild(item, context, offset); diff --git a/frameworks/core/pipeline/pipeline_context.cpp b/frameworks/core/pipeline/pipeline_context.cpp index 7440589d102..770de5eea1a 100644 --- a/frameworks/core/pipeline/pipeline_context.cpp +++ b/frameworks/core/pipeline/pipeline_context.cpp @@ -428,7 +428,7 @@ void PipelineContext::FlushRender(const RefPtr& ctx) RefPtr context = isSub_ ? ctx : RenderContext::Create(); if (transparentHole_.IsValid()) { - LOGE("Hole: set transparentHole_ in FlushRender"); + LOGI("Hole: set transparentHole_ in FlushRender"); context->SetClipHole(transparentHole_); } if (!dirtyRenderNodes_.empty()) { @@ -543,10 +543,6 @@ void PipelineContext::ProcessPreFlush() CHECK_RUN_ON(UI); ACE_FUNCTION_TRACE(); - LOGI("Hole: set before flush."); - if (transparentHole_.IsValid()) { - hasMeetSubWindowNode_ = false; - } if (preFlushListeners_.empty()) { return; }