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