diff --git a/frameworks/bridge/cj_frontend/BUILD.gn b/frameworks/bridge/cj_frontend/BUILD.gn index 4ab94a90d4bc3a2c19b2f5157b04f6f550379a69..ccff543f174b5738e3b5ba90daf3c355a0f0b918 100644 --- a/frameworks/bridge/cj_frontend/BUILD.gn +++ b/frameworks/bridge/cj_frontend/BUILD.gn @@ -229,6 +229,12 @@ template("cj_frontend") { external_deps += [ "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", + "ability_runtime:ability_context_native", + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "ability_runtime:data_ability_helper", + "ability_runtime:napi_base_context", + "ipc:ipc_core", ] external_deps += [ "graphic_2d:2d_graphics" ] diff --git a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/cj_observer.cpp b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/cj_observer.cpp index 1d4c360bc6a74088af42d0c9bf08f7413cdc17ca..7006c63e52d653913f63a2d50cb5643a0261d5a2 100644 --- a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/cj_observer.cpp +++ b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/cj_observer.cpp @@ -35,6 +35,36 @@ ObserverProcess& ObserverProcess::GetInstance() return instance; } +void ObserverProcess::ProcessNavigationRegister(int64_t callbackId) +{ + if (!isNavigationHandleFuncSetted_) { + Ace::NG::UIObserverHandler::GetInstance().SetHandleNavigationChangeFunc( + &CJObserver::HandleNavigationStateChange); + isNavigationHandleFuncSetted_ = true; + } + CJObserver::RegisterNavigationCallback(callbackId); +} + +void ObserverProcess::ProcessNavigationUnRegister(int64_t callbackId) +{ + CJObserver::UnRegisterNavigationCallback(callbackId); +} + +void ObserverProcess::ProcessNavigationRegister(const char *navigationId, int64_t callbackId) +{ + if (!isNavigationHandleFuncSetted_) { + Ace::NG::UIObserverHandler::GetInstance().SetHandleNavigationChangeFunc( + &CJObserver::HandleNavigationStateChange); + isNavigationHandleFuncSetted_ = true; + } + CJObserver::RegisterNavigationCallback(navigationId, callbackId); +} + +void ObserverProcess::ProcessNavigationUnRegister(const char *navigationId, int64_t callbackId) +{ + CJObserver::UnRegisterNavigationCallback(navigationId, callbackId); +} + void ObserverProcess::ProcessScrollEventRegister(int64_t callbackId) { if (!isScrollEventChangeFuncSetted_) { diff --git a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/cj_observer.h b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/cj_observer.h index 179918a740c271673f4f1c12c3090e8b246ba95a..e786408a2bb7c57bee5309dd634a3865fecb2029 100644 --- a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/cj_observer.h +++ b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/cj_observer.h @@ -28,6 +28,10 @@ public: ~ObserverProcess() = default; static ObserverProcess& GetInstance(); + void ProcessNavigationRegister(int64_t callbackId); + void ProcessNavigationUnRegister(int64_t callbackId); + void ProcessNavigationRegister(const char* navigationId, int64_t callbackId); + void ProcessNavigationUnRegister(const char* navigationId, int64_t callbackId); void ProcessScrollEventRegister(int64_t callbackId); void ProcessScrollEventUnRegister(int64_t callbackId); void ProcessScrollEventRegisterWithOptions(const char* options, int64_t callbackId); @@ -40,9 +44,10 @@ public: private: bool isScrollEventChangeFuncSetted_ = false; bool isTabContentUpdateFuncSetted_ = false; + bool isNavigationHandleFuncSetted_ = false; }; } // namespace Rosen } // namespace OHOS -#endif // OHOS_CJ_OBSERVER_H \ No newline at end of file +#endif // OHOS_CJ_OBSERVER_H diff --git a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer.cpp b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer.cpp index 0e4a2d5484e099b15f7d3206db6682aa1fb242cd..4a93169821746d059e920807af57ce8cc4a599f5 100644 --- a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer.cpp +++ b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer.cpp @@ -19,17 +19,113 @@ #include "base/utils/utils.h" +using namespace OHOS::FFI; + +const int BAD_CALLBACK_ID = -1; namespace OHOS { namespace Rosen { +using NavIdAndListenersMap = + std::unordered_map, std::list>>; +std::unordered_map> CJObserver::navDestinationUpdateListeners_; +std::unordered_map>> + CJObserver::specifiedUniqueIdNavigationListeners_; +std::list> CJObserver::unspecifiedNavigationListeners_; +std::unordered_map>> + CJObserver::specifiedCNavigationListeners_; std::unordered_map> CJObserver::scrollEventListeners_; std::unordered_map>> CJObserver::specifiedScrollEventListeners_; - std::unordered_map> CJObserver::tabContentUpdateListeners_; std::unordered_map>> CJObserver::specifiedTabContentUpdateListeners_; +void CJObserver::RegisterNavigationCallback(int64_t callbackId) +{ + auto listener = std::make_shared(); + listener->AddCallback(EVENT_NAV_DST_UPDATE, callbackId); + if (std::find(unspecifiedNavigationListeners_.begin(), unspecifiedNavigationListeners_.end(), listener) != + unspecifiedNavigationListeners_.end()) { + return; + } + unspecifiedNavigationListeners_.emplace_back(listener); +} + +void CJObserver::RegisterNavigationCallback(const std::string &navigationId, int64_t callbackId) +{ + auto listener = std::make_shared(); + listener->AddCallback(EVENT_NAV_DST_UPDATE, callbackId); + auto iter = specifiedCNavigationListeners_.find(navigationId); + if (iter == specifiedCNavigationListeners_.end()) { + specifiedCNavigationListeners_.emplace( + navigationId, std::list>({listener})); + return; + } + auto &holder = iter->second; + if (std::find(holder.begin(), holder.end(), listener) != holder.end()) { + return; + } + holder.emplace_back(listener); +} + +void CJObserver::UnRegisterNavigationCallback(int64_t callbackId) +{ + if (callbackId == BAD_CALLBACK_ID) { + unspecifiedNavigationListeners_.clear(); + return; + } + unspecifiedNavigationListeners_.erase( + std::remove_if(unspecifiedNavigationListeners_.begin(), + unspecifiedNavigationListeners_.end(), + [callbackId](const std::shared_ptr ®isteredListener) { + return registeredListener->RemoveCallback(EVENT_NAV_DST_UPDATE, callbackId); + }), + unspecifiedNavigationListeners_.end()); +} + +void CJObserver::UnRegisterNavigationCallback(const std::string &navigationId, int64_t callbackId) +{ + auto iter = specifiedCNavigationListeners_.find(navigationId); + if (iter == specifiedCNavigationListeners_.end()) { + return; + } + auto &holder = iter->second; + if (callbackId == BAD_CALLBACK_ID) { + holder.clear(); + return; + } + holder.erase(std::remove_if(holder.begin(), + holder.end(), + [callbackId](const std::shared_ptr ®isteredListener) { + return registeredListener->RemoveCallback(EVENT_NAV_DST_UPDATE, callbackId); + }), + holder.end()); +} + +void CJObserver::HandleNavigationStateChange(const Ace::NG::NavDestinationInfo &info) +{ + auto unspecifiedHolder = unspecifiedNavigationListeners_; + for (const auto &listener : unspecifiedHolder) { + listener->OnNavigationStateChange(info); + } + auto iter = specifiedCNavigationListeners_.find(info.navigationId); + if (iter != specifiedCNavigationListeners_.end()) { + auto holder = iter->second; + + for (const auto &listener : holder) { + listener->OnNavigationStateChange(info); + } + } + auto navigationdUniqueIdIter = specifiedUniqueIdNavigationListeners_.find(info.navigationUniqueId); + if (navigationdUniqueIdIter != specifiedUniqueIdNavigationListeners_.end()) { + auto holder = navigationdUniqueIdIter->second; + + for (const auto &listener : holder) { + listener->OnNavigationStateChange(info); + } + } +} + // Scroll event callbacks void CJObserver::RegisterScrollEventCallback(int64_t callbackId) { @@ -210,4 +306,4 @@ void CJObserver::HandleTabContentUpdateStateChange(const Ace::NG::TabContentInfo } } // namespace Rosen -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer.h b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer.h index b7508ebf2955f4b6ad174dfdb50f8e461cf79b83..2aa658ad97c9801fa2614a7eca244e3bfd006ba5 100644 --- a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer.h +++ b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer.h @@ -27,6 +27,7 @@ #include "base/memory/referenced.h" #include "core/components_ng/base/frame_node.h" #include "core/components_ng/base/observer_handler.h" +#include "ability_runtime/cj_ability_context.h" namespace OHOS { namespace Rosen { @@ -36,13 +37,17 @@ public: CJObserver() = delete; ~CJObserver() = delete; + static void RegisterNavigationCallback(int64_t callbackId); + static void UnRegisterNavigationCallback(int64_t callbackId); + static void RegisterNavigationCallback(const std::string& navigationId, int64_t callbackId); + static void UnRegisterNavigationCallback(const std::string& navigationId, int64_t callbackId); + static void HandleNavigationStateChange(const Ace::NG::NavDestinationInfo& info); static void RegisterScrollEventCallback(int64_t callbackId); static void RegisterScrollEventCallback(const std::string& id, int64_t callbackId); static void UnRegisterScrollEventCallback(int64_t callbackId); static void UnRegisterScrollEventCallback(const std::string& id, int64_t callbackId); static void HandleScrollEventStateChange( const std::string& id, int32_t uniqueId, Ace::NG::ScrollEventType eventType, float offset, Ace::Axis axis); - static void RegisterTabContentUpdateCallback(int64_t callbackId); static void RegisterTabContentUpdateCallback(const std::string& id, int64_t callbackId); static void UnRegisterTabContentUpdateCallback(int64_t callbackId); @@ -50,6 +55,8 @@ public: static void HandleTabContentUpdateStateChange(const Ace::NG::TabContentInfo& tabContentInfo); private: + static std::unordered_map>> specifiedRouterPageListeners_; + static std::unordered_map> navDestinationUpdateListeners_; static std::unordered_map> scrollEventListeners_; static std::unordered_map>> specifiedScrollEventListeners_; @@ -57,9 +64,16 @@ private: static std::unordered_map> tabContentUpdateListeners_; static std::unordered_map>> specifiedTabContentUpdateListeners_; + using NavIdAndListenersMap = + std::unordered_map, std::list>>; + static std::list> unspecifiedNavigationListeners_; + static std::unordered_map>> + specifiedCNavigationListeners_; + static std::unordered_map>> + specifiedUniqueIdNavigationListeners_; }; } // namespace Rosen } // namespace OHOS -#endif // OHOS_OBSERVER_H \ No newline at end of file +#endif // OHOS_OBSERVER_H diff --git a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_ffi.cpp b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_ffi.cpp index e927400133ff538604801002fa10f781ac787838..b086fbf1de4e5c3a71c12f5abaf630bbd89294e8 100644 --- a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_ffi.cpp +++ b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_ffi.cpp @@ -26,6 +26,30 @@ namespace OHOS { namespace Rosen { extern "C" { +void FfiOHOSObserverRegisterNavDestinationUpdateCallback(int64_t callbackId) +{ + LOGI("FfiOHOSObserverRegisterNavDestinationUpdateCallback start"); + return ObserverProcess::GetInstance().ProcessNavigationRegister(callbackId); +} + +void FfiOHOSObserverUnRegisterNavDestinationUpdateCallback(int64_t callbackId) +{ + LOGI("FfiOHOSObserverUnRegisterNavDestinationUpdateCallback start"); + return ObserverProcess::GetInstance().ProcessNavigationUnRegister(callbackId); +} + +void FfiOHOSObserverRegisterNavDestinationUpdateCallbackWithOptions(const char *navigationId, int64_t callbackId) +{ + LOGI("FfiOHOSObserverRegisterNavDestinationUpdateCallbackWithOptions start"); + return ObserverProcess::GetInstance().ProcessNavigationRegister(navigationId, callbackId); +} + +void FfiOHOSObserverUnRegisterNavDestinationUpdateCallbackWithOptions(const char *options, int64_t callbackId) +{ + LOGI("FfiOHOSObserverUnRegisterNavDestinationUpdateCallbackWithOptions start"); + return ObserverProcess::GetInstance().ProcessNavigationUnRegister(options, callbackId); +} + void FfiOHOSObserverRegisterScrollEventCallback(int64_t callbackId) { LOGI("FfiOHOSObserverRegisterScrollEventCallback start"); diff --git a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_ffi.h b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_ffi.h index fa075272f5473de4b84b2103e4cd415b8bbc4d70..bca361fe61d98b469105e95dde873b65d856978c 100644 --- a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_ffi.h +++ b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_ffi.h @@ -21,6 +21,10 @@ #include "bridge/cj_frontend/interfaces/cj_ffi/cj_macro.h" extern "C" { +CJ_EXPORT void FfiOHOSObserverRegisterNavDestinationUpdateCallback(int64_t callbackId); +CJ_EXPORT void FfiOHOSObserverUnRegisterNavDestinationUpdateCallback(int64_t callbackId); +CJ_EXPORT void FfiOHOSObserverRegisterNavDestinationUpdateCallbackWithOptions(const char* options, int64_t callbackId); +CJ_EXPORT void FfiOHOSObserverUnRegisterNavDestinationUpdateCallbackWithOptions(const char* options, int64_t callbackId); CJ_EXPORT void FfiOHOSObserverRegisterScrollEventCallback(int64_t callbackId); CJ_EXPORT void FfiOHOSObserverUnRegisterScrollEventCallback(int64_t callbackId); CJ_EXPORT void FfiOHOSObserverRegisterScrollEventCallbackWithOptions(const char* options, int64_t callbackId); diff --git a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_listener.cpp b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_listener.cpp index 6fd93cd1e48d9ae49d9a4a0004f4c25a24606c9a..f473bc9e4f22bca350b6acc3915b54c480dd3989 100644 --- a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_listener.cpp +++ b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_listener.cpp @@ -50,18 +50,20 @@ void CJObserverListener::RemoveAllCallback(const std::string& type) cjCallBack_.erase(it); } -void CJObserverListener::RemoveCallback(const std::string& type, int64_t callbackObject) +bool CJObserverListener::RemoveCallback(const std::string& type, int64_t callbackObject) { + bool result = false; std::lock_guard lock(mtx_); LOGI("CJObserverListener::RemoveCallback is called with type %{public}s", type.c_str()); auto it = cjCallBack_.find(type); if (it == cjCallBack_.end()) { LOGE("CJObserverListener::RemoveCallback no callback to remove"); - return; + return result; } auto& callbacks = it->second; for (auto iter = callbacks.begin(); iter != callbacks.end();) { if (iter->first == callbackObject) { + result = true; iter = callbacks.erase(iter); } else { iter++; @@ -69,6 +71,7 @@ void CJObserverListener::RemoveCallback(const std::string& type, int64_t callbac } LOGI("CJObserverListener::RemoveCallback success, cjCallBack_ size %{public}u!", static_cast(callbacks.size())); + return result; } void CJObserverListener::CallCJMethod(const std::string& methodName, void* argv) @@ -108,6 +111,37 @@ void CJObserverListener::OnScrollEventStateChange( CallCJMethod(EVENT_SCROLL, &info); } +void CJObserverListener::OnNavigationStateChange(const Ace::NG::NavDestinationInfo& navDestinationInfo) +{ + std::lock_guard lock(mtx_); + LOGI("CJObserverListener::OnNavigationStateChange is called"); + if (cjCallBack_.empty()) { + LOGI("CJObserverListener::OnNavigationStateChange not register!"); + return; + } + if (cjCallBack_.find(EVENT_NAV_DST_UPDATE) == cjCallBack_.end()) { + LOGE("CJObserverListener::OnNavigationStateChange not this event!"); + return; + } + struct NavDestinationInfo { + char* navigationId; + char* name; + uint32_t state; + uint32_t index; + char* param; + char* navDestinationId; + int32_t mode; + int32_t uniqueId; + } info = { const_cast(navDestinationInfo.navigationId.c_str()), + const_cast(navDestinationInfo.name.c_str()), + static_cast(navDestinationInfo.state), navDestinationInfo.index, nullptr, + const_cast(navDestinationInfo.navDestinationId.c_str()), + static_cast(navDestinationInfo.mode), + navDestinationInfo.uniqueId + }; + CallCJMethod(EVENT_NAV_DST_UPDATE, &info); +} + void CJObserverListener::OnTabContentUpdateStateChange(const Ace::NG::TabContentInfo& tabContentInfo) { std::lock_guard lock(mtx_); diff --git a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_listener.h b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_listener.h index 3bdf0fb649d99ed24add961fbdf8ec536f22f426..c474db506d2a2dd02f82dc7e2f5878d426363931 100644 --- a/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_listener.h +++ b/frameworks/bridge/cj_frontend/interfaces/cj_ffi/observer/observer_listener.h @@ -23,6 +23,7 @@ namespace OHOS { namespace Rosen { +const std::string EVENT_NAV_DST_UPDATE = "navDestinationUpdate"; const std::string EVENT_SCROLL = "scrollEvent"; const std::string EVENT_TAB_CONTENT_UPDATE = "tabContentUpdate"; @@ -32,11 +33,12 @@ public: ~CJObserverListener(); void AddCallback(const std::string& type, int64_t callbackObject); void RemoveAllCallback(const std::string& type); - void RemoveCallback(const std::string& type, int64_t callbackObject); + bool RemoveCallback(const std::string& type, int64_t callbackObject); void OnScrollEventStateChange( const std::string& id, int32_t uniqueId, Ace::NG::ScrollEventType eventType, float offset, Ace::Axis axis); void OnTabContentUpdateStateChange(const Ace::NG::TabContentInfo& tabContentInfo); + void OnNavigationStateChange(const Ace::NG::NavDestinationInfo& info); private: void CallCJMethod(const std::string& methodName, void* argv);