1 /*
2 * Copyright (c) 2022 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 "minimize_app.h"
17
18 #include <ability_manager_client.h>
19 #include "window_manager_hilog.h"
20 #include "window_inner_manager.h"
21
22 namespace OHOS {
23 namespace Rosen {
24 namespace {
25 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "MinimizeApp"};
26 }
27
28 std::map<MinimizeReason, std::vector<wptr<WindowNode>>> MinimizeApp::needMinimizeAppNodes_;
29 bool MinimizeApp::isMinimizedByOtherWindow_ = true;
30 std::recursive_mutex MinimizeApp::mutex_;
AddNeedMinimizeApp(const sptr<WindowNode> & node,MinimizeReason reason)31 void MinimizeApp::AddNeedMinimizeApp(const sptr<WindowNode>& node, MinimizeReason reason)
32 {
33 std::lock_guard<std::recursive_mutex> lock(mutex_);
34 if (!EnableMinimize(reason)) {
35 return;
36 }
37 if (!node) {
38 WLOGFE("AddNeedMinimizeApp failed since node is nullptr");
39 return;
40 }
41 wptr<WindowNode> weakNode(node);
42 for (auto& appNodes: needMinimizeAppNodes_) {
43 auto windowId = node->GetWindowId();
44 auto iter = std::find_if(appNodes.second.begin(), appNodes.second.end(),
45 [windowId](wptr<WindowNode> srcNode) {
46 auto weakSrcNode = srcNode.promote();
47 if (weakSrcNode == nullptr) {
48 return false;
49 }
50 return weakSrcNode->GetWindowId() == windowId;
51 });
52 if (iter != appNodes.second.end()) {
53 WLOGI("[Minimize] Window %{public}u is already in minimize list", node->GetWindowId());
54 return;
55 }
56 }
57 WLOGI("[Minimize] Add Window %{public}u to minimize list, reason %{public}u", node->GetWindowId(), reason);
58 needMinimizeAppNodes_[reason].emplace_back(weakNode);
59 }
60
GetNeedMinimizeAppNodesWithReason(MinimizeReason reason)61 std::vector<wptr<WindowNode>> MinimizeApp::GetNeedMinimizeAppNodesWithReason(MinimizeReason reason)
62 {
63 std::lock_guard<std::recursive_mutex> lock(mutex_);
64 std::vector<wptr<WindowNode>> needMinimizeAppNodes;
65 if (needMinimizeAppNodes_.find(reason) != needMinimizeAppNodes_.end()) {
66 for (auto& node : needMinimizeAppNodes_[reason]) {
67 needMinimizeAppNodes.emplace_back(node);
68 }
69 }
70 return needMinimizeAppNodes;
71 }
72
ExecuteMinimizeAll()73 void MinimizeApp::ExecuteMinimizeAll()
74 {
75 std::lock_guard<std::recursive_mutex> lock(mutex_);
76 for (auto& appNodes: needMinimizeAppNodes_) {
77 bool isFromUser = IsFromUser(appNodes.first);
78 WLOGI("[Minimize] ExecuteMinimizeAll with size: %{public}zu, reason: %{public}u",
79 appNodes.second.size(), appNodes.first);
80 for (auto& node : appNodes.second) {
81 WindowInnerManager::GetInstance().MinimizeAbility(node, isFromUser);
82 }
83 appNodes.second.clear();
84 }
85 needMinimizeAppNodes_.clear();
86 }
87
ClearNodesWithReason(MinimizeReason reason)88 void MinimizeApp::ClearNodesWithReason(MinimizeReason reason)
89 {
90 WLOGI("[Minimize] ClearNodesWithReason reason %{public}u", reason);
91 std::lock_guard<std::recursive_mutex> lock(mutex_);
92 if (needMinimizeAppNodes_.find(reason) != needMinimizeAppNodes_.end()) {
93 needMinimizeAppNodes_.at(reason).clear();
94 }
95 }
96
GetRecoverdNodeFromMinimizeList()97 sptr<WindowNode> MinimizeApp::GetRecoverdNodeFromMinimizeList()
98 {
99 WLOGI("[Minimize] RevertMinimizedNodeForTile");
100 std::lock_guard<std::recursive_mutex> lock(mutex_);
101 if (needMinimizeAppNodes_.find(MinimizeReason::LAYOUT_TILE) != needMinimizeAppNodes_.end()) {
102 auto& tileNodesForMinimize = needMinimizeAppNodes_.at(MinimizeReason::LAYOUT_TILE);
103 if (!tileNodesForMinimize.empty()) {
104 auto recoverNode = tileNodesForMinimize.back().promote();
105 tileNodesForMinimize.pop_back();
106 return recoverNode;
107 }
108 }
109 return nullptr;
110 }
111
IsNodeNeedMinimize(const sptr<WindowNode> & node)112 bool MinimizeApp::IsNodeNeedMinimize(const sptr<WindowNode>& node)
113 {
114 if (node == nullptr) {
115 WLOGFE("[Minimize] node is nullptr");
116 return false;
117 }
118 for (auto iter : needMinimizeAppNodes_) {
119 auto nodes = iter.second;
120 if (std::find(nodes.begin(), nodes.end(), node) != nodes.end()) {
121 return true;
122 }
123 }
124 return false;
125 }
126
IsNodeNeedMinimizeWithReason(const sptr<WindowNode> & node,MinimizeReason reason)127 bool MinimizeApp::IsNodeNeedMinimizeWithReason(const sptr<WindowNode>& node, MinimizeReason reason)
128 {
129 if (node == nullptr) {
130 WLOGFE("[Minimize] node is nullptr");
131 return false;
132 }
133 if (needMinimizeAppNodes_.find(reason) == needMinimizeAppNodes_.end()) {
134 WLOGFD("[Minimize] no need to minimize with id:%{public}u reason:%{public}u",
135 node->GetWindowId(), reason);
136 return false;
137 }
138 auto nodes = needMinimizeAppNodes_.at(reason);
139 if (std::find(nodes.begin(), nodes.end(), node) != nodes.end()) {
140 WLOGI("[Minimize] id:%{public}u need to minimize with reason:%{public}u",
141 node->GetWindowId(), reason);
142 return true;
143 }
144 return false;
145 }
146
EnableMinimize(MinimizeReason reason)147 bool MinimizeApp::EnableMinimize(MinimizeReason reason)
148 {
149 bool isFromUser = IsFromUser(reason);
150 if (!isMinimizedByOtherWindow_ && !isFromUser) {
151 return false;
152 }
153 return true;
154 }
155
ExecuteMinimizeTargetReasons(uint32_t reasons)156 void MinimizeApp::ExecuteMinimizeTargetReasons(uint32_t reasons)
157 {
158 std::lock_guard<std::recursive_mutex> lock(mutex_);
159 while (reasons) {
160 MinimizeReason reason = static_cast<MinimizeReason>(reasons & (~reasons + 1));
161 if (needMinimizeAppNodes_.find(reason) != needMinimizeAppNodes_.end()) {
162 WLOGI("[Minimize] ExecuteMinimizeTargetReason with size: %{public}zu, reason: %{public}u",
163 needMinimizeAppNodes_.at(reason).size(), reason);
164 bool isFromUser = IsFromUser(reason);
165 for (auto& node : needMinimizeAppNodes_.at(reason)) {
166 WindowInnerManager::GetInstance().MinimizeAbility(node, isFromUser);
167 }
168 needMinimizeAppNodes_.at(reason).clear();
169 }
170 reasons -= reason;
171 }
172 }
173
SetMinimizedByOtherConfig(bool isMinimizedByOther)174 void MinimizeApp::SetMinimizedByOtherConfig(bool isMinimizedByOther)
175 {
176 isMinimizedByOtherWindow_ = isMinimizedByOther;
177 }
178 } // Rosen
179 } // OHOS
180