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