1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include <ability_manager_client.h> 17#include <transaction/rs_transaction.h> 18#include <unordered_set> 19 20#include "display_manager_service_inner.h" 21#include "dm_common.h" 22#include "singleton_container.h" 23#include "window_adapter.h" 24#include "window_group_mgr.h" 25#include "window_manager_hilog.h" 26#include "window_manager_service.h" 27#include "minimize_app.h" 28#include "wm_common.h" 29 30namespace OHOS { 31namespace Rosen { 32 33namespace { 34constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowGroupMgr"}; 35} 36 37WMError WindowGroupMgr::MoveMissionsToForeground(const std::vector<int32_t>& missionIds, int32_t topMissionId) 38{ 39 WLOGFD("%{public}s, topMissionId: %{public}d ", DumpVector(missionIds).c_str(), topMissionId); 40 if (missionIds.empty()) { 41 return WMError::WM_DO_NOTHING; 42 } 43 44 WMError res = WMError::WM_OK; 45 for (auto it = missionIds.rbegin(); it != missionIds.rend(); it++) { 46 if (*it == topMissionId) { 47 continue; 48 } 49 WMError tempRes = MoveMissionToForeground(*it); 50 res = tempRes != WMError::WM_OK ? tempRes : res; 51 } 52 53 if (topMissionId != DEFAULT_MISSION_ID) { 54 WMError tempRes = MoveMissionToForeground(topMissionId); 55 res = tempRes == WMError::WM_OK ? tempRes : res; 56 WLOGFD("raise zOrder, missindId: %{public}d ", topMissionId); 57 auto windowNode = windowRoot_->GetWindowNodeByMissionId(topMissionId); 58 windowRoot_->RaiseZOrderForAppWindow(windowNode); 59 OHOS::Rosen::RSTransaction::FlushImplicitTransaction(); 60 } 61 return res; 62} 63 64WMError WindowGroupMgr::MoveMissionsToBackground(const std::vector<int32_t>& missionIds, std::vector<int32_t>& result) 65{ 66 WLOGFD("%{public}s ", DumpVector(missionIds).c_str()); 67 if (missionIds.empty()) { 68 return WMError::WM_DO_NOTHING; 69 } 70 71 std::vector<sptr<WindowNode>> windowNodes; 72 std::vector<uint32_t> hideWindowIds; 73 for (auto missionId : missionIds) { 74 sptr<WindowNode> windowNode = windowRoot_->GetWindowNodeByMissionId(missionId); 75 if (!windowNode) { 76 continue; 77 } 78 windowNodes.emplace_back(windowNode); 79 } 80 std::sort(windowNodes.begin(), windowNodes.end(), [](const sptr<WindowNode>& w1, const sptr<WindowNode>& w2) { 81 return w1->zOrder_ > w2->zOrder_; 82 }); 83 84 std::unordered_set<DisplayId> displayIds; 85 for (auto windowNode : windowNodes) { 86 result.emplace_back(windowNode->abilityInfo_.missionId_); 87 hideWindowIds.emplace_back(windowNode->GetWindowId()); 88 backupWindowModes_[windowNode->GetWindowId()] = windowNode->GetWindowMode(); 89 WLOGFD("windowId: %{public}d, missionId: %{public}d, node: %{public}s, zOrder: %{public}d, " 90 "mode: %{public}d ", windowNode->GetWindowId(), windowNode->abilityInfo_.missionId_, 91 (windowNode == nullptr ? "NUll" : windowNode->GetWindowName().c_str()), 92 windowNode->zOrder_, windowNode->GetWindowMode()); 93 displayIds.insert(windowNode->GetDisplayId()); 94 } 95 96 for (auto displayId : displayIds) { 97 auto container = windowRoot_->GetOrCreateWindowNodeContainer(displayId); 98 if (container != nullptr) { 99 auto windowPair = container->GetDisplayGroupController()->GetWindowPairByDisplayId(displayId); 100 if (windowPair && windowPair->GetDividerWindow()) { 101 backupDividerWindowRect_[displayId] = windowPair->GetDividerWindow()->GetWindowRect(); 102 } 103 } 104 } 105 106 WLOGFD("WindowGroupMgr::HideWindowGroup, hide WindowIds: %{public}s", DumpVector(hideWindowIds).c_str()); 107 windowRoot_->MinimizeTargetWindows(hideWindowIds); 108 MinimizeApp::ExecuteMinimizeTargetReasons(MinimizeReason::GESTURE_ANIMATION); 109 return WMError::WM_OK; 110} 111 112WMError WindowGroupMgr::MoveMissionToForeground(int32_t missionId) 113{ 114 auto windowNode = windowRoot_->GetWindowNodeByMissionId(missionId); 115 if (windowNode == nullptr || windowNode->GetWindowToken() == nullptr) { 116 WLOGFE("GetWindowToken failed, missionId: %{public}d", missionId); 117 return WMError::WM_ERROR_NULLPTR; 118 } 119 auto property = windowNode->GetWindowToken()->GetWindowProperty(); 120 if (property == nullptr) { 121 WLOGFE("Get property failed , skip, missionId: %{public}d ", missionId); 122 return WMError::WM_ERROR_NULLPTR; 123 } 124 std::set<DisplayId> displayIds; 125 if (backupWindowModes_.count(windowNode->GetWindowId()) > 0) { 126 auto mode = backupWindowModes_.at(windowNode->GetWindowId()); 127 if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) { 128 property->SetWindowMode(mode); 129 windowNode->SetWindowMode(mode); 130 // when change mode, need to reset shadow and radius 131 WindowSystemEffect::SetWindowEffect(windowNode); 132 displayIds.insert(windowNode->GetDisplayId()); 133 windowNode->GetWindowToken()->RestoreSplitWindowMode(static_cast<uint32_t>(mode)); 134 WLOGFD("Restore windowId: %{public}d, missionId: %{public}d, node: %{public}s, \ 135 zOrder: %{public}d, mode: %{public}d ", 136 windowNode->GetWindowId(), windowNode->abilityInfo_.missionId_, 137 (windowNode == nullptr ? "NUll" : windowNode->GetWindowName().c_str()), 138 windowNode->zOrder_, windowNode->GetWindowMode()); 139 } 140 } 141 for (auto displayId : displayIds) { 142 auto container = windowRoot_->GetOrCreateWindowNodeContainer(displayId); 143 if (container != nullptr) { 144 auto windowPair = container->GetDisplayGroupController()->GetWindowPairByDisplayId(displayId); 145 if (windowPair != nullptr) { 146 windowPair->SetAllSplitAppWindowsRestoring(true); 147 } 148 } 149 } 150 windowNode->GetWindowToken()->UpdateWindowState(WindowState::STATE_SHOWN); 151 WindowManagerService::GetInstance().AddWindow(property); 152 for (auto displayId : displayIds) { 153 auto container = windowRoot_->GetOrCreateWindowNodeContainer(displayId); 154 if (container != nullptr) { 155 auto windowPair = container->GetDisplayGroupController()->GetWindowPairByDisplayId(displayId); 156 if (windowPair != nullptr) { 157 windowPair->SetAllSplitAppWindowsRestoring(false); 158 container->GetLayoutPolicy()->SetSplitDividerWindowRects(backupDividerWindowRect_); 159 } 160 } 161 } 162 return WMError::WM_OK; 163} 164 165void WindowGroupMgr::OnWindowDestroyed(uint32_t windowId) 166{ 167 WLOGFD("OnWindowDestroyed WindowIds: %{public}d", windowId); 168 backupWindowModes_.erase(windowId); 169} 170 171void WindowGroupMgr::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, 172 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type) 173{ 174 WLOGFD("OnDisplayStateChange displayId: %{public}" PRIu64", type: %{public}d", defaultDisplayId, type); 175 if (type == DisplayStateChangeType::DESTROY) { 176 backupDividerWindowRect_.erase(defaultDisplayId); 177 } 178} 179 180} 181} 182