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 22namespace OHOS { 23namespace Rosen { 24namespace { 25constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "MinimizeApp"}; 26} 27 28std::map<MinimizeReason, std::vector<wptr<WindowNode>>> MinimizeApp::needMinimizeAppNodes_; 29bool MinimizeApp::isMinimizedByOtherWindow_ = true; 30std::recursive_mutex MinimizeApp::mutex_; 31void 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 61std::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 73void 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 88void 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 97sptr<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 112bool 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 127bool 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 147bool MinimizeApp::EnableMinimize(MinimizeReason reason) 148{ 149 bool isFromUser = IsFromUser(reason); 150 if (!isMinimizedByOtherWindow_ && !isFromUser) { 151 return false; 152 } 153 return true; 154} 155 156void 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 174void MinimizeApp::SetMinimizedByOtherConfig(bool isMinimizedByOther) 175{ 176 isMinimizedByOtherWindow_ = isMinimizedByOther; 177} 178} // Rosen 179} // OHOS 180