1 /*
2  * Copyright (C) 2021 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 "ipc_object_proxy.h"
17 
18 #include <cstdint>
19 
20 #include "__mutex_base"
21 #include "algorithm"
22 #include "backtrace_local.h"
23 #include "errors.h"
24 #include "hilog/log_c.h"
25 #include "hilog/log_cpp.h"
26 #include "iosfwd"
27 #include "ipc_debug.h"
28 #include "ipc_process_skeleton.h"
29 #include "ipc_thread_skeleton.h"
30 #include "ipc_types.h"
31 #include "iremote_invoker.h"
32 #include "iremote_object.h"
33 #include "log_tags.h"
34 #include "message_option.h"
35 #include "message_parcel.h"
36 #include "mutex"
37 #include "process_skeleton.h"
38 #include "refbase.h"
39 #include "string"
40 #include "string_ex.h"
41 #include "type_traits"
42 #include "unistd.h"
43 #include "vector"
44 
45 #ifndef CONFIG_IPC_SINGLE
46 #include "access_token_adapter.h"
47 #include "dbinder_databus_invoker.h"
48 #endif
49 
50 namespace OHOS {
51 #ifdef CONFIG_IPC_SINGLE
52 using namespace IPC_SINGLE;
53 #endif
54 
55 #define PRINT_SEND_REQUEST_FAIL_INFO(handle, error, desc, proxy) \
56     uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(   \
57         std::chrono::steady_clock::now().time_since_epoch()).count());                               \
58     ZLOGE(LABEL, "failed, handle:%{public}d error:%{public}d desc:%{public}s proxy:%{public}u time:%{public}" PRIu64, \
59         handle, error, (desc).c_str(), proxy, curTime)
60 
61 using namespace OHOS::HiviewDFX;
62 static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC_PROXY, "IPCObjectProxy" };
63 static constexpr int SEND_REQUEST_TIMEOUT = 2000;
64 
IPCObjectProxy(int handle,std::u16string descriptor,int proto)65 IPCObjectProxy::IPCObjectProxy(int handle, std::u16string descriptor, int proto)
66     : IRemoteObject(std::move(descriptor)), handle_(handle), proto_(proto), isFinishInit_(false), isRemoteDead_(false)
67 {
68     ZLOGD(LABEL, "handle:%{public}u desc:%{public}s %{public}u", handle_,
69         ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str(), ProcessSkeleton::ConvertAddr(this));
70     ExtendObjectLifetime();
71     ProcessSkeleton *current = ProcessSkeleton::GetInstance();
72     if (current == nullptr) {
73         ZLOGE(LABEL, "ProcessSkeleton is null");
74         return;
75     }
76     std::u16string str(descriptor_);
77     current->AttachValidObject(this, str);
78 }
79 
~IPCObjectProxy()80 IPCObjectProxy::~IPCObjectProxy()
81 {
82     std::string desc;
83     {
84         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
85         ZLOGD(LABEL, "handle:%{public}u desc:%{public}s %{public}u", handle_,
86             ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)).c_str(),
87             ProcessSkeleton::ConvertAddr(this));
88         desc = Str16ToStr8(remoteDescriptor_);
89     }
90     if (desc == "ohos.aafwk.AbilityToken" || desc == "ohos.aafwk.AbilityManager") {
91         ZLOGI(LABEL, "destroy handle:%{public}u desc:%{public}s %{public}u", handle_,
92             ProcessSkeleton::ConvertToSecureDesc(desc).c_str(), ProcessSkeleton::ConvertAddr(this));
93     }
94     auto pos = desc.find("IVpnStateCallback");
95     if (pos != std::string::npos) {
96         ZLOGI(LABEL, "handle:%{public}u desc:%{public}s %{public}u", handle_,
97             ProcessSkeleton::ConvertToSecureDesc(desc).c_str(), ProcessSkeleton::ConvertAddr(this));
98     }
99     ProcessSkeleton *current = ProcessSkeleton::GetInstance();
100     if (current == nullptr) {
101         ZLOGE(LABEL, "ProcessSkeleton is null");
102         return;
103     }
104     current->DetachValidObject(this);
105     // for map clean
106     {
107         std::lock_guard<std::recursive_mutex> lock(mutex_);
108         if (!recipients_.empty()) {
109             recipients_.clear();
110         }
111     }
112 }
113 
GetObjectRefCount()114 int32_t IPCObjectProxy::GetObjectRefCount()
115 {
116     MessageParcel data, reply;
117     MessageOption option;
118     int err = SendRequestInner(false, SYNCHRONIZE_REFERENCE, data, reply, option);
119     if (err == ERR_NONE) {
120         return reply.ReadInt32();
121     }
122     {
123         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
124         PRINT_SEND_REQUEST_FAIL_INFO(handle_, err,
125             ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)),
126             ProcessSkeleton::ConvertAddr(this));
127     }
128     return 0;
129 }
130 
Dump(int fd,const std::vector<std::u16string> & args)131 int IPCObjectProxy::Dump(int fd, const std::vector<std::u16string> &args)
132 {
133     MessageParcel data, reply;
134     MessageOption option { MessageOption::TF_SYNC };
135     data.WriteFileDescriptor(fd);
136     data.WriteString16Vector(args);
137     return SendRequestInner(false, DUMP_TRANSACTION, data, reply, option);
138 }
139 
SendRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)140 int IPCObjectProxy::SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
141 {
142     if (code != DUMP_TRANSACTION && code > MAX_TRANSACTION_ID) {
143         return IPC_PROXY_INVALID_CODE_ERR;
144     }
145     std::string desc;
146     {
147         std::unique_lock<std::shared_mutex> lockGuard(descMutex_);
148         if (remoteDescriptor_.empty()) {
149             remoteDescriptor_ = data.GetInterfaceToken();
150         }
151         desc = Str16ToStr8(remoteDescriptor_);
152     }
153     if (desc == "ohos.aafwk.AbilityManager") {
154         ZLOGI(LABEL, "handle:%{public}u desc:%{public}s refcnt:%{public}d %{public}u", handle_,
155             ProcessSkeleton::ConvertToSecureDesc(desc).c_str(), GetSptrRefCount(), ProcessSkeleton::ConvertAddr(this));
156     }
157 
158     auto beginTime = std::chrono::steady_clock::now();
159     int err = SendRequestInner(false, code, data, reply, option);
160     auto endTime = std::chrono::steady_clock::now();
161     auto timeInterval = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - beginTime).count();
162     if (timeInterval > SEND_REQUEST_TIMEOUT) {
163         ZLOGW(LABEL, "DFX_BlockMonitor IPC cost %{public}lld ms, interface code:%{public}u, desc:%{public}s",
164             timeInterval, code, ProcessSkeleton::ConvertToSecureDesc(desc).c_str());
165     }
166     if (err != ERR_NONE && ProcessSkeleton::IsPrint(err, lastErr_, lastErrCnt_)) {
167         PRINT_SEND_REQUEST_FAIL_INFO(handle_, err, ProcessSkeleton::ConvertToSecureDesc(desc),
168             ProcessSkeleton::ConvertAddr(this));
169         if (err == BR_FAILED_REPLY) {
170             std::string backtrace;
171             if (!GetBacktrace(backtrace, false)) {
172                 ZLOGE(LABEL, "GetBacktrace fail");
173             } else {
174                 ZLOGW(LABEL, "backtrace info:\n%{public}s", backtrace.c_str());
175             }
176         }
177     }
178     return err;
179 }
180 
SendLocalRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)181 int IPCObjectProxy::SendLocalRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
182 {
183     return SendRequestInner(true, code, data, reply, option);
184 }
185 
SendRequestInner(bool isLocal,uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)186 int IPCObjectProxy::SendRequestInner(bool isLocal, uint32_t code, MessageParcel &data, MessageParcel &reply,
187     MessageOption &option)
188 {
189     if (IsObjectDead()) {
190         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
191         ZLOGD(LABEL, "proxy is already dead, handle:%{public}d desc:%{public}s",
192             handle_, ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)).c_str());
193         return ERR_DEAD_OBJECT;
194     }
195 
196     IRemoteInvoker *invoker = nullptr;
197     if (isLocal) {
198         invoker = IPCThreadSkeleton::GetDefaultInvoker();
199     } else {
200         invoker = IPCThreadSkeleton::GetRemoteInvoker(proto_);
201     }
202     if (invoker == nullptr) {
203         ZLOGE(LABEL, "invoker is null, handle:%{public}u proto:%{public}d", handle_, proto_);
204         return ERR_NULL_OBJECT;
205     }
206 
207     IPCThreadSkeleton::UpdateSendRequestCount(1);
208     int status = invoker->SendRequest(handle_, code, data, reply, option);
209     if (status == ERR_DEAD_OBJECT) {
210         SetObjectDied(true);
211     }
212     IPCThreadSkeleton::UpdateSendRequestCount(-1);
213     return status;
214 }
215 
GetInterfaceDescriptor()216 std::u16string IPCObjectProxy::GetInterfaceDescriptor()
217 {
218     if (!interfaceDesc_.empty()) {
219         return interfaceDesc_;
220     }
221     if (handle_ == 0) {
222         ZLOGD(LABEL, "handle == 0, do nothing");
223         return std::u16string();
224     }
225 
226     MessageParcel data, reply;
227     MessageOption option;
228     std::string desc;
229     {
230         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
231         desc = Str16ToStr8(remoteDescriptor_);
232     }
233     if (desc == "ohos.aafwk.AbilityToken") {
234         ZLOGI(LABEL, "handle:%{public}u desc:%{public}s refcnt:%{public}d %{public}u", handle_,
235             ProcessSkeleton::ConvertToSecureDesc(desc).c_str(), GetSptrRefCount(), ProcessSkeleton::ConvertAddr(this));
236     }
237 
238     int err = SendRequestInner(false, INTERFACE_TRANSACTION, data, reply, option);
239     if (err != ERR_NONE) {
240         PRINT_SEND_REQUEST_FAIL_INFO(handle_, err, ProcessSkeleton::ConvertToSecureDesc(desc),
241             ProcessSkeleton::ConvertAddr(this));
242         return std::u16string();
243     }
244     interfaceDesc_ = reply.ReadString16();
245 
246     return interfaceDesc_;
247 }
248 
GetSessionName()249 std::string IPCObjectProxy::GetSessionName()
250 {
251     MessageParcel data, reply;
252     MessageOption option;
253 
254     int err = SendRequestInner(false, GET_SESSION_NAME, data, reply, option);
255     if (err != ERR_NONE) {
256         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
257         PRINT_SEND_REQUEST_FAIL_INFO(handle_, err,
258             ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)),
259             ProcessSkeleton::ConvertAddr(this));
260         return std::string("");
261     }
262     return reply.ReadString();
263 }
264 
GetGrantedSessionName()265 std::string IPCObjectProxy::GetGrantedSessionName()
266 {
267     MessageParcel data, reply;
268     MessageOption option;
269 
270     int err = SendRequestInner(false, GET_GRANTED_SESSION_NAME, data, reply, option);
271     if (err != ERR_NONE) {
272         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
273         PRINT_SEND_REQUEST_FAIL_INFO(handle_, err,
274             ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)),
275             ProcessSkeleton::ConvertAddr(this));
276         return std::string("");
277     }
278 
279     if (reply.ReadUint32() != IRemoteObject::IF_PROT_DATABUS) {
280         ZLOGE(LABEL, "GetDataBusName normal binder");
281         return std::string("");
282     }
283 
284     return reply.ReadString();
285 }
286 
GetSessionNameForPidUid(uint32_t uid,uint32_t pid)287 std::string IPCObjectProxy::GetSessionNameForPidUid(uint32_t uid, uint32_t pid)
288 {
289     if (pid == static_cast<uint32_t>(getpid())) {
290         ZLOGE(LABEL, "TransDataBusName can't write local pid. my/remotePid:%{public}u/%{public}u", getpid(), pid);
291         return std::string("");
292     }
293 
294     MessageParcel data, reply;
295     MessageOption option;
296     if (!data.WriteUint32(pid) || !data.WriteUint32(uid)) {
297         ZLOGE(LABEL, "TransDataBusName write pid/uid:%{public}u/%{public}u failed", pid, uid);
298         return std::string("");
299     }
300     int err = SendRequestInner(false, GET_SESSION_NAME_PID_UID, data, reply, option);
301     if (err != ERR_NONE) {
302         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
303         PRINT_SEND_REQUEST_FAIL_INFO(handle_, err,
304             ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)),
305             ProcessSkeleton::ConvertAddr(this));
306         return std::string("");
307     }
308 
309     if (reply.ReadUint32() != IRemoteObject::IF_PROT_DATABUS) {
310         ZLOGE(LABEL, "TransDataBusName normal binder");
311         return std::string("");
312     }
313 
314     return reply.ReadString();
315 }
316 
RemoveSessionName(const std::string & sessionName)317 int IPCObjectProxy::RemoveSessionName(const std::string &sessionName)
318 {
319     MessageParcel data, reply;
320     MessageOption option { MessageOption::TF_ASYNC };
321     if (!data.WriteString(sessionName)) {
322         ZLOGE(LABEL, "write parcel fail, sessionName:%{public}s", sessionName.c_str());
323         return IPC_PROXY_WRITE_PARCEL_ERR;
324     }
325     int err = SendRequestInner(false, REMOVE_SESSION_NAME, data, reply, option);
326     if (err != ERR_NONE) {
327         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
328         PRINT_SEND_REQUEST_FAIL_INFO(handle_, err,
329             ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)),
330             ProcessSkeleton::ConvertAddr(this));
331     }
332     return err;
333 }
334 
GetPidUid(MessageParcel & reply)335 int IPCObjectProxy::GetPidUid(MessageParcel &reply)
336 {
337     MessageParcel data;
338     MessageOption option;
339 
340     return SendRequestInner(true, GET_PID_UID, data, reply, option);
341 }
342 
OnFirstStrongRef(const void * objectId)343 void IPCObjectProxy::OnFirstStrongRef(const void *objectId)
344 {
345     // IPC proxy: AcquireHandle->AttachObject
346     IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
347     if (invoker != nullptr) {
348         invoker->AcquireHandle(handle_);
349     }
350 }
351 
WaitForInit(const void * dbinderData)352 void IPCObjectProxy::WaitForInit(const void *dbinderData)
353 {
354     std::string desc;
355     {
356         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
357         desc = Str16ToStr8(remoteDescriptor_);
358     }
359     // RPC proxy: AcquireHandle->AttachObject->Open Session->IncRef to Remote Stub
360     {
361         std::lock_guard<std::mutex> lockGuard(initMutex_);
362         // When remote stub is gone, handle is reclaimed. But mapping from this handle to
363         // proxy may still exist before OnLastStrongRef called. If so, in FindOrNewObject
364         // we may find the same proxy that has been marked as dead. Thus, we need to check again.
365         if (IsObjectDead()) {
366             ZLOGW(LABEL, "proxy is dead, init again, handle:%{public}d desc:%{public}s",
367                 handle_, ProcessSkeleton::ConvertToSecureDesc(desc).c_str());
368             SetObjectDied(false);
369             isFinishInit_ = false;
370         }
371 
372         if (!isFinishInit_) {
373 #ifndef CONFIG_IPC_SINGLE
374             if (!UpdateProto(dbinderData)) {
375                 return;
376             }
377 #endif
378             isFinishInit_ = true;
379         } else {
380 #ifndef CONFIG_IPC_SINGLE
381             // Anoymous rpc proxy need to update proto anyway because ownership of session
382             // corresponding to this handle has been marked as null in TranslateRemoteHandleType
383             if (proto_ == IRemoteObject::IF_PROT_DATABUS) {
384                 if (!CheckHaveSession()) {
385                     SetProto(IRemoteObject::IF_PROT_ERROR);
386                     SetObjectDied(true);
387                 }
388             }
389 #endif
390         }
391     }
392 #ifndef CONFIG_IPC_SINGLE
393     if (proto_ == IRemoteObject::IF_PROT_DATABUS) {
394         if (IncRefToRemote() != ERR_NONE) {
395             SetProto(IRemoteObject::IF_PROT_ERROR);
396             SetObjectDied(true);
397         }
398     }
399 #endif
400 }
401 
OnLastStrongRef(const void * objectId)402 void IPCObjectProxy::OnLastStrongRef(const void *objectId)
403 {
404     // IPC proxy: DetachObject->ReleaseHandle
405     // RPC proxy: DecRef to Remote Stub->Close Session->DetachObject->ReleaseHandle
406     std::string desc;
407     {
408         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
409         desc = Str16ToStr8(remoteDescriptor_);
410     }
411     if (desc == "ohos.aafwk.AbilityToken" || desc == "ohos.aafwk.AbilityManager") {
412         ZLOGI(LABEL, "handle:%{public}u desc:%{public}s %{public}u", handle_,
413             ProcessSkeleton::ConvertToSecureDesc(desc).c_str(), ProcessSkeleton::ConvertAddr(this));
414     }
415     ZLOGD(LABEL, "handle:%{public}u proto:%{public}d", handle_, proto_);
416     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
417     if (current == nullptr) {
418         ZLOGE(LABEL, "skeleton is null");
419         return;
420     }
421 #ifndef CONFIG_IPC_SINGLE
422     ReleaseProto();
423 #endif
424     ClearDeathRecipients();
425     // This proxy is going to be destroyed, so we need to decrease refcount of binder_ref.
426     // It may has been replace with a new proxy, thus we have no need to check result.
427     IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
428     if (invoker != nullptr) {
429         invoker->ReleaseHandle(handle_);
430     }
431     current->DetachObject(this);
432 }
433 
SetObjectDied(bool isDied)434 void IPCObjectProxy::SetObjectDied(bool isDied)
435 {
436     isRemoteDead_.store(isDied);
437 }
438 
IsObjectDead() const439 bool IPCObjectProxy::IsObjectDead() const
440 {
441     return isRemoteDead_.load();
442 }
443 
AddDeathRecipient(const sptr<DeathRecipient> & recipient)444 bool IPCObjectProxy::AddDeathRecipient(const sptr<DeathRecipient> &recipient)
445 {
446     if (recipient == nullptr) {
447         ZLOGE(LABEL, "recipient is null");
448         return false;
449     }
450     std::string desc;
451     {
452         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
453         desc = Str16ToStr8(remoteDescriptor_);
454     }
455     std::lock_guard<std::recursive_mutex> lock(mutex_);
456     if (IsObjectDead()) {
457         ZLOGE(LABEL, "proxy is already dead, handle:%{public}d desc:%{public}s",
458             handle_, ProcessSkeleton::ConvertToSecureDesc(desc).c_str());
459         return false;
460     }
461     sptr<DeathRecipientAddrInfo> info = new DeathRecipientAddrInfo(recipient);
462     if (info == nullptr || info->soPath_.empty()) {
463         ZLOGE(LABEL, "invalid object, info is nullptr:%{public}d", info == nullptr);
464         return false;
465     }
466     recipients_.push_back(info);
467     if (recipients_.size() > 1 || handle_ >= IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
468         ZLOGD(LABEL, "death recipient is already registered, handle:%{public}d desc:%{public}s",
469             handle_, ProcessSkeleton::ConvertToSecureDesc(desc).c_str());
470         return true;
471     }
472     if (!RegisterBinderDeathRecipient()) {
473         ZLOGE(LABEL, "register failed, handle:%{public}d desc:%{public}s addr:%{public}u", handle_,
474             ProcessSkeleton::ConvertToSecureDesc(desc).c_str(), ProcessSkeleton::ConvertAddr(this));
475         recipients_.pop_back();
476     }
477     ZLOGD(LABEL, "success, handle:%{public}d desc:%{public}s %{public}u", handle_,
478         ProcessSkeleton::ConvertToSecureDesc(desc).c_str(), ProcessSkeleton::ConvertAddr(this));
479     return true;
480 }
481 
RemoveDeathRecipient(const sptr<DeathRecipient> & recipient)482 bool IPCObjectProxy::RemoveDeathRecipient(const sptr<DeathRecipient> &recipient)
483 {
484     if (recipient == nullptr) {
485         ZLOGE(LABEL, "recipient is null");
486         return false;
487     }
488     std::string desc;
489     {
490         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
491         desc = Str16ToStr8(remoteDescriptor_);
492     }
493     std::lock_guard<std::recursive_mutex> lock(mutex_);
494     if (IsObjectDead()) {
495         ZLOGD(LABEL, "proxy is already dead, handle:%{public}d desc:%{public}s",
496             handle_, ProcessSkeleton::ConvertToSecureDesc(desc).c_str());
497         return false;
498     }
499     bool recipientErased = false;
500     for (auto iter = recipients_.begin(); iter != recipients_.end(); iter++) {
501         if ((*iter)->recipient_ == recipient) {
502             recipients_.erase(iter);
503             recipientErased = true;
504             break;
505         }
506     }
507     if (handle_ >= IPCProcessSkeleton::DBINDER_HANDLE_BASE && recipientErased == true) {
508         ZLOGI(LABEL, "death recipient is already unregistered, handle:%{public}d desc:%{public}s",
509             handle_, ProcessSkeleton::ConvertToSecureDesc(desc).c_str());
510         return true;
511     }
512 
513     if (recipientErased && recipients_.empty() && !UnRegisterBinderDeathRecipient()) {
514         ZLOGE(LABEL, "unregister failed, handle:%{public}d desc:%{public}s addr:%{public}u",
515             handle_, ProcessSkeleton::ConvertToSecureDesc(desc).c_str(), ProcessSkeleton::ConvertAddr(this));
516     }
517 
518     ZLOGD(LABEL, "handle:%{public}d desc:%{public}s addr:%{public}u, result:%{public}d", handle_,
519         ProcessSkeleton::ConvertToSecureDesc(desc).c_str(), ProcessSkeleton::ConvertAddr(this), recipientErased);
520     return recipientErased;
521 }
522 
SendObituary()523 void IPCObjectProxy::SendObituary()
524 {
525     {
526         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
527         ZLOGW(LABEL, "handle:%{public}d desc:%{public}s %{public}u", handle_,
528             ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)).c_str(),
529             ProcessSkeleton::ConvertAddr(this));
530     }
531 
532 #ifndef CONFIG_IPC_SINGLE
533     if (handle_ < IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
534         if (proto_ == IRemoteObject::IF_PROT_DATABUS || proto_ == IRemoteObject::IF_PROT_ERROR) {
535             RemoveDbinderDeathRecipient();
536         }
537     }
538 #endif
539     SetObjectDied(true);
540     std::vector<sptr<DeathRecipientAddrInfo>> toBeReport;
541     {
542         std::lock_guard<std::recursive_mutex> lock(mutex_);
543         toBeReport.swap(recipients_);
544     }
545 
546     if (toBeReport.size() > 0 && handle_ < IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
547         IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
548         if (invoker != nullptr) {
549             invoker->RemoveDeathRecipient(handle_, this);
550         } else {
551             ZLOGE(LABEL, "invoker is null");
552         }
553     }
554     for (auto iter = toBeReport.begin(); iter != toBeReport.end(); iter++) {
555         if ((*iter)->IsDlclosed()) {
556             ZLOGE(LABEL, "so has been dlclosed, sopath:%{public}s", (*iter)->soPath_.c_str());
557             continue;
558         }
559         sptr<DeathRecipient> recipient = (*iter)->recipient_;
560         if (recipient != nullptr) {
561             ZLOGD(LABEL, "handle:%{public}u call OnRemoteDied begin", handle_);
562             recipient->OnRemoteDied(this);
563             ZLOGD(LABEL, "handle:%{public}u call OnRemoteDied end", handle_);
564         }
565     }
566 }
567 
ClearDeathRecipients()568 void IPCObjectProxy::ClearDeathRecipients()
569 {
570     std::lock_guard<std::recursive_mutex> lock(mutex_);
571     if (recipients_.empty()) {
572         return;
573     }
574     recipients_.clear();
575     if (handle_ >= IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
576         return;
577     }
578     IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
579     if (invoker != nullptr) {
580         invoker->RemoveDeathRecipient(handle_, this);
581     }
582 #ifndef CONFIG_IPC_SINGLE
583     if (proto_ == IRemoteObject::IF_PROT_DATABUS || proto_ == IRemoteObject::IF_PROT_ERROR) {
584         RemoveDbinderDeathRecipient();
585     }
586 #endif
587 }
588 
GetProto() const589 int IPCObjectProxy::GetProto() const
590 {
591     return proto_;
592 }
593 
NoticeServiceDie()594 int32_t IPCObjectProxy::NoticeServiceDie()
595 {
596     std::string desc;
597     {
598         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
599         desc = Str16ToStr8(remoteDescriptor_);
600     }
601     ZLOGW(LABEL, "handle:%{public}d desc:%{public}s", handle_,
602         ProcessSkeleton::ConvertToSecureDesc(desc).c_str());
603     MessageParcel data;
604     MessageParcel reply;
605     MessageOption option(MessageOption::TF_ASYNC);
606     data.WriteInt32(IRemoteObject::DeathRecipient::NOTICE_DEATH_RECIPIENT);
607 
608     int err = SendLocalRequest(DBINDER_OBITUARY_TRANSACTION, data, reply, option);
609     if (err != ERR_NONE || reply.ReadInt32() != ERR_NONE) {
610         PRINT_SEND_REQUEST_FAIL_INFO(handle_, err, ProcessSkeleton::ConvertToSecureDesc(desc),
611             ProcessSkeleton::ConvertAddr(this));
612         return IPC_PROXY_TRANSACTION_ERR;
613     }
614 
615     return ERR_NONE;
616 }
617 
InvokeListenThread(MessageParcel & data,MessageParcel & reply)618 int IPCObjectProxy::InvokeListenThread(MessageParcel &data, MessageParcel &reply)
619 {
620     MessageOption option;
621     return SendRequestInner(false, INVOKE_LISTEN_THREAD, data, reply, option);
622 }
623 
GetStrongRefCountForStub()624 uint32_t IPCObjectProxy::GetStrongRefCountForStub()
625 {
626     BinderInvoker *invoker = reinterpret_cast<BinderInvoker *>(IPCThreadSkeleton::GetDefaultInvoker());
627     if (invoker == nullptr) {
628         ZLOGE(LABEL, "get default invoker failed");
629         return 0;  // 0 means get failed
630     }
631     return invoker->GetStrongRefCountForStub(handle_);
632 }
633 
634 #ifndef EMULATOR_PLATFORM
CanPromote()635 bool IPCObjectProxy::CanPromote()
636 {
637     return (GetSptrRefCount() > 0);
638 }
639 #endif
640 
641 #ifndef CONFIG_IPC_SINGLE
UpdateProto()642 int IPCObjectProxy::UpdateProto()
643 {
644     int proto = GetProtoInfo();
645     SetProto(proto);
646     return proto;
647 }
648 
UpdateProto(const void * dbinderData)649 bool IPCObjectProxy::UpdateProto(const void *dbinderData)
650 {
651     auto data = reinterpret_cast<const dbinder_negotiation_data *>(dbinderData);
652     if (data != nullptr && data->proto == IRemoteObject::IF_PROT_DATABUS) {
653         dbinderData_ = std::make_unique<uint8_t[]>(sizeof(dbinder_negotiation_data));
654         if (dbinderData_ == nullptr) {
655             SetObjectDied(true);
656             SetProto(IRemoteObject::IF_PROT_ERROR);
657             ZLOGE(LABEL, "malloc dbinderData fail, handle:%{public}d", handle_);
658             return false;
659         }
660         auto tmp = reinterpret_cast<dbinder_negotiation_data *>(dbinderData_.get());
661         *tmp = *data;
662         if (!UpdateDatabusClientSession()) {
663             ZLOGE(LABEL, "UpdateDatabusClientSession fail, handle:%{public}d", handle_);
664             SetObjectDied(true);
665             SetProto(IRemoteObject::IF_PROT_ERROR);
666             dbinderData_ = nullptr;
667             return false;
668         }
669         SetProto(IRemoteObject::IF_PROT_DATABUS);
670         {
671             std::unique_lock<std::shared_mutex> lockGuard(descMutex_);
672             remoteDescriptor_ = data->desc;
673         }
674     } else if (CheckHaveSession()) {
675         SetProto(IRemoteObject::IF_PROT_DATABUS);
676     }
677     return true;
678 }
679 
IncRefToRemote()680 int32_t IPCObjectProxy::IncRefToRemote()
681 {
682     MessageParcel data, reply;
683     MessageOption option;
684 
685     int32_t err = SendRequestInner(false, DBINDER_INCREFS_TRANSACTION, data, reply, option);
686     if (err != ERR_NONE) {
687         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
688         PRINT_SEND_REQUEST_FAIL_INFO(handle_, err,
689             ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)),
690             ProcessSkeleton::ConvertAddr(this));
691         // do nothing
692     }
693     return err;
694 }
695 
696 
ReleaseProto()697 void IPCObjectProxy::ReleaseProto()
698 {
699     switch (GetProto()) {
700         case IRemoteObject::IF_PROT_BINDER: {
701             ReleaseBinderProto();
702             break;
703         }
704         case IRemoteObject::IF_PROT_DATABUS:
705         case IRemoteObject::IF_PROT_ERROR: {
706             ReleaseDatabusProto();
707             break;
708         }
709         default: {
710             ZLOGE(LABEL, "release invalid proto:%{public}d", proto_);
711             break;
712         }
713     }
714 }
715 
SetProto(int proto)716 void IPCObjectProxy::SetProto(int proto)
717 {
718     proto_ = proto;
719 }
720 
GetProtoInfo()721 int IPCObjectProxy::GetProtoInfo()
722 {
723     if (CheckHaveSession()) {
724         return IRemoteObject::IF_PROT_DATABUS;
725     }
726     if (handle_ >= IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
727         ZLOGE(LABEL, "cannot find session for handle:%{public}u", handle_);
728         return IRemoteObject::IF_PROT_ERROR;
729     }
730 
731     MessageParcel data, reply;
732     MessageOption option;
733     int err = SendRequestInner(true, GET_PROTO_INFO, data, reply, option);
734     if (err != ERR_NONE && err != -EBADMSG) {
735         uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
736             std::chrono::steady_clock::now().time_since_epoch()).count());
737         ZLOGW(LABEL, "GET_PROTO_INFO transact return error:%{public}d handle:%{public}u time:%{public}" PRIu64,
738             err, handle_, curTime);
739         return IRemoteObject::IF_PROT_ERROR;
740     }
741 
742     switch (reply.ReadUint32()) {
743         case IRemoteObject::IF_PROT_BINDER: {
744             std::unique_lock<std::shared_mutex> lockGuard(descMutex_);
745             remoteDescriptor_ = reply.ReadString16();
746             ZLOGD(LABEL, "binder, handle:%{public}u desc:%{public}s",
747                 handle_, ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)).c_str());
748             break;
749         }
750         case IRemoteObject::IF_PROT_DATABUS: {
751             if (UpdateDatabusClientSession(handle_, reply)) {
752                 std::unique_lock<std::shared_mutex> lockGuard(descMutex_);
753                 remoteDescriptor_ = reply.ReadString16();
754                 ZLOGD(LABEL, "dbinder, handle:%{public}u desc:%{public}s",
755                     handle_, ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)).c_str());
756                 return IRemoteObject::IF_PROT_DATABUS;
757             } else {
758                 ZLOGE(LABEL, "UpdateDatabusClientSession failed");
759                 return IRemoteObject::IF_PROT_ERROR;
760             }
761         }
762         default: {
763             ZLOGE(LABEL, "get Invalid proto");
764             return IRemoteObject::IF_PROT_ERROR;
765         }
766     }
767 
768     return IRemoteObject::IF_PROT_BINDER;
769 }
770 
AddDbinderDeathRecipient()771 bool IPCObjectProxy::AddDbinderDeathRecipient()
772 {
773     std::string desc;
774     std::u16string remoteDescriptorTmp;
775     {
776         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
777         remoteDescriptorTmp = remoteDescriptor_;
778         desc = Str16ToStr8(remoteDescriptor_);
779     }
780     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
781     if (current == nullptr) {
782         ZLOGW(LABEL, "get current fail, handle:%{public}d desc:%{public}s",
783             handle_, ProcessSkeleton::ConvertToSecureDesc(desc).c_str());
784         return false;
785     }
786 
787     if (current->QueryCallbackStub(this) != nullptr) {
788         ZLOGW(LABEL, "already attach callback stub, handle:%{public}d desc:%{public}s",
789             handle_, ProcessSkeleton::ConvertToSecureDesc(desc).c_str());
790         return true;
791     }
792 
793     //note that cannot use this proxy's descriptor
794     sptr<IPCObjectStub> callbackStub = new (std::nothrow) IPCObjectStub(u"DbinderDeathRecipient" + remoteDescriptorTmp);
795     if (callbackStub == nullptr) {
796         ZLOGE(LABEL, "create IPCObjectStub object failed, handle:%{public}d desc:%{public}s",
797             handle_, ProcessSkeleton::ConvertToSecureDesc(desc).c_str());
798         return false;
799     }
800     if (!current->AttachCallbackStub(this, callbackStub)) {
801         ZLOGW(LABEL, "already attach new callback stub, handle:%{public}d desc:%{public}s",
802             handle_, ProcessSkeleton::ConvertToSecureDesc(desc).c_str());
803         return false;
804     }
805 
806     MessageParcel data;
807     MessageParcel reply;
808     MessageOption option(MessageOption::TF_SYNC);
809     data.WriteInt32(IRemoteObject::DeathRecipient::ADD_DEATH_RECIPIENT);
810     data.WriteRemoteObject(callbackStub);
811 
812     int err = SendLocalRequest(DBINDER_OBITUARY_TRANSACTION, data, reply, option);
813     if (err != ERR_NONE) {
814         PRINT_SEND_REQUEST_FAIL_INFO(handle_, err, ProcessSkeleton::ConvertToSecureDesc(desc),
815             ProcessSkeleton::ConvertAddr(this));
816         current->DetachCallbackStub(this);
817         return false;
818     }
819 
820     return true;
821 }
822 
RemoveDbinderDeathRecipient()823 bool IPCObjectProxy::RemoveDbinderDeathRecipient()
824 {
825     std::string desc;
826     {
827         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
828         desc = Str16ToStr8(remoteDescriptor_);
829     }
830     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
831     if (current == nullptr) {
832         ZLOGE(LABEL, "get current fail");
833         return false;
834     }
835     ZLOGW(LABEL, "handle:%{public}d desc:%{public}s", handle_,
836         ProcessSkeleton::ConvertToSecureDesc(desc).c_str());
837     sptr<IPCObjectStub> callbackStub = current->DetachCallbackStub(this);
838     if (callbackStub == nullptr) {
839         ZLOGE(LABEL, "get callbackStub fail, handle:%{public}d desc:%{public}s",
840             handle_, ProcessSkeleton::ConvertToSecureDesc(desc).c_str());
841         return false;
842     }
843 
844     MessageParcel data;
845     MessageParcel reply;
846     MessageOption option(MessageOption::TF_SYNC);
847     data.WriteInt32(IRemoteObject::DeathRecipient::REMOVE_DEATH_RECIPIENT);
848     data.WriteRemoteObject(callbackStub);
849 
850     int err = SendLocalRequest(DBINDER_OBITUARY_TRANSACTION, data, reply, option);
851     if (err != ERR_NONE) {
852         PRINT_SEND_REQUEST_FAIL_INFO(handle_, err, ProcessSkeleton::ConvertToSecureDesc(desc),
853             ProcessSkeleton::ConvertAddr(this));
854         // do nothing, even send request failed
855     }
856     return err == ERR_NONE;
857 }
858 
CheckHaveSession()859 bool IPCObjectProxy::CheckHaveSession()
860 {
861     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
862     if (current == nullptr) {
863         ZLOGE(LABEL, "IPCProcessSkeleton is null");
864         return false;
865     }
866 
867     return current->ProxyMoveDBinderSession(handle_, this);
868 }
869 
MakeDBinderTransSession(const DBinderNegotiationData & data)870 bool IPCObjectProxy::MakeDBinderTransSession(const DBinderNegotiationData &data)
871 {
872     DBinderDatabusInvoker *invoker =
873         reinterpret_cast<DBinderDatabusInvoker *>(IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS));
874     if (invoker == nullptr) {
875         ZLOGE(LABEL, "invoker is null");
876         return false;
877     }
878     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
879     if (current == nullptr) {
880         ZLOGE(LABEL, "skeleton is nullptr");
881         return false;
882     }
883     if (data.peerServiceName.empty()) {
884         ZLOGE(LABEL, "serviceName is empty");
885         return false;
886     }
887 
888     auto dbinderSession = std::make_shared<DBinderSessionObject>(
889         data.peerServiceName, data.peerDeviceId, data.stubIndex, this, data.peerTokenId);
890     if (dbinderSession == nullptr) {
891         ZLOGE(LABEL, "make DBinderSessionObject fail!");
892         return false;
893     }
894     dbinderSession->SetPeerPid(data.peerPid);
895     dbinderSession->SetPeerUid(data.peerUid);
896 
897     if (!current->CreateSoftbusServer(data.localServiceName)) {
898         ZLOGE(LABEL, "CreateSoftbusServer fail, name:%{public}s localID:%{public}s", data.localServiceName.c_str(),
899             IPCProcessSkeleton::ConvertToSecureString(data.localDeviceId).c_str());
900         return false;
901     }
902     if (!invoker->UpdateClientSession(dbinderSession)) {
903         // no need to remove softbus server
904         ZLOGE(LABEL, "UpdateClientSession fail!");
905         return false;
906     }
907     if (!current->ProxyAttachDBinderSession(handle_, dbinderSession)) {
908         // should not get here
909         ZLOGW(LABEL, "ProxyAttachDBinderSession fail for handle:%{public}d, maybe a concurrent scenarios", handle_);
910         if (current->QuerySessionByInfo(data.peerServiceName, data.peerDeviceId) == nullptr) {
911             ZLOGE(LABEL, "session is not exist, service:%{public}s devId:%{public}s",
912                 data.peerServiceName.c_str(), IPCProcessSkeleton::ConvertToSecureString(data.peerDeviceId).c_str());
913             dbinderSession->CloseDatabusSession();
914             return false;
915         }
916     }
917     ZLOGI(LABEL, "succ");
918     return true;
919 }
920 
GetDBinderNegotiationData(int handle,MessageParcel & reply,DBinderNegotiationData & dbinderData)921 int IPCObjectProxy::GetDBinderNegotiationData(int handle, MessageParcel &reply,
922     DBinderNegotiationData &dbinderData)
923 {
924     dbinderData.stubIndex = reply.ReadUint64();
925     dbinderData.peerServiceName = reply.ReadString();
926     dbinderData.peerDeviceId = reply.ReadString();
927     dbinderData.localDeviceId = reply.ReadString();
928     dbinderData.localServiceName = reply.ReadString();
929     dbinderData.peerTokenId = reply.ReadUint32();
930     if (dbinderData.peerServiceName.empty() || dbinderData.peerDeviceId.empty() ||
931         dbinderData.localDeviceId.empty() || dbinderData.localServiceName.empty()) {
932         ZLOGE(LABEL, "invalid param");
933         return ERR_INVALID_DATA;
934     }
935 
936     std::string str = dbinderData.peerServiceName.substr(DBINDER_SOCKET_NAME_PREFIX.length());
937     std::string::size_type pos = str.find("_");
938     if (pos == str.npos) {
939         ZLOGE(LABEL, "ServiceName format error");
940         return ERR_INVALID_DATA;
941     }
942     dbinderData.peerUid = std::stoi(str.substr(0, pos));
943     dbinderData.peerPid = std::stoi(str.substr(pos + 1));
944     return ERR_NONE;
945 }
946 
UpdateDatabusClientSession(int handle,MessageParcel & reply)947 bool IPCObjectProxy::UpdateDatabusClientSession(int handle, MessageParcel &reply)
948 {
949     DBinderNegotiationData dbinderData;
950     if (GetDBinderNegotiationData(handle, reply, dbinderData) != ERR_NONE) {
951         return false;
952     }
953     return MakeDBinderTransSession(dbinderData);
954 }
955 
GetDBinderNegotiationData(DBinderNegotiationData & dbinderData)956 int IPCObjectProxy::GetDBinderNegotiationData(DBinderNegotiationData &dbinderData)
957 {
958     if (dbinderData_ == nullptr) {
959         ZLOGE(LABEL, "dbinderData_ is null");
960         return ERR_INVALID_DATA;
961     }
962     auto data = reinterpret_cast<const dbinder_negotiation_data *>(dbinderData_.get());
963     dbinderData.stubIndex = data->stub_index;
964     dbinderData.peerServiceName = data->target_name;
965     dbinderData.peerDeviceId = data->target_device;
966     dbinderData.localDeviceId = data->local_device;
967     dbinderData.localServiceName = data->local_name;
968     dbinderData.peerTokenId = data->tokenid;
969 
970     std::string str = dbinderData.peerServiceName.substr(DBINDER_SOCKET_NAME_PREFIX.length());
971     std::string::size_type pos = str.find("_");
972     if (pos == str.npos) {
973         ZLOGW(LABEL, "ServiceName format error");
974         return ERR_INVALID_DATA;
975     }
976     dbinderData.peerUid = std::stoi(str.substr(0, pos));
977     dbinderData.peerPid = std::stoi(str.substr(pos + 1));
978     return ERR_NONE;
979 }
980 
UpdateDatabusClientSession()981 bool IPCObjectProxy::UpdateDatabusClientSession()
982 {
983     DBinderNegotiationData dbinderData;
984     if (GetDBinderNegotiationData(dbinderData) != ERR_NONE) {
985         return false;
986     }
987     return MakeDBinderTransSession(dbinderData);
988 }
989 
ReleaseDatabusProto()990 void IPCObjectProxy::ReleaseDatabusProto()
991 {
992     if (handle_ == 0) {
993         ZLOGW(LABEL, "handle == 0, do nothing");
994         return;
995     }
996 
997     MessageParcel data, reply;
998     MessageOption option = { MessageOption::TF_ASYNC };
999     int err = SendRequestInner(false, DBINDER_DECREFS_TRANSACTION, data, reply, option);
1000     if (err != ERR_NONE) {
1001         std::shared_lock<std::shared_mutex> lockGuard(descMutex_);
1002         PRINT_SEND_REQUEST_FAIL_INFO(handle_, err,
1003             ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(remoteDescriptor_)),
1004             ProcessSkeleton::ConvertAddr(this));
1005         // do nothing, if this cmd failed, stub's refcount will be decreased when OnSessionClosed called
1006     }
1007 
1008     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
1009     if (current == nullptr) {
1010         ZLOGE(LABEL, "release databus proto skeleton is null");
1011         return;
1012     }
1013     std::shared_ptr<DBinderSessionObject> toBeDelete = current->ProxyDetachDBinderSession(handle_, this);
1014     if (toBeDelete != nullptr &&
1015         // make sure session corresponding to this sessionName and deviceId is no longer used by other proxy
1016         current->QuerySessionByInfo(toBeDelete->GetServiceName(), toBeDelete->GetDeviceId()) == nullptr) {
1017         // close session in lock
1018         toBeDelete->CloseDatabusSession();
1019     }
1020 }
1021 
ReleaseBinderProto()1022 void IPCObjectProxy::ReleaseBinderProto()
1023 {
1024     // do nothing
1025 }
1026 #endif
1027 
RegisterBinderDeathRecipient()1028 bool IPCObjectProxy::RegisterBinderDeathRecipient()
1029 {
1030     IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
1031     if (invoker == nullptr) {
1032         ZLOGE(LABEL, "invoker is null");
1033         return false;
1034     }
1035     if (!invoker->AddDeathRecipient(handle_, this)) {
1036         ZLOGE(LABEL, "add failed, handle:%{public}d", handle_);
1037         return false;
1038     }
1039 #ifndef CONFIG_IPC_SINGLE
1040     if (proto_ == IRemoteObject::IF_PROT_DATABUS && !AddDbinderDeathRecipient()) {
1041         ZLOGE(LABEL, "add failed, handle:%{public}d", handle_);
1042         return false;
1043     }
1044 #endif
1045     ZLOGD(LABEL, "success, handle:%{public}d", handle_);
1046     return true;
1047 }
1048 
UnRegisterBinderDeathRecipient()1049 bool IPCObjectProxy::UnRegisterBinderDeathRecipient()
1050 {
1051     IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
1052     if (invoker == nullptr) {
1053         ZLOGE(LABEL, "invoker is null");
1054         return false;
1055     }
1056 
1057     bool dbinderStatus = true;
1058     bool status = invoker->RemoveDeathRecipient(handle_, this);
1059 #ifndef CONFIG_IPC_SINGLE
1060     if (proto_ == IRemoteObject::IF_PROT_DATABUS || proto_ == IRemoteObject::IF_PROT_ERROR) {
1061         dbinderStatus = RemoveDbinderDeathRecipient();
1062     }
1063 #endif
1064     ZLOGD(LABEL, "unregister result:%{public}d, handle:%{public}d",
1065         status && dbinderStatus, handle_);
1066     return status && dbinderStatus;
1067 }
1068 
DeathRecipientAddrInfo(const sptr<DeathRecipient> & recipient)1069 IPCObjectProxy::DeathRecipientAddrInfo::DeathRecipientAddrInfo(const sptr<DeathRecipient> &recipient)
1070     : recipient_(recipient), soFuncAddr_(nullptr), soPath_()
1071 {
1072     if (recipient_ == nullptr) {
1073         ZLOGD(LABEL, "recipient is null");
1074         return;
1075     }
1076     soFuncAddr_ = reinterpret_cast<void *>(GET_FIRST_VIRTUAL_FUNC_ADDR(recipient_.GetRefPtr()));
1077     soPath_ = GetNewSoPath();
1078 }
1079 
GetNewSoPath()1080 std::string IPCObjectProxy::DeathRecipientAddrInfo::GetNewSoPath()
1081 {
1082     if (soFuncAddr_ == nullptr) {
1083         ZLOGE(LABEL, "empty function addr");
1084         return "";
1085     }
1086 
1087     Dl_info info;
1088     int32_t ret = dladdr(soFuncAddr_, &info);
1089     if ((ret == 0) || (info.dli_fname == nullptr)) {
1090         ZLOGE(LABEL, "dladdr failed ret:%{public}d", ret);
1091         return "";
1092     }
1093     return info.dli_fname;
1094 }
1095 
IsDlclosed()1096 bool IPCObjectProxy::DeathRecipientAddrInfo::IsDlclosed()
1097 {
1098     std::string newSoPath = GetNewSoPath();
1099     if (newSoPath.empty() || (newSoPath != soPath_)) {
1100         return true;
1101     }
1102     return false;
1103 }
1104 } // namespace OHOS
1105