/* * Copyright (c) 2023 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 "running_lock_proxy.h" #include <cmath> #include "power_log.h" namespace OHOS { namespace PowerMgr { void RunningLockProxy::AddRunningLock(pid_t pid, pid_t uid, const sptr<IRemoteObject>& remoteObj) { std::string proxyKey = AssembleProxyKey(pid, uid); auto proxyIter = proxyMap_.find(proxyKey); if (proxyIter == proxyMap_.end()) { std::vector<sptr<IRemoteObject>> tmpLockList {}; tmpLockList.push_back(remoteObj); std::tie(proxyIter, std::ignore) = proxyMap_.emplace(proxyKey, std::make_pair(tmpLockList, 0)); POWER_HILOGD(FEATURE_RUNNING_LOCK, "Add runninglock proxy, proxyKey=%{public}s", proxyKey.c_str()); } else { auto& remoteObjList = proxyIter->second.first; if (std::find(remoteObjList.begin(), remoteObjList.end(), remoteObj) != remoteObjList.end()) { POWER_HILOGD(FEATURE_RUNNING_LOCK, "Runninglock is existed, proxyKey=%{public}s", proxyKey.c_str()); return; } remoteObjList.push_back(remoteObj); POWER_HILOGD(FEATURE_RUNNING_LOCK, "Insert runninglock, proxyKey=%{public}s", proxyKey.c_str()); } } void RunningLockProxy::RemoveRunningLock(pid_t pid, pid_t uid, const sptr<IRemoteObject>& remoteObj) { std::string proxyKey = AssembleProxyKey(pid, uid); auto proxyIter = proxyMap_.find(proxyKey); if (proxyIter == proxyMap_.end()) { POWER_HILOGI(FEATURE_RUNNING_LOCK, "Runninglock proxyKey is not existed, proxyKey=%{public}s", proxyKey.c_str()); return; } auto& remoteObjList = proxyIter->second.first; auto remoteObjIter = std::find(remoteObjList.begin(), remoteObjList.end(), remoteObj); if (remoteObjIter == remoteObjList.end()) { POWER_HILOGD(FEATURE_RUNNING_LOCK, "Runninglock is not existed, proxyKey=%{public}s", proxyKey.c_str()); return; } remoteObjList.erase(remoteObjIter); if (remoteObjList.empty()) { proxyMap_.erase(proxyKey); POWER_HILOGD(FEATURE_RUNNING_LOCK, "Runninglock list is empty, earse proxyKey=%{public}s", proxyKey.c_str()); } } std::vector<sptr<IRemoteObject>> RunningLockProxy::GetRemoteObjectList(pid_t pid, pid_t uid) { std::string proxyKey = AssembleProxyKey(pid, uid); auto proxyIter = proxyMap_.find(proxyKey); if (proxyIter != proxyMap_.end()) { return proxyIter->second.first; } return std::vector<sptr<IRemoteObject>>(); } bool RunningLockProxy::IsProxied(pid_t pid, pid_t uid) { std::string proxyKey = AssembleProxyKey(pid, uid); auto proxyIter = proxyMap_.find(proxyKey); if (proxyIter == proxyMap_.end()) { return false; } return proxyIter->second.second != 0; } bool RunningLockProxy::IncreaseProxyCnt(pid_t pid, pid_t uid, const std::function<void(void)>& proxyRunningLock) { std::string proxyKey = AssembleProxyKey(pid, uid); auto proxyIter = proxyMap_.find(proxyKey); if (proxyIter == proxyMap_.end()) { std::tie(proxyIter, std::ignore) = proxyMap_.emplace(proxyKey, std::make_pair<std::vector<sptr<IRemoteObject>>, int32_t>({}, 0)); } proxyIter->second.second++; POWER_HILOGI(FEATURE_RUNNING_LOCK, "IncreaseProxyCnt proxykey=%{public}s proxycnt=%{public}d", proxyKey.c_str(), proxyIter->second.second); if (proxyIter->second.second > 1) { return false; } proxyRunningLock(); return true; } bool RunningLockProxy::DecreaseProxyCnt(pid_t pid, pid_t uid, const std::function<void(void)>& unProxyRunningLock) { std::string proxyKey = AssembleProxyKey(pid, uid); auto proxyIter = proxyMap_.find(proxyKey); if (proxyIter == proxyMap_.end()) { return false; } proxyIter->second.second = std::max(0, proxyIter->second.second - 1); POWER_HILOGI(FEATURE_RUNNING_LOCK, "DecreaseProxyCnt proxykey=%{public}s proxycnt=%{public}d", proxyKey.c_str(), proxyIter->second.second); if (proxyIter->second.second > 0) { return false; } if (proxyIter->second.first.empty()) { proxyMap_.erase(proxyIter); } unProxyRunningLock(); return true; } std::string RunningLockProxy::DumpProxyInfo() { std::string result {""}; int index = 0; for (const auto& [key, value] : proxyMap_) { index++; result.append(" index=").append(std::to_string(index)) .append(" pid_uid=").append(key) .append(" lock_cnt=").append(std::to_string(value.first.size())) .append(" proxy_cnt=").append(std::to_string(value.second)).append("\n"); } return result; } void RunningLockProxy::ResetRunningLocks() { POWER_HILOGI(FEATURE_RUNNING_LOCK, "reset proxycnt"); for (auto proxyIter = proxyMap_.begin(); proxyIter != proxyMap_.end();) { proxyIter->second.second = 0; if (proxyIter->second.first.empty()) { proxyMap_.erase(proxyIter++); } else { proxyIter++; } } } void RunningLockProxy::Clear() { proxyMap_.clear(); } std::string RunningLockProxy::AssembleProxyKey(pid_t pid, pid_t uid) { return std::to_string(pid) + "_" + std::to_string(uid); } } // namespace PowerMgr } // namespace OHOS