From 9300f5211adf635fcf1d60f7f0d418f4e9987739 Mon Sep 17 00:00:00 2001 From: chyyy0213 Date: Tue, 28 Feb 2023 18:42:15 +0800 Subject: [PATCH] add implment for session Signed-off-by: chyyy0213 Change-Id: I2a96a9b28b3fc40fa7cf02067d9313db39155282 Signed-off-by: chyyy0213 --- bundle.json | 3 +- window_scene/common/BUILD.gn | 37 +++++ .../common/include/message_scheduler.h | 62 ++++++++ window_scene/common/src/message_scheduler.cpp | 56 +++++++ window_scene/interfaces/include/ws_common.h | 1 + .../session/container/include/session_stage.h | 103 ++++++++++++- .../container/src/extension_session_stage.cpp | 12 +- .../session/container/src/session_stage.cpp | 106 ++++++++++++-- .../container/src/window_event_channel.cpp | 14 +- .../src/zidl/session_stage_proxy.cpp | 52 ++++++- .../container/src/zidl/session_stage_stub.cpp | 7 + .../src/zidl/window_event_channel_proxy.cpp | 46 +++++- .../src/zidl/window_event_channel_stub.cpp | 22 +++ window_scene/session/host/include/session.h | 20 +-- .../host/include/zidl/session_interface.h | 4 +- .../session/host/include/zidl/session_proxy.h | 2 +- .../session/host/include/zidl/session_stub.h | 2 +- window_scene/session/host/src/session.cpp | 109 +++++++++++--- .../session/host/src/zidl/session_proxy.cpp | 137 +++++++++++++++++- .../session/host/src/zidl/session_stub.cpp | 34 ++++- window_scene/session_manager/BUILD.gn | 1 + .../include/extension_session_manager.h | 14 +- .../include/session_manager_base.h | 5 +- .../src/extension_session_manager.cpp | 131 ++++++++++++++++- 24 files changed, 897 insertions(+), 83 deletions(-) create mode 100644 window_scene/common/BUILD.gn create mode 100644 window_scene/common/include/message_scheduler.h create mode 100644 window_scene/common/src/message_scheduler.cpp diff --git a/bundle.json b/bundle.json index 356e15ffff..c2157db404 100755 --- a/bundle.json +++ b/bundle.json @@ -74,7 +74,8 @@ "//foundation/window/window_manager/extension/window_extension:libwindow_extension", "//foundation/window/window_manager/extension/window_extension:window_extension_module", "//foundation/window/window_manager/wm:libwm", - "//foundation/window/window_manager/utils:libwmutil" + "//foundation/window/window_manager/utils:libwmutil", + "//foundation/window/window_manager/window_scene/common:window_scene_common" ], "service_group": [ "//foundation/window/window_manager/sa_profile:wms_sa_profile", diff --git a/window_scene/common/BUILD.gn b/window_scene/common/BUILD.gn new file mode 100644 index 0000000000..3a6e7c908d --- /dev/null +++ b/window_scene/common/BUILD.gn @@ -0,0 +1,37 @@ +# 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. + +import("//build/ohos.gni") +import("//foundation/window/window_manager/windowmanager_aafwk.gni") +config("libwscommon_public_config") { + include_dirs = [ + "${window_base_path}/window_scene", + + # for window_manager_hilog + "${window_base_path}/utils/include", + ] +} + +## Build libwindow_scene_common.so +ohos_shared_library("window_scene_common") { + sources = [ "src/message_scheduler.cpp" ] + + public_configs = [ ":libwscommon_public_config" ] + + external_deps = [ + "eventhandler:libeventhandler", + "hilog_native:libhilog", + ] + part_name = "window_manager" + subsystem_name = "window" +} diff --git a/window_scene/common/include/message_scheduler.h b/window_scene/common/include/message_scheduler.h new file mode 100644 index 0000000000..75c3ea00af --- /dev/null +++ b/window_scene/common/include/message_scheduler.h @@ -0,0 +1,62 @@ +/* + * 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_MESSAGE_SCHEDULER_H +#define OHOS_ROSEN_WINDOW_SCENE_MESSAGE_SCHEDULER_H +#include "event_handler.h" +#include "window_manager_hilog.h" +namespace OHOS::Rosen { +#ifndef WS_CHECK_NULL_SCHE_VOID +#define WS_CHECK_NULL_SCHE_VOID(ptr, task) \ + do { \ + if (!(ptr)) { \ + task(); \ + return; \ + } \ + } while (0) +#endif + +#ifndef WS_CHECK_NULL_SCHE_RETURN +#define WS_CHECK_NULL_SCHE_RETURN(ptr, task) \ + do { \ + if (!(ptr)) { \ + return task(); \ + } \ + } while (0) +#endif + +class MessageScheduler { +public: + using Task = std::function; + MessageScheduler(const std::string& threadName); + MessageScheduler(const std::shared_ptr& handler) : handler_(handler) {}; + ~MessageScheduler(); + void PostVoidSyncTask(Task task); + void PostAsyncTask(Task task, int64_t delayTime = 0); + template> + Return PostSyncTask(SyncTask&& task) + { + Return ret; + std::function syncTask([&ret, &task]() {ret = task();}); + if (handler_) { + handler_->PostSyncTask(syncTask, AppExecFwk::EventQueue::Priority::IMMEDIATE); + } + return ret; + } +private: + std::shared_ptr handler_ = nullptr; +}; +} // namespace OHOS::Rosen +#endif // OHOS_ROSEN_WINDOW_SCENE_MESSAGE_SCHEDULER_H \ No newline at end of file diff --git a/window_scene/common/src/message_scheduler.cpp b/window_scene/common/src/message_scheduler.cpp new file mode 100644 index 0000000000..6c31b36f77 --- /dev/null +++ b/window_scene/common/src/message_scheduler.cpp @@ -0,0 +1,56 @@ +/* + * 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 "common/include/message_scheduler.h" +namespace OHOS::Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WSMessageScheduler"}; +} +MessageScheduler::MessageScheduler(const std::string& threadName) +{ + auto runner = AppExecFwk::EventRunner::Create(threadName); + handler_ = std::make_shared(runner); +} + +MessageScheduler::~MessageScheduler() +{ + handler_ = nullptr; +} + +void MessageScheduler::PostVoidSyncTask(Task task) +{ + if (handler_ == nullptr) { + WLOGFE("Failed to post task, handler is null!"); + return; + } + + bool ret = handler_->PostSyncTask(std::move(task), AppExecFwk::EventQueue::Priority::IMMEDIATE); + if (!ret) { + WLOGFE("EventHandler PostTask Failed"); + } +} + +void MessageScheduler::PostAsyncTask(Task task, int64_t delayTime) +{ + if (handler_ == nullptr) { + WLOGFE("Failed to post task, handler is null!"); + return; + } + bool ret = handler_->PostTask(std::move(task), delayTime, AppExecFwk::EventQueue::Priority::IMMEDIATE); + if (!ret) { + WLOGFE("EventHandler PostTask Failed"); + } +} +} // namespace OHOS::Rosen \ No newline at end of file diff --git a/window_scene/interfaces/include/ws_common.h b/window_scene/interfaces/include/ws_common.h index a3253fece6..a5f4783c94 100644 --- a/window_scene/interfaces/include/ws_common.h +++ b/window_scene/interfaces/include/ws_common.h @@ -64,6 +64,7 @@ enum class SessionState : uint32_t { STATE_ACTIVE, STATE_INACTIVE, STATE_BACKGROUND, + STATE_END, }; struct SessionInfo { diff --git a/window_scene/session/container/include/session_stage.h b/window_scene/session/container/include/session_stage.h index 6753581949..a976384d66 100644 --- a/window_scene/session/container/include/session_stage.h +++ b/window_scene/session/container/include/session_stage.h @@ -35,10 +35,10 @@ class AxisEvent; namespace OHOS::Rosen { class ISessionStageStateListener { public: - virtual void AfterForeground() = 0; - virtual void AfterBackground() = 0; - virtual void AfterActive() = 0; - virtual void AfterInactive() = 0; + virtual void AfterForeground() {}; + virtual void AfterBackground() {}; + virtual void AfterActive() {}; + virtual void AfterInactive() {}; }; class ISizeChangeListener { @@ -57,6 +57,15 @@ public: }; class SessionStage : public SessionStageStub, public virtual RefBase { +#define CALL_SESSION_STATE_LISTENER(sessionStateCb, listeners) \ + do { \ + for (auto& listener : (listeners)) { \ + if (!listener.expired()) { \ + listener.lock()->sessionStateCb(); \ + } \ + } \ + } while (0) + public: SessionStage(const sptr& session); virtual ~SessionStage() = default; @@ -68,7 +77,7 @@ public: virtual WSError PendingSessionActivation(const SessionInfo& info); // for scene session stage virtual WSError Recover(); - virtual WSError Maximum(); + virtual WSError Maximize(); // IPC WSError SetActive(bool active) override; @@ -90,9 +99,93 @@ public: protected: void NotifySizeChange(const WSRect& rect, SizeChangeReason reason); + inline void NotifyAfterForeground() + { + auto sessionStateListeners = GetListeners(); + CALL_SESSION_STATE_LISTENER(AfterForeground, sessionStateListeners); + } + + inline void NotifyAfterBackground() + { + auto sessionStateListeners = GetListeners(); + CALL_SESSION_STATE_LISTENER(AfterBackground, sessionStateListeners); + } + + inline void NotifyAfterActive() + { + auto sessionStateListeners = GetListeners(); + CALL_SESSION_STATE_LISTENER(AfterActive, sessionStateListeners); + } + + inline void NotifyAfterInactive(bool needNotifyUiContent = true) + { + auto sessionStateListeners = GetListeners(); + CALL_SESSION_STATE_LISTENER(AfterInactive, sessionStateListeners); + } + sptr session_; private: + template + bool RegisterListenerLocked(std::vector>& holder, const std::shared_ptr& listener); + template + bool UnregisterListenerLocked(std::vector>& holder, const std::shared_ptr& listener); + + template + using EnableIfSame = typename std::enable_if, Ret>::type; + template + inline EnableIfSame>> + GetListeners() + { + std::vector> sessionStageStateListeners; + { + std::lock_guard lock(mutex_); + for (auto& listener : sessionStageStateListeners_) { + sessionStageStateListeners.push_back(listener); + } + } + return sessionStageStateListeners; + } + + template + inline EnableIfSame>> GetListeners() + { + std::vector> sizeChangeListeners; + { + std::lock_guard lock(mutex_); + for (auto& listener : sizeChangeListeners_) { + sizeChangeListeners.push_back(listener); + } + } + return sizeChangeListeners; + } + + template + inline EnableIfSame>> GetListeners() + { + std::vector> pointerEventListeners; + { + std::lock_guard lock(mutex_); + for (auto& listener : pointerEventListeners_) { + pointerEventListeners.push_back(listener); + } + } + return pointerEventListeners; + } + + template + inline EnableIfSame>> GetListeners() + { + std::vector> keyEventListeners; + { + std::lock_guard lock(mutex_); + for (auto& listener : keyEventListeners_) { + keyEventListeners.push_back(listener); + } + } + return keyEventListeners; + } + std::recursive_mutex mutex_; std::vector> pointerEventListeners_; std::vector> keyEventListeners_; diff --git a/window_scene/session/container/src/extension_session_stage.cpp b/window_scene/session/container/src/extension_session_stage.cpp index 517d439252..3cc072df61 100644 --- a/window_scene/session/container/src/extension_session_stage.cpp +++ b/window_scene/session/container/src/extension_session_stage.cpp @@ -18,11 +18,21 @@ #include "session/container/include/window_event_channel.h" #include "window_manager_hilog.h" namespace OHOS::Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "ExtensionSessionStage" }; +} + ExtensionSessionStage::ExtensionSessionStage(const sptr& extensionSession) : SessionStage(extensionSession) {} WSError ExtensionSessionStage::Connect() { - return WSError::WS_OK; + if (session_ == nullptr) { + WLOGFE("session is invalid"); + return WSError::WS_ERROR_NULLPTR; + } + sptr extensionSessionStage(this); + sptr eventChannel(new WindowEventChannel(extensionSessionStage)); + return session_->Connect(extensionSessionStage, eventChannel); } } // namespace OHOS::Rosen diff --git a/window_scene/session/container/src/session_stage.cpp b/window_scene/session/container/src/session_stage.cpp index 0148cfe790..585aa03664 100644 --- a/window_scene/session/container/src/session_stage.cpp +++ b/window_scene/session/container/src/session_stage.cpp @@ -26,83 +26,164 @@ SessionStage::SessionStage(const sptr& session) : session_(session) {} bool SessionStage::RegisterSessionStageStateListener(const std::shared_ptr& listener) { - return false; + return RegisterListenerLocked(sessionStageStateListeners_, listener); } bool SessionStage::UnregisterSessionStageStateListener(const std::shared_ptr& listener) { - return false; + return UnregisterListenerLocked(sessionStageStateListeners_, listener); } bool SessionStage::RegisterSizeChangeListener(const std::shared_ptr& listener) { - return false; + return RegisterListenerLocked(sizeChangeListeners_, listener); } bool SessionStage::UnregisterSizeChangeListener(const std::shared_ptr& listener) { - return false; + return UnregisterListenerLocked(sizeChangeListeners_, listener); } bool SessionStage::RegisterPointerEventListener(const std::shared_ptr& listener) { - return false; + return RegisterListenerLocked(pointerEventListeners_, listener); } bool SessionStage::UnregisterPointerEventListener(const std::shared_ptr& listener) { - return false; + return UnregisterListenerLocked(pointerEventListeners_, listener); } bool SessionStage::RegisterKeyEventListener(const std::shared_ptr& listener) { - return false; + return RegisterListenerLocked(keyEventListeners_, listener); } bool SessionStage::UnregisterKeyEventListener(const std::shared_ptr& listener) { - return false; + return UnregisterListenerLocked(keyEventListeners_, listener); +} + +template +bool SessionStage::RegisterListenerLocked(std::vector>& holder, const std::shared_ptr& listener) +{ + if (listener == nullptr) { + WLOGFE("listener is nullptr"); + return false; + } + std::lock_guard lock(mutex_); + if (std::find(holder.begin(), holder.end(), listener) != holder.end()) { + WLOGFW("Listener already registered"); + return true; + } + holder.emplace_back(listener); + return true; +} + +template +bool SessionStage::UnregisterListenerLocked(std::vector>& holder, const std::shared_ptr& listener) +{ + if (listener == nullptr) { + WLOGFE("listener could not be null"); + return false; + } + std::lock_guard lock(mutex_); + holder.erase(std::remove_if(holder.begin(), holder.end(), + [listener](std::shared_ptr registeredListener) { return registeredListener == listener; }), + holder.end()); + return true; } void SessionStage::NotifySizeChange(const WSRect& rect, SizeChangeReason reason) { + auto sizeChangeListeners = GetListeners(); + for (auto& listener : sizeChangeListeners) { + if (!listener.expired()) { + listener.lock()->OnSizeChange(rect, reason); + } + } } void SessionStage::NotifyPointerEvent(const std::shared_ptr& pointerEvent) { + auto pointerEventListeners = GetListeners(); + for (auto& listener : pointerEventListeners) { + if (!listener.expired()) { + listener.lock()->OnPointerEvent(pointerEvent); + } + } } void SessionStage::NotifyKeyEvent(const std::shared_ptr& keyEvent) { + auto keyEventListeners = GetListeners(); + for (auto& listener : keyEventListeners) { + if (!listener.expired()) { + listener.lock()->OnKeyEvent(keyEvent); + } + } } WSError SessionStage::Connect() { - return WSError::WS_OK; + if (session_ == nullptr) { + WLOGFE("session is invalid"); + return WSError::WS_ERROR_NULLPTR; + } + sptr sessionStage(this); + sptr eventChannel(new WindowEventChannel(sessionStage)); + return session_->Connect(sessionStage, eventChannel); } WSError SessionStage::Foreground() { - return WSError::WS_OK; + if (session_ == nullptr) { + WLOGFE("session is invalid"); + return WSError::WS_ERROR_NULLPTR; + } + WSError res = session_->Foreground(); + if (res == WSError::WS_OK) { + NotifyAfterForeground(); + } + return res; } WSError SessionStage::Background() { + if (session_ == nullptr) { + WLOGFE("session is invalid"); + return WSError::WS_ERROR_NULLPTR; + } + NotifyAfterBackground(); return WSError::WS_OK; } WSError SessionStage::Disconnect() { + if (session_ == nullptr) { + WLOGFE("session is invalid"); + return WSError::WS_ERROR_NULLPTR; + } return WSError::WS_OK; } WSError SessionStage::PendingSessionActivation(const SessionInfo& info) { - return WSError::WS_OK; + if (session_ == nullptr) { + WLOGFE("session is invalid"); + return WSError::WS_ERROR_NULLPTR; + } + return session_->PendingSessionActivation(info); } WSError SessionStage::SetActive(bool active) { + WLOGFD("active status: %{public}d", active); + if (active) { + NotifyAfterActive(); + } else { + NotifyAfterInactive(); + } return WSError::WS_OK; } @@ -110,6 +191,7 @@ WSError SessionStage::UpdateRect(const WSRect& rect, SizeChangeReason reason) { WLOGFI("update rect [%{public}d, %{public}d, %{public}u, %{public}u], reason:%{public}u", rect.posX_, rect.posY_, rect.width_, rect.height_, reason); + NotifySizeChange(rect, reason); return WSError::WS_OK; } @@ -118,7 +200,7 @@ WSError SessionStage::Recover() return WSError::WS_OK; } -WSError SessionStage::Maximum() +WSError SessionStage::Maximize() { return WSError::WS_OK; } diff --git a/window_scene/session/container/src/window_event_channel.cpp b/window_scene/session/container/src/window_event_channel.cpp index 84bc88ff5b..3ae25881aa 100644 --- a/window_scene/session/container/src/window_event_channel.cpp +++ b/window_scene/session/container/src/window_event_channel.cpp @@ -28,13 +28,23 @@ constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "Window WSError WindowEventChannel::TransferKeyEvent(const std::shared_ptr& keyEvent) { - WLOGFI("WindowEventChannel receive key event"); + WLOGFD("WindowEventChannel receive key event"); + if (!sessionStage_) { + WLOGFE("session stage is null!"); + return WSError::WS_ERROR_NULLPTR; + } + sessionStage_->NotifyKeyEvent(keyEvent); return WSError::WS_OK; } WSError WindowEventChannel::TransferPointerEvent(const std::shared_ptr& pointerEvent) { - WLOGFI("WindowEventChannel receive pointer event"); + WLOGFD("WindowEventChannel receive pointer event"); + if (!sessionStage_) { + WLOGFE("session stage is null!"); + return WSError::WS_ERROR_NULLPTR; + } + sessionStage_->NotifyPointerEvent(pointerEvent); return WSError::WS_OK; } } // namespace OHOS::Rosen diff --git a/window_scene/session/container/src/zidl/session_stage_proxy.cpp b/window_scene/session/container/src/zidl/session_stage_proxy.cpp index cc936d26c3..431a2e197f 100644 --- a/window_scene/session/container/src/zidl/session_stage_proxy.cpp +++ b/window_scene/session/container/src/zidl/session_stage_proxy.cpp @@ -22,13 +22,61 @@ #include "window_manager_hilog.h" namespace OHOS::Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SessionStageProxy"}; +} + WSError SessionStageProxy::SetActive(bool active) { - return WSError::WS_OK; + 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(active)) { + WLOGFE("Write active failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + + if (Remote()->SendRequest(static_cast(SessionStageMessage::TRANS_ID_SET_ACTIVE), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + int32_t ret = reply.ReadUint32(); + return static_cast(ret); } WSError SessionStageProxy::UpdateRect(const WSRect& rect, SizeChangeReason reason) { - return WSError::WS_OK; + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + + if (!(data.WriteInt32(rect.posX_) && data.WriteInt32(rect.posY_) && + data.WriteUint32(rect.width_) && data.WriteUint32(rect.height_))) { + WLOGFE("Write WindowRect failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + + if (!data.WriteUint32(static_cast(reason))) { + WLOGFE("Write SessionSizeChangeReason failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + + if (Remote()->SendRequest(static_cast(SessionStageMessage::TRANS_ID_NOTIFY_SIZE_CHANGE), + 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/container/src/zidl/session_stage_stub.cpp b/window_scene/session/container/src/zidl/session_stage_stub.cpp index 07091df8c2..cd508276a2 100644 --- a/window_scene/session/container/src/zidl/session_stage_stub.cpp +++ b/window_scene/session/container/src/zidl/session_stage_stub.cpp @@ -51,12 +51,19 @@ int SessionStageStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Messag int SessionStageStub::HandleSetActive(MessageParcel& data, MessageParcel& reply) { WLOGFD("SetActive!"); + bool active = data.ReadBool(); + WSError errCode = SetActive(active); + reply.WriteUint32(static_cast(errCode)); return ERR_NONE; } int SessionStageStub::HandleUpdateRect(MessageParcel& data, MessageParcel& reply) { WLOGFD("UpdateRect!"); + WSRect rect = { data.ReadInt32(), data.ReadInt32(), data.ReadUint32(), data.ReadUint32() }; + SizeChangeReason reason = static_cast(data.ReadUint32()); + WSError errCode = UpdateRect(rect, reason); + reply.WriteUint32(static_cast(errCode)); return ERR_NONE; } } // namespace OHOS::Rosen diff --git a/window_scene/session/container/src/zidl/window_event_channel_proxy.cpp b/window_scene/session/container/src/zidl/window_event_channel_proxy.cpp index 11659b4950..9be8bb61ce 100644 --- a/window_scene/session/container/src/zidl/window_event_channel_proxy.cpp +++ b/window_scene/session/container/src/zidl/window_event_channel_proxy.cpp @@ -25,13 +25,55 @@ #include "window_manager_hilog.h" namespace OHOS::Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowEventChannelProxy"}; +} + WSError WindowEventChannelProxy::TransferKeyEvent(const std::shared_ptr& keyEvent) { - return WSError::WS_OK; + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + + if (!keyEvent->WriteToParcel(data)) { + WLOGFE("Failed to write key event"); + return WSError::WS_ERROR_IPC_FAILED; + } + + if (Remote()->SendRequest(static_cast(WindowEventChannelMessage::TRANS_ID_TRANSFER_KEY_EVENT), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + int32_t ret = reply.ReadUint32(); + return static_cast(ret); } WSError WindowEventChannelProxy::TransferPointerEvent(const std::shared_ptr& pointerEvent) { - return WSError::WS_OK; + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + + if (!pointerEvent->WriteToParcel(data)) { + WLOGFE("Failed to write pointer event"); + return WSError::WS_ERROR_IPC_FAILED; + } + + if (Remote()->SendRequest(static_cast(WindowEventChannelMessage::TRANS_ID_TRANSFER_POINTER_EVENT), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + int32_t ret = reply.ReadUint32(); + return static_cast(ret); } } \ No newline at end of file diff --git a/window_scene/session/container/src/zidl/window_event_channel_stub.cpp b/window_scene/session/container/src/zidl/window_event_channel_stub.cpp index 459f2f06be..5434d3e329 100644 --- a/window_scene/session/container/src/zidl/window_event_channel_stub.cpp +++ b/window_scene/session/container/src/zidl/window_event_channel_stub.cpp @@ -55,12 +55,34 @@ int WindowEventChannelStub::OnRemoteRequest(uint32_t code, MessageParcel &data, int WindowEventChannelStub::HandleTransferKeyEvent(MessageParcel& data, MessageParcel& reply) { WLOGFD("TransferKeyEvent!"); + auto keyEvent = MMI::KeyEvent::Create(); + if (keyEvent == nullptr) { + WLOGFE("Failed to create key event!"); + return ERR_INVALID_DATA; + } + if (!keyEvent->ReadFromParcel(data)) { + WLOGFE("Read Key Event failed"); + return ERR_INVALID_DATA; + } + WSError errCode = TransferKeyEvent(keyEvent); + reply.WriteUint32(static_cast(errCode)); return ERR_NONE; } int WindowEventChannelStub::HandleTransferPointerEvent(MessageParcel& data, MessageParcel& reply) { WLOGFD("TransferPointerEvent!"); + auto pointerEvent = MMI::PointerEvent::Create(); + if (pointerEvent == nullptr) { + WLOGFE("Failed to create pointer event!"); + return ERR_INVALID_DATA; + } + if (!pointerEvent->ReadFromParcel(data)) { + WLOGFE("Read Pointer Event failed"); + return ERR_INVALID_DATA; + } + WSError errCode = TransferPointerEvent(pointerEvent); + reply.WriteUint32(static_cast(errCode)); return ERR_NONE; } } diff --git a/window_scene/session/host/include/session.h b/window_scene/session/host/include/session.h index ee7f0cf7f0..3ad3f6722f 100644 --- a/window_scene/session/host/include/session.h +++ b/window_scene/session/host/include/session.h @@ -37,10 +37,9 @@ using NotifyPendingSessionActivationFunc = std::function& pointerEvent); WSError TransferKeyEvent(const std::shared_ptr& keyEvent); - bool RegisterLifecycleListener(const std::shared_ptr& listener); - bool UnregisterLifecycleListener(const std::shared_ptr& listener); - const SessionInfo& GetSessionInfo() const; void SetPendingSessionActivationEventListener(const NotifyPendingSessionActivationFunc& func); @@ -87,19 +80,12 @@ protected: NotifyPendingSessionActivationFunc pendingSessionActivationFunc_; private: - template - bool RegisterListenerLocked(std::vector>& holder, const std::shared_ptr& listener); - template - bool UnregisterListenerLocked(std::vector>& holder, const std::shared_ptr& listener); - std::shared_ptr CreateSurfaceNode(std::string name); uint64_t persistentId_ = INVALID_SESSION_ID; std::shared_ptr surfaceNode_ = nullptr; SessionState state_ = SessionState::STATE_DISCONNECT; - std::recursive_mutex mutex_; - std::vector> lifecycleListeners_; sptr windowEventChannel_ = nullptr; }; } // namespace OHOS::Rosen diff --git a/window_scene/session/host/include/zidl/session_interface.h b/window_scene/session/host/include/zidl/session_interface.h index 8688b46dd6..f23581c089 100644 --- a/window_scene/session/host/include/zidl/session_interface.h +++ b/window_scene/session/host/include/zidl/session_interface.h @@ -36,7 +36,7 @@ public: // Scene TRANS_ID_RECOVER = 100, - TRANS_ID_MAXIMUM, + TRANS_ID_MAXIMIZE, }; virtual WSError Connect(const sptr& sessionStage, const sptr& eventChannel) = 0; virtual WSError Foreground() = 0; @@ -46,7 +46,7 @@ public: // scene session virtual WSError Recover() = 0; - virtual WSError Maximum() = 0; + virtual WSError Maximize() = 0; }; } // namespace OHOS::Rosen #endif // OHOS_ROSEN_WINDOW_SCENE_SESSION_INTERFACE_H \ No newline at end of file diff --git a/window_scene/session/host/include/zidl/session_proxy.h b/window_scene/session/host/include/zidl/session_proxy.h index a3b20d0e1d..102faee384 100644 --- a/window_scene/session/host/include/zidl/session_proxy.h +++ b/window_scene/session/host/include/zidl/session_proxy.h @@ -35,7 +35,7 @@ public: WSError PendingSessionActivation(const SessionInfo& info) override; WSError Recover() override; - WSError Maximum() override; + WSError Maximize() override; private: static inline BrokerDelegator delegator_; }; diff --git a/window_scene/session/host/include/zidl/session_stub.h b/window_scene/session/host/include/zidl/session_stub.h index b3468207ed..f1f815dc37 100644 --- a/window_scene/session/host/include/zidl/session_stub.h +++ b/window_scene/session/host/include/zidl/session_stub.h @@ -42,7 +42,7 @@ private: int HandlePendingSessionActivation(MessageParcel& data, MessageParcel& reply); // for scene int HandleRecover(MessageParcel& data, MessageParcel& reply); - int HandleMaximum(MessageParcel& data, MessageParcel& reply); + int HandleMaximize(MessageParcel& data, MessageParcel& reply); }; } // namespace OHOS::Rosen #endif // OHOS_ROSEN_WINDOW_SCENE_SESSION_STUB_H diff --git a/window_scene/session/host/src/session.cpp b/window_scene/session/host/src/session.cpp index 6e8a414e2f..6e04706d22 100644 --- a/window_scene/session/host/src/session.cpp +++ b/window_scene/session/host/src/session.cpp @@ -53,24 +53,6 @@ const SessionInfo& Session::GetSessionInfo() const return sessionInfo_; } -bool Session::RegisterLifecycleListener(const std::shared_ptr& listener) -{ - return false; -} - -bool Session::UnregisterLifecycleListener(const std::shared_ptr& listener) -{ - return false; -} - -void Session::NotifyForeground() -{ -} - -void Session::NotifyBackground() -{ -} - SessionState Session::GetSessionState() const { return state_; @@ -83,18 +65,40 @@ void Session::UpdateSessionState(SessionState state) bool Session::IsSessionValid() const { - return false; + bool res = state_ > SessionState::STATE_DISCONNECT && state_ < SessionState::STATE_END; + if (!res) { + WLOGFI("session is already destroyed or not created! id: %{public}" PRIu64 " state: %{public}u", + GetPersistentId(), state_); + } + return res; } RSSurfaceNode::SharedPtr Session::CreateSurfaceNode(std::string name) { - return nullptr; + // expect one session with one surfaceNode + if (name.empty()) { + WLOGFI("name is empty"); + name = UNDEFINED + std::to_string(persistentId_); + } else { + std::string surfaceNodeName = name + std::to_string(persistentId_); + std::size_t pos = surfaceNodeName.find_last_of('.'); + name = (pos == std::string::npos) ? surfaceNodeName : surfaceNodeName.substr(pos + 1); // skip '.' + } + struct RSSurfaceNodeConfig rsSurfaceNodeConfig; + rsSurfaceNodeConfig.SurfaceNodeName = name; + return RSSurfaceNode::Create(rsSurfaceNodeConfig); } WSError Session::UpdateRect(const WSRect& rect, SizeChangeReason reason) { WLOGFI("session update rect: id: %{public}" PRIu64 ", rect[%{public}d, %{public}d, %{public}u, %{public}u], "\ "reason:%{public}u", GetPersistentId(), rect.posX_, rect.posY_, rect.width_, rect.height_, reason); + if (!IsSessionValid()) { + winRect_ = rect; + return WSError::WS_ERROR_INVALID_SESSION; + } + sessionStage_->UpdateRect(rect, reason); + winRect_ = rect; return WSError::WS_OK; } @@ -102,6 +106,20 @@ WSError Session::Connect(const sptr& sessionStage, const sptr(GetSessionState())); + if (GetSessionState() != SessionState::STATE_DISCONNECT) { + WLOGFE("state is not disconnect!"); + return WSError::WS_ERROR_INVALID_SESSION; + } + if (sessionStage == nullptr || eventChannel == nullptr) { + WLOGFE("session stage or eventChannel is nullptr"); + return WSError::WS_ERROR_NULLPTR; + } + sessionStage_ = sessionStage; + windowEventChannel_ = eventChannel; + + UpdateSessionState(SessionState::STATE_CONNECT); + // once update rect before connect, update again when connect + UpdateRect(winRect_, SizeChangeReason::SHOW); return WSError::WS_OK; } @@ -110,6 +128,17 @@ WSError Session::Foreground() SessionState state = GetSessionState(); WLOGFI("Foreground session, id: %{public}" PRIu64 ", state: %{public}u", GetPersistentId(), static_cast(state)); + if (state != SessionState::STATE_CONNECT && state != SessionState::STATE_BACKGROUND) { + WLOGFE("state invalid!"); + return WSError::WS_ERROR_INVALID_SESSION; + } + + if (!isActive_) { + sessionStage_->SetActive(true); + UpdateSessionState(SessionState::STATE_ACTIVE); + } else { + UpdateSessionState(SessionState::STATE_FOREGROUND); + } return WSError::WS_OK; } @@ -118,6 +147,11 @@ WSError Session::Background() SessionState state = GetSessionState(); WLOGFI("Background session, id: %{public}" PRIu64 ", state: %{public}u", GetPersistentId(), static_cast(state)); + if (state < SessionState::STATE_INACTIVE) { // only STATE_INACTIVE can transfer to background + WLOGFE("state invalid!"); + return WSError::WS_ERROR_INVALID_SESSION; + } + UpdateSessionState(SessionState::STATE_BACKGROUND); return WSError::WS_OK; } @@ -126,6 +160,10 @@ WSError Session::Disconnect() SessionState state = GetSessionState(); WLOGFI("Disconnect session, id: %{public}" PRIu64 ", state: %{public}u", GetPersistentId(), static_cast(state)); + Background(); + if (GetSessionState() == SessionState::STATE_BACKGROUND) { + UpdateSessionState(SessionState::STATE_DISCONNECT); + } return WSError::WS_OK; } @@ -134,11 +172,30 @@ WSError Session::SetActive(bool active) SessionState state = GetSessionState(); WLOGFI("Session update active: %{public}d, id: %{public}" PRIu64 ", state: %{public}u", active, GetPersistentId(), static_cast(state)); + if (!IsSessionValid()) { + return WSError::WS_ERROR_INVALID_SESSION; + } + if (active == isActive_) { + WLOGFD("Session active do not change: [%{public}d]", active); + return WSError::WS_DO_NOTHING; + } + isActive_ = active; + if (active && GetSessionState() == SessionState::STATE_FOREGROUND) { + sessionStage_->SetActive(true); + UpdateSessionState(SessionState::STATE_ACTIVE); + } + if (!active && GetSessionState() == SessionState::STATE_ACTIVE) { + sessionStage_->SetActive(false); + UpdateSessionState(SessionState::STATE_INACTIVE); + } return WSError::WS_OK; } WSError Session::PendingSessionActivation(const SessionInfo& info) { + if (pendingSessionActivationFunc_) { + pendingSessionActivationFunc_(info); + } return WSError::WS_OK; } @@ -152,7 +209,7 @@ WSError Session::Recover() return WSError::WS_OK; } -WSError Session::Maximum() +WSError Session::Maximize() { return WSError::WS_OK; } @@ -161,12 +218,22 @@ WSError Session::Maximum() WSError Session::TransferPointerEvent(const std::shared_ptr& pointerEvent) { WLOGFD("Session TransferPointEvent"); + if (!windowEventChannel_) { + WLOGFE("windowEventChannel_ is null"); + return WSError::WS_ERROR_NULLPTR; + } + windowEventChannel_->TransferPointerEvent(pointerEvent); return WSError::WS_OK; } WSError Session::TransferKeyEvent(const std::shared_ptr& keyEvent) { WLOGFD("Session TransferPointEvent"); + if (!windowEventChannel_) { + WLOGFE("windowEventChannel_ is null"); + return WSError::WS_ERROR_NULLPTR; + } + windowEventChannel_->TransferKeyEvent(keyEvent); 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 51a2510f72..fcf12fd907 100644 --- a/window_scene/session/host/src/zidl/session_proxy.cpp +++ b/window_scene/session/host/src/zidl/session_proxy.cpp @@ -22,38 +22,159 @@ #include "window_manager_hilog.h" namespace OHOS::Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SessionProxy"}; +} + WSError SessionProxy::Foreground() { - return WSError::WS_OK; + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + + if (Remote()->SendRequest(static_cast(SessionMessage::TRANS_ID_FOREGROUND), + 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::Background() { - return WSError::WS_OK; + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + + if (Remote()->SendRequest(static_cast(SessionMessage::TRANS_ID_BACKGROUND), + 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::Disconnect() { - return WSError::WS_OK; + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + + if (Remote()->SendRequest(static_cast(SessionMessage::TRANS_ID_DISCONNECT), + 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::Connect(const sptr& sessionStage, const sptr& eventChannel) { - return WSError::WS_OK; + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + 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 (Remote()->SendRequest(static_cast(SessionMessage::TRANS_ID_CONNECT), + 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::PendingSessionActivation(const SessionInfo& info) { - return WSError::WS_OK; + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + if (!(data.WriteString(info.bundleName_) && data.WriteString(info.abilityName_))) { + WLOGFE("Write ability info failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + if (info.callerToken_) { + if (!data.WriteBool(true) || !data.WriteRemoteObject(info.callerToken_)) { + WLOGFE("Write ability info failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + } else { + if (!data.WriteBool(false)) { + WLOGFE("Write ability info failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + } + if (Remote()->SendRequest(static_cast(SessionMessage::TRANS_ID_ACTIVE_PENDING_SESSION), + 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::Recover() { - return WSError::WS_OK; + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + if (Remote()->SendRequest(static_cast(SessionMessage::TRANS_ID_RECOVER), + 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::Maximum() +WSError SessionProxy::Maximize() { - return WSError::WS_OK; + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + if (Remote()->SendRequest(static_cast(SessionMessage::TRANS_ID_MAXIMIZE), + 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/host/src/zidl/session_stub.cpp b/window_scene/session/host/src/zidl/session_stub.cpp index a36c8efbce..b015e5ac6e 100644 --- a/window_scene/session/host/src/zidl/session_stub.cpp +++ b/window_scene/session/host/src/zidl/session_stub.cpp @@ -32,7 +32,7 @@ const std::map SessionStub::stubFuncMap_{ // for scene only std::make_pair(static_cast(SessionMessage::TRANS_ID_RECOVER), &SessionStub::HandleRecover), - std::make_pair(static_cast(SessionMessage::TRANS_ID_MAXIMUM), &SessionStub::HandleMaximum) + std::make_pair(static_cast(SessionMessage::TRANS_ID_MAXIMIZE), &SessionStub::HandleMaximize) }; int SessionStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) @@ -55,42 +55,70 @@ int SessionStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParc int SessionStub::HandleForeground(MessageParcel& data, MessageParcel& reply) { WLOGFD("Foreground!"); + WSError errCode = Foreground(); + reply.WriteUint32(static_cast(errCode)); return ERR_NONE; } int SessionStub::HandleBackground(MessageParcel& data, MessageParcel& reply) { WLOGFD("Background!"); + WSError errCode = Background(); + reply.WriteUint32(static_cast(errCode)); return ERR_NONE; } int SessionStub::HandleDisconnect(MessageParcel& data, MessageParcel& reply) { WLOGFD("Disconnect!"); + WSError errCode = Disconnect(); + reply.WriteUint32(static_cast(errCode)); return ERR_NONE; } int SessionStub::HandleConnect(MessageParcel& data, MessageParcel& reply) { WLOGFD("Connect!"); + sptr sessionStageObject = data.ReadRemoteObject(); + sptr sessionStageProxy = iface_cast(sessionStageObject); + sptr eventChannelObject = data.ReadRemoteObject(); + sptr eventChannelProxy = iface_cast(eventChannelObject); + if (sessionStageProxy == nullptr || eventChannelProxy == nullptr) { + WLOGFE("Failed to read scene session stage object or event channel object!"); + return ERR_INVALID_DATA; + } + WSError errCode = Connect(sessionStageProxy, eventChannelProxy); + reply.WriteUint32(static_cast(errCode)); return ERR_NONE; } int SessionStub::HandleRecover(MessageParcel& data, MessageParcel& reply) { WLOGFD("Recover!"); + WSError errCode = Recover(); + reply.WriteUint32(static_cast(errCode)); return ERR_NONE; } -int SessionStub::HandleMaximum(MessageParcel& data, MessageParcel& reply) +int SessionStub::HandleMaximize(MessageParcel& data, MessageParcel& reply) { - WLOGFD("Maximum!"); + WLOGFD("Maximize!"); + WSError errCode = Maximize(); + reply.WriteUint32(static_cast(errCode)); return ERR_NONE; } int SessionStub::HandlePendingSessionActivation(MessageParcel& data, MessageParcel& reply) { WLOGFD("PendingSessionActivation!"); + SessionInfo info; + info.bundleName_ = data.ReadString(); + info.abilityName_ = data.ReadString(); + if (data.ReadBool()) { + info.callerToken_ = data.ReadRemoteObject(); + } + WSError errCode = PendingSessionActivation(info); + 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 eb2b63122e..d7373ee00e 100644 --- a/window_scene/session_manager/BUILD.gn +++ b/window_scene/session_manager/BUILD.gn @@ -32,6 +32,7 @@ ohos_shared_library("scene_session_manager") { deps = [ "${graphic_base_path}/graphic_2d/rosen/modules/render_service_client:librender_service_client", + "${window_base_path}/window_scene/common:window_scene_common", "${window_base_path}/window_scene/session:scene_session", ] diff --git a/window_scene/session_manager/include/extension_session_manager.h b/window_scene/session_manager/include/extension_session_manager.h index e6ec448912..4afab00a23 100644 --- a/window_scene/session_manager/include/extension_session_manager.h +++ b/window_scene/session_manager/include/extension_session_manager.h @@ -25,11 +25,21 @@ #include "interfaces/include/ws_common.h" #include "session_manager_base.h" #include "wm_single_instance.h" + +namespace OHOS::AAFwk { +class SessionInfo; +} namespace OHOS::Rosen { class ExtensionSession; class ExtensionSessionManager : public SessionManagerBase { WM_DECLARE_SINGLE_INSTANCE_BASE(ExtensionSessionManager) public: + /** + * @brief init extension session manager + * + * @return WSError + */ + WSError Init(); /** * @brief create extension session * @@ -62,12 +72,12 @@ public: */ WSError RequestExtensionSessionDestruction(const sptr& extensionSession); protected: + sptr SetAbilitySessionInfo(const sptr& extensionSession); ExtensionSessionManager(); virtual ~ExtensionSessionManager() = default; private: - void Init(); - std::map, sptr>> abilityExtensionMap_; + std::map> extensionMap_; }; } // namespace OHOS::Rosen #endif // OHOS_ROSEN_WINDOW_SCENE_EXTENSION_SESSION_MANAGER_H diff --git a/window_scene/session_manager/include/session_manager_base.h b/window_scene/session_manager/include/session_manager_base.h index 72bd221f66..921a9a06e7 100644 --- a/window_scene/session_manager/include/session_manager_base.h +++ b/window_scene/session_manager/include/session_manager_base.h @@ -16,6 +16,8 @@ #ifndef OHOS_ROSEN_WINDOW_SCENE_SESSION_MANAGER_BASE_H #define OHOS_ROSEN_WINDOW_SCENE_SESSION_MANAGER_BASE_H +#include "common/include/message_scheduler.h" + namespace OHOS::Rosen { class SessionManagerBase { public: @@ -26,7 +28,8 @@ public: return (((uint64_t)pid_ << 32) | (++sessionId_)); // 32: high bit for uint64 } protected: - + std::shared_ptr mmsScheduler_ = nullptr; + std::atomic mmsSchedulerInit_ = false; private: int pid_ = getpid(); // shared by scene session and extension session once in same process diff --git a/window_scene/session_manager/src/extension_session_manager.cpp b/window_scene/session_manager/src/extension_session_manager.cpp index 386b3e9d95..f0a255513a 100644 --- a/window_scene/session_manager/src/extension_session_manager.cpp +++ b/window_scene/session_manager/src/extension_session_manager.cpp @@ -20,9 +20,14 @@ #include #include "session/host/include/extension_session.h" +#include "session_info.h" #include "window_manager_hilog.h" namespace OHOS::Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "ExtensionSessionManager" }; + const std::string EXTENSION_SESSION_MANAGER_THREAD = "ExtensionSessionManager"; +} WM_IMPLEMENT_SINGLE_INSTANCE(ExtensionSessionManager) @@ -30,27 +35,149 @@ ExtensionSessionManager::ExtensionSessionManager() { } -void ExtensionSessionManager::Init() +WSError ExtensionSessionManager::Init() { + WLOGFI("extension session manager init."); + if (mmsSchedulerInit_) { + WLOGFW("mmsScheduler_ already init!"); + return WSError::WS_DO_NOTHING; + } + mmsScheduler_ = std::make_shared(EXTENSION_SESSION_MANAGER_THREAD); + if (!mmsScheduler_) { + WLOGFE("new mmsScheduler_ failed!"); + return WSError::WS_ERROR_NULLPTR; + } + mmsSchedulerInit_ = true; + return WSError::WS_OK; +} + +sptr ExtensionSessionManager::SetAbilitySessionInfo(const sptr& extSession) +{ + sptr abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo(); + if (!abilitySessionInfo) { + WLOGFE("abilitySessionInfo is nullptr"); + return nullptr; + } + auto sessionInfo = extSession->GetSessionInfo(); + abilitySessionInfo->sessionToken = extSession; + abilitySessionInfo->surfaceNode = extSession->GetSurfaceNode(); + abilitySessionInfo->callerToken = sessionInfo.callerToken_; + abilitySessionInfo->persistentId = extSession->GetPersistentId(); + return abilitySessionInfo; } sptr ExtensionSessionManager::RequestExtensionSession(const SessionInfo& sessionInfo) { - return nullptr; + if (!mmsSchedulerInit_) { + WLOGFE("mmsScheduler_ not init!"); + return nullptr; + } + auto task = [this, sessionInfo]() { + sptr extensionSession = new (std::nothrow) ExtensionSession(sessionInfo); + if (extensionSession == nullptr) { + WLOGFE("extensionSession is nullptr!"); + return extensionSession; + } + uint64_t persistentId = GeneratePersistentId(); + extensionSession->SetPersistentId(persistentId); + WLOGFI("create session persistentId: %{public}" PRIu64 ", bundleName: %{public}s, abilityName: %{public}s", + persistentId, sessionInfo.bundleName_.c_str(), sessionInfo.abilityName_.c_str()); + extensionMap_.insert({ persistentId, extensionSession }); + return extensionSession; + }; + // once init but mmsScheduler_ is nullptr + WS_CHECK_NULL_SCHE_RETURN(mmsScheduler_, task); + return mmsScheduler_->PostSyncTask(task); } WSError ExtensionSessionManager::RequestExtensionSessionActivation(const sptr& extensionSession) { + wptr weakExtSession(extensionSession); + auto task = [this, weakExtSession]() { + auto extSession = weakExtSession.promote(); + if (extSession == nullptr) { + WLOGFE("session is nullptr"); + return WSError::WS_ERROR_NULLPTR; + } + auto persistentId = extSession->GetPersistentId(); + WLOGFI("active persistentId: %{public}" PRIu64 "", persistentId); + if (extensionMap_.count(persistentId) == 0) { + WLOGFE("session is invalid with %{public}" PRIu64 "", persistentId); + return WSError::WS_ERROR_INVALID_SESSION; + } + AAFwk::Want want; + auto sessionInfo = extSession->GetSessionInfo(); + want.SetElementName(sessionInfo.bundleName_, sessionInfo.abilityName_); + AAFwk::StartOptions startOptions; + auto extSessionInfo = SetAbilitySessionInfo(extSession); + if (!extSessionInfo) { + return WSError::WS_ERROR_NULLPTR; + } + AAFwk::AbilityManagerClient::GetInstance()->StartUIExtensionAbility(want, extSessionInfo, + AAFwk::DEFAULT_INVAL_VALUE, + AppExecFwk::ExtensionAbilityType::UI); + return WSError::WS_OK; + }; + WS_CHECK_NULL_SCHE_RETURN(mmsScheduler_, task); + mmsScheduler_->PostAsyncTask(task); return WSError::WS_OK; } WSError ExtensionSessionManager::RequestExtensionSessionBackground(const sptr& extensionSession) { + wptr weakExtSession(extensionSession); + auto task = [this, weakExtSession]() { + auto extSession = weakExtSession.promote(); + if (extSession == nullptr) { + WLOGFE("session is nullptr"); + return WSError::WS_ERROR_NULLPTR; + } + auto persistentId = extSession->GetPersistentId(); + WLOGFI("background session persistentId: %{public}" PRIu64 "", persistentId); + extSession->SetActive(false); + extSession->Background(); + if (extensionMap_.count(persistentId) == 0) { + WLOGFE("session is invalid with %{public}" PRIu64 "", persistentId); + return WSError::WS_ERROR_INVALID_SESSION; + } + auto extSessionInfo = SetAbilitySessionInfo(extSession); + if (!extSessionInfo) { + return WSError::WS_ERROR_NULLPTR; + } + AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIExtensionAbility(extSessionInfo); + return WSError::WS_OK; + }; + WS_CHECK_NULL_SCHE_RETURN(mmsScheduler_, task); + mmsScheduler_->PostAsyncTask(task); return WSError::WS_OK; } WSError ExtensionSessionManager::RequestExtensionSessionDestruction(const sptr& extensionSession) { + wptr weakExtSession(extensionSession); + auto task = [this, weakExtSession]() { + auto extSession = weakExtSession.promote(); + if (extSession == nullptr) { + WLOGFE("session is nullptr"); + return WSError::WS_ERROR_NULLPTR; + } + auto persistentId = extSession->GetPersistentId(); + WLOGFI("destroy session persistentId: %{public}" PRIu64 "", persistentId); + extSession->Disconnect(); + if (extensionMap_.count(persistentId) == 0) { + WLOGFE("session is invalid with %{public}" PRIu64 "", persistentId); + return WSError::WS_ERROR_INVALID_SESSION; + } + auto extSessionInfo = SetAbilitySessionInfo(extSession); + if (!extSessionInfo) { + return WSError::WS_ERROR_NULLPTR; + } + AAFwk::AbilityManagerClient::GetInstance()->TerminateUIExtensionAbility(extSessionInfo); + extensionMap_.erase(persistentId); + return WSError::WS_OK; + }; + WS_CHECK_NULL_SCHE_RETURN(mmsScheduler_, task); + mmsScheduler_->PostAsyncTask(task); return WSError::WS_OK; } } // namespace OHOS::Rosen