1 /* 2 * Copyright (c) 2024 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 "client_death_handler.h" 17 #include "mmi_log.h" 18 19 #undef MMI_LOG_TAG 20 #define MMI_LOG_TAG "ClientDeathHandler" 21 22 namespace OHOS { 23 namespace MMI { ClientDeathHandler()24 ClientDeathHandler::ClientDeathHandler() {} 25 ~ClientDeathHandler()26 ClientDeathHandler::~ClientDeathHandler() {} 27 RegisterClientDeathRecipient(const sptr<IRemoteObject> & binderClientSrv,int32_t pid)28 bool ClientDeathHandler::RegisterClientDeathRecipient(const sptr<IRemoteObject> &binderClientSrv, int32_t pid) 29 { 30 CALL_DEBUG_ENTER; 31 if (!RegisterClientDeathRecipient(binderClientSrv)) { 32 return false; 33 } 34 if (!AddClientPid(binderClientSrv, pid)) { 35 return false; 36 } 37 return true; 38 } 39 AddClientDeathCallback(CallBackType type,ClientDeathCallback callback)40 bool ClientDeathHandler::AddClientDeathCallback(CallBackType type, ClientDeathCallback callback) 41 { 42 CALL_DEBUG_ENTER; 43 CHKPF(callback); 44 std::lock_guard<std::mutex> callBackLock(mutexCallbacks_); 45 [[ maybe_unused ]] bool bFind = false; 46 auto it = deathCallbacks_.find(type); 47 if (it != deathCallbacks_.end()) { 48 MMI_HILOGE("Death callBack has existed type:%{public}d", type); 49 return false; 50 } 51 deathCallbacks_.insert(std::make_pair(type, callback)); 52 return true; 53 } 54 UnregisterClientDeathRecipient(const wptr<IRemoteObject> & remoteObj)55 bool ClientDeathHandler::UnregisterClientDeathRecipient(const wptr<IRemoteObject> &remoteObj) 56 { 57 CALL_DEBUG_ENTER; 58 CHKPF(remoteObj); 59 CHKPF(deathRecipient_); 60 return remoteObj->RemoveDeathRecipient(deathRecipient_); 61 } 62 RemoveClientDeathCallback(CallBackType type)63 void ClientDeathHandler::RemoveClientDeathCallback(CallBackType type) 64 { 65 CALL_DEBUG_ENTER; 66 std::lock_guard<std::mutex> callBackLock(mutexCallbacks_); 67 deathCallbacks_.erase(type); 68 } 69 OnDeath(const wptr<IRemoteObject> & remoteObj)70 void ClientDeathHandler::OnDeath(const wptr<IRemoteObject> &remoteObj) 71 { 72 CALL_DEBUG_ENTER; 73 CHKPV(remoteObj); 74 auto sptrRemote = sptr<IRemoteObject>(remoteObj.GetRefPtr()); 75 CHKPV(sptrRemote); 76 int32_t pid = FindClientPid(sptrRemote); 77 if (pid == INVALID_PID) { 78 MMI_HILOGE("Failed to found pid"); 79 } else { 80 NotifyDeath(pid); 81 } 82 UnregisterClientDeathRecipient(remoteObj); 83 RemoveClientPid(pid); 84 } 85 RegisterClientDeathRecipient(const sptr<IRemoteObject> & binderClientSrv)86 bool ClientDeathHandler::RegisterClientDeathRecipient(const sptr<IRemoteObject> &binderClientSrv) 87 { 88 CALL_DEBUG_ENTER; 89 std::lock_guard<std::mutex> clientDeathLock(mutexDeathRecipient_); 90 CHKPF(binderClientSrv); 91 auto deathCallback = [this](const wptr<IRemoteObject> &object) { 92 CALL_DEBUG_ENTER; 93 OnDeath(object); 94 }; 95 if (deathRecipient_ == nullptr) { 96 deathRecipient_ = new (std::nothrow) InputBinderClientDeathRecipient(deathCallback); 97 } 98 CHKPF(deathRecipient_); 99 if (!binderClientSrv->AddDeathRecipient(deathRecipient_)) { 100 MMI_HILOGE("Failed to add death recipient"); 101 return false; 102 } 103 return true; 104 } 105 AddClientPid(const sptr<IRemoteObject> & binderClientSrv,int32_t pid)106 bool ClientDeathHandler::AddClientPid(const sptr<IRemoteObject> &binderClientSrv, int32_t pid) 107 { 108 CALL_DEBUG_ENTER; 109 CHKPF(binderClientSrv); 110 std::lock_guard<std::mutex> lockPidMap(mutexPidMap_); 111 auto it = clientPidMap_.find(pid); 112 if (it == clientPidMap_.end()) { 113 MMI_HILOGI("Insert Death recipient pid:%{public}d has existed", pid); 114 } 115 clientPidMap_.insert(std::make_pair(pid, binderClientSrv)); 116 return true; 117 } 118 RemoveClientPid(int32_t pid)119 void ClientDeathHandler::RemoveClientPid(int32_t pid) 120 { 121 CALL_DEBUG_ENTER; 122 std::lock_guard<std::mutex> lock(mutexPidMap_); 123 auto it = clientPidMap_.begin(); 124 while (it != clientPidMap_.end()) { 125 if (it->first == pid) { 126 clientPidMap_.erase(it); 127 break; 128 } 129 it++; 130 } 131 } 132 FindClientPid(const sptr<IRemoteObject> & binderClientSrv)133 int32_t ClientDeathHandler::FindClientPid(const sptr<IRemoteObject> &binderClientSrv) 134 { 135 CALL_DEBUG_ENTER; 136 CHKPR(binderClientSrv, INVALID_PID); 137 std::lock_guard<std::mutex> lock(mutexPidMap_); 138 std::vector<int32_t> pids; 139 auto it = clientPidMap_.begin(); 140 for (; it != clientPidMap_.end(); it++) { 141 if (it->second == binderClientSrv) { 142 pids.push_back(it->first); 143 } 144 } 145 if (pids.size() > 0) { 146 if (pids.size() > 1) { 147 MMI_HILOGI("Found one remote to many %{public}zu pid", pids.size()); 148 } 149 return pids[0]; 150 } 151 return INVALID_PID; 152 } NotifyDeath(int32_t pid)153 void ClientDeathHandler::NotifyDeath(int32_t pid) 154 { 155 CALL_DEBUG_ENTER; 156 std::lock_guard<std::mutex> lock(mutexCallbacks_); 157 auto it = deathCallbacks_.begin(); 158 for (; it != deathCallbacks_.end(); it++) { 159 CHKPC(it->second); 160 (it->second)(pid); 161 } 162 } 163 } // namespace MMI 164 } // namespace OHOS 165