From fa4827819745416e04f9d6915da2dbc8667190ea Mon Sep 17 00:00:00 2001 From: humeng Date: Sat, 17 Aug 2024 14:56:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9ENavPushPathHelper=E7=94=A8?= =?UTF-8?q?=E4=BA=8Enavigation=E5=88=86=E5=8C=85=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: humeng --- adapter/ohos/capability/BUILD.gn | 1 + .../package/package_event_proxy_ohos.cpp | 91 +++++++ .../package/package_event_proxy_ohos.h | 68 +++++ adapter/ohos/osal/navigation_route_ohos.cpp | 22 +- adapter/ohos/osal/navigation_route_ohos.h | 8 +- adapter/preview/osal/BUILD.gn | 1 + .../osal/package_event_proxy_preview.cpp | 25 ++ advanced_ui_component/BUILD.gn | 1 + .../navpushpathhelper/BUILD.gn | 76 ++++++ .../include/hsp_silentinstall.h | 36 +++ .../include/hsp_silentinstall_napi.h | 58 ++++ .../include/silent_install_callback.h | 170 ++++++++++++ .../navpushpathhelper/navpushpathhelper.js | 139 ++++++++++ .../src/hsp_silentinstall.cpp | 108 ++++++++ .../src/hsp_silentinstall_napi.cpp | 252 ++++++++++++++++++ .../src/navpushpathhelper.cpp | 74 +++++ .../navigation/navigation_group_node.cpp | 9 + .../pattern/navigation/navigation_route.h | 12 +- .../event/package/package_change_listener.h | 44 +++ .../core/event/package/package_event_proxy.h | 61 +++++ .../core/package/mock_package_event_proxy.cpp | 22 ++ test/unittest/BUILD.gn | 1 + test/unittest/core/pipeline/BUILD.gn | 1 + test/unittest/interfaces/BUILD.gn | 1 + 24 files changed, 1276 insertions(+), 5 deletions(-) create mode 100644 adapter/ohos/capability/package/package_event_proxy_ohos.cpp create mode 100644 adapter/ohos/capability/package/package_event_proxy_ohos.h create mode 100644 adapter/preview/osal/package_event_proxy_preview.cpp create mode 100644 advanced_ui_component/navpushpathhelper/BUILD.gn create mode 100644 advanced_ui_component/navpushpathhelper/include/hsp_silentinstall.h create mode 100644 advanced_ui_component/navpushpathhelper/include/hsp_silentinstall_napi.h create mode 100644 advanced_ui_component/navpushpathhelper/include/silent_install_callback.h create mode 100644 advanced_ui_component/navpushpathhelper/navpushpathhelper.js create mode 100644 advanced_ui_component/navpushpathhelper/src/hsp_silentinstall.cpp create mode 100644 advanced_ui_component/navpushpathhelper/src/hsp_silentinstall_napi.cpp create mode 100644 advanced_ui_component/navpushpathhelper/src/navpushpathhelper.cpp create mode 100644 frameworks/core/event/package/package_change_listener.h create mode 100644 frameworks/core/event/package/package_event_proxy.h create mode 100644 test/mock/core/package/mock_package_event_proxy.cpp diff --git a/adapter/ohos/capability/BUILD.gn b/adapter/ohos/capability/BUILD.gn index e372aaaf6de..3ea1e83c117 100644 --- a/adapter/ohos/capability/BUILD.gn +++ b/adapter/ohos/capability/BUILD.gn @@ -31,6 +31,7 @@ template("ace_capability_ohos_source_set") { "environment/environment_proxy_impl.cpp", "html/html_to_span.cpp", "html/span_to_html.cpp", + "package/package_event_proxy_ohos.cpp", "preference/storage_impl.cpp", "time/time_event_proxy_ohos.cpp", ] diff --git a/adapter/ohos/capability/package/package_event_proxy_ohos.cpp b/adapter/ohos/capability/package/package_event_proxy_ohos.cpp new file mode 100644 index 00000000000..0ba02a45e37 --- /dev/null +++ b/adapter/ohos/capability/package/package_event_proxy_ohos.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "adapter/ohos/capability/package/package_event_proxy_ohos.h" + +#include "common_event_manager.h" +#include "common_event_support.h" + +#include "frameworks/core/common/container.h" +#include "frameworks/core/common/container_scope.h" + +namespace OHOS::Ace { +std::unique_ptr PackageEventProxy::instance_; +std::mutex PackageEventProxy::mutex_; + +PackageEventProxy* PackageEventProxy::GetInstance() +{ + if (!instance_) { + std::scoped_lock lock(mutex_); + if (!instance_) { + instance_ = std::make_unique(); + } + } + return instance_.get(); +} + +using OHOS::EventFwk::CommonEventManager; +using OHOS::EventFwk::CommonEventSubscribeInfo; +using OHOS::EventFwk::CommonEventSupport; +using OHOS::EventFwk::MatchingSkills; + +void PackageEventSubscriber::OnReceiveEvent(const CommonEventData& /* data */) +{ + LOGI("Package Change Common Event Received"); + PackageEventProxy::GetInstance()->OnPackageChange(); +} + +PackageEventProxyOhos::PackageEventProxyOhos() +{ + MatchingSkills matchingSkills; + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED); + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED); + + CommonEventSubscribeInfo subscribeInfo(matchingSkills); + subscribeInfo.SetThreadMode(CommonEventSubscribeInfo::ThreadMode::HANDLER); + + packageEventSubscriber_ = std::make_shared(subscribeInfo); +} + +PackageEventProxyOhos::~PackageEventProxyOhos() +{ + CommonEventManager::UnSubscribeCommonEvent(packageEventSubscriber_); +} + +void PackageEventProxyOhos::OnPackageChange() +{ + auto it = listeners_.begin(); + while (it != listeners_.end()) { + auto listener = it->first.Upgrade(); + if (listener) { + ContainerScope scope(it->second); + listener->OnPackageChange(); + ++it; + } else { + it = listeners_.erase(it); + if (listeners_.empty()) { + CommonEventManager::UnSubscribeCommonEvent(packageEventSubscriber_); + } + } + } +} + +void PackageEventProxyOhos::Register(const WeakPtr& listener) +{ + if (listeners_.empty()) { + CommonEventManager::SubscribeCommonEvent(packageEventSubscriber_); + } + listeners_.insert({ listener, Container::CurrentId() }); +} +} // namespace OHOS::Ace \ No newline at end of file diff --git a/adapter/ohos/capability/package/package_event_proxy_ohos.h b/adapter/ohos/capability/package/package_event_proxy_ohos.h new file mode 100644 index 00000000000..ad5009c03f4 --- /dev/null +++ b/adapter/ohos/capability/package/package_event_proxy_ohos.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_ADAPTER_OHOS_CAPABILITY_EVENT_PROXY_PACKAGE_H +#define FOUNDATION_ACE_ADAPTER_OHOS_CAPABILITY_EVENT_PROXY_PACKAGE_H + +#include +#include +#include + +#include "common_event_subscriber.h" + +#include "base/memory/referenced.h" +#include "base/utils/noncopyable.h" +#include "core/event/package/package_event_proxy.h" + +namespace OHOS::Ace { +using EventFwk::CommonEventData; +using EventFwk::CommonEventSubscribeInfo; +using EventFwk::CommonEventSubscriber; + +/** + * @brief The PackageEventSubscriber class is a subclass of CommonEventSubscriber. + * It represents a subscriber for package events. + */ +class PackageEventSubscriber : public CommonEventSubscriber { +public: + explicit PackageEventSubscriber(const CommonEventSubscribeInfo& subscribeInfo) + : CommonEventSubscriber(subscribeInfo) {} + void OnReceiveEvent(const CommonEventData& data) override; +}; + +class ACE_EXPORT PackageEventProxyOhos : public PackageEventProxy { +public: + PackageEventProxyOhos(); + ~PackageEventProxyOhos() override; + + void Register(const WeakPtr& listener) override; + + void OnPackageChange() override; + +private: + /** + * @brief A set of package change listeners paired with their Container IDs. + * + * Need to switch to the correct container ID before notifying the listener. + */ + std::set, int32_t>> listeners_; + + std::shared_ptr packageEventSubscriber_; + + ACE_DISALLOW_COPY_AND_MOVE(PackageEventProxyOhos); +}; +} // namespace OHOS::Ace + +#endif // FOUNDATION_ACE_ADAPTER_OHOS_CAPABILITY_EVENT_PROXY_PACKAGE_H \ No newline at end of file diff --git a/adapter/ohos/osal/navigation_route_ohos.cpp b/adapter/ohos/osal/navigation_route_ohos.cpp index f0b3caadfe8..3fa1bd84727 100644 --- a/adapter/ohos/osal/navigation_route_ohos.cpp +++ b/adapter/ohos/osal/navigation_route_ohos.cpp @@ -37,7 +37,7 @@ sptr NavigationRouteOhos::GetBundleManager() return iface_cast(bundleObj); } -void NavigationRouteOhos::InitRouteMap(const std::string& bundleName) +void NavigationRouteOhos::InitRouteMap() { auto bundleManager = GetBundleManager(); if (!bundleManager) { @@ -55,6 +55,11 @@ void NavigationRouteOhos::InitRouteMap(const std::string& bundleName) allRouteItems_ = bundleInfo.routerArray; } +void NavigationRouteOhos::OnPackageChange() +{ + InitRouteMap(); +} + bool NavigationRouteOhos::GetRouteItem(const std::string& name, NG::RouteItem& info) { AppExecFwk::RouterItem routeItem; @@ -89,10 +94,25 @@ int32_t NavigationRouteOhos::LoadPage(const std::string& name) TAG_LOGE(AceLogTag::ACE_NAVIGATION, "get route name failed"); return ERROR_CODE_BUILDER_FUNCTION_NOT_REGISTERED; } + if (callback_ == nullptr) { + return -1; + } int32_t res = callback_(item.bundleName, item.moduleName, item.ohmurl, false); if (res == 0) { names_.emplace_back(name); } return res; } + +bool NavigationRouteOhos::IsNavigationItemExits(const std::string& name) +{ + if (HasLoaded(name)) { + return true; + } + AppExecFwk::RouterItem item; + if (GetRouteItemFromBundle(name, item)) { + return true; + } + return false; +} } // namespace OHOS::Ace \ No newline at end of file diff --git a/adapter/ohos/osal/navigation_route_ohos.h b/adapter/ohos/osal/navigation_route_ohos.h index dcc4cdae463..18f159a7333 100644 --- a/adapter/ohos/osal/navigation_route_ohos.h +++ b/adapter/ohos/osal/navigation_route_ohos.h @@ -29,7 +29,7 @@ class ACE_EXPORT NavigationRouteOhos : public NG::NavigationRoute { public: explicit NavigationRouteOhos(const std::string& bundleName) { - InitRouteMap(bundleName); + InitRouteMap(); } ~NavigationRouteOhos() = default; @@ -42,9 +42,13 @@ public: int32_t LoadPage(const std::string& name) override; + bool IsNavigationItemExits(const std::string& name) override; + + void OnPackageChange() override; + private: bool GetRouteItemFromBundle(const std::string& name, AppExecFwk::RouterItem& routeItem); - void InitRouteMap(const std::string& bundleName); + void InitRouteMap(); sptr GetBundleManager(); AppExecFwk::RouterItem GetRouteItem(const std::string name); std::vector allRouteItems_; diff --git a/adapter/preview/osal/BUILD.gn b/adapter/preview/osal/BUILD.gn index a65c45b98b6..f67eb5cbe94 100644 --- a/adapter/preview/osal/BUILD.gn +++ b/adapter/preview/osal/BUILD.gn @@ -74,6 +74,7 @@ ohos_source_set("preview_osal_source") { "input_method_manager_preview.cpp", "modal_ui_extension_impl.cpp", "mouse_style_ohos.cpp", + "package_event_proxy_preview.cpp", "pixel_map_preview.cpp", "response_data.cpp", "ressched_report.cpp", diff --git a/adapter/preview/osal/package_event_proxy_preview.cpp b/adapter/preview/osal/package_event_proxy_preview.cpp new file mode 100644 index 00000000000..7de1b520e01 --- /dev/null +++ b/adapter/preview/osal/package_event_proxy_preview.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "core/event/package/package_event_proxy.h" + +namespace OHOS::Ace { +std::unique_ptr PackageEventProxy::instance_; +std::mutex PackageEventProxy::mutex_; + +PackageEventProxy* PackageEventProxy::GetInstance() +{ + return nullptr; +} +} // namespace OHOS::Ace diff --git a/advanced_ui_component/BUILD.gn b/advanced_ui_component/BUILD.gn index cd8f60c1073..6cf09bf3380 100644 --- a/advanced_ui_component/BUILD.gn +++ b/advanced_ui_component/BUILD.gn @@ -31,6 +31,7 @@ group("advanced_ui_component") { "fullscreenlaunchcomponent/interfaces:fullscreenlaunchcomponent", "gridobjectsortcomponent/interfaces:gridobjectsortcomponent", "interstitialdialogaction/interfaces:interstitialdialogaction", + "navpushpathhelper:navpushpathhelper", "popup/interfaces:popup", "progressbutton/interfaces:progressbutton", "segmentbutton/interfaces:segmentbutton", diff --git a/advanced_ui_component/navpushpathhelper/BUILD.gn b/advanced_ui_component/navpushpathhelper/BUILD.gn new file mode 100644 index 00000000000..856103c64ae --- /dev/null +++ b/advanced_ui_component/navpushpathhelper/BUILD.gn @@ -0,0 +1,76 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//arkcompiler/ets_frontend/es2panda/es2abc_config.gni") +import("//build/ohos.gni") +import("//foundation/arkui/ace_engine/ace_config.gni") +import("//foundation/arkui/ace_engine/adapter/preview/build/config.gni") +import("//foundation/arkui/ace_engine/build/ace_gen_obj.gni") + +es2abc_gen_abc("gen_navpushpathhelper_abc") { + src_js = rebase_path("navpushpathhelper.js") + dst_file = rebase_path(target_out_dir + "/navpushpathhelper.abc") + in_puts = [ "navpushpathhelper.js" ] + out_puts = [ target_out_dir + "/navpushpathhelper.abc" ] + extra_args = [ "--module" ] +} + +gen_js_obj("navpushpathhelper_abc") { + input = get_label_info(":gen_navpushpathhelper_abc", "target_out_dir") + + "/navpushpathhelper.abc" + output = target_out_dir + "/navpushpathhelper_abc.o" + dep = ":gen_navpushpathhelper_abc" +} + +gen_obj("navpushpathhelper_abc_preview") { + input = get_label_info(":gen_navpushpathhelper_abc", "target_out_dir") + + "/navpushpathhelper.abc" + output = target_out_dir + "/navpushpathhelper_abc.c" + snapshot_dep = [ ":gen_navpushpathhelper_abc" ] +} + +additional_include_dirs = [ "${ace_root}" ] + +ohos_shared_library("navpushpathhelper") { + sources = [ + "src/hsp_silentinstall.cpp", + "src/hsp_silentinstall_napi.cpp", + "src/navpushpathhelper.cpp", + ] + + if (use_mingw_win || use_mac || use_linux) { + deps = [ ":gen_obj_src_navpushpathhelper_abc_preview" ] + } else { + deps = [ ":navpushpathhelper_abc" ] + } + + include_dirs = additional_include_dirs + include_dirs += [ "${ace_root}/frameworks" ] + deps += [ "$ace_root/build:libace_compatible" ] + + external_deps = [ + "ability_base:want", + "ability_runtime:abilitykit_native", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "napi:ace_napi", + "samgr:samgr_proxy", + ] + + relative_install_dir = "module/atomicservice" + subsystem_name = ace_engine_subsystem + part_name = ace_engine_part +} diff --git a/advanced_ui_component/navpushpathhelper/include/hsp_silentinstall.h b/advanced_ui_component/navpushpathhelper/include/hsp_silentinstall.h new file mode 100644 index 00000000000..6337fcf89e7 --- /dev/null +++ b/advanced_ui_component/navpushpathhelper/include/hsp_silentinstall.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ADVANCED_UI_COMPONENT_NAVPUSHPATHHELPER_INCLUDE_HSP_SILENTINSTALL_H +#define ADVANCED_UI_COMPONENT_NAVPUSHPATHHELPER_INCLUDE_HSP_SILENTINSTALL_H + +#include "bundlemgr/bundle_mgr_interface.h" +#include "interfaces/inner_api/ace/ui_content.h" +namespace OHOS::NavPushPathHelper { + +class HspSilentInstall { +public: + HspSilentInstall() = default; + ~HspSilentInstall() = default; + + static int32_t SilentInstall(const std::string& moduleName, const std::function& callback, + const std::function& silentInstallErrorCallBack); + static bool IsHspExist(const std::string& moduleName, const std::string& pathName); + +private: + static OHOS::sptr GetBundleManager(); +}; +} // namespace OHOS::NavPushPathHelper +#endif \ No newline at end of file diff --git a/advanced_ui_component/navpushpathhelper/include/hsp_silentinstall_napi.h b/advanced_ui_component/navpushpathhelper/include/hsp_silentinstall_napi.h new file mode 100644 index 00000000000..4ccee0910b9 --- /dev/null +++ b/advanced_ui_component/navpushpathhelper/include/hsp_silentinstall_napi.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ADVANCED_UI_COMPONENT_NAVPUSHPATHHELPER_INCLUDE_HSP_SILENT_INSTALL_NAPI_H +#define ADVANCED_UI_COMPONENT_NAVPUSHPATHHELPER_INCLUDE_HSP_SILENT_INSTALL_NAPI_H + +#include "native_engine/native_engine.h" + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS::NavPushPathHelper { +class HspSilentInstallNapi { + public: + static napi_value SilentInstall(napi_env env, napi_callback_info info); + static napi_value IsHspExist(napi_env env, napi_callback_info info); + + private: + struct CallbackData { + napi_env env = nullptr; + int32_t errCode = 0; + std::string errorMessage; + napi_ref successCallback = nullptr; + napi_ref failCallback = nullptr; + + ~CallbackData() + { + if (this->successCallback != nullptr) { + napi_delete_reference(this->env, this->successCallback); + this->successCallback = nullptr; + } + if (this->failCallback != nullptr) { + napi_delete_reference(this->env, this->failCallback); + this->failCallback = nullptr; + } + } + }; + + static void SendSuccessBackWork(uv_work_t *work, int statusIn); + static void SendFailBackWork(uv_work_t *work, int statusIn); + static napi_value CreateResultMessage(CallbackData *callbackData); + static napi_value getModuleName(napi_env env, napi_value args, std::string& moduleName); +}; +} + +#endif \ No newline at end of file diff --git a/advanced_ui_component/navpushpathhelper/include/silent_install_callback.h b/advanced_ui_component/navpushpathhelper/include/silent_install_callback.h new file mode 100644 index 00000000000..5297d2ec58a --- /dev/null +++ b/advanced_ui_component/navpushpathhelper/include/silent_install_callback.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef ADVANCED_UI_COMPONENT_NAVPUSHPATHHELPER_INCLUDE_SILENT_INSTALL_CALLBACK_H +#define ADVANCED_UI_COMPONENT_NAVPUSHPATHHELPER_INCLUDE_SILENT_INSTALL_CALLBACK_H + +#include "atomic_service_status_callback.h" +#include "errors.h" +#include "iremote_broker.h" +#include "iremote_object.h" +#include "iremote_stub.h" +#include "base/log/log.h" +#include "want_params_wrapper.h" +#include "want.h" + +namespace OHOS::NavPushPathHelper { +constexpr int32_t SILENT_INSTALL_SUCCESS = 0; +constexpr int32_t SILENT_INSTALL_FAIL_CODE = 300001; +constexpr char SILENT_INSTALL_FAIL_MESSAGE[] = "hsp silent install fail"; + +/** + * @class IAtomicServiceStatusCallback + * IAtomicServiceStatusCallback is used to notify caller ability that free install is complete. + */ +class IAtomicServiceStatusCallback : public OHOS::IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.IAtomicServiceStatusCallback"); + + /** + * @brief OnActionEvent. + */ + virtual int32_t OnActionEvent() = 0; + /** + * @brief OnError. + * @param code The code. + * @param msg The msg. + */ + virtual int32_t OnError(int32_t code, const std::string& msg) = 0; +}; + +/** + * @class AtomicServiceStatusCallbackStub + * AtomicServiceStatusCallbackStub. + */ +class AtomicServiceStatusCallbackStub : public OHOS::IRemoteStub { +public: + AtomicServiceStatusCallbackStub() + { + handleOnActionEventFunc_ = &AtomicServiceStatusCallbackStub::HandleOnActionEvent; + handleOnErrorFunc_ = &AtomicServiceStatusCallbackStub::HandleOnError; + } + ~AtomicServiceStatusCallbackStub() override + { + handleOnActionEventFunc_ = nullptr; + handleOnErrorFunc_ = nullptr; + } + + int32_t OnRemoteRequest(uint32_t code, OHOS::MessageParcel &data, OHOS::MessageParcel &reply, + OHOS::MessageOption &option) override + { + TAG_LOGD(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, + "AtomicServiceStatusCallbackStub::OnReceived, code = %{public}u, flags= %{public}d.", + code, option.GetFlags()); + std::u16string descriptor = AtomicServiceStatusCallbackStub::GetDescriptor(); + std::u16string remoteDescriptor = data.ReadInterfaceToken(); + if (descriptor != remoteDescriptor) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, + "%{public}s failed, local descriptor is not equal to remote", __func__); + return OHOS::ERR_INVALID_VALUE; + } + + auto resultCode = data.ReadInt32(); + if (resultCode == SILENT_INSTALL_SUCCESS) { + if (handleOnActionEventFunc_ != nullptr) { + return (this->*handleOnActionEventFunc_)(); + } + } + + if (resultCode < SILENT_INSTALL_SUCCESS) { + if (handleOnErrorFunc_ != nullptr) { + return (this->*handleOnErrorFunc_)(); + } + } + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + +private: + int32_t HandleOnActionEvent() + { + return OnActionEvent(); + } + int32_t HandleOnError() + { + return OnError(SILENT_INSTALL_FAIL_CODE, SILENT_INSTALL_FAIL_MESSAGE); + } + + using HandleOnActionEventFunc = int32_t (AtomicServiceStatusCallbackStub::*)(); + HandleOnActionEventFunc handleOnActionEventFunc_; + + using HandleOnErrorFunc = int32_t (AtomicServiceStatusCallbackStub::*)(); + HandleOnErrorFunc handleOnErrorFunc_; + + DISALLOW_COPY_AND_MOVE(AtomicServiceStatusCallbackStub); +}; + +/** + * @class AtomicServiceStatusCallback + * AtomicServiceStatusCallback. + */ +class AtomicServiceStatusCallback : public AtomicServiceStatusCallbackStub { +public: + AtomicServiceStatusCallback() = default; + ~AtomicServiceStatusCallback() override = default; + + /** + * @brief OnActionEvent. + */ + int32_t OnActionEvent() override + { + if (!actionEventHandler_) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "actionEventHandler_ is null."); + return OHOS::ERR_INVALID_VALUE; + } + actionEventHandler_(); + return OHOS::ERR_OK; + } + /** + * @brief OnError. + * @param code The code. + * @param msg The msg. + */ + int32_t OnError(int32_t code, const std::string& msg) override + { + TAG_LOGI(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "OnError code: %{public}d, msg: %{public}s", + code, msg.c_str()); + if (!errorEventHandler_) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "errorEventHandler_ is null"); + return OHOS::ERR_INVALID_VALUE; + } + + errorEventHandler_(code, msg); + return OHOS::ERR_OK; + } + + void SetActionEventHandler(const std::function& listener) + { + actionEventHandler_ = listener; + } + void SetErrorEventHandler(const std::function& listener) + { + errorEventHandler_ = listener; + } + +private: + std::function actionEventHandler_; + std::function errorEventHandler_; +}; +} +#endif \ No newline at end of file diff --git a/advanced_ui_component/navpushpathhelper/navpushpathhelper.js b/advanced_ui_component/navpushpathhelper/navpushpathhelper.js new file mode 100644 index 00000000000..34baa4c0885 --- /dev/null +++ b/advanced_ui_component/navpushpathhelper/navpushpathhelper.js @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const navPushPathHelperApi = requireInternal('atomicservice.NavPushPathHelper'); +const hilog = requireNapi('hilog'); + +const tag = 'NavPushPathHelper::JS::'; + +export class NavPushPathHelper { + static currentID = 0; + constructor(navPathStack) { + this.navPathStack_ = navPathStack; + this.currentHelperId_ = NavPushPathHelper.currentID; + NavPushPathHelper.currentID++; + } + + async pushPath(moduleName, info, optionParam) { + hilog.info(0x3900, tag, `pushPath -> currentID: ${this.currentHelperId_}`); + if (navPushPathHelperApi.isHspExist(moduleName, info.name)) { + this.navPathStack_?.pushPath(info, optionParam); + return; + } + return new Promise((resolve, reject) => { + navPushPathHelperApi.silentInstall(moduleName, () => { + this.navPathStack_?.pushPath(info, optionParam); + resolve(); + }, + (error) => { + const err = new Error(error.message); + err.code = error.code; + reject(err); + }); + }); + } + + async pushDestination(moduleName, info, optionParam) { + hilog.info(0x3900, tag, `pushDestination -> currentID: ${this.currentHelperId_}`); + if (navPushPathHelperApi.isHspExist(moduleName, info.name)) { + await this.navPathStack_?.pushDestination(info, optionParam); + return; + } + return new Promise((resolve, reject) => { + navPushPathHelperApi.silentInstall(moduleName, () => { + this.navPathStack_?.pushDestination(info, optionParam) + .then(resolve).catch(reject); + }, (error) => { + const err = new Error(error.message); + err.code = error.code; + reject(err); + }); + }); + } + + async pushPathByName(moduleName, name, param, onPop, optionParam) { + hilog.info(0x3900, tag, `pushPathByName -> currentID: ${this.currentHelperId_}`); + if (navPushPathHelperApi.isHspExist(moduleName, name)) { + this.navPathStack_?.pushPathByName(name, param, onPop, optionParam); + return; + } + return new Promise((resolve, reject) => { + navPushPathHelperApi.silentInstall(moduleName, () => { + this.navPathStack_?.pushPathByName(name, param, onPop, optionParam); + resolve(); + }, (error) => { + const err = new Error(error.message); + err.code = error.code; + reject(err); + }); + }); + } + + async pushDestinationByName(moduleName, name, param, onPop, optionParam) { + hilog.info(0x3900, tag, `pushDestinationByName -> currentID: ${this.currentHelperId_}`); + if (navPushPathHelperApi.isHspExist(moduleName, name)) { + await this.navPathStack_?.pushDestinationByName(name, param, onPop, optionParam); + return; + } + return new Promise((resolve, reject) => { + navPushPathHelperApi.silentInstall(moduleName, () => { + this.navPathStack_?.pushDestinationByName(name, param, onPop, optionParam) + .then(resolve).catch(reject); + }, (error) => { + const err = new Error(error.message); + err.code = error.code; + reject(err); + }); + }); + } + + async replacePath(moduleName, info, optionParam) { + hilog.info(0x3900, tag, `replacePath -> currentID: ${this.currentHelperId_}`); + if (navPushPathHelperApi.isHspExist(moduleName, info.name)) { + this.navPathStack_?.replacePath(info, optionParam); + return; + } + return new Promise((resolve, reject) => { + navPushPathHelperApi.silentInstall(moduleName, () => { + this.navPathStack_?.replacePath(info, optionParam); + resolve(); + }, (error) => { + const err = new Error(error.message); + err.code = error.code; + reject(err); + }); + }); + } + + async replacePathByName(moduleName, name, param, optionParam) { + hilog.info(0x3900, tag, `replacePathByName -> currentID: ${this.currentHelperId_}`); + if (navPushPathHelperApi.isHspExist(moduleName, name)) { + this.navPathStack_?.replacePathByName(name, param, optionParam); + return; + } + return new Promise((resolve, reject) => { + navPushPathHelperApi.silentInstall(moduleName, () => { + this.navPathStack_?.replacePathByName(name, param, optionParam); + resolve(); + }, (error) => { + const err = new Error(error.message); + err.code = error.code; + reject(err); + }); + }); + } +} + +export default { NavPushPathHelper }; \ No newline at end of file diff --git a/advanced_ui_component/navpushpathhelper/src/hsp_silentinstall.cpp b/advanced_ui_component/navpushpathhelper/src/hsp_silentinstall.cpp new file mode 100644 index 00000000000..865afdecdf8 --- /dev/null +++ b/advanced_ui_component/navpushpathhelper/src/hsp_silentinstall.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "advanced_ui_component/navpushpathhelper/include/hsp_silentinstall.h" +#include "advanced_ui_component/navpushpathhelper/include/silent_install_callback.h" + +#include "iservice_registry.h" +#include "system_ability_definition.h" +#include "ability_runtime/context/context.h" +#include "want.h" +#include "adapter/ohos/entrance/ace_container.h" +#include "core/pipeline_ng/pipeline_context.h" +#include "base/log/log.h" +#include "base/utils/utils.h" +#include "core/components_ng/manager/navigation/navigation_manager.h" +#include "core/components_ng/pattern/image/image_pattern.h" + +namespace OHOS::NavPushPathHelper { + +OHOS::sptr HspSilentInstall::GetBundleManager() +{ + auto systemAbilityMgr = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (!systemAbilityMgr) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "get system ability failed"); + return nullptr; + } + auto bundleObj = systemAbilityMgr->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (!bundleObj) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "get bundle service failed"); + return nullptr; + } + return OHOS::iface_cast(bundleObj); +} + +int32_t HspSilentInstall::SilentInstall(const std::string& moduleName, const std::function& callback, + const std::function& silentInstallErrorCallBack) +{ + auto pipeline = OHOS::Ace::NG::PipelineContext::GetCurrentContextSafely(); + CHECK_NULL_RETURN(pipeline, -1); + + auto runtimeContext = OHOS::Ace::Platform::AceContainer::GetRuntimeContext(pipeline->GetInstanceId()); + CHECK_NULL_RETURN(runtimeContext, -1); + + auto bundleName = runtimeContext->GetBundleName(); + if (bundleName.empty()) { + return -1; + } + + auto appInfo = runtimeContext->GetApplicationInfo(); + if (!appInfo) { + return -1; + } + auto bms = GetBundleManager(); + CHECK_NULL_RETURN(bms, -1); + + OHOS::AAFwk::Want want; + want.SetBundle(bundleName); + want.SetModuleName(moduleName); + OHOS::sptr routerCallback = new AtomicServiceStatusCallback(); + routerCallback->SetActionEventHandler(callback); + routerCallback->SetErrorEventHandler(silentInstallErrorCallBack); + if (bms->SilentInstall(want, appInfo->uid / OHOS::AppExecFwk::Constants::BASE_USER_RANGE, routerCallback)) { + TAG_LOGI(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "Begin to silent install"); + return 0; + } + return -1; +} + +bool HspSilentInstall::IsHspExist(const std::string &moduleName, const std::string &pathName) +{ + auto pipeline = OHOS::Ace::NG::PipelineContext::GetCurrentContextSafely(); + CHECK_NULL_RETURN(pipeline, false); + auto container = OHOS::Ace::Container::Current(); + CHECK_NULL_RETURN(container, false); + auto navigationRoute = container->GetNavigationRoute(); + CHECK_NULL_RETURN(navigationRoute, false); + if (navigationRoute->IsNavigationItemExits(pathName)) { + return true; + } + + auto runtimeContext = OHOS::Ace::Platform::AceContainer::GetRuntimeContext(pipeline->GetInstanceId()); + CHECK_NULL_RETURN(runtimeContext, false); + + auto appInfo = runtimeContext->GetApplicationInfo(); + if (!appInfo) { + return false; + } + std::vector moduleList = appInfo->moduleInfos; + auto res = std::any_of(moduleList.begin(), moduleList.end(), [moduleName](const auto &module) { + return module.moduleName == moduleName; + }); + if (res) { + return true; + } + return false; +} +} // namespace OHOS::NavPushPathHelper \ No newline at end of file diff --git a/advanced_ui_component/navpushpathhelper/src/hsp_silentinstall_napi.cpp b/advanced_ui_component/navpushpathhelper/src/hsp_silentinstall_napi.cpp new file mode 100644 index 00000000000..14339b0e731 --- /dev/null +++ b/advanced_ui_component/navpushpathhelper/src/hsp_silentinstall_napi.cpp @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "advanced_ui_component/navpushpathhelper/include/hsp_silentinstall_napi.h" +#include "advanced_ui_component/navpushpathhelper/include/hsp_silentinstall.h" +#include "base/log/log.h" + +using namespace std; + +namespace OHOS::NavPushPathHelper { + +napi_value HspSilentInstallNapi::IsHspExist(napi_env env, napi_callback_info info) +{ + size_t argc = 2; + size_t requireArgc = 2; + napi_value args[2] = { nullptr }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); + NAPI_ASSERT(env, argc >= requireArgc, "Wrong number of arguments"); + + // get first parameter:moduleName + napi_valuetype moduleNameType; + NAPI_CALL(env, napi_typeof(env, args[0], &moduleNameType)); + NAPI_ASSERT(env, moduleNameType == napi_string, "Wrong argument type. String expected."); + + size_t maxValueLen = 1024; + char moduleNameValue[maxValueLen]; + size_t moduleNameLength = 0; + napi_get_value_string_utf8(env, args[0], moduleNameValue, maxValueLen, &moduleNameLength); + std::string moduleName = moduleNameValue; + + // get second parameter:pathName + napi_valuetype pathNameType; + NAPI_CALL(env, napi_typeof(env, args[1], &pathNameType)); + NAPI_ASSERT(env, pathNameType == napi_string, "Wrong argument type. String expected."); + + char pathNameValue[maxValueLen]; + size_t pathNameLength = 0; + napi_get_value_string_utf8(env, args[1], pathNameValue, maxValueLen, &pathNameLength); + std::string pathName = pathNameValue; + + bool isHspExits = HspSilentInstall::IsHspExist(moduleName, pathName); + napi_value jsResult; + NAPI_CALL(env, napi_get_boolean(env, isHspExits, &jsResult)); + return jsResult; +} + +napi_value HspSilentInstallNapi::SilentInstall(napi_env env, napi_callback_info info) +{ + napi_value result = nullptr; + size_t argc = 3; + size_t requireArgc = 3; + napi_value args[3] = { nullptr }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); + NAPI_ASSERT(env, argc >= requireArgc, "Wrong number of arguments"); + + // get first parameter:moduleName + std::string moduleName; + getModuleName(env, args[0], moduleName); + + auto callbackData = new CallbackData(); + int parameterNum = 1; + const int indexTwo = 2; + napi_create_reference(env, args[1], parameterNum, &(callbackData->successCallback)); + napi_create_reference(env, args[indexTwo], parameterNum, &(callbackData->failCallback)); + callbackData->env = env; + + auto successCallback = [callbackData]() { + uv_loop_s *loop = nullptr; + napi_get_uv_event_loop(callbackData->env, &loop); + uv_work_t *work = new (std::nothrow) uv_work_t; + work->data = reinterpret_cast(callbackData); + uv_queue_work(loop, work, [](uv_work_t *work) { (void)work; }, SendSuccessBackWork); + }; + + auto failCallback = [callbackData](int32_t errorCode, const std::string& errorMessage) { + callbackData->errCode = errorCode; + callbackData->errorMessage = errorMessage; + + uv_loop_s *loop = nullptr; + napi_get_uv_event_loop(callbackData->env, &loop); + uv_work_t *work = new (std::nothrow) uv_work_t; + work->data = reinterpret_cast(callbackData); + uv_queue_work(loop, work, [](uv_work_t *work) { (void)work; }, SendFailBackWork); + }; + + HspSilentInstall::SilentInstall(moduleName, successCallback, failCallback); + return result; +} + +napi_value HspSilentInstallNapi::getModuleName(napi_env env, napi_value args, std::string& moduleName) +{ + napi_valuetype moduleNameType; + NAPI_CALL(env, napi_typeof(env, args, &moduleNameType)); + NAPI_ASSERT(env, moduleNameType == napi_string, "Wrong argument type. String expected."); + + napi_status status; + size_t maxValueLen = 1024; + char moduleNameValue[maxValueLen]; + size_t moduleNameLength = 0; + status = napi_get_value_string_utf8(env, args, moduleNameValue, maxValueLen, &moduleNameLength); + NAPI_ASSERT(env, status == napi_ok, "Failed to napi_get_value_string_utf8"); + moduleName = moduleNameValue; + return nullptr; +} + +void HspSilentInstallNapi::SendSuccessBackWork(uv_work_t *work, int statusIn) +{ + (void)statusIn; + napi_status status; + napi_handle_scope scope = nullptr; + CallbackData *callbackData = reinterpret_cast(work->data); + if (callbackData == nullptr) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendSuccessBackWork -> callbackData is null"); + return; + } + + napi_open_handle_scope(callbackData->env, &scope); + if (scope == nullptr) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendSuccessBackWork -> scope is null"); + return; + } + + napi_value callback = nullptr; + status = napi_get_reference_value(callbackData->env, callbackData->successCallback, &callback); + if (status != napi_ok) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendSuccessBackWork -> napi_get_reference_value error"); + napi_close_handle_scope(callbackData->env, scope); + return; + } + + napi_value result; + status = napi_call_function(callbackData->env, nullptr, callback, 0, nullptr, &result); + if (status != napi_ok) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendSuccessBackWork -> napi_call_function error"); + napi_close_handle_scope(callbackData->env, scope); + return; + } + + napi_close_handle_scope(callbackData->env, scope); + + if (callbackData != nullptr) { + delete callbackData; + callbackData = nullptr; + } + + if (work != nullptr) { + delete work; + work = nullptr; + } +} + +void HspSilentInstallNapi::SendFailBackWork(uv_work_t *work, int statusIn) +{ + (void)statusIn; + napi_status status; + napi_handle_scope scope = nullptr; + CallbackData *callbackData = reinterpret_cast(work->data); + if (callbackData == nullptr) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendFailBackWork -> callbackData is null"); + return; + } + + napi_open_handle_scope(callbackData->env, &scope); + if (scope == nullptr) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendFailBackWork -> scope is null"); + return; + } + + napi_value callback = nullptr; + status = napi_get_reference_value(callbackData->env, callbackData->failCallback, &callback); + if (status != napi_ok) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendFailBackWork -> napi_get_reference_value error"); + napi_close_handle_scope(callbackData->env, scope); + return; + } + + size_t resultLength = 1; + napi_value resultMessage = CreateResultMessage(callbackData); + napi_value result[] = { resultMessage }; + status = napi_call_function(callbackData->env, nullptr, callback, resultLength, result, nullptr); + if (status != napi_ok) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendFailBackWork -> napi_call_function error"); + napi_close_handle_scope(callbackData->env, scope); + return; + } + + napi_close_handle_scope(callbackData->env, scope); + + if (callbackData != nullptr) { + delete callbackData; + callbackData = nullptr; + } + + if (work != nullptr) { + delete work; + work = nullptr; + } +} + +napi_value HspSilentInstallNapi::CreateResultMessage(CallbackData *callbackData) +{ + napi_status status; + napi_value result = nullptr; + napi_value code = nullptr; + + status = napi_create_int32(callbackData->env, callbackData->errCode, &code); + if (status != napi_ok) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "CreateResultMessage -> napi_create_int32 error"); + return result; + } + + napi_value message = nullptr; + status = napi_create_string_utf8(callbackData->env, callbackData->errorMessage.c_str(), + NAPI_AUTO_LENGTH, &message); + if (status != napi_ok) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "CreateResultMessage -> napi_create_string_utf8 error"); + return result; + } + + napi_value businessError = nullptr; + status = napi_create_object(callbackData->env, &businessError); + if (status != napi_ok) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "CreateResultMessage -> napi_create_object error"); + return result; + } + + status = napi_set_named_property(callbackData->env, businessError, "code", code); + if (status != napi_ok) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "CreateResultMessage -> napi_set_named_property error"); + return result; + } + + status = napi_set_named_property(callbackData->env, businessError, "message", message); + if (status != napi_ok) { + TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "CreateResultMessage -> napi_set_named_property error"); + return result; + } + return businessError; +} +} \ No newline at end of file diff --git a/advanced_ui_component/navpushpathhelper/src/navpushpathhelper.cpp b/advanced_ui_component/navpushpathhelper/src/navpushpathhelper.cpp new file mode 100644 index 00000000000..95a8eefe291 --- /dev/null +++ b/advanced_ui_component/navpushpathhelper/src/navpushpathhelper.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "native_engine/native_engine.h" + +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "advanced_ui_component/navpushpathhelper/include/hsp_silentinstall_napi.h" + +extern const char _binary_navpushpathhelper_abc_start[]; +extern const char _binary_navpushpathhelper_abc_end[]; + +namespace OHOS::NavPushPathHelper { + /* + * function for module exports + */ + static napi_value Init(napi_env env, napi_value exports) + { + /* + * Properties define + */ + napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("silentInstall", HspSilentInstallNapi::SilentInstall), + DECLARE_NAPI_FUNCTION("isHspExist", HspSilentInstallNapi::IsHspExist), + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + return exports; + } + + // Napi get abc code function + extern "C" __attribute__((visibility("default"))) + void NAPI_atomicservice_NavPushPathHelper_GetABCCode(const char **buf, int *buflen) + { + if (buf != nullptr) { + *buf = _binary_navpushpathhelper_abc_start; + } + if (buflen != nullptr) { + *buflen = _binary_navpushpathhelper_abc_end - _binary_navpushpathhelper_abc_start; + } + } + + /* + * Module define + */ + static napi_module NavPushPathHelperModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "atomicservice.NavPushPathHelper", + .nm_priv = ((void*)0), + .reserved = { 0 }, + }; + + /* + * Module registerfunction + */ + extern "C" __attribute__((constructor)) void NavPushPathHelperRegisterModule(void) + { + napi_module_register(&NavPushPathHelperModule); + } +} \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/navigation/navigation_group_node.cpp b/frameworks/core/components_ng/pattern/navigation/navigation_group_node.cpp index dc0ca36f440..4fd70d14dfe 100644 --- a/frameworks/core/components_ng/pattern/navigation/navigation_group_node.cpp +++ b/frameworks/core/components_ng/pattern/navigation/navigation_group_node.cpp @@ -56,6 +56,7 @@ #include "core/components_ng/property/property.h" #include "core/components_ng/render/render_context.h" #include "core/components_v2/inspector/inspector_constants.h" +#include "core/event/package/package_event_proxy.h" namespace OHOS::Ace::NG { namespace { @@ -1158,6 +1159,14 @@ void NavigationGroupNode::OnAttachToMainTree(bool recursive) if (!findNavdestination) { pipelineContext->AddNavigationNode(pageId, WeakClaim(this)); } + auto* eventProxy = PackageEventProxy::GetInstance(); + if (eventProxy) { + auto container = OHOS::Ace::Container::CurrentSafely(); + CHECK_NULL_VOID(container); + auto navigationRoute = container->GetNavigationRoute(); + CHECK_NULL_VOID(navigationRoute); + eventProxy->Register(WeakClaim(AceType::RawPtr(navigationRoute))); + } } void NavigationGroupNode::FireHideNodeChange(NavDestinationLifecycle lifecycle) diff --git a/frameworks/core/components_ng/pattern/navigation/navigation_route.h b/frameworks/core/components_ng/pattern/navigation/navigation_route.h index 57328f70f4a..39f0c39d989 100644 --- a/frameworks/core/components_ng/pattern/navigation/navigation_route.h +++ b/frameworks/core/components_ng/pattern/navigation/navigation_route.h @@ -19,6 +19,7 @@ #include #include "base/memory/ace_type.h" #include "base/memory/referenced.h" +#include "core/event/package/package_change_listener.h" namespace OHOS::Ace::NG { using NavigationLoadPageCallback = std::function data; }; -class ACE_EXPORT NavigationRoute : public AceType { - DECLARE_ACE_TYPE(NavigationRoute, AceType) +class ACE_EXPORT NavigationRoute : public PackageChangeListener { + DECLARE_ACE_TYPE(NavigationRoute, PackageChangeListener) public: NavigationRoute() = default; ~NavigationRoute() = default; @@ -59,6 +60,13 @@ public: callback_ = std::move(callback); } + virtual bool IsNavigationItemExits(const std::string& name) + { + return false; + } + + void OnPackageChange() override {} + protected: NavigationLoadPageCallback callback_; }; diff --git a/frameworks/core/event/package/package_change_listener.h b/frameworks/core/event/package/package_change_listener.h new file mode 100644 index 00000000000..0b0e617fd46 --- /dev/null +++ b/frameworks/core/event/package/package_change_listener.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_PACKAGE_CHANGE_LISTENER_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_PACKAGE_CHANGE_LISTENER_H + +#include "base/memory/ace_type.h" +#include "base/utils/noncopyable.h" + +namespace OHOS::Ace { +/** + * @brief an interface for package change listeners. + * Listeners need to register to PackageEventProxy to receive package change + */ +class PackageChangeListener : public AceType { + DECLARE_ACE_TYPE(PackageChangeListener, AceType); +public: + PackageChangeListener() = default; + ~PackageChangeListener() override = default; + + /** + * @brief This function is called when the system time changes. + * + * Subclasses should override this function to perform specific actions when the time changes. + */ + virtual void OnPackageChange() = 0; + + ACE_DISALLOW_COPY_AND_MOVE(PackageChangeListener); +}; +} // namespace OHOS::Ace + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_PACKAGE_CHANGE_LISTENER_H \ No newline at end of file diff --git a/frameworks/core/event/package/package_event_proxy.h b/frameworks/core/event/package/package_event_proxy.h new file mode 100644 index 00000000000..86792ee3e04 --- /dev/null +++ b/frameworks/core/event/package/package_event_proxy.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_PACKAGE_EVENT_PROXY_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_PACKAGE_EVENT_PROXY_H + +#include +#include + +#include "base/memory/referenced.h" +#include "base/utils/noncopyable.h" +#include "core/event/package/package_change_listener.h" + +namespace OHOS::Ace { +/** + * @class PackageEventProxy + * @brief The PackageEventProxy class is responsible for managing package event subscriptions and notifying subscribers + * It provides a singleton instance and allows subscribers to register for package events. + */ +class ACE_EXPORT PackageEventProxy { +public: + virtual ~PackageEventProxy() = default; + + /** + * @brief Get the singleton instance of PackageEventProxy. + * @return The singleton instance of PackageEventProxy. + */ + static PackageEventProxy* GetInstance(); + + /** + * @brief Register a package event listener. + * @param listener The package event listener to register. + */ + virtual void Register(const WeakPtr& listener) = 0; + + virtual void OnPackageChange() = 0; + +protected: + PackageEventProxy() = default; + +private: + + static std::unique_ptr instance_; /**< The singleton instance of PackageEventProxy. */ + static std::mutex mutex_; /**< Mutex for thread-safe creation of the singleton instance. */ + + ACE_DISALLOW_COPY_AND_MOVE(PackageEventProxy); +}; +} // namespace OHOS::Ace +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_PACKAGE_EVENT_PROXY_H \ No newline at end of file diff --git a/test/mock/core/package/mock_package_event_proxy.cpp b/test/mock/core/package/mock_package_event_proxy.cpp new file mode 100644 index 00000000000..486fb7dcf81 --- /dev/null +++ b/test/mock/core/package/mock_package_event_proxy.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "core/event/package/package_event_proxy.h" + +namespace OHOS::Ace { +PackageEventProxy* PackageEventProxy::GetInstance() +{ + return nullptr; +} +} // namespace OHOS::Ace diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index f0fa046443d..630b7f9bbde 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -530,6 +530,7 @@ ohos_source_set("ace_components_mock") { "$ace_root/test/mock/core/image_provider/mock_image_cache.cpp", "$ace_root/test/mock/core/image_provider/mock_image_loading_context.cpp", "$ace_root/test/mock/core/image_provider/mock_image_source_info.cpp", + "$ace_root/test/mock/core/package/mock_package_event_proxy.cpp", "$ace_root/test/mock/core/pattern/mock_app_bar_view.cpp", "$ace_root/test/mock/core/pattern/mock_container_modal_utils.cpp", "$ace_root/test/mock/core/pipeline/mock_element_register.cpp", diff --git a/test/unittest/core/pipeline/BUILD.gn b/test/unittest/core/pipeline/BUILD.gn index cf44eda1c5f..5879ecf879b 100644 --- a/test/unittest/core/pipeline/BUILD.gn +++ b/test/unittest/core/pipeline/BUILD.gn @@ -82,6 +82,7 @@ ace_unittest("pipeline_context_test_ng") { "$ace_root/test/mock/core/image_provider/mock_image_file_cache.cpp", "$ace_root/test/mock/core/image_provider/mock_image_loading_context.cpp", "$ace_root/test/mock/core/image_provider/mock_image_source_info.cpp", + "$ace_root/test/mock/core/package/mock_package_event_proxy.cpp", "$ace_root/test/mock/core/pattern/mock_app_bar_view.cpp", "$ace_root/test/mock/core/pattern/mock_container_modal_utils.cpp", "$ace_root/test/mock/core/pipeline/mock_element_register.cpp", diff --git a/test/unittest/interfaces/BUILD.gn b/test/unittest/interfaces/BUILD.gn index 387f8b86921..f3028fe4d8d 100644 --- a/test/unittest/interfaces/BUILD.gn +++ b/test/unittest/interfaces/BUILD.gn @@ -135,6 +135,7 @@ ohos_unittest("form_render_group_test") { "$ace_root/test/mock/core/common/mock_frame_report.cpp", "$ace_root/test/mock/core/common/mock_raw_recognizer.cpp", "$ace_root/test/mock/core/image_provider/mock_image_source_info.cpp", + "$ace_root/test/mock/core/package/mock_package_event_proxy.cpp", "$ace_root/test/mock/core/pipeline/mock_element_register.cpp", "$ace_root/test/mock/core/pipeline/mock_pipeline_context.cpp", "$ace_root/test/mock/core/render/mock_animation_utils.cpp", -- Gitee