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
30 namespace OHOS {
31 namespace Rosen {
32
33 namespace {
34 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowGroupMgr"};
35 }
36
MoveMissionsToForeground(const std::vector<int32_t> & missionIds,int32_t topMissionId)37 WMError 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
MoveMissionsToBackground(const std::vector<int32_t> & missionIds,std::vector<int32_t> & result)64 WMError 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
MoveMissionToForeground(int32_t missionId)112 WMError 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
OnWindowDestroyed(uint32_t windowId)165 void WindowGroupMgr::OnWindowDestroyed(uint32_t windowId)
166 {
167 WLOGFD("OnWindowDestroyed WindowIds: %{public}d", windowId);
168 backupWindowModes_.erase(windowId);
169 }
170
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)171 void 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