1ba5c3796Sopenharmony_ci/* 2ba5c3796Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3ba5c3796Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4ba5c3796Sopenharmony_ci * you may not use this file except in compliance with the License. 5ba5c3796Sopenharmony_ci * You may obtain a copy of the License at 6ba5c3796Sopenharmony_ci * 7ba5c3796Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8ba5c3796Sopenharmony_ci * 9ba5c3796Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10ba5c3796Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11ba5c3796Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12ba5c3796Sopenharmony_ci * See the License for the specific language governing permissions and 13ba5c3796Sopenharmony_ci * limitations under the License. 14ba5c3796Sopenharmony_ci */ 15ba5c3796Sopenharmony_ci 16ba5c3796Sopenharmony_ci#include "window_visibility_observer.h" 17ba5c3796Sopenharmony_ci 18ba5c3796Sopenharmony_ci#include "event_handler.h" 19ba5c3796Sopenharmony_ci#include "memmgr_log.h" 20ba5c3796Sopenharmony_ci#include "memmgr_ptr_util.h" 21ba5c3796Sopenharmony_ci#include "singleton.h" 22ba5c3796Sopenharmony_ci 23ba5c3796Sopenharmony_cinamespace OHOS { 24ba5c3796Sopenharmony_cinamespace Memory { 25ba5c3796Sopenharmony_cinamespace { 26ba5c3796Sopenharmony_ciconst std::string TAG = "WindowVisibilityObserver"; 27ba5c3796Sopenharmony_ciconst std::string WINDOW_OBSERVER_HANDLER = "WindowVisibilityObserverHandler"; 28ba5c3796Sopenharmony_ciconstexpr int TIMER_PEROID_MIN = 5; 29ba5c3796Sopenharmony_ciconstexpr int TIMER_PEROID_MS = TIMER_PEROID_MIN * 60 * 1000; 30ba5c3796Sopenharmony_ciconstexpr int TRIGGER_BY_TIME = 1; 31ba5c3796Sopenharmony_ciconstexpr int TRIGGER_BY_SIZE = 2; 32ba5c3796Sopenharmony_ci} 33ba5c3796Sopenharmony_ci 34ba5c3796Sopenharmony_ciIMPLEMENT_SINGLE_INSTANCE(WindowVisibilityObserver); 35ba5c3796Sopenharmony_ci 36ba5c3796Sopenharmony_ciWindowVisibilityObserver::WindowVisibilityObserver() 37ba5c3796Sopenharmony_ci{ 38ba5c3796Sopenharmony_ci if (!handler_) { 39ba5c3796Sopenharmony_ci MAKE_POINTER(handler_, shared, AppExecFwk::EventHandler, "failed to create event handler", return, 40ba5c3796Sopenharmony_ci AppExecFwk::EventRunner::Create()); 41ba5c3796Sopenharmony_ci } 42ba5c3796Sopenharmony_ci SetTimer(); 43ba5c3796Sopenharmony_ci} 44ba5c3796Sopenharmony_ci 45ba5c3796Sopenharmony_civoid WindowVisibilityObserver::OnProcessDied(int pid) 46ba5c3796Sopenharmony_ci{ 47ba5c3796Sopenharmony_ci HILOGD("called"); 48ba5c3796Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 49ba5c3796Sopenharmony_ci windowVisibleMap_.erase(pid); 50ba5c3796Sopenharmony_ci HILOGD("remove pid=%{public}d from WindowVisibilityObserver", pid); 51ba5c3796Sopenharmony_ci} 52ba5c3796Sopenharmony_ci 53ba5c3796Sopenharmony_civoid WindowVisibilityObserver::UpdateWindowVisibilityPriority( 54ba5c3796Sopenharmony_ci const std::vector<sptr<MemMgrWindowInfo>> &memMgrWindowInfo) 55ba5c3796Sopenharmony_ci{ 56ba5c3796Sopenharmony_ci HILOGD("called"); 57ba5c3796Sopenharmony_ci handler_->PostImmediateTask([this, memMgrWindowInfo] { 58ba5c3796Sopenharmony_ci this->UpdateWindowVisibilityPriorityInner(memMgrWindowInfo); 59ba5c3796Sopenharmony_ci }); 60ba5c3796Sopenharmony_ci} 61ba5c3796Sopenharmony_ci 62ba5c3796Sopenharmony_civoid WindowVisibilityObserver::UpdateWindowVisibilityPriorityInner( 63ba5c3796Sopenharmony_ci const std::vector<sptr<MemMgrWindowInfo>> &MemMgrWindowInfo) 64ba5c3796Sopenharmony_ci{ 65ba5c3796Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 66ba5c3796Sopenharmony_ci for (auto &info : MemMgrWindowInfo) { 67ba5c3796Sopenharmony_ci if (!info) { 68ba5c3796Sopenharmony_ci continue; 69ba5c3796Sopenharmony_ci } 70ba5c3796Sopenharmony_ci auto windowId = info->windowId_; 71ba5c3796Sopenharmony_ci auto isVisible = info->isVisible_; 72ba5c3796Sopenharmony_ci auto pid = info->pid_; 73ba5c3796Sopenharmony_ci auto uid = info->uid_; 74ba5c3796Sopenharmony_ci HILOGI("MemMgrWindowInfo[pid=%{public}d, uid=%{public}d, winId=%{public}d, visible=%{public}d]", 75ba5c3796Sopenharmony_ci pid, uid, windowId, isVisible); 76ba5c3796Sopenharmony_ci if (isVisible) { 77ba5c3796Sopenharmony_ci auto windowInfoPtr = windowVisibleMap_.find(pid); 78ba5c3796Sopenharmony_ci if (windowInfoPtr != windowVisibleMap_.end()) { 79ba5c3796Sopenharmony_ci windowInfoPtr->second.visibleWindowIds.insert(windowId); 80ba5c3796Sopenharmony_ci } else { 81ba5c3796Sopenharmony_ci ProcessWindowVisibilityInfo info; 82ba5c3796Sopenharmony_ci info.uid = uid; 83ba5c3796Sopenharmony_ci info.visible = false; 84ba5c3796Sopenharmony_ci info.visibleWindowIds.insert(windowId); 85ba5c3796Sopenharmony_ci windowVisibleMap_.insert(std::make_pair(pid, info)); 86ba5c3796Sopenharmony_ci } 87ba5c3796Sopenharmony_ci } else { 88ba5c3796Sopenharmony_ci auto windowInfoPtr = windowVisibleMap_.find(pid); 89ba5c3796Sopenharmony_ci if (windowInfoPtr != windowVisibleMap_.end()) { 90ba5c3796Sopenharmony_ci windowInfoPtr->second.visibleWindowIds.erase(windowId); 91ba5c3796Sopenharmony_ci } 92ba5c3796Sopenharmony_ci } 93ba5c3796Sopenharmony_ci } 94ba5c3796Sopenharmony_ci 95ba5c3796Sopenharmony_ci HILOGI("windowVisibleMap_size=%{public}zu", windowVisibleMap_.size()); 96ba5c3796Sopenharmony_ci UpdatePriorityForVisible(windowVisibleMap_); 97ba5c3796Sopenharmony_ci if (windowVisibleMap_.size() >= 2048) { //2048: max process num 98ba5c3796Sopenharmony_ci if (handler_) { 99ba5c3796Sopenharmony_ci handler_->PostImmediateTask([this] { this->CheckMapSize(TRIGGER_BY_SIZE); }); 100ba5c3796Sopenharmony_ci } 101ba5c3796Sopenharmony_ci } 102ba5c3796Sopenharmony_ci} 103ba5c3796Sopenharmony_ci 104ba5c3796Sopenharmony_civoid WindowVisibilityObserver::UpdatePriorityForVisible( 105ba5c3796Sopenharmony_ci std::map<int32_t, ProcessWindowVisibilityInfo> &windowVisibleMap_) 106ba5c3796Sopenharmony_ci{ 107ba5c3796Sopenharmony_ci std::vector<unsigned int> toBeDeleted; 108ba5c3796Sopenharmony_ci ReclaimHandleRequest request; 109ba5c3796Sopenharmony_ci for (auto &pair : windowVisibleMap_) { 110ba5c3796Sopenharmony_ci ProcessWindowVisibilityInfo &info = pair.second; 111ba5c3796Sopenharmony_ci if (info.visibleWindowIds.size() > 0 && info.visible == false) { 112ba5c3796Sopenharmony_ci info.visible = true; 113ba5c3796Sopenharmony_ci ReclaimPriorityManager::GetInstance().UpdateReclaimPriority( 114ba5c3796Sopenharmony_ci SingleRequest({pair.first, info.uid, "", ""}, AppStateUpdateReason::VISIBLE)); 115ba5c3796Sopenharmony_ci } else if (info.visibleWindowIds.size() == 0) { 116ba5c3796Sopenharmony_ci if (info.visible == true) { 117ba5c3796Sopenharmony_ci info.visible = false; 118ba5c3796Sopenharmony_ci ReclaimPriorityManager::GetInstance().UpdateReclaimPriority( 119ba5c3796Sopenharmony_ci SingleRequest({pair.first, info.uid, "", ""}, AppStateUpdateReason::UN_VISIBLE)); 120ba5c3796Sopenharmony_ci } 121ba5c3796Sopenharmony_ci toBeDeleted.push_back(pair.first); 122ba5c3796Sopenharmony_ci } 123ba5c3796Sopenharmony_ci HILOGD("ProcessWindowVisibilityInfo[pid=%{public}d, uid=%{public}d, vWins=%{public}zu," 124ba5c3796Sopenharmony_ci "visible=%{public}d]", pair.first, info.uid, info.visibleWindowIds.size(), info.visible); 125ba5c3796Sopenharmony_ci } 126ba5c3796Sopenharmony_ci for (auto pid : toBeDeleted) { 127ba5c3796Sopenharmony_ci windowVisibleMap_.erase(pid); 128ba5c3796Sopenharmony_ci } 129ba5c3796Sopenharmony_ci} 130ba5c3796Sopenharmony_ci 131ba5c3796Sopenharmony_civoid WindowVisibilityObserver::SetTimer() 132ba5c3796Sopenharmony_ci{ 133ba5c3796Sopenharmony_ci //set timer and call CheckMapSize each TIMER_PEROID_MIN min. 134ba5c3796Sopenharmony_ci handler_->PostTask([this] { this->CheckMapSize(TRIGGER_BY_TIME); }, 135ba5c3796Sopenharmony_ci TIMER_PEROID_MS, AppExecFwk::EventQueue::Priority::HIGH); 136ba5c3796Sopenharmony_ci HILOGD("set timer after %{public}d mins", TIMER_PEROID_MIN); 137ba5c3796Sopenharmony_ci} 138ba5c3796Sopenharmony_ci 139ba5c3796Sopenharmony_civoid WindowVisibilityObserver::CheckMapSize(int type) 140ba5c3796Sopenharmony_ci{ 141ba5c3796Sopenharmony_ci HILOGD("called"); 142ba5c3796Sopenharmony_ci 143ba5c3796Sopenharmony_ci std::vector<unsigned int> alivePids; 144ba5c3796Sopenharmony_ci if (!KernelInterface::GetInstance().GetAllProcPids(alivePids)) { 145ba5c3796Sopenharmony_ci return; 146ba5c3796Sopenharmony_ci } 147ba5c3796Sopenharmony_ci 148ba5c3796Sopenharmony_ci std::vector<unsigned int> toBeDeleted; 149ba5c3796Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 150ba5c3796Sopenharmony_ci for (auto &pair : windowVisibleMap_) { 151ba5c3796Sopenharmony_ci auto pid = pair.first; 152ba5c3796Sopenharmony_ci if (std::find(alivePids.begin(), alivePids.end(), pid) == alivePids.end()) { 153ba5c3796Sopenharmony_ci toBeDeleted.push_back(pid); 154ba5c3796Sopenharmony_ci } 155ba5c3796Sopenharmony_ci } 156ba5c3796Sopenharmony_ci 157ba5c3796Sopenharmony_ci for (auto pid : toBeDeleted) { 158ba5c3796Sopenharmony_ci windowVisibleMap_.erase(pid); 159ba5c3796Sopenharmony_ci } 160ba5c3796Sopenharmony_ci 161ba5c3796Sopenharmony_ci if (type == TRIGGER_BY_TIME) { 162ba5c3796Sopenharmony_ci SetTimer(); 163ba5c3796Sopenharmony_ci } 164ba5c3796Sopenharmony_ci} 165ba5c3796Sopenharmony_ci} // namespace Memory 166ba5c3796Sopenharmony_ci} // namespace OHOS 167