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