From 9344de51f1a5a635adc62ad35171c9e6798af8c4 Mon Sep 17 00:00:00 2001 From: l00574490 Date: Fri, 12 May 2023 16:04:59 +0800 Subject: [PATCH] add system session Signed-off-by: l00574490 Change-Id: Ida9e67bc803a15e7b4122569dbe350e1c2d7e86a --- .../window_napi/js_window_register_manager.h | 4 +- window_scene/interfaces/include/ws_common.h | 8 +- .../js_scene_session.cpp | 95 ++++++++++----- .../scene_session_manager/js_scene_session.h | 12 +- .../js_scene_session_manager.cpp | 115 +++++++++++++++++- .../js_scene_session_manager.h | 18 ++- .../scene_session_manager/js_scene_utils.cpp | 45 +++++++ .../scene_session_manager/js_scene_utils.h | 2 + window_scene/session/host/include/session.h | 12 +- .../host/include/zidl/session_interface.h | 2 + .../session/host/include/zidl/session_proxy.h | 1 + .../session/host/include/zidl/session_stub.h | 1 + window_scene/session/host/src/session.cpp | 43 +++++++ .../session/host/src/zidl/session_proxy.cpp | 22 ++++ .../session/host/src/zidl/session_stub.cpp | 11 ++ window_scene/session_manager/BUILD.gn | 8 +- .../include/scene_session_manager.h | 11 +- .../session_manager/include/session_manager.h | 20 ++- .../zidl/scene_session_manager_interface.h | 43 +++++++ .../zidl/scene_session_manager_proxy.h | 40 ++++++ .../include/zidl/scene_session_manager_stub.h | 35 ++++++ .../src/scene_session_manager.cpp | 54 ++++++++ .../session_manager/src/session_manager.cpp | 98 ++++++++++++++- .../src/zidl/scene_session_manager_proxy.cpp | 102 ++++++++++++++++ .../src/zidl/scene_session_manager_stub.cpp | 79 ++++++++++++ window_scene/session_manager_service/BUILD.gn | 4 + .../include/session_manager_service.h | 2 + .../session_manager_service_interface.h | 3 + .../include/session_manager_service_proxy.h | 7 +- .../include/session_manager_service_stub.h | 2 + .../src/session_manager_service.cpp | 10 +- .../src/session_manager_service_proxy.cpp | 33 ++++- .../src/session_manager_service_stub.cpp | 6 +- wm/BUILD.gn | 3 + wm/include/window_session_impl.h | 6 + wm/src/window.cpp | 2 + wm/src/window_session_impl.cpp | 95 ++++++++++++++- 37 files changed, 993 insertions(+), 61 deletions(-) create mode 100644 window_scene/session_manager/include/zidl/scene_session_manager_interface.h create mode 100644 window_scene/session_manager/include/zidl/scene_session_manager_proxy.h create mode 100644 window_scene/session_manager/include/zidl/scene_session_manager_stub.h create mode 100644 window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp create mode 100644 window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window_register_manager.h b/interfaces/kits/napi/window_runtime/window_napi/js_window_register_manager.h index 77a5f95a6b..4840147b8b 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window_register_manager.h +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window_register_manager.h @@ -54,10 +54,10 @@ private: bool isRegister); WmErrorCode ProcessGestureNavigationEnabledChangeRegister(sptr listener, sptr window, bool isRegister); - using Func_t = WmErrorCode(JsWindowRegisterManager::*)(sptr, sptr window, bool); + using Func = WmErrorCode(JsWindowRegisterManager::*)(sptr, sptr window, bool); std::map, sptr>> jsCbMap_; std::mutex mtx_; - std::map> listenerProcess_; + std::map> listenerProcess_; }; } // namespace Rosen } // namespace OHOS diff --git a/window_scene/interfaces/include/ws_common.h b/window_scene/interfaces/include/ws_common.h index 79570d6624..7aa1459d9e 100644 --- a/window_scene/interfaces/include/ws_common.h +++ b/window_scene/interfaces/include/ws_common.h @@ -92,10 +92,10 @@ enum class SizeChangeReason : uint32_t { }; struct WSRect { - int32_t posX_; - int32_t posY_; - uint32_t width_; - uint32_t height_; + int32_t posX_ = 0; + int32_t posY_ = 0; + uint32_t width_ = 0; + uint32_t height_ = 0; bool operator==(const WSRect& a) const { diff --git a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session.cpp b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session.cpp index cbe2675c47..1e887a81b5 100644 --- a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session.cpp +++ b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session.cpp @@ -26,6 +26,7 @@ using namespace AbilityRuntime; namespace { constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "JsSceneSession" }; const std::string PENDING_SCENE_CB = "pendingSceneSessionActivation"; +const std::string SESSION_STATE_CHANGE_CB = "sessionStateChange"; } // namespace NativeValue* JsSceneSession::Create(NativeEngine& engine, const sptr& session) @@ -33,8 +34,8 @@ NativeValue* JsSceneSession::Create(NativeEngine& engine, const sptr(objValue); - if (object == nullptr) { - WLOGFE("[NAPI]Object is null!"); + if (object == nullptr || session == nullptr) { + WLOGFE("[NAPI]Object or session is null!"); return engine.CreateUndefined(); } @@ -48,6 +49,31 @@ NativeValue* JsSceneSession::Create(NativeEngine& engine, const sptr& session) + : engine_(engine), session_(session) +{ + listenerFunc_ = { + { PENDING_SCENE_CB, &JsSceneSession::ProcessPendingSceneSessionActivationRegister }, + { SESSION_STATE_CHANGE_CB, &JsSceneSession::ProcessSessionStateChangeRegister }, + }; +} + +void JsSceneSession::ProcessPendingSceneSessionActivationRegister() +{ + NotifyPendingSessionActivationFunc func = [this](const SessionInfo& info) { + this->PendingSessionActivation(info); + }; + session_->SetPendingSessionActivationEventListener(func); +} + +void JsSceneSession::ProcessSessionStateChangeRegister() +{ + NotifySessionStateChangeFunc func = [this](const SessionState& state) { + this->OnSessionStateChange(state); + }; + session_->SetSessionStateChangeListenser(func); +} + void JsSceneSession::Finalizer(NativeEngine* engine, void* data, void* hint) { WLOGI("[NAPI]Finalizer"); @@ -61,6 +87,21 @@ NativeValue* JsSceneSession::RegisterCallback(NativeEngine* engine, NativeCallba return (me != nullptr) ? me->OnRegisterCallback(*engine, *info) : nullptr; } +bool JsSceneSession::IsCallbackRegistered(const std::string& type, NativeValue* jsListenerObject) +{ + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + return false; + } + + for (auto iter = jsCbMap_.begin(); iter != jsCbMap_.end(); ++iter) { + if (jsListenerObject->StrictEquals(iter->second->Get())) { + WLOGFE("[NAPI]Method %{public}s has already been registered", type.c_str()); + return true; + } + } + return false; +} + NativeValue* JsSceneSession::OnRegisterCallback(NativeEngine& engine, NativeCallbackInfo& info) { if (info.argc < 2) { // 2: params num @@ -93,23 +134,35 @@ NativeValue* JsSceneSession::OnRegisterCallback(NativeEngine& engine, NativeCall return engine.CreateUndefined(); } - auto sessionWptr = weak_from_this(); - NotifyPendingSessionActivationFunc func = [sessionWptr](const SessionInfo& info) { - auto jsSceneSession = sessionWptr.lock(); - if (jsSceneSession == nullptr) { - WLOGFE("[NAPI]this scene session is null"); - return; - } - jsSceneSession->PendingSessionActivation(info); - }; - session_->SetPendingSessionActivationEventListener(func); + (this->*listenerFunc_[cbType])(); std::shared_ptr callbackRef; callbackRef.reset(engine.CreateReference(value, 1)); jsCbMap_[cbType] = callbackRef; - WLOGFI("[NAPI]Register end, type = %{public}s, callback = %{public}p", cbType.c_str(), value); + WLOGFI("[NAPI]Register end, type = %{public}s", cbType.c_str()); return engine.CreateUndefined(); } +void JsSceneSession::OnSessionStateChange(const SessionState& state) +{ + WLOGFI("[NAPI]OnSessionStateChange, state: %{public}u", static_cast(state)); + auto iter = jsCbMap_.find(SESSION_STATE_CHANGE_CB); + if (iter == jsCbMap_.end()) { + return; + } + auto jsCallBack = iter->second; + auto complete = std::make_unique( + [state, jsCallBack, eng = &engine_](NativeEngine& engine, AsyncTask& task, int32_t status) { + NativeValue* jsSessionStateObj = CreateJsValue(engine, state); + NativeValue* argv[] = { jsSessionStateObj }; + engine.CallFunction(engine.CreateUndefined(), jsCallBack->Get(), argv, ArraySize(argv)); + }); + + NativeReference* callback = nullptr; + std::unique_ptr execute = nullptr; + AsyncTask::Schedule("JsSceneSession::OnSessionStateChange", engine_, + std::make_unique(callback, std::move(execute), std::move(complete))); +} + void JsSceneSession::PendingSessionActivation(const SessionInfo& info) { WLOGFI("[NAPI]pending session activation: bundleName = %{public}s, id = %{public}s", info.bundleName_.c_str(), @@ -141,22 +194,6 @@ void JsSceneSession::PendingSessionActivation(const SessionInfo& info) std::make_unique(callback, std::move(execute), std::move(complete))); } -bool JsSceneSession::IsCallbackRegistered(const std::string& type, NativeValue* jsListenerObject) -{ - if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { - WLOGFI("[NAPI]Method %{public}s has not been registered", type.c_str()); - return false; - } - - for (auto iter = jsCbMap_.begin(); iter != jsCbMap_.end(); ++iter) { - if (jsListenerObject->StrictEquals(iter->second->Get())) { - WLOGFE("[NAPI]Method %{public}s has already been registered", type.c_str()); - return true; - } - } - return false; -} - sptr JsSceneSession::GetNativeSession() const { return session_; diff --git a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session.h b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session.h index 7861e0fb02..73e27f2b7a 100644 --- a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session.h +++ b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session.h @@ -29,13 +29,12 @@ namespace OHOS::Rosen { class SceneSession; class JsSceneSession : public std::enable_shared_from_this { public: - JsSceneSession(NativeEngine& engine, const sptr& session) : engine_(engine), session_(session) {} + JsSceneSession(NativeEngine& engine, const sptr& session); ~JsSceneSession() = default; static NativeValue* Create(NativeEngine& engine, const sptr& session); static void Finalizer(NativeEngine* engine, void* data, void* hint); - void PendingSessionActivation(const SessionInfo& info); sptr GetNativeSession() const; private: @@ -43,10 +42,17 @@ private: NativeValue* OnRegisterCallback(NativeEngine& engine, NativeCallbackInfo& info); bool IsCallbackRegistered(const std::string& type, NativeValue* jsListenerObject); + void ProcessPendingSceneSessionActivationRegister(); + void ProcessSessionStateChangeRegister(); + + void PendingSessionActivation(const SessionInfo& info); + void OnSessionStateChange(const SessionState& state); + NativeEngine& engine_; sptr session_; std::map> jsCbMap_; - std::shared_ptr jsCallBack_ = nullptr; + using Func = void(JsSceneSession::*)(); + std::map listenerFunc_; }; } // namespace OHOS::Rosen diff --git a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp index 61f02062e6..a78887c45a 100644 --- a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp +++ b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp @@ -28,6 +28,7 @@ namespace OHOS::Rosen { using namespace AbilityRuntime; namespace { constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "JsSceneSessionManager" }; +const std::string CREATE_SPECIFIC_SCENE_CB = "createSpecificSession"; } // namespace NativeValue* JsSceneSessionManager::Init(NativeEngine* engine, NativeValue* exportObj) @@ -44,8 +45,9 @@ NativeValue* JsSceneSessionManager::Init(NativeEngine* engine, NativeValue* expo return nullptr; } - std::unique_ptr jsSceneSessionManager = std::make_unique(); + std::unique_ptr jsSceneSessionManager = std::make_unique(*engine); object->SetNativePointer(jsSceneSessionManager.release(), JsSceneSessionManager::Finalizer, nullptr); + object->SetProperty("SessionState", SessionStateInit(engine)); const char* moduleName = "JsSceneSessionManager"; BindNativeFunction(*engine, *object, "getRootSceneSession", moduleName, JsSceneSessionManager::GetRootSceneSession); @@ -56,9 +58,71 @@ NativeValue* JsSceneSessionManager::Init(NativeEngine* engine, NativeValue* expo JsSceneSessionManager::RequestSceneSessionBackground); BindNativeFunction(*engine, *object, "requestSceneSessionDestruction", moduleName, JsSceneSessionManager::RequestSceneSessionDestruction); + BindNativeFunction(*engine, *object, "on", moduleName, JsSceneSessionManager::RegisterCallback); return engine->CreateUndefined(); } +JsSceneSessionManager::JsSceneSessionManager(NativeEngine& engine) : engine_(engine) +{ + listenerFunc_ = { + { CREATE_SPECIFIC_SCENE_CB, &JsSceneSessionManager::ProcessCreateSpecificSessionRegister }, + }; +} + +void JsSceneSessionManager::OnCreateSpecificSession(const sptr& sceneSession) +{ + if (sceneSession == nullptr) { + WLOGFI("[NAPI]sceneSession is nullptr"); + return; + } + + WLOGFI("[NAPI]OnCreateSpecificSession"); + auto iter = jsCbMap_.find(CREATE_SPECIFIC_SCENE_CB); + if (iter == jsCbMap_.end()) { + return; + } + + auto jsCallBack = iter->second; + wptr weakSession(sceneSession); + auto complete = std::make_unique( + [this, weakSession, jsCallBack, eng = &engine_](NativeEngine& engine, AsyncTask& task, int32_t status) { + auto specificSession = weakSession.promote(); + if (specificSession == nullptr) { + WLOGFE("[NAPI]specific session is nullptr"); + return; + } + NativeValue* jsSceneSessionObj = JsSceneSession::Create(*eng, specificSession); + if (jsSceneSessionObj == nullptr) { + WLOGFE("[NAPI]jsSceneSessionObj is nullptr"); + engine.Throw(CreateJsError( + engine, static_cast(WSErrorCode::WS_ERROR_STATE_ABNORMALLY), "System is abnormal")); + } + NativeValue* argv[] = { jsSceneSessionObj }; + engine.CallFunction(engine.CreateUndefined(), jsCallBack->Get(), argv, ArraySize(argv)); + }); + + NativeReference* callback = nullptr; + std::unique_ptr execute = nullptr; + AsyncTask::Schedule("JsSceneSessionManager::OnCreateSpecificSession", engine_, + std::make_unique(callback, std::move(execute), std::move(complete))); +} + +void JsSceneSessionManager::ProcessCreateSpecificSessionRegister() +{ + NotifyCreateSpecificSessionFunc func = [this](const sptr& session) { + WLOGFD("NotifyCreateSpecificSessionFunc"); + this->OnCreateSpecificSession(session); + }; + SceneSessionManager::GetInstance().SetCreateSpecificSessionListener(func); +} + +NativeValue* JsSceneSessionManager::RegisterCallback(NativeEngine* engine, NativeCallbackInfo* info) +{ + WLOGFI("[NAPI]RegisterCallback"); + JsSceneSessionManager* me = CheckParamsAndGetThis(engine, info); + return (me != nullptr) ? me->OnRegisterCallback(*engine, *info) : nullptr; +} + void JsSceneSessionManager::Finalizer(NativeEngine* engine, void* data, void* hint) { WLOGI("[NAPI]Finalizer"); @@ -100,6 +164,55 @@ NativeValue* JsSceneSessionManager::RequestSceneSessionDestruction(NativeEngine* return (me != nullptr) ? me->OnRequestSceneSessionDestruction(*engine, *info) : nullptr; } +bool JsSceneSessionManager::IsCallbackRegistered(const std::string& type, NativeValue* jsListenerObject) +{ + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + return false; + } + + for (auto iter = jsCbMap_.begin(); iter != jsCbMap_.end(); ++iter) { + if (jsListenerObject->StrictEquals(iter->second->Get())) { + WLOGFE("[NAPI]Method %{public}s has already been registered", type.c_str()); + return true; + } + } + return false; +} + +NativeValue* JsSceneSessionManager::OnRegisterCallback(NativeEngine& engine, NativeCallbackInfo& info) +{ + if (info.argc < 2) { // 2: params num + WLOGFE("[NAPI]Argc is invalid: %{public}zu", info.argc); + engine.Throw(CreateJsError(engine, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM), + "Input parameter is missing or invalid")); + return engine.CreateUndefined(); + } + std::string cbType; + if (!ConvertFromJsValue(engine, info.argv[0], cbType)) { + WLOGFE("[NAPI]Failed to convert parameter to callbackType"); + engine.Throw(CreateJsError(engine, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM), + "Input parameter is missing or invalid")); + return engine.CreateUndefined(); + } + NativeValue* value = info.argv[1]; + if (value == nullptr || !value->IsCallable()) { + WLOGFE("[NAPI]Callback is nullptr or not callable"); + engine.Throw(CreateJsError(engine, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM), + "Input parameter is missing or invalid")); + return engine.CreateUndefined(); + } + if (IsCallbackRegistered(cbType, value)) { + return engine.CreateUndefined(); + } + + (this->*listenerFunc_[cbType])(); + std::shared_ptr callbackRef; + callbackRef.reset(engine.CreateReference(value, 1)); + jsCbMap_[cbType] = callbackRef; + WLOGFI("[NAPI]Register end, type = %{public}s", cbType.c_str()); + return engine.CreateUndefined(); +} + NativeValue* JsSceneSessionManager::OnGetRootSceneSession(NativeEngine& engine, NativeCallbackInfo& info) { WLOGFI("[NAPI]OnGetRootSceneSession"); diff --git a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h index a3c9e67802..e7e8307d4c 100644 --- a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h +++ b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h @@ -16,13 +16,18 @@ #ifndef OHOS_WINDOW_SCENE_JS_SCENE_SESSION_MANAGER_H #define OHOS_WINDOW_SCENE_JS_SCENE_SESSION_MANAGER_H +#include + #include #include +#include "interfaces/include/ws_common.h" +#include "session/host/include/scene_session.h" + namespace OHOS::Rosen { class JsSceneSessionManager final { public: - JsSceneSessionManager() = default; + explicit JsSceneSessionManager(NativeEngine& engine); ~JsSceneSessionManager() = default; static NativeValue* Init(NativeEngine* engine, NativeValue* exportObj); @@ -33,13 +38,24 @@ public: static NativeValue* RequestSceneSessionActivation(NativeEngine* engine, NativeCallbackInfo* info); static NativeValue* RequestSceneSessionBackground(NativeEngine* engine, NativeCallbackInfo* info); static NativeValue* RequestSceneSessionDestruction(NativeEngine* engine, NativeCallbackInfo* info); + static NativeValue* RegisterCallback(NativeEngine* engine, NativeCallbackInfo* info); private: + NativeValue* OnRegisterCallback(NativeEngine& engine, NativeCallbackInfo& info); NativeValue* OnGetRootSceneSession(NativeEngine& engine, NativeCallbackInfo& info); NativeValue* OnRequestSceneSession(NativeEngine& engine, NativeCallbackInfo& info); NativeValue* OnRequestSceneSessionActivation(NativeEngine& engine, NativeCallbackInfo& info); NativeValue* OnRequestSceneSessionBackground(NativeEngine& engine, NativeCallbackInfo& info); NativeValue* OnRequestSceneSessionDestruction(NativeEngine& engine, NativeCallbackInfo& info); + + void OnCreateSpecificSession(const sptr& sceneSession); + void ProcessCreateSpecificSessionRegister(); + bool IsCallbackRegistered(const std::string& type, NativeValue* jsListenerObject); + + NativeEngine& engine_; + std::map> jsCbMap_; + using Func = void(JsSceneSessionManager::*)(); + std::map listenerFunc_; }; } // namespace OHOS::Rosen diff --git a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_utils.cpp b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_utils.cpp index e317baeca4..03cf9950a8 100644 --- a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_utils.cpp +++ b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_utils.cpp @@ -61,4 +61,49 @@ NativeValue* CreateJsSessionInfo(NativeEngine& engine, const SessionInfo& sessio object->SetProperty("abilityName", CreateJsValue(engine, sessionInfo.abilityName_)); return objValue; } + +NativeValue* CreateJsSessionState(NativeEngine& engine, const SessionState& state) +{ + WLOGFI("[NAPI]CreateJsSessionState"); + NativeValue* objValue = engine.CreateObject(); + NativeObject* object = ConvertNativeValueTo(objValue); + if (object == nullptr) { + WLOGFE("[NAPI]Failed to convert sessionInfo to jsObject"); + return nullptr; + } + object->SetProperty("sessionState", CreateJsValue(engine, state)); + return objValue; +} + +NativeValue* SessionStateInit(NativeEngine* engine) +{ + if (engine == nullptr) { + WLOGFE("Engine is nullptr"); + return nullptr; + } + + NativeValue *objValue = engine->CreateObject(); + NativeObject *object = ConvertNativeValueTo(objValue); + if (object == nullptr) { + WLOGFE("Failed to get object"); + return nullptr; + } + + object->SetProperty("STATE_DISCONNECT", CreateJsValue(*engine, + static_cast(SessionState::STATE_DISCONNECT))); + object->SetProperty("STATE_CONNECT", CreateJsValue(*engine, + static_cast(SessionState::STATE_CONNECT))); + object->SetProperty("STATE_FOREGROUND", CreateJsValue(*engine, + static_cast(SessionState::STATE_FOREGROUND))); + object->SetProperty("STATE_ACTIVE", CreateJsValue(*engine, + static_cast(SessionState::STATE_ACTIVE))); + object->SetProperty("STATE_INACTIVE", CreateJsValue(*engine, + static_cast(SessionState::STATE_INACTIVE))); + object->SetProperty("STATE_BACKGROUND", CreateJsValue(*engine, + static_cast(SessionState::STATE_BACKGROUND))); + object->SetProperty("STATE_END", CreateJsValue(*engine, + static_cast(SessionState::STATE_END))); + + return objValue; +} } // namespace OHOS::Rosen diff --git a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_utils.h b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_utils.h index 73af9d05fe..81be26046d 100644 --- a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_utils.h +++ b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_utils.h @@ -25,6 +25,8 @@ namespace OHOS::Rosen { bool GetAbilityInfoFromJs(NativeEngine& engine, NativeObject* jsObject, SessionInfo& sessionInfo); NativeValue* CreateJsSessionInfo(NativeEngine& engine, const SessionInfo& sessionInfo); +NativeValue* CreateJsSessionState(NativeEngine& engine, const SessionState& state); +NativeValue* SessionStateInit(NativeEngine* engine); } // namespace OHOS::Rosen #endif // OHOS_WINDOW_SCENE_JS_SCENE_UTILS_H diff --git a/window_scene/session/host/include/session.h b/window_scene/session/host/include/session.h index 7662f3e48d..5159af1513 100644 --- a/window_scene/session/host/include/session.h +++ b/window_scene/session/host/include/session.h @@ -38,6 +38,7 @@ class PixelMap; namespace OHOS::Rosen { class RSSurfaceNode; using NotifyPendingSessionActivationFunc = std::function; +using NotifySessionStateChangeFunc = std::function; class ILifecycleListener { public: @@ -53,10 +54,13 @@ public: void SetPersistentId(uint64_t persistentId); uint64_t GetPersistentId() const; + void SetSessionRect(const WSRect& rect); + WSRect GetSessionRect() const; std::shared_ptr GetSurfaceNode() const; std::shared_ptr GetSnapshot() const; SessionState GetSessionState() const; + const SessionInfo& GetSessionInfo() const; virtual WSError SetActive(bool active); virtual WSError UpdateRect(const WSRect& rect, SizeChangeReason reason); @@ -67,7 +71,6 @@ public: WSError Foreground() override; WSError Background() override; WSError Disconnect() override; - WSError PendingSessionActivation(const SessionInfo& info) override; WSError Recover() override; WSError Maximize() override; @@ -81,9 +84,11 @@ public: bool RegisterLifecycleListener(const std::shared_ptr& listener); bool UnregisterLifecycleListener(const std::shared_ptr& listener); - - const SessionInfo& GetSessionInfo() const; void SetPendingSessionActivationEventListener(const NotifyPendingSessionActivationFunc& func); + WSError PendingSessionActivation(const SessionInfo& info) override; + void SetSessionStateChangeListenser(const NotifySessionStateChangeFunc& func); + void NotifySessionStateChange(const SessionState& state); + WSError UpdateActiveStatus(bool isActive) override; // update active status from session_stage protected: void UpdateSessionState(SessionState state); @@ -93,6 +98,7 @@ protected: sptr sessionStage_; SessionInfo sessionInfo_; NotifyPendingSessionActivationFunc pendingSessionActivationFunc_; + NotifySessionStateChangeFunc sessionStateChangeFunc_; sptr property_ = nullptr; private: template diff --git a/window_scene/session/host/include/zidl/session_interface.h b/window_scene/session/host/include/zidl/session_interface.h index b4f77a4aef..1e30c8dc9f 100644 --- a/window_scene/session/host/include/zidl/session_interface.h +++ b/window_scene/session/host/include/zidl/session_interface.h @@ -35,6 +35,7 @@ public: TRANS_ID_BACKGROUND, TRANS_ID_DISCONNECT, TRANS_ID_ACTIVE_PENDING_SESSION, + TRANS_ID_UPDATE_ACTIVE_STATUS, // Scene TRANS_ID_RECOVER = 100, @@ -47,6 +48,7 @@ public: virtual WSError Background() = 0; virtual WSError Disconnect() = 0; virtual WSError PendingSessionActivation(const SessionInfo& info) = 0; + virtual WSError UpdateActiveStatus(bool isActive) = 0; // scene session virtual WSError Recover() = 0; diff --git a/window_scene/session/host/include/zidl/session_proxy.h b/window_scene/session/host/include/zidl/session_proxy.h index 8714c786c1..cc707674f8 100644 --- a/window_scene/session/host/include/zidl/session_proxy.h +++ b/window_scene/session/host/include/zidl/session_proxy.h @@ -33,6 +33,7 @@ public: const std::shared_ptr& surfaceNode, uint64_t& persistentId, sptr property = nullptr) override; + WSError UpdateActiveStatus(bool isActive) override; WSError PendingSessionActivation(const SessionInfo& info) override; WSError Recover() override; WSError Maximize() override; diff --git a/window_scene/session/host/include/zidl/session_stub.h b/window_scene/session/host/include/zidl/session_stub.h index f1f815dc37..6d75de660a 100644 --- a/window_scene/session/host/include/zidl/session_stub.h +++ b/window_scene/session/host/include/zidl/session_stub.h @@ -40,6 +40,7 @@ private: int HandleDisconnect(MessageParcel& data, MessageParcel& reply); int HandleConnect(MessageParcel& data, MessageParcel& reply); int HandlePendingSessionActivation(MessageParcel& data, MessageParcel& reply); + int HandleUpdateActivateStatus(MessageParcel& data, MessageParcel& reply); // for scene int HandleRecover(MessageParcel& data, MessageParcel& reply); int HandleMaximize(MessageParcel& data, MessageParcel& reply); diff --git a/window_scene/session/host/src/session.cpp b/window_scene/session/host/src/session.cpp index e21aa85f21..4cdf8a1250 100644 --- a/window_scene/session/host/src/session.cpp +++ b/window_scene/session/host/src/session.cpp @@ -127,6 +127,7 @@ SessionState Session::GetSessionState() const void Session::UpdateSessionState(SessionState state) { state_ = state; + NotifySessionStateChange(state); } bool Session::IsSessionValid() const @@ -307,4 +308,46 @@ std::shared_ptr Session::Snapshot() } return pixelMap; } + +void Session::SetSessionStateChangeListenser(const NotifySessionStateChangeFunc& func) +{ + sessionStateChangeFunc_ = func; +} + +void Session::NotifySessionStateChange(const SessionState& state) +{ + WLOGFI("state: %{public}u", static_cast(state)); + if (sessionStateChangeFunc_) { + sessionStateChangeFunc_(state); + } +} + +void Session::SetSessionRect(const WSRect& rect) +{ + winRect_ = rect; +} +WSRect Session::GetSessionRect() const +{ + return winRect_; +} + +WSError Session::UpdateActiveStatus(bool isActive) +{ + if (!IsSessionValid()) { + return WSError::WS_ERROR_INVALID_SESSION; + } + if (isActive == isActive_) { + WLOGFD("Session active do not change: [%{public}d]", isActive); + return WSError::WS_DO_NOTHING; + } + isActive_ = isActive; + if (isActive && GetSessionState() == SessionState::STATE_FOREGROUND) { + UpdateSessionState(SessionState::STATE_ACTIVE); + } + if (!isActive && GetSessionState() == SessionState::STATE_ACTIVE) { + UpdateSessionState(SessionState::STATE_INACTIVE); + } + WLOGFD("UpdateActiveStatus, status: %{public}d", isActive); + return WSError::WS_OK; +} } // namespace OHOS::Rosen diff --git a/window_scene/session/host/src/zidl/session_proxy.cpp b/window_scene/session/host/src/zidl/session_proxy.cpp index e11e96e34e..1e0a771362 100644 --- a/window_scene/session/host/src/zidl/session_proxy.cpp +++ b/window_scene/session/host/src/zidl/session_proxy.cpp @@ -179,6 +179,28 @@ WSError SessionProxy::Recover() return static_cast(ret); } +WSError SessionProxy::UpdateActiveStatus(bool isActive) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + if (!(data.WriteBool(isActive))) { + WLOGFE("Write active status failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + if (Remote()->SendRequest(static_cast(SessionMessage::TRANS_ID_UPDATE_ACTIVE_STATUS), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + int32_t ret = reply.ReadUint32(); + return static_cast(ret); +} + WSError SessionProxy::Maximize() { MessageParcel data; diff --git a/window_scene/session/host/src/zidl/session_stub.cpp b/window_scene/session/host/src/zidl/session_stub.cpp index f85d5e0964..da51448306 100644 --- a/window_scene/session/host/src/zidl/session_stub.cpp +++ b/window_scene/session/host/src/zidl/session_stub.cpp @@ -31,6 +31,8 @@ const std::map SessionStub::stubFuncMap_{ std::make_pair(static_cast(SessionMessage::TRANS_ID_CONNECT), &SessionStub::HandleConnect), std::make_pair(static_cast(SessionMessage::TRANS_ID_ACTIVE_PENDING_SESSION), &SessionStub::HandlePendingSessionActivation), + std::make_pair(static_cast(SessionMessage::TRANS_ID_UPDATE_ACTIVE_STATUS), + &SessionStub::HandleUpdateActivateStatus), // for scene only std::make_pair(static_cast(SessionMessage::TRANS_ID_RECOVER), &SessionStub::HandleRecover), @@ -133,4 +135,13 @@ int SessionStub::HandlePendingSessionActivation(MessageParcel& data, MessageParc reply.WriteUint32(static_cast(errCode)); return ERR_NONE; } + +int SessionStub::HandleUpdateActivateStatus(MessageParcel& data, MessageParcel& reply) +{ + WLOGFD("HandleUpdateActivateStatus!"); + bool isActive = data.ReadBool(); + WSError errCode = UpdateActiveStatus(isActive); + reply.WriteUint32(static_cast(errCode)); + return ERR_NONE; +} } // namespace OHOS::Rosen diff --git a/window_scene/session_manager/BUILD.gn b/window_scene/session_manager/BUILD.gn index a4a24df74c..4f6fb4a843 100644 --- a/window_scene/session_manager/BUILD.gn +++ b/window_scene/session_manager/BUILD.gn @@ -18,6 +18,7 @@ config("session_manager_public_config") { include_dirs = [ "${window_base_path}/window_scene", "${window_base_path}/window_scene/session_manager/include", + "${window_base_path}/window_scene/session_manager/include/zidl", "${window_base_path}/window_scene/session_manager_service/include", # for window_manager_hilog @@ -29,6 +30,8 @@ ohos_shared_library("scene_session_manager") { sources = [ "src/extension_session_manager.cpp", "src/scene_session_manager.cpp", + "src/zidl/scene_session_manager_proxy.cpp", + "src/zidl/scene_session_manager_stub.cpp", ] public_configs = [ ":session_manager_public_config" ] @@ -46,6 +49,7 @@ ohos_shared_library("scene_session_manager") { "c_utils:utils", "eventhandler:libeventhandler", "hilog_native:libhilog", + "ipc:ipc_single", ] innerapi_tags = [ "platformsdk" ] part_name = "window_manager" @@ -77,6 +81,7 @@ ohos_shared_library("session_manager") { sources = [ "../session_manager_service/src/session_manager_service_proxy.cpp", "src/session_manager.cpp", + "src/zidl/scene_session_manager_proxy.cpp", ] cflags_cc = [ "-std=c++17" ] @@ -84,7 +89,6 @@ ohos_shared_library("session_manager") { public_configs = [ ":session_manager_public_config" ] deps = [ - "${ability_runtime_services_path}/abilitymgr:abilityms", "${graphic_base_path}/graphic_2d/rosen/modules/render_service_client:librender_service_client", "${window_base_path}/dmserver:libdms", "${window_base_path}/window_scene/common:window_scene_common", @@ -99,7 +103,7 @@ ohos_shared_library("session_manager") { "c_utils:utils", "eventhandler:libeventhandler", "hilog_native:libhilog", - "ipc:ipc_core", + "ipc:ipc_single", ] part_name = "window_manager" diff --git a/window_scene/session_manager/include/scene_session_manager.h b/window_scene/session_manager/include/scene_session_manager.h index 1fc55d5902..3a9a0b7c06 100644 --- a/window_scene/session_manager/include/scene_session_manager.h +++ b/window_scene/session_manager/include/scene_session_manager.h @@ -21,6 +21,7 @@ #include "wm_single_instance.h" #include "session_manager_base.h" +#include "session_manager/include/zidl/scene_session_manager_stub.h" namespace OHOS::Ace::NG { class UIWindow; @@ -32,7 +33,9 @@ class SessionInfo; namespace OHOS::Rosen { class SceneSession; -class SceneSessionManager : public SessionManagerBase { +using NotifyCreateSpecificSessionFunc = std::function& session)>; +class SceneSessionManager : public SceneSessionManagerStub, + public SessionManagerBase { WM_DECLARE_SINGLE_INSTANCE_BASE(SceneSessionManager) public: sptr RequestSceneSession(const SessionInfo& sessionInfo); @@ -42,6 +45,11 @@ public: sptr GetRootSceneSession(); sptr GetSceneSession(uint64_t persistentId); + WSError CreateAndConnectSpecificSession(const sptr& sessionStage, + const sptr& eventChannel, const std::shared_ptr& surfaceNode, + sptr property, uint64_t& persistentId, sptr& session); + WSError DestroyAndDisconnectSpecificSession(const uint64_t& persistentId); + void SetCreateSpecificSessionListener(const NotifyCreateSpecificSessionFunc& func); protected: SceneSessionManager(); @@ -53,6 +61,7 @@ private: std::map> abilitySceneMap_; sptr rootSceneSession_; std::shared_ptr rootScene_; + NotifyCreateSpecificSessionFunc createSpecificSessionFunc_; }; } // namespace OHOS::Rosen diff --git a/window_scene/session_manager/include/session_manager.h b/window_scene/session_manager/include/session_manager.h index 318183b7c1..8967a700d6 100644 --- a/window_scene/session_manager/include/session_manager.h +++ b/window_scene/session_manager/include/session_manager.h @@ -13,11 +13,17 @@ * limitations under the License. */ +#include "interfaces/include/ws_common.h" #include "iremote_object.h" +#include "session/host/include/zidl/session_interface.h" +#include "session_manager_service/include/session_manager_service_interface.h" +#include "wm_single_instance.h" +#include "zidl/scene_session_manager_interface.h" namespace OHOS::Rosen { class AbilityConnection; class SessionManager { +WM_DECLARE_SINGLE_INSTANCE_BASE(SessionManager); public: SessionManager(); @@ -25,12 +31,24 @@ public: void Init(); - sptr GetRemoteObject() const; + sptr GetRemoteObject(); + + void CreateAndConnectSpecificSession(const sptr& sessionStage, + const sptr& eventChannel, const std::shared_ptr& surfaceNode, + sptr property, uint64_t& persistentId, sptr& session); + void DestroyAndDisconnectSpecificSession(const uint64_t& persistentId); private: void ConnectToService(); + void InitSceneSessionManagerProxy(); + void CreateSessionManagerServiceProxy(); + void GetSceneSessionManagerProxy(); sptr abilityConnection_; + sptr remoteObject_ = nullptr; + sptr sessionManagerServiceProxy_ = nullptr; + sptr sceneSessionManagerProxy_ = nullptr; + std::recursive_mutex mutex_; }; } // namespace OHOS::Rosen \ No newline at end of file diff --git a/window_scene/session_manager/include/zidl/scene_session_manager_interface.h b/window_scene/session_manager/include/zidl/scene_session_manager_interface.h new file mode 100644 index 0000000000..0a65b45f2c --- /dev/null +++ b/window_scene/session_manager/include/zidl/scene_session_manager_interface.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023 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 OHOS_ROSEN_WINDOW_SCENE_SESSION_MANAGER_INTERFACE_H +#define OHOS_ROSEN_WINDOW_SCENE_SESSION_MANAGER_INTERFACE_H + +#include + +#include "common/include/window_session_property.h" +#include "interfaces/include/ws_common.h" +#include "session/container/include/zidl/session_stage_interface.h" +#include "session/container/include/zidl/window_event_channel_interface.h" +#include "session/host/include/session.h" + +namespace OHOS::Rosen { +class RSSurfaceNode; +class ISceneSessionManager : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.ISceneSessionManager"); + + enum class SceneSessionManagerMessage : uint32_t { + TRANS_ID_CREATE_AND_CONNECT_SPECIFIC_SESSION, + TRANS_ID_DESTROY_AND_DISCONNECT_SPECIFIC_SESSION, + }; + virtual WSError CreateAndConnectSpecificSession(const sptr& sessionStage, + const sptr& eventChannel, const std::shared_ptr& surfaceNode, + sptr property, uint64_t& persistentId, sptr& session) = 0; + virtual WSError DestroyAndDisconnectSpecificSession(const uint64_t& persistentId) = 0; +}; +} // namespace OHOS::Rosen +#endif // OHOS_ROSEN_WINDOW_SCENE_SESSION_MANAGER_INTERFACE_H \ No newline at end of file diff --git a/window_scene/session_manager/include/zidl/scene_session_manager_proxy.h b/window_scene/session_manager/include/zidl/scene_session_manager_proxy.h new file mode 100644 index 0000000000..521f5210a3 --- /dev/null +++ b/window_scene/session_manager/include/zidl/scene_session_manager_proxy.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 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 OHOS_ROSEN_WINDOW_SCENE_SESSION_MANAGER_PROXY_H +#define OHOS_ROSEN_WINDOW_SCENE_SESSION_MANAGER_PROXY_H + +#include +#include +#include "session_manager/include/zidl/scene_session_manager_interface.h" + +namespace OHOS::Rosen { +class SceneSessionManagerProxy : public IRemoteProxy { +public: + explicit SceneSessionManagerProxy(const sptr& impl) + : IRemoteProxy(impl) {}; + + ~SceneSessionManagerProxy() {}; + + WSError CreateAndConnectSpecificSession(const sptr& sessionStage, + const sptr& eventChannel, const std::shared_ptr& surfaceNode, + sptr property, uint64_t& persistentId, sptr& session) override; + WSError DestroyAndDisconnectSpecificSession(const uint64_t& persistentId) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace OHOS::Rosen +#endif // OHOS_ROSEN_WINDOW_SCENE_SESSION_MANAGER_PROXY_H diff --git a/window_scene/session_manager/include/zidl/scene_session_manager_stub.h b/window_scene/session_manager/include/zidl/scene_session_manager_stub.h new file mode 100644 index 0000000000..6ef03d0f31 --- /dev/null +++ b/window_scene/session_manager/include/zidl/scene_session_manager_stub.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 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 OHOS_ROSEN_WINDOW_SCENE_SESSION_MANAGER_STUB_H +#define OHOS_ROSEN_WINDOW_SCENE_SESSION_MANAGER_STUB_H + +#include + +#include +#include +#include "session_manager/include/zidl/scene_session_manager_interface.h" + +namespace OHOS::Rosen { +class SceneSessionManagerStub : public IRemoteStub { +public: + SceneSessionManagerStub() = default; + virtual ~SceneSessionManagerStub() = default; + + int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) override; +}; +} // namespace OHOS::Rosen +#endif // OHOS_ROSEN_WINDOW_SCENE_SESSION_STUB_H diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index 0e9b6a15fd..2346132031 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -32,6 +32,7 @@ const std::string SCENE_SESSION_MANAGER_THREAD = "SceneSessionManager"; } WM_IMPLEMENT_SINGLE_INSTANCE(SceneSessionManager) + SceneSessionManager::SceneSessionManager() { Init(); @@ -203,4 +204,57 @@ WSError SceneSessionManager::RequestSceneSessionDestruction(const sptrPostAsyncTask(task); return WSError::WS_OK; } + +WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr& sessionStage, + const sptr& eventChannel, const std::shared_ptr& surfaceNode, + sptr property, uint64_t& persistentId, sptr& session) +{ + auto task = [this, sessionStage, eventChannel, surfaceNode, property, &persistentId, &session]() { + // create specific session + SessionInfo info; + sptr sceneSession = RequestSceneSession(info); + if (sceneSession == nullptr) { + return WSError::WS_ERROR_NULLPTR; + } + if (createSpecificSessionFunc_) { + createSpecificSessionFunc_(sceneSession); + } + // connect specific session and sessionStage + WSError errCode = sceneSession->Connect(sessionStage, eventChannel, surfaceNode, persistentId, property); + session = sceneSession; + return errCode; + }; + WS_CHECK_NULL_SCHE_RETURN(msgScheduler_, task); + msgScheduler_->PostSyncTask(task); + return WSError::WS_OK; +} + +void SceneSessionManager::SetCreateSpecificSessionListener(const NotifyCreateSpecificSessionFunc& func) +{ + WLOGFD("SetCreateSpecificSessionListener"); + createSpecificSessionFunc_ = func; +} + +WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const uint64_t& persistentId) +{ + auto task = [this, persistentId]() { + WLOGFI("Deatroy session persistentId: %{public}" PRIu64 "", persistentId); + auto iter = abilitySceneMap_.find(persistentId); + if (iter == abilitySceneMap_.end()) { + return WSError::WS_ERROR_INVALID_SESSION; + } + const auto& sceneSession = iter->second; + if (sceneSession == nullptr) { + return WSError::WS_ERROR_NULLPTR; + } + auto ret = sceneSession->UpdateActiveStatus(false); + ret = sceneSession->Disconnect(); + abilitySceneMap_.erase(persistentId); + return ret; + }; + + WS_CHECK_NULL_SCHE_RETURN(msgScheduler_, task); + msgScheduler_->PostSyncTask(task); + return WSError::WS_OK; +} } // namespace OHOS::Rosen diff --git a/window_scene/session_manager/src/session_manager.cpp b/window_scene/session_manager/src/session_manager.cpp index 0d5f9a182e..ac86b83665 100644 --- a/window_scene/session_manager/src/session_manager.cpp +++ b/window_scene/session_manager/src/session_manager.cpp @@ -14,15 +14,23 @@ */ #include "session_manager.h" + +#include #include "ability_manager_client.h" #include "ability_connect_callback_stub.h" +#include "session_manager_service/include/session_manager_service_proxy.h" #include "window_manager_hilog.h" +#include "zidl/scene_session_manager_proxy.h" namespace OHOS::Rosen { namespace { -constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "SessionManager"}; +constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SessionManager"}; +constexpr int CONNECT_COUNT = 10; +constexpr int SLEEP_US = 100; } +WM_IMPLEMENT_SINGLE_INSTANCE(SessionManager) + class AbilityConnection : public AAFwk::AbilityConnectionStub { public: void OnAbilityConnectDone( @@ -62,12 +70,27 @@ void SessionManager::Init() } } -sptr SessionManager::GetRemoteObject() const +sptr SessionManager::GetRemoteObject() { + if (remoteObject_) { + return remoteObject_; + } if (abilityConnection_) { - return abilityConnection_->GetRemoteObject(); + remoteObject_ = abilityConnection_->GetRemoteObject(); + if (remoteObject_) { + return remoteObject_; + } + } + + int count = 0; + std::lock_guard lock(mutex_); + while (remoteObject_ == nullptr && count < CONNECT_COUNT) { + usleep(SLEEP_US); + if (abilityConnection_) { + remoteObject_ = abilityConnection_->GetRemoteObject(); + } } - return nullptr; + return remoteObject_; } void SessionManager::ConnectToService() @@ -77,11 +100,76 @@ void SessionManager::ConnectToService() } AAFwk::Want want; - want.SetElementName("com.ohos.launcher", "com.ohos.launcher.MainAbility"); + want.SetElementName("com.ohos.sceneboard", "com.ohos.sceneboard.MainAbility"); ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, abilityConnection_, nullptr); if (ret != ERR_OK) { WLOGFE("ConnectToService failed, errorcode: %{public}d", ret); } } +void SessionManager::CreateSessionManagerServiceProxy() +{ + sptr remoteObject = GetRemoteObject(); + if (remoteObject) { + sessionManagerServiceProxy_ = iface_cast(remoteObject); + if (!sessionManagerServiceProxy_) { + WLOGFE("sessionManagerServiceProxy_ is nullptr"); + } + } else { + WLOGFE("GetRemoteObject null"); + } +} + +void SessionManager::GetSceneSessionManagerProxy() +{ + if (sceneSessionManagerProxy_) { + return; + } + if (!sessionManagerServiceProxy_) { + WLOGFE("sessionManagerServiceProxy_ is nullptr"); + } + + sptr remoteObject = sessionManagerServiceProxy_->GetSceneSessionManager(); + if (!remoteObject) { + WLOGFW("Get screen session manager proxy failed, screen session manager service is null"); + return; + } + sceneSessionManagerProxy_ = iface_cast(remoteObject); + if (!sceneSessionManagerProxy_) { + WLOGFW("Get screen session manager proxy failed, nullptr"); + } +} + +void SessionManager::InitSceneSessionManagerProxy() +{ + WLOGFD("InitSceneSessionManagerProxy"); + Init(); + CreateSessionManagerServiceProxy(); + GetSceneSessionManagerProxy(); +} + +void SessionManager::CreateAndConnectSpecificSession(const sptr& sessionStage, + const sptr& eventChannel, const std::shared_ptr& surfaceNode, + sptr property, uint64_t& persistentId, sptr& session) +{ + WLOGFD("CreateAndConnectSpecificSession"); + InitSceneSessionManagerProxy(); + if (!sceneSessionManagerProxy_) { + WLOGFE("sceneSessionManagerProxy_ is nullptr"); + return; + } + sceneSessionManagerProxy_->CreateAndConnectSpecificSession(sessionStage, eventChannel, + surfaceNode, property, persistentId, session); +} + +void SessionManager::DestroyAndDisconnectSpecificSession(const uint64_t& persistentId) +{ + WLOGFD("DestroyAndDisconnectSpecificSession"); + InitSceneSessionManagerProxy(); + if (!sceneSessionManagerProxy_) { + WLOGFE("sceneSessionManagerProxy_ is nullptr"); + return; + } + sceneSessionManagerProxy_->DestroyAndDisconnectSpecificSession(persistentId); +} } // namespace OHOS::Rosen \ No newline at end of file diff --git a/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp b/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp new file mode 100644 index 0000000000..94331131d2 --- /dev/null +++ b/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2023 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 "session_manager/include/zidl/scene_session_manager_proxy.h" + +#include +#include +#include +#include + +#include "window_manager_hilog.h" + +namespace OHOS::Rosen { +namespace { +constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionManagerProxy"}; +} +WSError SceneSessionManagerProxy::CreateAndConnectSpecificSession(const sptr& sessionStage, + const sptr& eventChannel, const std::shared_ptr& surfaceNode, + sptr property, uint64_t& persistentId, sptr& session) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_SYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + if (!data.WriteRemoteObject(sessionStage->AsObject())) { + WLOGFE("Write ISessionStage failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + if (!data.WriteRemoteObject(eventChannel->AsObject())) { + WLOGFE("Write IWindowEventChannel failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + if (!surfaceNode->Marshalling(data)) { + WLOGFE("Write surfaceNode failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + + if (property) { + if (!data.WriteBool(true) || !property->Marshalling(data)) { + WLOGFE("Write property failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + } else { + if (!data.WriteBool(false)) { + WLOGFE("Write property failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + } + if (Remote()->SendRequest(static_cast( + SceneSessionManagerMessage::TRANS_ID_CREATE_AND_CONNECT_SPECIFIC_SESSION), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + persistentId = reply.ReadUint64(); + sptr sessionObject = reply.ReadRemoteObject(); + if (sessionObject == nullptr) { + WLOGFE("ReadRemoteObject failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + session = iface_cast(sessionObject); + int32_t ret = reply.ReadUint32(); + return static_cast(ret); +} + +WSError SceneSessionManagerProxy::DestroyAndDisconnectSpecificSession(const uint64_t& persistentId) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_SYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + if (!data.WriteUint64(persistentId)) { + WLOGFE("Write uint64_t failed"); + } + if (Remote()->SendRequest(static_cast( + SceneSessionManagerMessage::TRANS_ID_DESTROY_AND_DISCONNECT_SPECIFIC_SESSION), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + int32_t ret = reply.ReadUint32(); + return static_cast(ret); +} +} // namespace OHOS::Rosen \ No newline at end of file diff --git a/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp b/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp new file mode 100644 index 0000000000..de51d49d35 --- /dev/null +++ b/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2023 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 "session_manager/include/zidl/scene_session_manager_stub.h" + +#include +#include +#include "session/host/include/scene_session.h" +#include "window_manager_hilog.h" + +namespace OHOS::Rosen { +namespace { +constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionManagerStub"}; +} + +int SceneSessionManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, + MessageParcel &reply, MessageOption &option) +{ + WLOGFD("Scene session on remote request!, code: %{public}u", code); + if (data.ReadInterfaceToken() != GetDescriptor()) { + WLOGFE("Failed to check interface token!"); + return ERR_INVALID_STATE; + } + + SceneSessionManagerMessage msgId = static_cast(code); + switch (msgId) { + case SceneSessionManagerMessage::TRANS_ID_CREATE_AND_CONNECT_SPECIFIC_SESSION : { + sptr sessionStageObject = data.ReadRemoteObject(); + sptr sessionStage = iface_cast(sessionStageObject); + sptr eventChannelObject = data.ReadRemoteObject(); + sptr eventChannel = iface_cast(eventChannelObject); + std::shared_ptr surfaceNode = RSSurfaceNode::Unmarshalling(data); + if (sessionStage == nullptr || eventChannel == nullptr || surfaceNode == nullptr) { + WLOGFE("Failed to read scene session stage object or event channel object!"); + return ERR_INVALID_DATA; + } + + sptr property = nullptr; + if (data.ReadBool()) { + property = data.ReadStrongParcelable(); + } else { + WLOGFW("Property not exist!"); + } + uint64_t persistentId = INVALID_SESSION_ID; + sptr sceneSession; + CreateAndConnectSpecificSession(sessionStage, eventChannel, surfaceNode, + property, persistentId, sceneSession); + if (sceneSession== nullptr) { + return ERR_INVALID_STATE; + } + reply.WriteUint64(persistentId); + reply.WriteRemoteObject(sceneSession->AsObject()); + reply.WriteUint32(static_cast(WSError::WS_OK)); + break; + } + case SceneSessionManagerMessage::TRANS_ID_DESTROY_AND_DISCONNECT_SPECIFIC_SESSION: { + uint64_t persistentId = data.ReadUint64(); + const WSError& ret = DestroyAndDisconnectSpecificSession(persistentId); + reply.WriteUint32(static_cast(ret)); + break; + } + default: + WLOGFE("Unknown session message!"); + } + return ERR_NONE; +} +} // namespace OHOS::Rosen diff --git a/window_scene/session_manager_service/BUILD.gn b/window_scene/session_manager_service/BUILD.gn index 23706b65de..6db290186d 100644 --- a/window_scene/session_manager_service/BUILD.gn +++ b/window_scene/session_manager_service/BUILD.gn @@ -18,8 +18,11 @@ config("session_manager_service_public_config") { include_dirs = [ "${window_base_path}/window_scene", + "${window_base_path}/interfaces/innerkits/wm", + # for window_manager_hilog "${window_base_path}/utils/include", + "${window_base_path}/window_scene/session_manager/include", "${window_base_path}/window_scene/session_manager_service/include", ] } @@ -40,6 +43,7 @@ ohos_shared_library("session_manager_service") { "${window_base_path}/utils:libwmutil", "${window_base_path}/window_scene/common:window_scene_common", "${window_base_path}/window_scene/session:scene_session", + "${window_base_path}/window_scene/session_manager:scene_session_manager", ] external_deps = [ diff --git a/window_scene/session_manager_service/include/session_manager_service.h b/window_scene/session_manager_service/include/session_manager_service.h index e00617e00c..a8d8584d86 100644 --- a/window_scene/session_manager_service/include/session_manager_service.h +++ b/window_scene/session_manager_service/include/session_manager_service.h @@ -31,6 +31,8 @@ public: IRemoteObject* GetRemoteObject(); + sptr GetSceneSessionManager() override; + private: void Init(); diff --git a/window_scene/session_manager_service/include/session_manager_service_interface.h b/window_scene/session_manager_service/include/session_manager_service_interface.h index c6f46b5992..c95edaa227 100644 --- a/window_scene/session_manager_service/include/session_manager_service_interface.h +++ b/window_scene/session_manager_service/include/session_manager_service_interface.h @@ -17,6 +17,7 @@ #define FOUNDATION_WINDOW_SCENE_SESSION_MANAGER_SERVICE_INTERFACE_H #include +#include "iremote_object.h" namespace OHOS::Rosen { class ISessionManagerService : public IRemoteBroker { @@ -26,9 +27,11 @@ public: enum class SessionManagerServiceMessage : uint32_t { TRANS_ID_SCREEN_BASE = 0, TRANS_ID_GET_SCREEN_INFO_BY_ID, + TRANS_ID_GET_SCENE_SESSION_MANAGER, }; virtual int GetValueById(int id) = 0; + virtual sptr GetSceneSessionManager() = 0; }; } // namespace OHOS::Rosen diff --git a/window_scene/session_manager_service/include/session_manager_service_proxy.h b/window_scene/session_manager_service/include/session_manager_service_proxy.h index f6402ffcae..59cf993429 100644 --- a/window_scene/session_manager_service/include/session_manager_service_proxy.h +++ b/window_scene/session_manager_service/include/session_manager_service_proxy.h @@ -23,11 +23,16 @@ namespace OHOS::Rosen { class SessionManagerServiceProxy : public IRemoteProxy { public: - explicit SessionManagerServiceProxy(sptr& remoteObject); + explicit SessionManagerServiceProxy(const sptr& remoteObject); ~SessionManagerServiceProxy() override; int GetValueById(int id) override; + + sptr GetSceneSessionManager() override; + +private: + static inline BrokerDelegator delegator_; }; } // namespace OHOS::Rosen #endif // FOUNDATION_WINDOW_SCENE_SESSION_MANAGER_SERVICE_PROXY_H \ No newline at end of file diff --git a/window_scene/session_manager_service/include/session_manager_service_stub.h b/window_scene/session_manager_service/include/session_manager_service_stub.h index 5d81f9c602..4b9991456a 100644 --- a/window_scene/session_manager_service/include/session_manager_service_stub.h +++ b/window_scene/session_manager_service/include/session_manager_service_stub.h @@ -19,6 +19,8 @@ #include "session_manager_service_interface.h" #include +#include "interfaces/include/ws_common.h" +#include "session/host/include/session.h" namespace OHOS::Rosen { class SessionManagerServiceStub : public IRemoteStub { diff --git a/window_scene/session_manager_service/src/session_manager_service.cpp b/window_scene/session_manager_service/src/session_manager_service.cpp index ccf8649734..3963f6cc49 100644 --- a/window_scene/session_manager_service/src/session_manager_service.cpp +++ b/window_scene/session_manager_service/src/session_manager_service.cpp @@ -16,12 +16,12 @@ #include "session_manager_service.h" #include - +#include "session_manager/include/scene_session_manager.h" #include "window_manager_hilog.h" namespace OHOS::Rosen { namespace { - // constexpr HiviewDFX::HiLogLabel LEVEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "SessionManagerService"}; +constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SessionManagerService"}; } WM_IMPLEMENT_SINGLE_INSTANCE(SessionManagerService) @@ -34,6 +34,12 @@ int SessionManagerService::GetValueById(int id) return id + 1; } +sptr SessionManagerService::GetSceneSessionManager() +{ + WLOGFD("GetSceneSessionManager success"); + return &(SceneSessionManager::GetInstance()); +} + IRemoteObject* SessionManagerService::GetRemoteObject() { return dynamic_cast(this); diff --git a/window_scene/session_manager_service/src/session_manager_service_proxy.cpp b/window_scene/session_manager_service/src/session_manager_service_proxy.cpp index 9d99991c91..2052fb60f9 100644 --- a/window_scene/session_manager_service/src/session_manager_service_proxy.cpp +++ b/window_scene/session_manager_service/src/session_manager_service_proxy.cpp @@ -18,10 +18,11 @@ namespace OHOS::Rosen { namespace { - constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "SessionManagerServiceProxy"}; +constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SessionManagerServiceProxy"}; } -SessionManagerServiceProxy::SessionManagerServiceProxy(sptr& remoteObject) : IRemoteProxy(remoteObject) +SessionManagerServiceProxy::SessionManagerServiceProxy(const sptr& remoteObject) + : IRemoteProxy(remoteObject) { } @@ -62,4 +63,32 @@ int SessionManagerServiceProxy::GetValueById(int id) return value; } + +sptr SessionManagerServiceProxy::GetSceneSessionManager() +{ + sptr remote = Remote(); + if (remote == nullptr) { + WLOGFE("GetValueById remote is nullptr"); + return nullptr; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("GetValueById: WriteInterfacetoken failed"); + return nullptr; + } + + int ret = remote->SendRequest(static_cast( + SessionManagerServiceMessage::TRANS_ID_GET_SCENE_SESSION_MANAGER), + data, reply, option); + if (ret != ERR_NONE) { + WLOGFW("GetValueById: SendRequest failed, errorCode %{public}d", ret); + return nullptr; + } + + return reply.ReadRemoteObject(); +} } // namespace OHOS::Rosen \ No newline at end of file diff --git a/window_scene/session_manager_service/src/session_manager_service_stub.cpp b/window_scene/session_manager_service/src/session_manager_service_stub.cpp index a51997a82a..6c1eb500ed 100644 --- a/window_scene/session_manager_service/src/session_manager_service_stub.cpp +++ b/window_scene/session_manager_service/src/session_manager_service_stub.cpp @@ -22,7 +22,7 @@ namespace OHOS::Rosen { namespace { -constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "SessionManagerServiceStub"}; +constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SessionManagerServiceStub"}; } int32_t SessionManagerServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, @@ -45,6 +45,10 @@ int32_t SessionManagerServiceStub::OnRemoteRequest(uint32_t code, MessageParcel reply.WriteInt32(value); break; } + case SessionManagerServiceMessage::TRANS_ID_GET_SCENE_SESSION_MANAGER: { + reply.WriteRemoteObject(GetSceneSessionManager()); + break; + } default: { WLOGFW("unknown transaction code."); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); diff --git a/wm/BUILD.gn b/wm/BUILD.gn index ebf5b98f40..d690e91615 100644 --- a/wm/BUILD.gn +++ b/wm/BUILD.gn @@ -74,6 +74,7 @@ ohos_static_library("libwm_static") { "${window_base_path}/utils:libwmutil", "${window_base_path}/window_scene/common:window_scene_common", "${window_base_path}/window_scene/session:scene_session", + "${window_base_path}/window_scene/session_manager:session_manager", ] external_deps = [ @@ -169,8 +170,10 @@ ohos_shared_library("libwm") { public_configs = [ ":libwm_public_config" ] deps = [ + "${window_base_path}/window_scene/common:window_scene_common", "${window_base_path}/window_scene/common:window_scene_common", "${window_base_path}/window_scene/session:scene_session", + "${window_base_path}/window_scene/session_manager:session_manager", "../dm:libdm", "../utils:libwmutil", "//foundation/graphic/graphic_2d/rosen/modules/render_service_client:librender_service_client", diff --git a/wm/include/window_session_impl.h b/wm/include/window_session_impl.h index 2b6fa04641..337ea7bea3 100644 --- a/wm/include/window_session_impl.h +++ b/wm/include/window_session_impl.h @@ -72,6 +72,7 @@ public: WMError UnregisterLifeCycleListener(const sptr& listener) override; WMError RegisterWindowChangeListener(const sptr& listener) override; WMError UnregisterWindowChangeListener(const sptr& listener) override; + void RegisterWindowDestroyedListener(const NotifyNativeWinDestroyFunc& func) override; uint64_t GetPersistentId() const; protected: @@ -106,11 +107,16 @@ private: void UpdateViewportConfig(const Rect& rect, WindowSizeChangeReason reason); void ClearListenersById(uint64_t persistentId); void NotifySizeChange(Rect rect, WindowSizeChangeReason reason); + WMError CreateAndConnectSpecificSession(); + WMError WindowSessionCreateCheck(); + bool IsValidSystemWindowType(const WindowType& type); + static std::map>> lifecycleListeners_; static std::map>> windowChangeListeners_; static std::recursive_mutex globalMutex_; std::recursive_mutex mutex_; NotifyNativeWinDestroyFunc notifyNativefunc_; + static std::map>> windowSessionMap_; }; } // namespace Rosen } // namespace OHOS diff --git a/wm/src/window.cpp b/wm/src/window.cpp index a14028b9ce..2010dd31d0 100644 --- a/wm/src/window.cpp +++ b/wm/src/window.cpp @@ -47,6 +47,8 @@ static sptr CreateWindowWithSession(sptr& option, WLOGFE("malloc windowSessionImpl failed"); return nullptr; } + + windowSessionImpl->SetWindowType(option->GetWindowType()); WMError error = windowSessionImpl->Create(context, iSession); if (error != WMError::WM_OK) { errCode = error; diff --git a/wm/src/window_session_impl.cpp b/wm/src/window_session_impl.cpp index 7f8d564691..86f4cccb72 100644 --- a/wm/src/window_session_impl.cpp +++ b/wm/src/window_session_impl.cpp @@ -22,6 +22,7 @@ #include "window_manager_hilog.h" #include "window_helper.h" #include "session/container/include/window_event_channel.h" +#include "session_manager/include/session_manager.h" #include "vsync_station.h" namespace OHOS { @@ -33,6 +34,7 @@ constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowS std::map>> WindowSessionImpl::lifecycleListeners_; std::map>> WindowSessionImpl::windowChangeListeners_; std::recursive_mutex WindowSessionImpl::globalMutex_; +std::map>> WindowSessionImpl::windowSessionMap_; #define CALL_LIFECYCLE_LISTENER(windowLifecycleCb, listeners) \ do { \ @@ -122,6 +124,62 @@ uint64_t WindowSessionImpl::GetPersistentId() const return property_->GetPersistentId(); } +WMError WindowSessionImpl::CreateAndConnectSpecificSession() +{ + sptr iSessionStage(this); + sptr channel = new (std::nothrow) WindowEventChannel(iSessionStage); + if (channel == nullptr) { + return WMError::WM_ERROR_NULLPTR; + } + sptr eventChannel(channel); + uint64_t persistentId = INVALID_SESSION_ID; + sptr session; + SessionManager::GetInstance().CreateAndConnectSpecificSession(iSessionStage, eventChannel, surfaceNode_, + property_, persistentId, session); + property_->SetPersistentId(persistentId); + if (session != nullptr) { + hostSession_ = session; + } else { + return WMError::WM_ERROR_NULLPTR; + } + WLOGFI("CreateAndConnectSpecificSession [name:%{public}s, id:%{public}" PRIu64 ", type: %{public}u], ", + property_->GetWindowName().c_str(), property_->GetPersistentId(), property_->GetWindowType()); + return WMError::WM_OK; +} + +bool WindowSessionImpl::IsValidSystemWindowType(const WindowType& type) +{ + if (!(type == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW || type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || + type == WindowType::WINDOW_TYPE_FLOAT_CAMERA || type == WindowType::WINDOW_TYPE_DIALOG || + type == WindowType::WINDOW_TYPE_FLOAT || type == WindowType::WINDOW_TYPE_SCREENSHOT || + type == WindowType::WINDOW_TYPE_VOICE_INTERACTION)) { + return false; + } + return true; +} + +WMError WindowSessionImpl::WindowSessionCreateCheck() +{ + const auto& name = property_->GetWindowName(); + // check window name, same window names are forbidden + if (windowSessionMap_.find(name) != windowSessionMap_.end()) { + WLOGFE("WindowName(%{public}s) already exists.", name.c_str()); + return WMError::WM_ERROR_REPEAT_OPERATION; + } + + // check if camera floating window is already exists + if (property_->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) { + for (const auto& item : windowSessionMap_) { + if (item.second.second && item.second.second->property_ && + item.second.second->property_->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) { + WLOGFE("Camera floating window is already exists."); + return WMError::WM_ERROR_REPEAT_OPERATION; + } + } + } + return WMError::WM_OK; +} + WMError WindowSessionImpl::Create(const std::shared_ptr& context, const sptr& iSession) { @@ -136,7 +194,20 @@ WMError WindowSessionImpl::Create(const std::shared_ptr if (hostSession_) { ret = Connect(); state_ = WindowState::STATE_CREATED; + } else { + // Not valid system window type for session should return WMError::WM_OK; + if (!IsValidSystemWindowType(property_->GetWindowType())) { + return WMError::WM_OK; + } + ret = WindowSessionCreateCheck(); + if (ret != WMError::WM_OK) { + return ret; + } + ret = CreateAndConnectSpecificSession(); } + + windowSessionMap_.insert(std::make_pair(property_->GetWindowName(), + std::pair>(property_->GetPersistentId(), this))); return ret; } @@ -147,7 +218,11 @@ WMError WindowSessionImpl::Connect() return WMError::WM_ERROR_NULLPTR; } sptr iSessionStage(this); - sptr eventChannel(new WindowEventChannel(iSessionStage)); + sptr channel = new (std::nothrow) WindowEventChannel(iSessionStage); + if (channel == nullptr) { + return WMError::WM_ERROR_NULLPTR; + } + sptr eventChannel(channel); uint64_t persistentId = INVALID_SESSION_ID; WSError ret = hostSession_->Connect(iSessionStage, eventChannel, surfaceNode_, persistentId, property_); property_->SetPersistentId(persistentId); @@ -200,7 +275,11 @@ WMError WindowSessionImpl::Hide(uint32_t reason, bool withAnimation, bool isFrom WSError ret = WSError::WS_OK; if (!WindowHelper::IsMainWindow(GetType())) { // main window no need to notify host, since host knows hide first - // need to set host session SetActive(false) + // need to SetActive(false) for host session before background + ret = SetActive(false); + if (ret != WSError::WS_OK) { + return static_cast(ret); + } ret = hostSession_->Background(); } @@ -223,7 +302,7 @@ WMError WindowSessionImpl::Destroy(bool needClearListener) WSError ret = WSError::WS_OK; if (!WindowHelper::IsMainWindow(GetType())) { // main window no need to notify host, since host knows hide first - ret = hostSession_->Disconnect(); + SessionManager::GetInstance().DestroyAndDisconnectSpecificSession(property_->GetPersistentId()); } // delete after replace WSError with WMError WMError res = static_cast(ret); @@ -234,6 +313,7 @@ WMError WindowSessionImpl::Destroy(bool needClearListener) if (needClearListener) { ClearListenersById(GetPersistentId()); } + windowSessionMap_.erase(property_->GetWindowName()); return res; } @@ -245,6 +325,10 @@ WMError WindowSessionImpl::Destroy() WSError WindowSessionImpl::SetActive(bool active) { WLOGFD("active status: %{public}d", active); + WSError ret = hostSession_->UpdateActiveStatus(active); + if (ret != WSError::WS_OK) { + return ret; + } if (active) { NotifyAfterActive(); } else { @@ -499,6 +583,11 @@ void WindowSessionImpl::ClearListenersById(uint64_t persistentId) ClearUselessListeners(windowChangeListeners_, persistentId); } +void WindowSessionImpl::RegisterWindowDestroyedListener(const NotifyNativeWinDestroyFunc& func) +{ + notifyNativefunc_ = std::move(func); +} + void WindowSessionImpl::NotifyAfterForeground(bool needNotifyListeners, bool needNotifyUiContent) { if (needNotifyListeners) { -- Gitee