/* * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "minimize_app.h" #include #include "window_manager_hilog.h" #include "window_inner_manager.h" namespace OHOS { namespace Rosen { namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "MinimizeApp"}; } std::map>> MinimizeApp::needMinimizeAppNodes_; bool MinimizeApp::isMinimizedByOtherWindow_ = true; std::recursive_mutex MinimizeApp::mutex_; void MinimizeApp::AddNeedMinimizeApp(const sptr& node, MinimizeReason reason) { std::lock_guard lock(mutex_); if (!EnableMinimize(reason)) { return; } if (!node) { WLOGFE("AddNeedMinimizeApp failed since node is nullptr"); return; } wptr weakNode(node); for (auto& appNodes: needMinimizeAppNodes_) { auto windowId = node->GetWindowId(); auto iter = std::find_if(appNodes.second.begin(), appNodes.second.end(), [windowId](wptr srcNode) { auto weakSrcNode = srcNode.promote(); if (weakSrcNode == nullptr) { return false; } return weakSrcNode->GetWindowId() == windowId; }); if (iter != appNodes.second.end()) { WLOGI("[Minimize] Window %{public}u is already in minimize list", node->GetWindowId()); return; } } WLOGI("[Minimize] Add Window %{public}u to minimize list, reason %{public}u", node->GetWindowId(), reason); needMinimizeAppNodes_[reason].emplace_back(weakNode); } std::vector> MinimizeApp::GetNeedMinimizeAppNodesWithReason(MinimizeReason reason) { std::lock_guard lock(mutex_); std::vector> needMinimizeAppNodes; if (needMinimizeAppNodes_.find(reason) != needMinimizeAppNodes_.end()) { for (auto& node : needMinimizeAppNodes_[reason]) { needMinimizeAppNodes.emplace_back(node); } } return needMinimizeAppNodes; } void MinimizeApp::ExecuteMinimizeAll() { std::lock_guard lock(mutex_); for (auto& appNodes: needMinimizeAppNodes_) { bool isFromUser = IsFromUser(appNodes.first); WLOGI("[Minimize] ExecuteMinimizeAll with size: %{public}zu, reason: %{public}u", appNodes.second.size(), appNodes.first); for (auto& node : appNodes.second) { WindowInnerManager::GetInstance().MinimizeAbility(node, isFromUser); } appNodes.second.clear(); } needMinimizeAppNodes_.clear(); } void MinimizeApp::ClearNodesWithReason(MinimizeReason reason) { WLOGI("[Minimize] ClearNodesWithReason reason %{public}u", reason); std::lock_guard lock(mutex_); if (needMinimizeAppNodes_.find(reason) != needMinimizeAppNodes_.end()) { needMinimizeAppNodes_.at(reason).clear(); } } sptr MinimizeApp::GetRecoverdNodeFromMinimizeList() { WLOGI("[Minimize] RevertMinimizedNodeForTile"); std::lock_guard lock(mutex_); if (needMinimizeAppNodes_.find(MinimizeReason::LAYOUT_TILE) != needMinimizeAppNodes_.end()) { auto& tileNodesForMinimize = needMinimizeAppNodes_.at(MinimizeReason::LAYOUT_TILE); if (!tileNodesForMinimize.empty()) { auto recoverNode = tileNodesForMinimize.back().promote(); tileNodesForMinimize.pop_back(); return recoverNode; } } return nullptr; } bool MinimizeApp::IsNodeNeedMinimize(const sptr& node) { if (node == nullptr) { WLOGFE("[Minimize] node is nullptr"); return false; } for (auto iter : needMinimizeAppNodes_) { auto nodes = iter.second; if (std::find(nodes.begin(), nodes.end(), node) != nodes.end()) { return true; } } return false; } bool MinimizeApp::IsNodeNeedMinimizeWithReason(const sptr& node, MinimizeReason reason) { if (node == nullptr) { WLOGFE("[Minimize] node is nullptr"); return false; } if (needMinimizeAppNodes_.find(reason) == needMinimizeAppNodes_.end()) { WLOGFD("[Minimize] no need to minimize with id:%{public}u reason:%{public}u", node->GetWindowId(), reason); return false; } auto nodes = needMinimizeAppNodes_.at(reason); if (std::find(nodes.begin(), nodes.end(), node) != nodes.end()) { WLOGI("[Minimize] id:%{public}u need to minimize with reason:%{public}u", node->GetWindowId(), reason); return true; } return false; } bool MinimizeApp::EnableMinimize(MinimizeReason reason) { bool isFromUser = IsFromUser(reason); if (!isMinimizedByOtherWindow_ && !isFromUser) { return false; } return true; } void MinimizeApp::ExecuteMinimizeTargetReasons(uint32_t reasons) { std::lock_guard lock(mutex_); while (reasons) { MinimizeReason reason = static_cast(reasons & (~reasons + 1)); if (needMinimizeAppNodes_.find(reason) != needMinimizeAppNodes_.end()) { WLOGI("[Minimize] ExecuteMinimizeTargetReason with size: %{public}zu, reason: %{public}u", needMinimizeAppNodes_.at(reason).size(), reason); bool isFromUser = IsFromUser(reason); for (auto& node : needMinimizeAppNodes_.at(reason)) { WindowInnerManager::GetInstance().MinimizeAbility(node, isFromUser); } needMinimizeAppNodes_.at(reason).clear(); } reasons -= reason; } } void MinimizeApp::SetMinimizedByOtherConfig(bool isMinimizedByOther) { isMinimizedByOtherWindow_ = isMinimizedByOther; } } // Rosen } // OHOS