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