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 "errors.h"
23 #include "hilog/log_c.h"
24 #include "hilog/log_cpp.h"
25 #include "iosfwd"
26 #include "ipc_debug.h"
27 #include "ipc_process_skeleton.h"
28 #include "ipc_thread_skeleton.h"
29 #include "ipc_types.h"
30 #include "iremote_invoker.h"
31 #include "iremote_object.h"
32 #include "log_tags.h"
33 #include "message_option.h"
34 #include "message_parcel.h"
35 #include "mutex"
36 #include "refbase.h"
37 #include "string"
38 #include "string_ex.h"
39 #include "type_traits"
40 #include "unistd.h"
41 #include "vector"
42
43 #ifndef CONFIG_IPC_SINGLE
44 #include "access_token_adapter.h"
45 #include "dbinder_databus_invoker.h"
46 #endif
47
48 namespace OHOS {
49 #ifdef CONFIG_IPC_SINGLE
50 using namespace IPC_SINGLE;
51 #endif
52 static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC, "IPCObjectProxy" };
53
IPCObjectProxy(int handle,std::u16string descriptor,int proto)54 IPCObjectProxy::IPCObjectProxy(int handle, std::u16string descriptor, int proto)
55 : IRemoteObject(std::move(descriptor)), handle_(handle), proto_(proto), isFinishInit_(false), isRemoteDead_(false)
56 {
57 ExtendObjectLifetime();
58 ZLOGI(LABEL, "handle = %{public}u create, descriptor: %{public}s", handle_, Str16ToStr8(descriptor_).c_str());
59 }
60
~IPCObjectProxy()61 IPCObjectProxy::~IPCObjectProxy()
62 {
63 ZLOGW(LABEL, "handle = %{public}u destroyed, descriptor: %{public}s", handle_, Str16ToStr8(descriptor_).c_str());
64 }
65
GetObjectRefCount()66 int32_t IPCObjectProxy::GetObjectRefCount()
67 {
68 MessageParcel data, reply;
69 MessageOption option;
70 if (SendRequestInner(false, SYNCHRONIZE_REFERENCE, data, reply, option) == ERR_NONE) {
71 return reply.ReadInt32();
72 }
73 return 0;
74 }
75
Dump(int fd,const std::vector<std::u16string> & args)76 int IPCObjectProxy::Dump(int fd, const std::vector<std::u16string> &args)
77 {
78 MessageParcel data, reply;
79 MessageOption option { MessageOption::TF_SYNC };
80 data.WriteFileDescriptor(fd);
81 data.WriteString16Vector(args);
82 return SendRequestInner(false, DUMP_TRANSACTION, data, reply, option);
83 }
84
SendRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)85 int IPCObjectProxy::SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
86 {
87 if (code != DUMP_TRANSACTION && code > MAX_TRANSACTION_ID) {
88 return IPC_PROXY_INVALID_CODE_ERR;
89 }
90
91 return SendRequestInner(false, code, data, reply, option);
92 }
93
SendLocalRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)94 int IPCObjectProxy::SendLocalRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
95 {
96 return SendRequestInner(true, code, data, reply, option);
97 }
98
SendRequestInner(bool isLocal,uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)99 int IPCObjectProxy::SendRequestInner(bool isLocal, uint32_t code, MessageParcel &data, MessageParcel &reply,
100 MessageOption &option)
101 {
102 if (IsObjectDead()) {
103 return ERR_DEAD_OBJECT;
104 }
105
106 IRemoteInvoker *invoker = nullptr;
107 if (isLocal) {
108 invoker = IPCThreadSkeleton::GetDefaultInvoker();
109 } else {
110 invoker = IPCThreadSkeleton::GetRemoteInvoker(proto_);
111 }
112 if (invoker == nullptr) {
113 ZLOGE(LABEL, "%{public}s: handle: %{public}u, proto: %{public}d, invoker is null", __func__, handle_, proto_);
114 return ERR_NULL_OBJECT;
115 }
116
117 int status = invoker->SendRequest(handle_, code, data, reply, option);
118 if (status == ERR_DEAD_OBJECT) {
119 MarkObjectDied();
120 }
121 return status;
122 }
123
GetInterfaceDescriptor()124 std::u16string IPCObjectProxy::GetInterfaceDescriptor()
125 {
126 if (!remoteDescriptor_.empty()) {
127 return remoteDescriptor_;
128 }
129 if (handle_ == 0) {
130 ZLOGD(LABEL, "handle == 0, do nothing");
131 return std::u16string();
132 }
133
134 MessageParcel data, reply;
135 MessageOption option;
136
137 int err = SendRequestInner(false, INTERFACE_TRANSACTION, data, reply, option);
138 if (err != ERR_NONE) {
139 ZLOGE(LABEL, "send INTERFACE_TRANSACTION cmd failed, error: %{public}d", err);
140 return std::u16string();
141 }
142 remoteDescriptor_ = reply.ReadString16();
143
144 return remoteDescriptor_;
145 }
146
GetSessionName()147 std::string IPCObjectProxy::GetSessionName()
148 {
149 MessageParcel data, reply;
150 MessageOption option;
151
152 int err = SendRequestInner(false, GET_SESSION_NAME, data, reply, option);
153 if (err != ERR_NONE) {
154 ZLOGE(LABEL, "send GET_SESSION_NAME failed, error: %{public}d", err);
155 return std::string("");
156 }
157 return reply.ReadString();
158 }
159
GetGrantedSessionName()160 std::string IPCObjectProxy::GetGrantedSessionName()
161 {
162 MessageParcel data, reply;
163 MessageOption option;
164
165 int err = SendRequestInner(false, GET_GRANTED_SESSION_NAME, data, reply, option);
166 if (err != ERR_NONE) {
167 ZLOGE(LABEL, "send GET_GRANTED_SESSION_NAME failed, error: %{public}d", err);
168 return std::string("");
169 }
170
171 if (reply.ReadUint32() != IRemoteObject::IF_PROT_DATABUS) {
172 ZLOGE(LABEL, "GetDataBusName normal binder");
173 return std::string("");
174 }
175
176 return reply.ReadString();
177 }
178
GetSessionNameForPidUid(uint32_t uid,uint32_t pid)179 std::string IPCObjectProxy::GetSessionNameForPidUid(uint32_t uid, uint32_t pid)
180 {
181 if (pid == static_cast<uint32_t>(getpid())) {
182 ZLOGE(LABEL, "TransDataBusName can't write local pid. my/remotePid = %{public}u/%{public}u", getpid(), pid);
183 return std::string("");
184 }
185
186 MessageParcel data, reply;
187 MessageOption option;
188 if (!data.WriteUint32(pid) || !data.WriteUint32(uid)) {
189 ZLOGE(LABEL, "TransDataBusName write pid/uid = %{public}u/%{public}u failed", pid, uid);
190 return std::string("");
191 }
192 int err = SendRequestInner(false, GET_SESSION_NAME_PID_UID, data, reply, option);
193 if (err != ERR_NONE) {
194 ZLOGE(LABEL, "TransDataBusName transact return error = %{public}d", err);
195 return std::string("");
196 }
197
198 if (reply.ReadUint32() != IRemoteObject::IF_PROT_DATABUS) {
199 ZLOGE(LABEL, "TransDataBusName normal binder");
200 return std::string("");
201 }
202
203 return reply.ReadString();
204 }
205
GetPidUid(MessageParcel & reply)206 int IPCObjectProxy::GetPidUid(MessageParcel &reply)
207 {
208 MessageParcel data;
209 MessageOption option;
210
211 return SendRequestInner(true, GET_PID_UID, data, reply, option);
212 }
213
OnFirstStrongRef(const void * objectId)214 void IPCObjectProxy::OnFirstStrongRef(const void *objectId)
215 {
216 // IPC proxy: AcquireHandle->AttachObject
217 IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
218 if (invoker != nullptr) {
219 invoker->AcquireHandle(handle_);
220 }
221 }
222
WaitForInit()223 void IPCObjectProxy::WaitForInit()
224 {
225 // RPC proxy: AcquireHandle->AttachObject->Open Session->IncRef to Remote Stub
226 {
227 std::lock_guard<std::mutex> lockGuard(initMutex_);
228 // When remote stub is gone, handle is reclaimed. But mapping from this handle to
229 // proxy may still exist before OnLastStrongRef called. If so, in FindOrNewObject
230 // we may find the same proxy that has been marked as dead. Thus, we need to check again.
231 if (IsObjectDead()) {
232 ZLOGW(LABEL, "proxy is dead, init again");
233 isRemoteDead_ = false;
234 isFinishInit_ = false;
235 }
236
237 if (!isFinishInit_) {
238 #ifndef CONFIG_IPC_SINGLE
239 if (UpdateProto() == IRemoteObject::IF_PROT_ERROR) {
240 ZLOGE(LABEL, "UpdateProto get IF_PROT_ERROR");
241 isRemoteDead_ = true;
242 }
243 #endif
244 isFinishInit_ = true;
245 } else {
246 #ifndef CONFIG_IPC_SINGLE
247 // Anoymous rpc proxy need to update proto anyway because ownership of session
248 // corresponding to this handle has been marked as null in TranslateRemoteHandleType
249 if (proto_ == IRemoteObject::IF_PROT_DATABUS) {
250 if (!CheckHaveSession()) {
251 SetProto(IRemoteObject::IF_PROT_ERROR);
252 isRemoteDead_ = true;
253 }
254 }
255 #endif
256 }
257 }
258 #ifndef CONFIG_IPC_SINGLE
259 if (proto_ == IRemoteObject::IF_PROT_DATABUS) {
260 if (IncRefToRemote() != ERR_NONE) {
261 SetProto(IRemoteObject::IF_PROT_ERROR);
262 isRemoteDead_ = true;
263 }
264 }
265 #endif
266 }
267
OnLastStrongRef(const void * objectId)268 void IPCObjectProxy::OnLastStrongRef(const void *objectId)
269 {
270 // IPC proxy: DetachObject->ReleaseHandle
271 // RPC proxy: DecRef to Remote Stub->Close Session->DetachObject->ReleaseHandle
272 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
273 if (current == nullptr) {
274 ZLOGE(LABEL, "OnLastStrongRef skeleton is null");
275 return;
276 }
277 #ifndef CONFIG_IPC_SINGLE
278 ReleaseProto();
279 #endif
280 ClearDeathRecipients();
281 // This proxy is going to be destroyed, so we need to decrease refcount of binder_ref.
282 // It may has been replace with a new proxy, thus we have no need to check result.
283 current->DetachObject(this);
284 IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
285 if (invoker != nullptr) {
286 invoker->ReleaseHandle(handle_);
287 }
288 }
289
290 /* mutex_ should be called before set or get isRemoteDead_ status */
MarkObjectDied()291 void IPCObjectProxy::MarkObjectDied()
292 {
293 isRemoteDead_ = true;
294 }
295
IsObjectDead() const296 bool IPCObjectProxy::IsObjectDead() const
297 {
298 return isRemoteDead_;
299 }
300
AddDeathRecipient(const sptr<DeathRecipient> & recipient)301 bool IPCObjectProxy::AddDeathRecipient(const sptr<DeathRecipient> &recipient)
302 {
303 std::lock_guard<std::recursive_mutex> lock(mutex_);
304 if (IsObjectDead()) {
305 ZLOGW(LABEL, "%{public}s: proxy is already dead", __func__);
306 return false;
307 }
308 recipients_.push_back(recipient);
309 if (recipients_.size() > 1 || handle_ >= IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
310 return true;
311 }
312
313 IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
314 if (invoker == nullptr) {
315 ZLOGE(LABEL, "%{public}s : invoker is null", __func__);
316 return false;
317 }
318
319 if (!invoker->AddDeathRecipient(handle_, this)) {
320 ZLOGE(LABEL, "%{public}s: fail to add binder death recipient", __func__);
321 #ifndef BUILD_PUBLIC_VERSION
322 ReportDriverEvent(DbinderErrorCode::COMMON_DRIVER_ERROR, std::string(DbinderErrorCode::ERROR_TYPE),
323 DbinderErrorCode::IPC_DRIVER, std::string(DbinderErrorCode::ERROR_CODE),
324 DbinderErrorCode::SET_DEATH_RECIPIENT_FAILURE);
325 #endif
326 return false;
327 }
328 #ifndef CONFIG_IPC_SINGLE
329 if (proto_ == IRemoteObject::IF_PROT_DATABUS) {
330 if (!AddDbinderDeathRecipient()) {
331 ZLOGE(LABEL, "%{public}s: failed to add dbinder death recipient", __func__);
332 #ifndef BUILD_PUBLIC_VERSION
333 ReportDriverEvent(DbinderErrorCode::COMMON_DRIVER_ERROR, std::string(DbinderErrorCode::ERROR_TYPE),
334 DbinderErrorCode::RPC_DRIVER, std::string(DbinderErrorCode::ERROR_CODE),
335 DbinderErrorCode::SET_DEATH_RECIPIENT_FAILURE);
336 #endif
337 return false;
338 }
339 }
340 #endif
341 return true;
342 }
343
RemoveDeathRecipient(const sptr<DeathRecipient> & recipient)344 bool IPCObjectProxy::RemoveDeathRecipient(const sptr<DeathRecipient> &recipient)
345 {
346 std::lock_guard<std::recursive_mutex> lock(mutex_);
347
348 if (IsObjectDead()) {
349 ZLOGW(LABEL, "%{public}s: proxy is already dead", __func__);
350 return false;
351 }
352 bool recipientErased = false;
353 auto it = find(recipients_.begin(), recipients_.end(), recipient);
354 if (it != recipients_.end()) {
355 recipients_.erase(it);
356 recipientErased = true;
357 }
358
359 if (handle_ >= IPCProcessSkeleton::DBINDER_HANDLE_BASE && recipientErased == true) {
360 ZLOGW(LABEL, "%{public}s: death recipient is already unregistered", __func__);
361 return true;
362 }
363
364 if (recipientErased && recipients_.empty()) {
365 IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
366 if (invoker == nullptr) {
367 ZLOGE(LABEL, "%{public}s: invoker is null", __func__);
368 return false;
369 }
370
371 bool dbinderStatus = true;
372 bool status = invoker->RemoveDeathRecipient(handle_, this);
373 #ifndef CONFIG_IPC_SINGLE
374 if (proto_ == IRemoteObject::IF_PROT_DATABUS || proto_ == IRemoteObject::IF_PROT_ERROR) {
375 dbinderStatus = RemoveDbinderDeathRecipient();
376 }
377 #endif
378 return status && dbinderStatus;
379 }
380 return recipientErased;
381 }
382
SendObituary()383 void IPCObjectProxy::SendObituary()
384 {
385 ZLOGW(LABEL, "%{public}s: enter, handle: %{public}d", __func__, handle_);
386 #ifndef CONFIG_IPC_SINGLE
387 if (handle_ < IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
388 if (proto_ == IRemoteObject::IF_PROT_DATABUS || proto_ == IRemoteObject::IF_PROT_ERROR) {
389 RemoveDbinderDeathRecipient();
390 }
391 }
392 #endif
393 std::vector<sptr<DeathRecipient>> toBeReport;
394 {
395 std::lock_guard<std::recursive_mutex> lock(mutex_);
396 MarkObjectDied();
397 toBeReport = recipients_;
398 recipients_.clear();
399 }
400
401 if (toBeReport.size() > 0 && handle_ < IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
402 IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
403 if (invoker != nullptr) {
404 invoker->RemoveDeathRecipient(handle_, this);
405 } else {
406 ZLOGE(LABEL, "%{public}s: invoker is null", __func__);
407 }
408 }
409 const size_t size = toBeReport.size();
410 for (size_t i = 0; i < size; i++) {
411 sptr<DeathRecipient> recipient = toBeReport[i];
412 ZLOGW(LABEL, "%{public}s: handle = %{public}u call OnRemoteDied", __func__, handle_);
413 if (recipient != nullptr) {
414 recipient->OnRemoteDied(this);
415 }
416 }
417 }
418
ClearDeathRecipients()419 void IPCObjectProxy::ClearDeathRecipients()
420 {
421 std::lock_guard<std::recursive_mutex> lock(mutex_);
422 if (recipients_.empty()) {
423 return;
424 }
425 recipients_.clear();
426 if (handle_ >= IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
427 return;
428 }
429 IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
430 if (invoker != nullptr) {
431 invoker->RemoveDeathRecipient(handle_, this);
432 }
433 #ifndef CONFIG_IPC_SINGLE
434 if (proto_ == IRemoteObject::IF_PROT_DATABUS || proto_ == IRemoteObject::IF_PROT_ERROR) {
435 RemoveDbinderDeathRecipient();
436 }
437 #endif
438 }
439
GetProto() const440 int IPCObjectProxy::GetProto() const
441 {
442 return proto_;
443 }
444
NoticeServiceDie()445 int32_t IPCObjectProxy::NoticeServiceDie()
446 {
447 ZLOGW(LABEL, "%{public}s: handle: %{public}d", __func__, handle_);
448 MessageParcel data;
449 MessageParcel reply;
450 MessageOption option(MessageOption::TF_ASYNC);
451 data.WriteInt32(IRemoteObject::DeathRecipient::NOTICE_DEATH_RECIPIENT);
452
453 int status = SendLocalRequest(DBINDER_OBITUARY_TRANSACTION, data, reply, option);
454 if (status != ERR_NONE || reply.ReadInt32() != ERR_NONE) {
455 ZLOGE(LABEL, "%{public}s: send local request fail, status = %{public}d", __func__, status);
456 return IPC_PROXY_TRANSACTION_ERR;
457 }
458 return ERR_NONE;
459 }
460
InvokeListenThread(MessageParcel & data,MessageParcel & reply)461 int IPCObjectProxy::InvokeListenThread(MessageParcel &data, MessageParcel &reply)
462 {
463 MessageOption option;
464 return SendRequestInner(false, INVOKE_LISTEN_THREAD, data, reply, option);
465 }
466
467 #ifndef CONFIG_IPC_SINGLE
UpdateProto()468 int IPCObjectProxy::UpdateProto()
469 {
470 int proto = GetProtoInfo();
471 SetProto(proto);
472 return proto;
473 }
474
IncRefToRemote()475 int32_t IPCObjectProxy::IncRefToRemote()
476 {
477 MessageParcel data, reply;
478 MessageOption option;
479
480 int32_t err = SendRequestInner(false, DBINDER_INCREFS_TRANSACTION, data, reply, option);
481 if (err != ERR_NONE) {
482 ZLOGE(LABEL, "DBINDER_INCREFS_TRANSACTION transact return error = %{public}d", err);
483 // do nothing
484 }
485 return err;
486 }
487
488
ReleaseProto()489 void IPCObjectProxy::ReleaseProto()
490 {
491 switch (GetProto()) {
492 case IRemoteObject::IF_PROT_BINDER: {
493 ReleaseBinderProto();
494 break;
495 }
496 case IRemoteObject::IF_PROT_DATABUS:
497 case IRemoteObject::IF_PROT_ERROR: {
498 ReleaseDatabusProto();
499 break;
500 }
501 default: {
502 ZLOGE(LABEL, "release invalid proto %{public}d", proto_);
503 break;
504 }
505 }
506 }
507
SetProto(int proto)508 void IPCObjectProxy::SetProto(int proto)
509 {
510 proto_ = proto;
511 }
512
GetProtoInfo()513 int IPCObjectProxy::GetProtoInfo()
514 {
515 if (CheckHaveSession()) {
516 return IRemoteObject::IF_PROT_DATABUS;
517 }
518 if (handle_ >= IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
519 ZLOGE(LABEL, "cannot find session for handle:%{public}u", handle_);
520 return IRemoteObject::IF_PROT_ERROR;
521 }
522
523 MessageParcel data, reply;
524 MessageOption option;
525 int err = SendRequestInner(true, GET_PROTO_INFO, data, reply, option);
526 if (err != ERR_NONE && err != -EBADMSG) {
527 ZLOGW(LABEL, "GET_PROTO_INFO transact return error = %{public}d", err);
528 return IRemoteObject::IF_PROT_ERROR;
529 }
530
531 switch (reply.ReadUint32()) {
532 case IRemoteObject::IF_PROT_BINDER: {
533 break;
534 }
535 case IRemoteObject::IF_PROT_DATABUS: {
536 if (UpdateDatabusClientSession(handle_, reply)) {
537 ZLOGW(LABEL, "it is dbinder, not binder");
538 return IRemoteObject::IF_PROT_DATABUS;
539 } else {
540 ZLOGE(LABEL, "UpdateDatabusClientSession failed");
541 return IRemoteObject::IF_PROT_ERROR;
542 }
543 break;
544 }
545 default: {
546 ZLOGE(LABEL, "get Invalid proto");
547 return IRemoteObject::IF_PROT_ERROR;
548 break;
549 }
550 }
551
552 return IRemoteObject::IF_PROT_BINDER;
553 }
554
AddDbinderDeathRecipient()555 bool IPCObjectProxy::AddDbinderDeathRecipient()
556 {
557 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
558 if (current == nullptr) {
559 ZLOGE(LABEL, "%{public}s: get current fail", __func__);
560 return false;
561 }
562
563 if (current->QueryCallbackStub(this) != nullptr) {
564 ZLOGW(LABEL, "%{public}s: already attach callback stub", __func__);
565 return true;
566 }
567
568 //note that cannot use this proxy's descriptor
569 sptr<IPCObjectStub> callbackStub = new (std::nothrow) IPCObjectStub(u"DbinderDeathRecipient" + descriptor_);
570 if (callbackStub == nullptr) {
571 ZLOGE(LABEL, "create IPCObjectStub object failed");
572 return false;
573 }
574 if (!current->AttachCallbackStub(this, callbackStub)) {
575 ZLOGW(LABEL, "%{public}s: already attach new callback stub", __func__);
576 return false;
577 }
578
579 MessageParcel data;
580 MessageParcel reply;
581 MessageOption option(MessageOption::TF_SYNC);
582 data.WriteInt32(IRemoteObject::DeathRecipient::ADD_DEATH_RECIPIENT);
583 data.WriteRemoteObject(callbackStub);
584
585 int err = SendLocalRequest(DBINDER_OBITUARY_TRANSACTION, data, reply, option);
586 if (err != ERR_NONE) {
587 ZLOGE(LABEL, "AddDbinderDeathRecipient fail, err = %{public}d", err);
588 current->DetachCallbackStub(this);
589 return false;
590 }
591
592 return true;
593 }
594
RemoveDbinderDeathRecipient()595 bool IPCObjectProxy::RemoveDbinderDeathRecipient()
596 {
597 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
598 if (current == nullptr) {
599 ZLOGE(LABEL, "%{public}s: get current fail", __func__);
600 return false;
601 }
602
603 sptr<IPCObjectStub> callbackStub = current->DetachCallbackStub(this);
604 if (callbackStub == nullptr) {
605 ZLOGE(LABEL, "%{public}s: get callbackStub fail", __func__);
606 return false;
607 }
608
609 MessageParcel data;
610 MessageParcel reply;
611 MessageOption option(MessageOption::TF_SYNC);
612 data.WriteInt32(IRemoteObject::DeathRecipient::REMOVE_DEATH_RECIPIENT);
613 data.WriteRemoteObject(callbackStub);
614
615 int err = SendLocalRequest(DBINDER_OBITUARY_TRANSACTION, data, reply, option);
616 if (err != ERR_NONE) {
617 ZLOGE(LABEL, "%{public}s: send local request fail, err = %{public}d", __func__, err);
618 // do nothing, even send request failed
619 }
620 return err == ERR_NONE;
621 }
622
CheckHaveSession()623 bool IPCObjectProxy::CheckHaveSession()
624 {
625 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
626 if (current == nullptr) {
627 ZLOGE(LABEL, "IPCProcessSkeleton is null");
628 return false;
629 }
630
631 return current->ProxyMoveDBinderSession(handle_, this);
632 }
633
UpdateDatabusClientSession(int handle,MessageParcel & reply)634 bool IPCObjectProxy::UpdateDatabusClientSession(int handle, MessageParcel &reply)
635 {
636 DBinderDatabusInvoker *invoker =
637 reinterpret_cast<DBinderDatabusInvoker *>(IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS));
638 if (invoker == nullptr) {
639 ZLOGE(LABEL, "%{public}s: invoker is null", __func__);
640 return false;
641 }
642
643 uint64_t stubIndex = reply.ReadUint64();
644 std::string serviceName = reply.ReadString();
645 std::string peerID = reply.ReadString();
646 std::string localID = reply.ReadString();
647 std::string localBusName = reply.ReadString();
648 uint32_t peerTokenId = reply.ReadUint32();
649
650 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
651 if (current == nullptr) {
652 ZLOGE(LABEL, "%{public}s: skeleton is nullptr", __func__);
653 return false;
654 }
655
656 std::shared_ptr<DBinderSessionObject> dbinderSession = std::make_shared<DBinderSessionObject>(
657 nullptr, serviceName, peerID, stubIndex, this, peerTokenId);
658 if (dbinderSession == nullptr) {
659 ZLOGE(LABEL, "make DBinderSessionObject fail!");
660 return false;
661 }
662
663 if (!current->CreateSoftbusServer(localBusName)) {
664 ZLOGE(LABEL, "create softbus server fail, name = %{public}s, localID = %{public}s", localBusName.c_str(),
665 IPCProcessSkeleton::ConvertToSecureString(localID).c_str());
666 return false;
667 }
668
669 if (!invoker->UpdateClientSession(dbinderSession)) {
670 // no need to remove softbus server
671 ZLOGE(LABEL, "update server session object fail!");
672 return false;
673 }
674 if (!current->ProxyAttachDBinderSession(handle, dbinderSession)) {
675 // should not get here
676 ZLOGE(LABEL, "fail to attach session, handle: %{public}d", handle);
677 if (current->QuerySessionByInfo(serviceName, peerID) == nullptr) {
678 dbinderSession->CloseDatabusSession();
679 }
680 return false;
681 }
682 return true;
683 }
684
ReleaseDatabusProto()685 void IPCObjectProxy::ReleaseDatabusProto()
686 {
687 if (handle_ == 0) {
688 ZLOGW(LABEL, "%{public}s: handle == 0, do nothing", __func__);
689 return;
690 }
691
692 MessageParcel data, reply;
693 MessageOption option = { MessageOption::TF_ASYNC };
694 int err = SendRequestInner(false, DBINDER_DECREFS_TRANSACTION, data, reply, option);
695 if (err != ERR_NONE) {
696 ZLOGE(LABEL, "send DBINDER_DECREFS_TRANSACTION cmd failed, error: %{public}d", err);
697 // do nothing, if this cmd failed, stub's refcount will be decreased when OnSessionClosed called
698 }
699
700 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
701 if (current == nullptr) {
702 ZLOGE(LABEL, "release databus proto skeleton is null");
703 return;
704 }
705 std::shared_ptr<DBinderSessionObject> toBeDelete = current->ProxyDetachDBinderSession(handle_, this);
706 if (toBeDelete != nullptr &&
707 // make sure session corresponding to this sessionName and deviceId is no longer used by other proxy
708 current->QuerySessionByInfo(toBeDelete->GetServiceName(), toBeDelete->GetDeviceId()) == nullptr) {
709 // close session in lock
710 toBeDelete->CloseDatabusSession();
711 }
712 }
713
ReleaseBinderProto()714 void IPCObjectProxy::ReleaseBinderProto()
715 {
716 // do nothing
717 }
718 #endif
719 } // namespace OHOS
720