• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "rs_adapter.h"
23 #include "singleton_container.h"
24 #include "window_adapter.h"
25 #include "window_group_mgr.h"
26 #include "window_manager_hilog.h"
27 #include "window_manager_service.h"
28 #include "minimize_app.h"
29 #include "wm_common.h"
30 
31 namespace OHOS {
32 namespace Rosen {
33 
34 namespace {
35 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowGroupMgr"};
36 }
37 
MoveMissionsToForeground(const std::vector<int32_t> & missionIds,int32_t topMissionId)38 WMError WindowGroupMgr::MoveMissionsToForeground(const std::vector<int32_t>& missionIds, int32_t topMissionId)
39 {
40     WLOGFD("%{public}s, topMissionId: %{public}d ", DumpVector(missionIds).c_str(), topMissionId);
41     if (missionIds.empty()) {
42         return WMError::WM_DO_NOTHING;
43     }
44 
45     WMError res = WMError::WM_OK;
46     for (auto it = missionIds.rbegin(); it != missionIds.rend(); it++) {
47         if (*it == topMissionId) {
48             continue;
49         }
50         WMError tempRes = MoveMissionToForeground(*it);
51         res = tempRes != WMError::WM_OK ? tempRes : res;
52     }
53 
54     if (topMissionId != DEFAULT_MISSION_ID) {
55         WMError tempRes = MoveMissionToForeground(topMissionId);
56         res = tempRes == WMError::WM_OK ? tempRes : res;
57         WLOGFD("raise zOrder, missindId: %{public}d ", topMissionId);
58         auto windowNode = windowRoot_->GetWindowNodeByMissionId(topMissionId);
59         windowRoot_->RaiseZOrderForAppWindow(windowNode);
60         RSTransactionAdapter::FlushImplicitTransaction(windowNode->GetRSUIContext());
61     }
62     return res;
63 }
64 
MoveMissionsToBackground(const std::vector<int32_t> & missionIds,std::vector<int32_t> & result)65 WMError WindowGroupMgr::MoveMissionsToBackground(const std::vector<int32_t>& missionIds, std::vector<int32_t>& result)
66 {
67     WLOGFD("%{public}s ", DumpVector(missionIds).c_str());
68     if (missionIds.empty()) {
69         return WMError::WM_DO_NOTHING;
70     }
71 
72     std::vector<sptr<WindowNode>> windowNodes;
73     std::vector<uint32_t> hideWindowIds;
74     for (auto missionId : missionIds) {
75         sptr<WindowNode> windowNode = windowRoot_->GetWindowNodeByMissionId(missionId);
76         if (!windowNode) {
77             continue;
78         }
79         windowNodes.emplace_back(windowNode);
80     }
81     std::sort(windowNodes.begin(), windowNodes.end(), [](const sptr<WindowNode>& w1, const sptr<WindowNode>& w2) {
82         return w1->zOrder_ > w2->zOrder_;
83     });
84 
85     std::unordered_set<DisplayId> displayIds;
86     for (auto windowNode : windowNodes) {
87         result.emplace_back(windowNode->abilityInfo_.missionId_);
88         hideWindowIds.emplace_back(windowNode->GetWindowId());
89         backupWindowModes_[windowNode->GetWindowId()] = windowNode->GetWindowMode();
90         WLOGFD("windowId: %{public}d, missionId: %{public}d, node: %{public}s, zOrder: %{public}d, "
91             "mode: %{public}d ", windowNode->GetWindowId(), windowNode->abilityInfo_.missionId_,
92             (windowNode == nullptr ? "NUll" : windowNode->GetWindowName().c_str()),
93             windowNode->zOrder_, windowNode->GetWindowMode());
94         displayIds.insert(windowNode->GetDisplayId());
95     }
96 
97     for (auto displayId : displayIds) {
98         auto container = windowRoot_->GetOrCreateWindowNodeContainer(displayId);
99         if (container != nullptr) {
100             auto windowPair = container->GetDisplayGroupController()->GetWindowPairByDisplayId(displayId);
101             if (windowPair && windowPair->GetDividerWindow()) {
102                 backupDividerWindowRect_[displayId] = windowPair->GetDividerWindow()->GetWindowRect();
103             }
104         }
105     }
106 
107     WLOGFD("WindowGroupMgr::HideWindowGroup, hide WindowIds: %{public}s", DumpVector(hideWindowIds).c_str());
108     windowRoot_->MinimizeTargetWindows(hideWindowIds);
109     MinimizeApp::ExecuteMinimizeTargetReasons(MinimizeReason::GESTURE_ANIMATION);
110     return WMError::WM_OK;
111 }
112 
MoveMissionToForeground(int32_t missionId)113 WMError WindowGroupMgr::MoveMissionToForeground(int32_t missionId)
114 {
115     auto windowNode = windowRoot_->GetWindowNodeByMissionId(missionId);
116     if (windowNode == nullptr || windowNode->GetWindowToken() == nullptr) {
117         WLOGFE("GetWindowToken failed, missionId: %{public}d", missionId);
118         return WMError::WM_ERROR_NULLPTR;
119     }
120     auto property = windowNode->GetWindowToken()->GetWindowProperty();
121     if (property == nullptr) {
122         WLOGFE("Get property failed , skip, missionId: %{public}d ", missionId);
123         return WMError::WM_ERROR_NULLPTR;
124     }
125     std::set<DisplayId> displayIds;
126     if (backupWindowModes_.count(windowNode->GetWindowId()) > 0) {
127         auto mode = backupWindowModes_.at(windowNode->GetWindowId());
128         if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
129             property->SetWindowMode(mode);
130             windowNode->SetWindowMode(mode);
131             // when change mode, need to reset shadow and radius
132             WindowSystemEffect::SetWindowEffect(windowNode);
133             displayIds.insert(windowNode->GetDisplayId());
134             windowNode->GetWindowToken()->RestoreSplitWindowMode(static_cast<uint32_t>(mode));
135             WLOGFD("Restore windowId: %{public}d, missionId: %{public}d, node: %{public}s, \
136                 zOrder: %{public}d, mode: %{public}d ",
137                 windowNode->GetWindowId(), windowNode->abilityInfo_.missionId_,
138                 (windowNode == nullptr ? "NUll" : windowNode->GetWindowName().c_str()),
139                 windowNode->zOrder_, windowNode->GetWindowMode());
140         }
141     }
142     for (auto displayId : displayIds) {
143         auto container = windowRoot_->GetOrCreateWindowNodeContainer(displayId);
144         if (container != nullptr) {
145             auto windowPair = container->GetDisplayGroupController()->GetWindowPairByDisplayId(displayId);
146             if (windowPair != nullptr) {
147                 windowPair->SetAllSplitAppWindowsRestoring(true);
148             }
149         }
150     }
151     windowNode->GetWindowToken()->UpdateWindowState(WindowState::STATE_SHOWN);
152     WindowManagerService::GetInstance().AddWindow(property);
153     for (auto displayId : displayIds) {
154         auto container = windowRoot_->GetOrCreateWindowNodeContainer(displayId);
155         if (container != nullptr) {
156             auto windowPair = container->GetDisplayGroupController()->GetWindowPairByDisplayId(displayId);
157             if (windowPair != nullptr) {
158                 windowPair->SetAllSplitAppWindowsRestoring(false);
159                 container->GetLayoutPolicy()->SetSplitDividerWindowRects(backupDividerWindowRect_);
160             }
161         }
162     }
163     return WMError::WM_OK;
164 }
165 
OnWindowDestroyed(uint32_t windowId)166 void WindowGroupMgr::OnWindowDestroyed(uint32_t windowId)
167 {
168     WLOGFD("OnWindowDestroyed WindowIds: %{public}d", windowId);
169     backupWindowModes_.erase(windowId);
170 }
171 
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)172 void WindowGroupMgr::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
173     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
174 {
175     WLOGFD("OnDisplayStateChange displayId: %{public}" PRIu64", type: %{public}d", defaultDisplayId, type);
176     if (type == DisplayStateChangeType::DESTROY) {
177         backupDividerWindowRect_.erase(defaultDisplayId);
178     }
179 }
180 
181 }
182 }
183