From 84cf8481cf43648f31528dc54c24323451feb05e Mon Sep 17 00:00:00 2001 From: xingyanan Date: Thu, 13 Jan 2022 18:54:50 +0800 Subject: [PATCH] add split window addwindow setwindowmode and removewindow code Signed-off-by: xingyanan Change-Id: Ic9cc92730ec1aff0d6b318b48da4a1f4f1e4d1f8 --- wm/include/window_adapter.h | 2 + wm/include/window_property.h | 3 + wm/src/window_adapter.cpp | 18 +++ wm/src/window_impl.cpp | 17 ++- wm/src/window_property.cpp | 19 +++ wmserver/BUILD.gn | 3 + wmserver/include/window_controller.h | 3 +- wmserver/include/window_manager_interface.h | 2 + wmserver/include/window_manager_proxy.h | 1 + wmserver/include/window_manager_service.h | 1 + wmserver/include/window_node.h | 2 + wmserver/include/window_node_container.h | 16 +++ wmserver/include/window_root.h | 2 + wmserver/src/window_controller.cpp | 41 +++++- wmserver/src/window_manager_proxy.cpp | 21 +++ wmserver/src/window_manager_service.cpp | 13 +- wmserver/src/window_manager_stub.cpp | 6 + wmserver/src/window_node.cpp | 11 ++ wmserver/src/window_node_container.cpp | 144 ++++++++++++++++++++ wmserver/src/window_root.cpp | 21 +++ 20 files changed, 336 insertions(+), 10 deletions(-) diff --git a/wm/include/window_adapter.h b/wm/include/window_adapter.h index d92b87806b..74d2aa7b94 100644 --- a/wm/include/window_adapter.h +++ b/wm/include/window_adapter.h @@ -46,6 +46,8 @@ public: virtual WMError RequestFocus(uint32_t windowId); virtual WMError SetWindowFlags(uint32_t windowId, uint32_t flags); virtual WMError SetSystemBarProperty(uint32_t windowId, WindowType type, const SystemBarProperty& property); + virtual WMError SetWindowMode(uint32_t windowId, WindowMode mode); + virtual WMError MinimizeAllAppNodeAbility(uint32_t windowId); virtual void RegisterFocusChangedListener(const sptr& windowManagerAgent); virtual void UnregisterFocusChangedListener(const sptr& windowManagerAgent); diff --git a/wm/include/window_property.h b/wm/include/window_property.h index b9887da3a3..5fe75cb700 100644 --- a/wm/include/window_property.h +++ b/wm/include/window_property.h @@ -32,6 +32,8 @@ public: void SetWindowRect(const struct Rect& rect); void SetWindowType(WindowType type); void SetWindowMode(WindowMode mode); + void SetLastWindowMode(WindowMode mode); + void ResumeLastWindowMode(); void SetFullScreen(bool isFullScreen); void SetFocusable(bool isFocusable); void SetTouchable(bool isTouchable); @@ -65,6 +67,7 @@ private: Rect windowRect_ { 0, 0, 0, 0 }; WindowType type_ { WindowType::WINDOW_TYPE_APP_MAIN_WINDOW }; WindowMode mode_ { WindowMode::WINDOW_MODE_FULLSCREEN }; + WindowMode lastMode_ { WindowMode::WINDOW_MODE_FULLSCREEN }; uint32_t flags_ { 0 }; bool isFullScreen_ { true }; bool focusable_ { true }; diff --git a/wm/src/window_adapter.cpp b/wm/src/window_adapter.cpp index 08d1f93cbb..4aec9f3a8f 100644 --- a/wm/src/window_adapter.cpp +++ b/wm/src/window_adapter.cpp @@ -146,6 +146,24 @@ void WindowAdapter::UnregisterFocusChangedListener(const sptrUnregisterFocusChangedListener(windowManagerAgent); } +WMError WindowAdapter::SetWindowMode(uint32_t windowId, WindowMode mode) +{ + std::lock_guard lock(mutex_); + if (!InitWMSProxyLocked()) { + return WMError::WM_ERROR_SAMGR; + } + return windowManagerServiceProxy_->SetWindowMode(windowId, mode); +} + +WMError WindowAdapter::MinimizeAllAppNodeAbility(uint32_t windowId) +{ + std::lock_guard lock(mutex_); + if (!InitWMSProxyLocked()) { + return WMError::WM_ERROR_SAMGR; + } + return windowManagerServiceProxy_->MinimizeAllAppNodeAbility(windowId); +} + bool WindowAdapter::InitWMSProxyLocked() { if (!windowManagerServiceProxy_) { diff --git a/wm/src/window_impl.cpp b/wm/src/window_impl.cpp index e58209c87e..e14cb274d6 100644 --- a/wm/src/window_impl.cpp +++ b/wm/src/window_impl.cpp @@ -135,16 +135,20 @@ WMError WindowImpl::SetWindowType(WindowType type) WMError WindowImpl::SetWindowMode(WindowMode mode) { + WLOGFI("[Client] Window %{public}d mode %{public}d", property_->GetWindowId(), static_cast(mode)); if (!IsWindowValid()) { WLOGFI("window is already destroyed or not created! id: %{public}d", property_->GetWindowId()); return WMError::WM_ERROR_INVALID_WINDOW; } if (state_ == STATE_CREATED || state_ == STATE_HIDDEN) { property_->SetWindowMode(mode); - return WMError::WM_OK; + } else if (state_ == STATE_SHOWN) { + property_->SetWindowMode(mode); + return SingletonContainer::Get().SetWindowMode(property_->GetWindowId(), mode); } if (property_->GetWindowMode() != mode) { - // TODO + WLOGFE("set window mode filed! id: %{public}d", property_->GetWindowId()); + return WMError::WM_ERROR_INVALID_PARAM; } return WMError::WM_OK; } @@ -326,6 +330,15 @@ WMError WindowImpl::Show() WLOGFI("window is already destroyed or not created! id: %{public}d", property_->GetWindowId()); return WMError::WM_ERROR_INVALID_WINDOW; } + if (state_ == STATE_SHOWN && property_->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER) { + WLOGFI("Minimize all app window"); + WMError ret = SingletonContainer::Get().MinimizeAllAppNodeAbility(property_->GetWindowId()); + if (ret != WMError::WM_OK) { + WLOGFE("Minimize all app errCode:%{public}d for winId:%{public}d", + static_cast(ret), property_->GetWindowId()); + } + return ret; + } if (state_ == STATE_SHOWN) { WLOGFI("window is already shown id: %{public}d", property_->GetWindowId()); return WMError::WM_OK; diff --git a/wm/src/window_property.cpp b/wm/src/window_property.cpp index 6b22e7cbc8..5a25258fb5 100644 --- a/wm/src/window_property.cpp +++ b/wm/src/window_property.cpp @@ -29,9 +29,18 @@ void WindowProperty::SetWindowType(WindowType type) void WindowProperty::SetWindowMode(WindowMode mode) { + if (mode != WindowMode::WINDOW_MODE_SPLIT_PRIMARY && + mode != WindowMode::WINDOW_MODE_SPLIT_SECONDARY) { + SetLastWindowMode(mode); + } mode_ = mode; } +void WindowProperty::SetLastWindowMode(WindowMode mode) +{ + lastMode_ = mode; +} + void WindowProperty::SetFullScreen(bool isFullScreen) { isFullScreen_ = isFullScreen; @@ -79,6 +88,11 @@ void WindowProperty::SetSystemBarProperty(WindowType type, const SystemBarProper } } +void WindowProperty::ResumeLastWindowMode() +{ + mode_ = lastMode_; +} + Rect WindowProperty::GetWindowRect() const { return windowRect_; @@ -260,6 +274,10 @@ bool WindowProperty::Marshalling(Parcel& parcel) const if (!MapMarshalling(parcel)) { return false; } + // write lastMode_ + if (!parcel.WriteUint32(static_cast(lastMode_))) { + return false; + } return true; } @@ -281,6 +299,7 @@ sptr WindowProperty::Unmarshalling(Parcel& parcel) property->SetWindowId(parcel.ReadUint32()); property->SetParentId(parcel.ReadUint32()); MapUnmarshalling(parcel, property); + property->SetLastWindowMode(static_cast(parcel.ReadUint32())); return property; } } diff --git a/wmserver/BUILD.gn b/wmserver/BUILD.gn index bc675b2b31..b281429e47 100644 --- a/wmserver/BUILD.gn +++ b/wmserver/BUILD.gn @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import("//base/notification/ces_standard/event.gni") import("//build/ohos.gni") ## Build libwms.so @@ -20,6 +21,7 @@ config("libwms_config") { include_dirs = [ "include", "//utils/system/safwk/native/include", + "//base/notification/ces_standard/cesfwk/innerkits/include", "//foundation/windowmanager/interfaces/innerkits/wm", "//foundation/windowmanager/interfaces/innerkits/dm", "//foundation/windowmanager/wm/include", @@ -57,6 +59,7 @@ ohos_shared_library("libwms") { deps = [ "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + "//base/notification/ces_standard/frameworks/native:cesfwk_innerkits", "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", "//utils/native/base:utils", diff --git a/wmserver/include/window_controller.h b/wmserver/include/window_controller.h index f54f7c0781..11ada4842a 100644 --- a/wmserver/include/window_controller.h +++ b/wmserver/include/window_controller.h @@ -36,10 +36,11 @@ public: WMError Resize(uint32_t windowId, uint32_t width, uint32_t height); WMError RequestFocus(uint32_t windowId); WMError SaveAbilityToken(const sptr& abilityToken, uint32_t windowId); - WMError SetWindowMode(uint32_t windowId, WindowMode mode); + WMError SetWindowMode(uint32_t windowId, WindowMode dstMode); WMError SetWindowType(uint32_t windowId, WindowType type); WMError SetWindowFlags(uint32_t windowId, uint32_t flags); WMError SetSystemBarProperty(uint32_t windowId, WindowType type, const SystemBarProperty& property); + WMError MinimizeAllAppNodeAbility(uint32_t windowId); void RegisterFocusChangedListener(const sptr& windowManagerAgent); void UnregisterFocusChangedListener(const sptr& windowManagerAgent); diff --git a/wmserver/include/window_manager_interface.h b/wmserver/include/window_manager_interface.h index 4285e24067..b86cec15a2 100644 --- a/wmserver/include/window_manager_interface.h +++ b/wmserver/include/window_manager_interface.h @@ -43,6 +43,7 @@ public: TRANS_ID_SEND_ABILITY_TOKEN, TRANS_ID_REGISTER_FOCUS_CHANGED_LISTENER, TRANS_ID_UNREGISTER_FOCUS_CHANGED_LISTENER, + TRANS_ID_MINIMIZE_ALL_APP_WINDOW, }; virtual WMError CreateWindow(sptr& window, sptr& property, const std::shared_ptr& surfaceNode, uint32_t& windowId) = 0; @@ -57,6 +58,7 @@ public: virtual WMError SetWindowFlags(uint32_t windowId, uint32_t flags) = 0; virtual WMError SetSystemBarProperty(uint32_t windowId, WindowType type, const SystemBarProperty& prop) = 0; virtual WMError SaveAbilityToken(const sptr& abilityToken, uint32_t windowId) = 0; + virtual WMError MinimizeAllAppNodeAbility(uint32_t windowId) = 0; virtual void RegisterFocusChangedListener(const sptr& windowManagerAgent) = 0; virtual void UnregisterFocusChangedListener(const sptr& windowManagerAgent) = 0; diff --git a/wmserver/include/window_manager_proxy.h b/wmserver/include/window_manager_proxy.h index fbca792c22..1de0531679 100644 --- a/wmserver/include/window_manager_proxy.h +++ b/wmserver/include/window_manager_proxy.h @@ -40,6 +40,7 @@ public: WMError SetWindowType(uint32_t windowId, WindowType type) override; WMError SetWindowFlags(uint32_t windowId, uint32_t flags) override; WMError SetSystemBarProperty(uint32_t windowId, WindowType type, const SystemBarProperty& prop) override; + WMError MinimizeAllAppNodeAbility(uint32_t windowId) override; void RegisterFocusChangedListener(const sptr& windowManagerAgent) override; void UnregisterFocusChangedListener(const sptr& windowManagerAgent) override; diff --git a/wmserver/include/window_manager_service.h b/wmserver/include/window_manager_service.h index 2cee42de12..c1eb9b4357 100644 --- a/wmserver/include/window_manager_service.h +++ b/wmserver/include/window_manager_service.h @@ -52,6 +52,7 @@ public: WMError SetWindowType(uint32_t windowId, WindowType type) override; WMError SetWindowFlags(uint32_t windowId, uint32_t flags) override; WMError SetSystemBarProperty(uint32_t windowId, WindowType type, const SystemBarProperty& prop) override; + WMError MinimizeAllAppNodeAbility(uint32_t windowId) override; void RegisterFocusChangedListener(const sptr& windowManagerAgent) override; void UnregisterFocusChangedListener(const sptr& windowManagerAgent) override; diff --git a/wmserver/include/window_node.h b/wmserver/include/window_node.h index b1f8fd8ef2..4dc76246f8 100644 --- a/wmserver/include/window_node.h +++ b/wmserver/include/window_node.h @@ -44,6 +44,7 @@ public: void SetLayoutRect(const Rect& rect); void SetWindowProperty(const sptr& property); void SetSystemBarProperty(WindowType type, const SystemBarProperty& property); + void SetWindowMode(WindowMode mode); const sptr& GetWindowToken() const; uint32_t GetWindowId() const; @@ -56,6 +57,7 @@ public: int32_t GetCallingPid() const; int32_t GetCallingUid() const; const std::unordered_map& GetSystemBarProperty() const; + bool IsSplitMode() const; sptr parent_; std::vector> children_; diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index 04430981cf..0a971bca81 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -40,11 +40,13 @@ public: WMError SetFocusWindow(uint32_t windowId); uint32_t GetFocusWindow() const; WMError MinimizeOtherFullScreenAbility(); // adapt to api7 + WMError MinimizeAllAppNodeAbility(); void TraverseContainer(std::vector>& windowNodes); uint64_t GetScreenId() const; Rect GetDisplayRect() const; sptr GetTopImmersiveNode() const; void NotifySystemBarIfChanged(); + void HandleSplitWindowModeChange(sptr& triggerNode, bool isChangeToSplit); private: void AssignZOrder(sptr& node); @@ -55,6 +57,13 @@ private: void UpdateFocusStatus(uint32_t id, bool focused) const; void UpdateWindowTree(sptr& node); bool UpdateRSTree(sptr& node, bool isAdd); + + void SendSplitScreenEvent(WindowMode mode); + sptr FindSplitPairNode(sptr& node) const; + void HandleModeChangeToSplit(sptr& triggerNode); + void HandleModeChangeFromSplit(sptr& triggerNode); + void UpdateWindowPairInfo(sptr& triggerNode, sptr& pairNode); + sptr zorderPolicy_ = new WindowZorderPolicy(); sptr belowAppWindowNode_ = new WindowNode(); sptr appWindowNode_ = new WindowNode(); @@ -75,8 +84,15 @@ private: uint32_t focusedWindow_ { 0 }; Rect displayRect_; uint64_t screenId_ = 0; + const float DEFAULT_WINDOW_SPLIT_RATIO = 0.5; //default split ratio UpdateFocusStatusFunc focusStatusCallBack_; void DumpScreenWindowTree(); + + struct WindowPairInfo { + sptr pairNode; + float splitRatio; + }; + std::unordered_map pairedWindowMap_; }; } } diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index 486290089b..e43a7c63f3 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -67,6 +67,8 @@ public: WMError RequestFocus(uint32_t windowId); WMError MinimizeOtherFullScreenAbility(sptr& node); + WMError MinimizeAllAppNodeAbility(sptr& node); + WMError HandleSplitWindowModeChange(sptr& node, bool isChangeToSplit); void RegisterFocusChangedListener(const sptr& windowManagerAgent); void UnregisterFocusChangedListener(const sptr& windowManagerAgent); diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index a26a7fd86f..32c3f0ac27 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -140,22 +140,51 @@ WMError WindowController::RequestFocus(uint32_t windowId) return windowRoot_->RequestFocus(windowId); } -WMError WindowController::SetWindowMode(uint32_t windowId, WindowMode mode) +WMError WindowController::SetWindowMode(uint32_t windowId, WindowMode dstMode) { auto node = windowRoot_->GetWindowNode(windowId); if (node == nullptr) { WLOGFE("could not find window"); return WMError::WM_ERROR_NULLPTR; } - auto property = node->GetWindowProperty(); - property->SetWindowMode(mode); - WMError res = windowRoot_->UpdateWindowNode(windowId); + + if (node->GetWindowMode() == dstMode) { + return WMError::WM_OK; + } + WMError res = WMError::WM_OK; + if (node->IsSplitMode()) { + // change split mode to other + node->SetWindowMode(dstMode); + res = windowRoot_->HandleSplitWindowModeChange(node, false); + } else if(!node->IsSplitMode() && + (dstMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || dstMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY)) { + // change other mode to split + node->SetWindowMode(dstMode); + res = windowRoot_->HandleSplitWindowModeChange(node, true); + } else { + node->SetWindowMode(dstMode); + } + if (res != WMError::WM_OK) { + WLOGFE("HandleSplitWindowModeChange failed, resume last window mode"); + node->GetWindowProperty()->ResumeLastWindowMode(); + return res; + } + res = windowRoot_->UpdateWindowNode(windowId); if (res != WMError::WM_OK) { return res; } RSTransaction::FlushImplicitTransaction(); - WLOGFI("SetWindowMode FlushImplicitTransaction end"); - return res; + return WMError::WM_OK; +} + +WMError WindowController::MinimizeAllAppNodeAbility(uint32_t windowId) +{ + auto node = windowRoot_->GetWindowNode(windowId); + if (node == nullptr) { + WLOGFE("Count node find window"); + return WMError::WM_ERROR_NULLPTR; + } + return windowRoot_->MinimizeAllAppNodeAbility(node); } WMError WindowController::SetWindowType(uint32_t windowId, WindowType type) diff --git a/wmserver/src/window_manager_proxy.cpp b/wmserver/src/window_manager_proxy.cpp index 04270b7b60..03e2f276aa 100644 --- a/wmserver/src/window_manager_proxy.cpp +++ b/wmserver/src/window_manager_proxy.cpp @@ -387,5 +387,26 @@ void WindowManagerProxy::UnregisterFocusChangedListener(const sptrSendRequest(TRANS_ID_MINIMIZE_ALL_APP_WINDOW, data, reply, option) != ERR_NONE) { + return WMError::WM_ERROR_IPC_FAILED; + } + + int32_t ret = reply.ReadInt32(); + return static_cast(ret); +} } } diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index 594f9a0f6c..06a1b062fd 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -163,7 +163,11 @@ WMError WindowManagerService::SetWindowMode(uint32_t windowId, WindowMode mode) { WM_SCOPED_TRACE("wms:SetWindowMode"); std::lock_guard lock(mutex_); - return windowController_->SetWindowMode(windowId, mode); + WMError res = windowController_->SetWindowMode(windowId, mode); + if (res == WMError::WM_OK) { + inputWindowMonitor_->UpdateInputWindow(windowId); + } + return res; } WMError WindowManagerService::SetWindowType(uint32_t windowId, WindowType type) @@ -239,5 +243,12 @@ void WindowManagerService::RestoreSuspendedWindows() std::lock_guard lock(mutex_); // TODO: restore windows covered by keyguard } + +WMError WindowManagerService::MinimizeAllAppNodeAbility(uint32_t windowId) +{ + WM_SCOPED_TRACE("wms:MinimizeAllAppNodeAbility"); + std::lock_guard lock(mutex_); + return windowController_->MinimizeAllAppNodeAbility(windowId); +} } } \ No newline at end of file diff --git a/wmserver/src/window_manager_stub.cpp b/wmserver/src/window_manager_stub.cpp index 795f046961..1506e8ff79 100644 --- a/wmserver/src/window_manager_stub.cpp +++ b/wmserver/src/window_manager_stub.cpp @@ -132,6 +132,12 @@ int32_t WindowManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, M UnregisterFocusChangedListener(windowManagerAgentProxy); break; } + case TRANS_ID_MINIMIZE_ALL_APP_WINDOW: { + uint32_t windowId = data.ReadUint32(); + WMError errCode = MinimizeAllAppNodeAbility(windowId); + reply.WriteInt32(static_cast(errCode)); + break; + } default: WLOGFW("unknown transaction code"); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); diff --git a/wmserver/src/window_node.cpp b/wmserver/src/window_node.cpp index c81bcd8e1f..c7abd18886 100644 --- a/wmserver/src/window_node.cpp +++ b/wmserver/src/window_node.cpp @@ -38,6 +38,11 @@ void WindowNode::SetSystemBarProperty(WindowType type, const SystemBarProperty& property_->SetSystemBarProperty(type, property); } +void WindowNode::SetWindowMode(WindowMode mode) +{ + property_->SetWindowMode(mode); +} + const sptr& WindowNode::GetWindowToken() const { return windowToken_; @@ -92,5 +97,11 @@ const std::unordered_map& WindowNode::GetSystemBa { return property_->GetSystemBarProperty(); } + +bool WindowNode::IsSplitMode() const +{ + return (property_->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || + property_->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY); +} } } diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index ec268097bf..720210bef0 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -22,6 +22,7 @@ #include "window_helper.h" #include "window_manager_hilog.h" #include "wm_trace.h" +#include "common_event_manager.h" namespace OHOS { namespace Rosen { @@ -65,6 +66,20 @@ WMError WindowNodeContainer::MinimizeOtherFullScreenAbility() return WMError::WM_OK; } +WMError WindowNodeContainer::MinimizeAllAppNodeAbility() +{ + if (appWindowNode_->children_.empty()) { + return WMError::WM_OK; + } + for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end(); ++iter) { + if ((*iter)->abilityToken_ != nullptr) { + WLOGFI("Notify ability to minimize"); + AAFwk::AbilityManagerClient::GetInstance()->MinimizeAbility((*iter)->abilityToken_); + } + } + return WMError::WM_OK; +} + WMError WindowNodeContainer::AddWindowNode(sptr& node, sptr& parentNode) { if (!node->surfaceNode_ || !displayNode_) { @@ -96,6 +111,10 @@ WMError WindowNodeContainer::AddWindowNode(sptr& node, sptrparent_ = parentNode; + if (node->IsSplitMode()) { + HandleSplitWindowModeChange(node, true); + } + UpdateWindowTree(node); UpdateRSTree(node, true); AssignZOrder(); @@ -202,6 +221,11 @@ WMError WindowNodeContainer::RemoveWindowNode(sptr& node) for (auto& child : node->children_) { child->currentVisibility_ = false; } + + if (node->IsSplitMode()) { + HandleSplitWindowModeChange(node, false); + } + UpdateRSTree(node, false); UpdateFocusWindow(); layoutPolicy_->RemoveWindowNode(node); @@ -454,5 +478,125 @@ Rect WindowNodeContainer::GetDisplayRect() const { return displayRect_; } + +void WindowNodeContainer::SendSplitScreenEvent(WindowMode mode) +{ + // should define in common_event_support.h and @ohos.commonEvent.d.ts + WLOGFI("send split sceen event , trigger mode is %{public}d", mode); + const std::string eventName = "common.event.SPLIT_SCREEN"; + AAFwk::Want want; + want.SetAction(eventName); + EventFwk::CommonEventData commonEventData; + commonEventData.SetWant(want); + if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) { + commonEventData.SetData("Secondary"); + } else { + commonEventData.SetData("Primary"); + } + EventFwk::CommonEventManager::PublishCommonEvent(commonEventData); +} + +sptr WindowNodeContainer::FindSplitPairNode(sptr& triggerNode) const +{ + auto triggerMode = triggerNode->GetWindowMode(); + for (auto iter = appWindowNode_->children_.rbegin(); iter != appWindowNode_->children_.rend(); iter++) { + if ((*iter)->GetWindowId() == triggerNode->GetWindowId()) { + continue; + } + // Find Top FullScreen ppp main winodow or top paired split mode app main window + if ((*iter)->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN || + (triggerMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY && + (*iter)->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) || + (triggerMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY && + (*iter)->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) { + return *iter; + } + } + return nullptr; + +} + +void WindowNodeContainer::HandleModeChangeToSplit(sptr& triggerNode) +{ + WLOGFI("HandleModeChangeToSplit %{public}d", triggerNode->GetWindowId()); + auto pairNode = FindSplitPairNode(triggerNode); + if (pairNode != nullptr) { + WLOGFI("Window %{public}d find pair %{public}d", triggerNode->GetWindowId(), pairNode->GetWindowId()); + UpdateWindowPairInfo(triggerNode, pairNode); + } else { + // sent split event + // displayRects_->SetSplitRect(); + SendSplitScreenEvent(triggerNode->GetWindowMode()); + } + // UpdateDisplayInfo(); +} + +void WindowNodeContainer::HandleModeChangeFromSplit(sptr& triggerNode) +{ + WLOGFI("HandleModeChangeFromSplit %{public}d", triggerNode->GetWindowId()); + if (pairedWindowMap_.find(triggerNode->GetWindowId()) != pairedWindowMap_.end()) { + WindowPairInfo info = pairedWindowMap_.at(triggerNode->GetWindowId()); + auto pairNode = info.pairNode; + pairNode->GetWindowProperty()->ResumeLastWindowMode(); + pairNode->GetWindowToken()->UpdateWindowMode(pairNode->GetWindowMode()); + triggerNode->GetWindowProperty()->ResumeLastWindowMode(); + triggerNode->GetWindowToken()->UpdateWindowMode(pairNode->GetWindowMode()); + pairedWindowMap_.erase(pairNode->GetWindowId()); + pairedWindowMap_.erase(triggerNode->GetWindowId()); + WLOGFI("Split out, Id[%{public}d, %{public}d], Mode[%{public}d, %{public}d]", + triggerNode->GetWindowId(), pairNode->GetWindowId(), + triggerNode->GetWindowMode(), pairNode->GetWindowMode()); + } else { + WLOGFE("Split out, but can not find pair in map %{public}d", triggerNode->GetWindowId()); + } + if (pairedWindowMap_.empty()) { + // SingletonContainer::Get().SendMessage(INNER_WM_DESTROY_DIVIDER, screenId_); + } +} + +void WindowNodeContainer::HandleSplitWindowModeChange(sptr& triggerNode, bool isChangeToSplit) +{ + if (isChangeToSplit) { + HandleModeChangeToSplit(triggerNode); + } else { + HandleModeChangeFromSplit(triggerNode); + } +} + +void WindowNodeContainer::UpdateWindowPairInfo(sptr& triggerNode, sptr& pairNode) +{ + float splitRatio = DEFAULT_WINDOW_SPLIT_RATIO; + auto triggerMode = triggerNode->GetWindowMode(); + auto pairMode = pairNode->GetWindowMode(); + if (pairNode->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN) { + pairMode = (triggerMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) ? + WindowMode::WINDOW_MODE_SPLIT_SECONDARY : WindowMode::WINDOW_MODE_SPLIT_PRIMARY; + pairNode->SetWindowMode(pairMode); + pairNode->GetWindowToken()->UpdateWindowMode(pairMode); + layoutPolicy_->AddWindowNode(pairNode); + WLOGFI("Pair FullScreen [%{public}d, %{public}d], Mode[%{public}d, %{public}d], splitRatio = %{public}f", + triggerNode->GetWindowId(), pairNode->GetWindowId(), triggerMode, pairMode, splitRatio); + } else { + if (pairedWindowMap_.count(pairNode->GetWindowId() != 0)) { + WindowPairInfo info = pairedWindowMap_.at(pairNode->GetWindowId()); + auto prevPairNode = info.pairNode; + prevPairNode->GetWindowProperty()->ResumeLastWindowMode(); + prevPairNode->GetWindowToken()->UpdateWindowMode(prevPairNode->GetWindowMode()); + + pairedWindowMap_.erase(prevPairNode->GetWindowId()); + pairedWindowMap_.erase(pairNode->GetWindowId()); + + splitRatio = info.splitRatio; + WLOGFI("Pair Split [%{public}d, %{public}d], Mode[%{public}d, %{public}d], splitRatio = %{public}f", + triggerNode->GetWindowId(), pairNode->GetWindowId(), triggerMode, pairMode, splitRatio); + } + } + pairedWindowMap_.insert({triggerNode->GetWindowId(), {pairNode, splitRatio}}); + pairedWindowMap_.insert({pairNode->GetWindowId(), {triggerNode, 1 - splitRatio}}); + // displayRects_->SetSplitRect(splitRatio); + // Rect dividerRect = displayRects_->GetDividerRect(); + // SingletonContainer::Get().SendMessage(INNER_WM_CREATE_DIVIDER, screenId_, dividerRect); +} + } } diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index 739e1527b9..ee853df1ed 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -103,6 +103,16 @@ WMError WindowRoot::MinimizeOtherFullScreenAbility(sptr& node) return container->MinimizeOtherFullScreenAbility(); } +WMError WindowRoot::MinimizeAllAppNodeAbility(sptr& node) +{ + auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + if (container == nullptr) { + WLOGFE("Minimize all app node ability failed, window container could not be found"); + return WMError::WM_ERROR_NULLPTR; + } + return container->MinimizeAllAppNodeAbility(); +} + WMError WindowRoot::AddWindowNode(uint32_t parentId, sptr& node) { if (node == nullptr) { @@ -150,6 +160,17 @@ WMError WindowRoot::UpdateWindowNode(uint32_t windowId) return container->UpdateWindowNode(node); } +WMError WindowRoot::HandleSplitWindowModeChange(sptr& node, bool isSplitIn) +{ + auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + if (container == nullptr) { + WLOGFE("HandleSplitWindowModeChange failed, window container could not be found"); + return WMError::WM_ERROR_NULLPTR; + } + container->HandleSplitWindowModeChange(node, isSplitIn); + return WMError::WM_OK; +} + WMError WindowRoot::DestroyWindow(uint32_t windowId) { auto node = GetWindowNode(windowId); -- Gitee