1c29fa5a6Sopenharmony_ci/* 2c29fa5a6Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3c29fa5a6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4c29fa5a6Sopenharmony_ci * you may not use this file except in compliance with the License. 5c29fa5a6Sopenharmony_ci * You may obtain a copy of the License at 6c29fa5a6Sopenharmony_ci * 7c29fa5a6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8c29fa5a6Sopenharmony_ci * 9c29fa5a6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10c29fa5a6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11c29fa5a6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12c29fa5a6Sopenharmony_ci * See the License for the specific language governing permissions and 13c29fa5a6Sopenharmony_ci * limitations under the License. 14c29fa5a6Sopenharmony_ci */ 15c29fa5a6Sopenharmony_ci 16c29fa5a6Sopenharmony_ci#include "client_death_handler.h" 17c29fa5a6Sopenharmony_ci#include "mmi_log.h" 18c29fa5a6Sopenharmony_ci 19c29fa5a6Sopenharmony_ci#undef MMI_LOG_TAG 20c29fa5a6Sopenharmony_ci#define MMI_LOG_TAG "ClientDeathHandler" 21c29fa5a6Sopenharmony_ci 22c29fa5a6Sopenharmony_cinamespace OHOS { 23c29fa5a6Sopenharmony_cinamespace MMI { 24c29fa5a6Sopenharmony_ciClientDeathHandler::ClientDeathHandler() {} 25c29fa5a6Sopenharmony_ci 26c29fa5a6Sopenharmony_ciClientDeathHandler::~ClientDeathHandler() {} 27c29fa5a6Sopenharmony_ci 28c29fa5a6Sopenharmony_cibool ClientDeathHandler::RegisterClientDeathRecipient(const sptr<IRemoteObject> &binderClientSrv, int32_t pid) 29c29fa5a6Sopenharmony_ci{ 30c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 31c29fa5a6Sopenharmony_ci if (!RegisterClientDeathRecipient(binderClientSrv)) { 32c29fa5a6Sopenharmony_ci return false; 33c29fa5a6Sopenharmony_ci } 34c29fa5a6Sopenharmony_ci if (!AddClientPid(binderClientSrv, pid)) { 35c29fa5a6Sopenharmony_ci return false; 36c29fa5a6Sopenharmony_ci } 37c29fa5a6Sopenharmony_ci return true; 38c29fa5a6Sopenharmony_ci} 39c29fa5a6Sopenharmony_ci 40c29fa5a6Sopenharmony_cibool ClientDeathHandler::AddClientDeathCallback(CallBackType type, ClientDeathCallback callback) 41c29fa5a6Sopenharmony_ci{ 42c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 43c29fa5a6Sopenharmony_ci CHKPF(callback); 44c29fa5a6Sopenharmony_ci std::lock_guard<std::mutex> callBackLock(mutexCallbacks_); 45c29fa5a6Sopenharmony_ci [[ maybe_unused ]] bool bFind = false; 46c29fa5a6Sopenharmony_ci auto it = deathCallbacks_.find(type); 47c29fa5a6Sopenharmony_ci if (it != deathCallbacks_.end()) { 48c29fa5a6Sopenharmony_ci MMI_HILOGE("Death callBack has existed type:%{public}d", type); 49c29fa5a6Sopenharmony_ci return false; 50c29fa5a6Sopenharmony_ci } 51c29fa5a6Sopenharmony_ci deathCallbacks_.insert(std::make_pair(type, callback)); 52c29fa5a6Sopenharmony_ci return true; 53c29fa5a6Sopenharmony_ci} 54c29fa5a6Sopenharmony_ci 55c29fa5a6Sopenharmony_cibool ClientDeathHandler::UnregisterClientDeathRecipient(const wptr<IRemoteObject> &remoteObj) 56c29fa5a6Sopenharmony_ci{ 57c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 58c29fa5a6Sopenharmony_ci CHKPF(remoteObj); 59c29fa5a6Sopenharmony_ci CHKPF(deathRecipient_); 60c29fa5a6Sopenharmony_ci return remoteObj->RemoveDeathRecipient(deathRecipient_); 61c29fa5a6Sopenharmony_ci} 62c29fa5a6Sopenharmony_ci 63c29fa5a6Sopenharmony_civoid ClientDeathHandler::RemoveClientDeathCallback(CallBackType type) 64c29fa5a6Sopenharmony_ci{ 65c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 66c29fa5a6Sopenharmony_ci std::lock_guard<std::mutex> callBackLock(mutexCallbacks_); 67c29fa5a6Sopenharmony_ci deathCallbacks_.erase(type); 68c29fa5a6Sopenharmony_ci} 69c29fa5a6Sopenharmony_ci 70c29fa5a6Sopenharmony_civoid ClientDeathHandler::OnDeath(const wptr<IRemoteObject> &remoteObj) 71c29fa5a6Sopenharmony_ci{ 72c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 73c29fa5a6Sopenharmony_ci CHKPV(remoteObj); 74c29fa5a6Sopenharmony_ci auto sptrRemote = sptr<IRemoteObject>(remoteObj.GetRefPtr()); 75c29fa5a6Sopenharmony_ci CHKPV(sptrRemote); 76c29fa5a6Sopenharmony_ci int32_t pid = FindClientPid(sptrRemote); 77c29fa5a6Sopenharmony_ci if (pid == INVALID_PID) { 78c29fa5a6Sopenharmony_ci MMI_HILOGE("Failed to found pid"); 79c29fa5a6Sopenharmony_ci } else { 80c29fa5a6Sopenharmony_ci NotifyDeath(pid); 81c29fa5a6Sopenharmony_ci } 82c29fa5a6Sopenharmony_ci UnregisterClientDeathRecipient(remoteObj); 83c29fa5a6Sopenharmony_ci RemoveClientPid(pid); 84c29fa5a6Sopenharmony_ci} 85c29fa5a6Sopenharmony_ci 86c29fa5a6Sopenharmony_cibool ClientDeathHandler::RegisterClientDeathRecipient(const sptr<IRemoteObject> &binderClientSrv) 87c29fa5a6Sopenharmony_ci{ 88c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 89c29fa5a6Sopenharmony_ci std::lock_guard<std::mutex> clientDeathLock(mutexDeathRecipient_); 90c29fa5a6Sopenharmony_ci CHKPF(binderClientSrv); 91c29fa5a6Sopenharmony_ci auto deathCallback = [this](const wptr<IRemoteObject> &object) { 92c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 93c29fa5a6Sopenharmony_ci OnDeath(object); 94c29fa5a6Sopenharmony_ci }; 95c29fa5a6Sopenharmony_ci if (deathRecipient_ == nullptr) { 96c29fa5a6Sopenharmony_ci deathRecipient_ = new (std::nothrow) InputBinderClientDeathRecipient(deathCallback); 97c29fa5a6Sopenharmony_ci } 98c29fa5a6Sopenharmony_ci CHKPF(deathRecipient_); 99c29fa5a6Sopenharmony_ci if (!binderClientSrv->AddDeathRecipient(deathRecipient_)) { 100c29fa5a6Sopenharmony_ci MMI_HILOGE("Failed to add death recipient"); 101c29fa5a6Sopenharmony_ci return false; 102c29fa5a6Sopenharmony_ci } 103c29fa5a6Sopenharmony_ci return true; 104c29fa5a6Sopenharmony_ci} 105c29fa5a6Sopenharmony_ci 106c29fa5a6Sopenharmony_cibool ClientDeathHandler::AddClientPid(const sptr<IRemoteObject> &binderClientSrv, int32_t pid) 107c29fa5a6Sopenharmony_ci{ 108c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 109c29fa5a6Sopenharmony_ci CHKPF(binderClientSrv); 110c29fa5a6Sopenharmony_ci std::lock_guard<std::mutex> lockPidMap(mutexPidMap_); 111c29fa5a6Sopenharmony_ci auto it = clientPidMap_.find(pid); 112c29fa5a6Sopenharmony_ci if (it == clientPidMap_.end()) { 113c29fa5a6Sopenharmony_ci MMI_HILOGI("Insert Death recipient pid:%{public}d has existed", pid); 114c29fa5a6Sopenharmony_ci } 115c29fa5a6Sopenharmony_ci clientPidMap_.insert(std::make_pair(pid, binderClientSrv)); 116c29fa5a6Sopenharmony_ci return true; 117c29fa5a6Sopenharmony_ci} 118c29fa5a6Sopenharmony_ci 119c29fa5a6Sopenharmony_civoid ClientDeathHandler::RemoveClientPid(int32_t pid) 120c29fa5a6Sopenharmony_ci{ 121c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 122c29fa5a6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutexPidMap_); 123c29fa5a6Sopenharmony_ci auto it = clientPidMap_.begin(); 124c29fa5a6Sopenharmony_ci while (it != clientPidMap_.end()) { 125c29fa5a6Sopenharmony_ci if (it->first == pid) { 126c29fa5a6Sopenharmony_ci clientPidMap_.erase(it); 127c29fa5a6Sopenharmony_ci break; 128c29fa5a6Sopenharmony_ci } 129c29fa5a6Sopenharmony_ci it++; 130c29fa5a6Sopenharmony_ci } 131c29fa5a6Sopenharmony_ci} 132c29fa5a6Sopenharmony_ci 133c29fa5a6Sopenharmony_ciint32_t ClientDeathHandler::FindClientPid(const sptr<IRemoteObject> &binderClientSrv) 134c29fa5a6Sopenharmony_ci{ 135c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 136c29fa5a6Sopenharmony_ci CHKPR(binderClientSrv, INVALID_PID); 137c29fa5a6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutexPidMap_); 138c29fa5a6Sopenharmony_ci std::vector<int32_t> pids; 139c29fa5a6Sopenharmony_ci auto it = clientPidMap_.begin(); 140c29fa5a6Sopenharmony_ci for (; it != clientPidMap_.end(); it++) { 141c29fa5a6Sopenharmony_ci if (it->second == binderClientSrv) { 142c29fa5a6Sopenharmony_ci pids.push_back(it->first); 143c29fa5a6Sopenharmony_ci } 144c29fa5a6Sopenharmony_ci } 145c29fa5a6Sopenharmony_ci if (pids.size() > 0) { 146c29fa5a6Sopenharmony_ci if (pids.size() > 1) { 147c29fa5a6Sopenharmony_ci MMI_HILOGI("Found one remote to many %{public}zu pid", pids.size()); 148c29fa5a6Sopenharmony_ci } 149c29fa5a6Sopenharmony_ci return pids[0]; 150c29fa5a6Sopenharmony_ci } 151c29fa5a6Sopenharmony_ci return INVALID_PID; 152c29fa5a6Sopenharmony_ci} 153c29fa5a6Sopenharmony_civoid ClientDeathHandler::NotifyDeath(int32_t pid) 154c29fa5a6Sopenharmony_ci{ 155c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 156c29fa5a6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutexCallbacks_); 157c29fa5a6Sopenharmony_ci auto it = deathCallbacks_.begin(); 158c29fa5a6Sopenharmony_ci for (; it != deathCallbacks_.end(); it++) { 159c29fa5a6Sopenharmony_ci CHKPC(it->second); 160c29fa5a6Sopenharmony_ci (it->second)(pid); 161c29fa5a6Sopenharmony_ci } 162c29fa5a6Sopenharmony_ci} 163c29fa5a6Sopenharmony_ci} // namespace MMI 164c29fa5a6Sopenharmony_ci} // namespace OHOS 165