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 "dbinder_error_code.h"
19 #include "ipc_types.h"
20 #include "ipc_debug.h"
21 #include "ipc_thread_skeleton.h"
22 #include "ipc_process_skeleton.h"
23 #include "log_tags.h"
24 #include "securec.h"
25
26 #ifndef CONFIG_IPC_SINGLE
27 #include "dbinder_databus_invoker.h"
28 #endif
29
30 namespace OHOS {
31 #ifdef CONFIG_IPC_SINGLE
32 using namespace IPC_SINGLE;
33 #endif
34
35 static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC, "IPCObjectProxy" };
IPCObjectProxy(int handle,std::u16string descriptor,int proto)36 IPCObjectProxy::IPCObjectProxy(int handle, std::u16string descriptor, int proto)
37 : IRemoteObject(std::move(descriptor)), handle_(handle), proto_(proto), isFinishInit_(false), isRemoteDead_(false)
38 {}
39
~IPCObjectProxy()40 IPCObjectProxy::~IPCObjectProxy()
41 {
42 ZLOGW(LABEL, "handle = %{public}u destroyed", handle_);
43 }
44
GetObjectRefCount()45 int32_t IPCObjectProxy::GetObjectRefCount()
46 {
47 MessageParcel dummy, reply;
48 MessageOption option;
49 option.SetFlags(MessageOption::TF_SYNC);
50 if (SendRequestInner(false, SYNCHRONIZE_REFERENCE, dummy, reply, option) == ERR_NONE) {
51 return reply.ReadInt32();
52 }
53 return 0;
54 }
55
Dump(int fd,const std::vector<std::u16string> & args)56 int IPCObjectProxy::Dump(int fd, const std::vector<std::u16string> &args)
57 {
58 MessageParcel data, reply;
59 MessageOption option { MessageOption::TF_SYNC };
60 data.WriteFileDescriptor(fd);
61 data.WriteString16Vector(args);
62 return SendRequestInner(false, DUMP_TRANSACTION, data, reply, option);
63 }
64
SendRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)65 int IPCObjectProxy::SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
66 {
67 if (code != DUMP_TRANSACTION && code > MAX_TRANSACTION_ID) {
68 return IPC_PROXY_INVALID_CODE_ERR;
69 }
70
71 return SendRequestInner(false, code, data, reply, option);
72 }
73
SendLocalRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)74 int IPCObjectProxy::SendLocalRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
75 {
76 return SendRequestInner(true, code, data, reply, option);
77 }
78
SendRequestInner(bool isLocal,uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)79 int IPCObjectProxy::SendRequestInner(bool isLocal, uint32_t code, MessageParcel &data, MessageParcel &reply,
80 MessageOption &option)
81 {
82 if (IsObjectDead()) {
83 return ERR_DEAD_OBJECT;
84 }
85
86 IRemoteInvoker *invoker = nullptr;
87 if (isLocal) {
88 invoker = IPCThreadSkeleton::GetDefaultInvoker();
89 } else {
90 invoker = IPCThreadSkeleton::GetRemoteInvoker(proto_);
91 }
92 if (invoker == nullptr) {
93 ZLOGE(LABEL, "%s: null invoker, type = %d", __func__, proto_);
94 return ERR_NULL_OBJECT;
95 }
96
97 int status = invoker->SendRequest(handle_, code, data, reply, option);
98 if (status == ERR_DEAD_OBJECT) {
99 MarkObjectDied();
100 }
101 return status;
102 }
103
GetInterfaceDescriptor()104 std::u16string IPCObjectProxy::GetInterfaceDescriptor()
105 {
106 if (!remoteDescriptor_.empty()) {
107 return remoteDescriptor_;
108 }
109 if (handle_ == 0) {
110 ZLOGI(LABEL, "handle == 0, do nothing");
111 return std::u16string();
112 }
113
114 MessageParcel data, reply;
115 MessageOption option;
116
117 int32_t err = SendRequestInner(false, INTERFACE_TRANSACTION, data, reply, option);
118 if (err != ERR_NONE) {
119 ZLOGE(LABEL, "INTERFACE_TRANSACTION transact return error = %{public}d", err);
120 return std::u16string();
121 }
122 remoteDescriptor_ = reply.ReadString16();
123
124 return remoteDescriptor_;
125 }
126
GetPidAndUidInfo()127 std::string IPCObjectProxy::GetPidAndUidInfo()
128 {
129 MessageParcel data, reply;
130 MessageOption option;
131
132 int32_t err = SendRequestInner(false, GET_UIDPID_INFO, data, reply, option);
133 if (err != ERR_NONE) {
134 ZLOGE(LABEL, "GetPidAndUidInfo SendRequestInner return error = %{public}d", err);
135 return std::string("");
136 }
137 return reply.ReadString();
138 }
139
GetDataBusName()140 std::string IPCObjectProxy::GetDataBusName()
141 {
142 MessageParcel data, reply;
143 MessageOption option;
144
145 int32_t err = SendRequestInner(false, GRANT_DATABUS_NAME, data, reply, option);
146 if (err != ERR_NONE) {
147 ZLOGE(LABEL, "GetDataBusName transact return error = %{public}d", err);
148 return std::string("");
149 }
150
151 if (reply.ReadUint32() != IRemoteObject::IF_PROT_DATABUS) {
152 ZLOGE(LABEL, "GetDataBusName normal binder");
153 return std::string("");
154 }
155
156 return reply.ReadString();
157 }
158
TransDataBusName(uint32_t uid,uint32_t pid)159 std::string IPCObjectProxy::TransDataBusName(uint32_t uid, uint32_t pid)
160 {
161 if (pid == static_cast<uint32_t>(getpid())) {
162 ZLOGE(LABEL, "TransDataBusName can't write local pid. my/remotePid = %{public}u/%{public}u", getpid(), pid);
163 return std::string("");
164 }
165
166 MessageParcel data, reply;
167 MessageOption option;
168 if (!data.WriteUint32(pid) || !data.WriteUint32(uid)) {
169 ZLOGE(LABEL, "TransDataBusName write pid/uid = %{public}u/%{public}u failed", pid, uid);
170 return std::string("");
171 }
172 int32_t err = SendRequestInner(false, TRANS_DATABUS_NAME, data, reply, option);
173 if (err != ERR_NONE) {
174 ZLOGE(LABEL, "TransDataBusName transact return error = %{public}d", err);
175 return std::string("");
176 }
177
178 if (reply.ReadUint32() != IRemoteObject::IF_PROT_DATABUS) {
179 ZLOGE(LABEL, "TransDataBusName normal binder");
180 return std::string("");
181 }
182
183 return reply.ReadString();
184 }
185
OnFirstStrongRef(const void * objectId)186 void IPCObjectProxy::OnFirstStrongRef(const void *objectId)
187 {
188 IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
189 if (invoker != nullptr) {
190 invoker->AcquireHandle(handle_);
191 }
192 }
193
WaitForInit()194 void IPCObjectProxy::WaitForInit()
195 {
196 #ifndef CONFIG_IPC_SINGLE
197 int type = 0;
198 #endif
199 {
200 std::lock_guard<std::mutex> lockGuard(initMutex_);
201 if (IsObjectDead()) {
202 ZLOGW(LABEL, "check a dead proxy, init again");
203 isRemoteDead_ = false;
204 isFinishInit_ = false;
205 }
206
207 // check again is this object been initialized
208 if (isFinishInit_) {
209 return;
210 }
211 #ifndef CONFIG_IPC_SINGLE
212 type = UpdateProto();
213 #endif
214 isFinishInit_ = true;
215 }
216 #ifndef CONFIG_IPC_SINGLE
217 if (type == IRemoteObject::IF_PROT_DATABUS) {
218 IncRefToRemote();
219 }
220 #endif
221 }
222
OnLastStrongRef(const void * objectId)223 void IPCObjectProxy::OnLastStrongRef(const void *objectId)
224 {
225 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
226 if (current == nullptr) {
227 ZLOGE(LABEL, "OnLastStrongRef current is null");
228 return;
229 }
230 #ifndef CONFIG_IPC_SINGLE
231 std::shared_ptr<DBinderSessionObject> session = nullptr;
232 #endif
233 {
234 std::lock_guard<std::recursive_mutex> lock(current->mutex_);
235 if (current->DetachObjectInner(this) == false) { // if detach successfully, this proxy will be destroyed
236 return;
237 }
238 #ifndef CONFIG_IPC_SINGLE
239 ReleaseProto();
240 session = current->ProxyQueryDBinderSession(handle_);
241 (void)current->ProxyDetachDBinderSession(handle_);
242 (void)current->DetachHandleToIndex(handle_);
243 #endif
244 }
245 IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
246 if (invoker != nullptr) {
247 invoker->ReleaseHandle(handle_);
248 }
249 }
250
251
252 /* mutex_ should be called before set or get isRemoteDead_ status */
MarkObjectDied()253 void IPCObjectProxy::MarkObjectDied()
254 {
255 isRemoteDead_ = true;
256 }
257
IsObjectDead() const258 bool IPCObjectProxy::IsObjectDead() const
259 {
260 return isRemoteDead_;
261 }
262
AddDeathRecipient(const sptr<DeathRecipient> & recipient)263 bool IPCObjectProxy::AddDeathRecipient(const sptr<DeathRecipient> &recipient)
264 {
265 std::lock_guard<std::recursive_mutex> lock(mutex_);
266 if (IsObjectDead()) {
267 ZLOGW(LABEL, "%s: proxy is already dead", __func__);
268 return false;
269 }
270
271 bool registerRecipient = false;
272 if (recipients_.empty()) {
273 registerRecipient = true;
274 }
275 recipients_.push_back(recipient);
276
277 if (!registerRecipient || handle_ >= IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
278 ZLOGI(LABEL, "%s: death recipient is already registered", __func__);
279 return true;
280 }
281
282 IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
283 if (invoker == nullptr) {
284 ZLOGE(LABEL, "%s : invoker is null", __func__);
285 return false;
286 }
287
288 /* 1. Subscribe to death notifications, whether the stub comes from kernel or remote;
289 * 2. Subscribe to additional death notifications, if remote object.
290 * If step 1 is failed, do not execute step 2 and return false directly.
291 * If step 1 is successful but step 2 is failed, return false.
292 */
293 bool status = invoker->AddDeathRecipient(handle_, this);
294 if (!status) {
295 ZLOGE(LABEL, "%s: fail to add binder death recipient, status = %d", __func__, status);
296 #ifndef BUILD_PUBLIC_VERSION
297 ReportDriverEvent(DbinderErrorCode::COMMON_DRIVER_ERROR, DbinderErrorCode::ERROR_TYPE,
298 DbinderErrorCode::IPC_DRIVER, DbinderErrorCode::ERROR_CODE, DbinderErrorCode::SET_DEATH_RECIPIENT_FAILURE);
299 #endif
300 return status;
301 }
302 #ifndef CONFIG_IPC_SINGLE
303 if (proto_ == IRemoteObject::IF_PROT_DATABUS) {
304 status = AddDbinderDeathRecipient();
305 #ifndef BUILD_PUBLIC_VERSION
306 if (!status) {
307 ZLOGE(LABEL, "failed to add dbinder death recipient");
308 ReportDriverEvent(DbinderErrorCode::COMMON_DRIVER_ERROR, DbinderErrorCode::ERROR_TYPE,
309 DbinderErrorCode::RPC_DRIVER, DbinderErrorCode::ERROR_CODE,
310 DbinderErrorCode::SET_DEATH_RECIPIENT_FAILURE);
311 }
312 #endif
313 }
314 #endif
315 return status;
316 }
317
RemoveDeathRecipient(const sptr<DeathRecipient> & recipient)318 bool IPCObjectProxy::RemoveDeathRecipient(const sptr<DeathRecipient> &recipient)
319 {
320 std::lock_guard<std::recursive_mutex> lock(mutex_);
321
322 bool removeRecipient = false;
323
324 if (!IsObjectDead()) {
325 auto it = find(recipients_.begin(), recipients_.end(), recipient);
326 if (it != recipients_.end()) {
327 recipients_.erase(it);
328 removeRecipient = true;
329 }
330
331 if (!recipients_.empty()) {
332 removeRecipient = false;
333 }
334 }
335
336 if ((handle_ >= IPCProcessSkeleton::DBINDER_HANDLE_BASE) && (removeRecipient == true)) {
337 ZLOGI(LABEL, "%s: death recipient is already unregistered", __func__);
338 return true;
339 }
340
341 if (removeRecipient) {
342 IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
343 if (invoker == nullptr) {
344 ZLOGE(LABEL, "%s : invoker is null", __func__);
345 return false;
346 }
347
348 bool dbinderStatus = true;
349 bool binderStatus = invoker->RemoveDeathRecipient(handle_, this);
350 #ifndef CONFIG_IPC_SINGLE
351 if (proto_ == IRemoteObject::IF_PROT_DATABUS) {
352 dbinderStatus = RemoveDbinderDeathRecipient();
353 }
354 #endif
355 if (binderStatus && dbinderStatus) {
356 return true;
357 }
358 }
359
360 return false;
361 }
362
SendObituary()363 void IPCObjectProxy::SendObituary()
364 {
365 {
366 std::lock_guard<std::recursive_mutex> lock(mutex_);
367 MarkObjectDied();
368 size_t recipientCount = recipients_.size();
369 for (size_t i = 0; i < recipientCount; i++) {
370 sptr<DeathRecipient> recipient = recipients_[i];
371 ZLOGW(LABEL, "%s: handle = %{public}u call OnRemoteDied", __func__, handle_);
372 if (recipient != nullptr) {
373 recipient->OnRemoteDied(this);
374 }
375 }
376 recipients_.clear();
377
378 if (recipientCount > 0) {
379 IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
380 if (invoker != nullptr) {
381 invoker->RemoveDeathRecipient(handle_, this);
382 }
383 }
384 }
385 #ifndef CONFIG_IPC_SINGLE
386 if (proto_ == IRemoteObject::IF_PROT_DATABUS) {
387 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
388 if (current == nullptr) {
389 ZLOGE(LABEL, "%s: get current fail", __func__);
390 return;
391 }
392
393 current->DetachCallbackStubByProxy(this);
394 }
395 #endif
396 }
397
GetProto() const398 int IPCObjectProxy::GetProto() const
399 {
400 return proto_;
401 }
402
NoticeServiceDie()403 int32_t IPCObjectProxy::NoticeServiceDie()
404 {
405 MessageParcel data;
406 MessageParcel reply;
407 MessageOption option(MessageOption::TF_SYNC);
408 data.WriteInt32(IRemoteObject::DeathRecipient::NOTICE_DEATH_RECIPIENT);
409
410 int status = SendLocalRequest(DBINDER_OBITUARY_TRANSACTION, data, reply, option);
411 if (status != ERR_NONE || reply.ReadInt32() != ERR_NONE) {
412 ZLOGE(LABEL, "%s: send local request fail, status = %d", __func__, status);
413 return IPC_PROXY_TRANSACTION_ERR;
414 }
415
416 return ERR_NONE;
417 }
418
InvokeListenThread(MessageParcel & data,MessageParcel & reply)419 int IPCObjectProxy::InvokeListenThread(MessageParcel &data, MessageParcel &reply)
420 {
421 MessageOption option;
422 return SendRequestInner(false, INVOKE_LISTEN_THREAD, data, reply, option);
423 }
424
425 #ifndef CONFIG_IPC_SINGLE
UpdateProto()426 int IPCObjectProxy::UpdateProto()
427 {
428 int type = GetSessionFromDBinderService();
429 SetProto(type);
430 return type;
431 }
432
IncRefToRemote()433 void IPCObjectProxy::IncRefToRemote()
434 {
435 MessageParcel data, reply;
436 MessageOption option;
437
438 int32_t err = SendRequestInner(false, DBINDER_INCREFS_TRANSACTION, data, reply, option);
439 if (err != ERR_NONE) {
440 ZLOGE(LABEL, "DBINDER_INCREFS_TRANSACTION transact return error = %{public}d", err);
441 // do nothing
442 }
443 }
444
445
ReleaseProto()446 void IPCObjectProxy::ReleaseProto()
447 {
448 ReleaseDatabusProto();
449 }
450
SetProto(int proto)451 void IPCObjectProxy::SetProto(int proto)
452 {
453 proto_ = proto;
454 }
455
GetSessionFromDBinderService()456 int IPCObjectProxy::GetSessionFromDBinderService()
457 {
458 MessageParcel data, reply;
459 MessageOption option;
460 uint32_t type = IRemoteObject::IF_PROT_BINDER;
461
462 if (CheckHaveSession(type)) {
463 ZLOGE(LABEL, "GetSessionFromDBinderService type = %u", type);
464 return type;
465 }
466
467 int32_t err = SendRequestInner(true, GET_PROTO_INFO, data, reply, option);
468 if (err != ERR_NONE) {
469 ZLOGI(LABEL, "GET_PROTO_INFO transact return error = %{public}d", err);
470 return IRemoteObject::IF_PROT_BINDER;
471 }
472
473 switch (reply.ReadUint32()) {
474 case IRemoteObject::IF_PROT_BINDER: {
475 ZLOGW(LABEL, "it is normal binder, not dbinder");
476 break;
477 }
478 case IRemoteObject::IF_PROT_DATABUS: {
479 if (UpdateDatabusClientSession(handle_, reply)) {
480 ZLOGW(LABEL, "it is dbinder, not binder");
481 return IRemoteObject::IF_PROT_DATABUS;
482 }
483 break;
484 }
485 default: {
486 ZLOGE(LABEL, "GetSessionFromDBinderService Invalid Type");
487 break;
488 }
489 }
490
491 return IRemoteObject::IF_PROT_BINDER;
492 }
493
AddDbinderDeathRecipient()494 bool IPCObjectProxy::AddDbinderDeathRecipient()
495 {
496 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
497 if (current == nullptr) {
498 ZLOGE(LABEL, "%s: get current fail", __func__);
499 return false;
500 }
501
502 if (current->QueryCallbackStub(this) != nullptr) {
503 ZLOGW(LABEL, "%s: already attach callback stub", __func__);
504 return true;
505 }
506
507 sptr<IPCObjectStub> callbackStub = new IPCObjectStub(descriptor_);
508 if (!current->AttachCallbackStub(this, callbackStub)) {
509 ZLOGW(LABEL, "%s: already attach new callback stub", __func__);
510 return false;
511 }
512
513 MessageParcel data;
514 MessageParcel reply;
515 MessageOption option(MessageOption::TF_SYNC);
516 data.WriteInt32(IRemoteObject::DeathRecipient::ADD_DEATH_RECIPIENT);
517 data.WriteRemoteObject(callbackStub);
518
519 int err = SendLocalRequest(DBINDER_OBITUARY_TRANSACTION, data, reply, option);
520 if (err != ERR_NONE || reply.ReadInt32() != ERR_NONE) {
521 ZLOGE(LABEL, "%s: send local request fail, err = %d", __func__, err);
522 (void)current->DetachCallbackStubByProxy(this);
523 return false;
524 }
525
526 return true;
527 }
528
RemoveDbinderDeathRecipient()529 bool IPCObjectProxy::RemoveDbinderDeathRecipient()
530 {
531 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
532 if (current == nullptr) {
533 ZLOGE(LABEL, "%s: get current fail", __func__);
534 return false;
535 }
536
537 sptr<IPCObjectStub> callbackStub = current->QueryCallbackStub(this);
538 if (callbackStub == nullptr) {
539 ZLOGE(LABEL, "%s: get callbackStub fail", __func__);
540 return false;
541 }
542
543 MessageParcel data;
544 MessageParcel reply;
545 MessageOption option(MessageOption::TF_SYNC);
546 data.WriteInt32(IRemoteObject::DeathRecipient::REMOVE_DEATH_RECIPIENT);
547 data.WriteRemoteObject(callbackStub);
548
549 int err = SendLocalRequest(DBINDER_OBITUARY_TRANSACTION, data, reply, option);
550 if (err != ERR_NONE || reply.ReadInt32() != ERR_NONE) {
551 ZLOGE(LABEL, "%s: send local request fail, err = %d", __func__, err);
552 // do nothing, even send request failed
553 }
554
555 return current->DetachCallbackStubByProxy(this);
556 }
557
CheckHaveSession(uint32_t & type)558 bool IPCObjectProxy::CheckHaveSession(uint32_t &type)
559 {
560 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
561 if (current == nullptr) {
562 ZLOGE(LABEL, "IPCProcessSkeleton is null, set type as binder");
563 return false;
564 }
565
566 std::shared_ptr<DBinderSessionObject> session = current->ProxyQueryDBinderSession(handle_);
567 if (session == nullptr) {
568 ZLOGW(LABEL, "no databus session attach to this handle, maybe need update");
569 return false;
570 }
571 type = IRemoteObject::IF_PROT_DATABUS;
572 return true;
573 }
574
UpdateDatabusClientSession(int handle,MessageParcel & reply)575 bool IPCObjectProxy::UpdateDatabusClientSession(int handle, MessageParcel &reply)
576 {
577 DBinderDatabusInvoker *invoker =
578 reinterpret_cast<DBinderDatabusInvoker *>(IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS));
579 if (invoker == nullptr) {
580 ZLOGE(LABEL, "%s: invoker null", __func__);
581 return false;
582 }
583
584 uint64_t stubIndex = reply.ReadUint64();
585 std::string serviceName = reply.ReadString();
586 std::string peerID = reply.ReadString();
587 std::string localID = reply.ReadString();
588 std::string localBusName = reply.ReadString();
589
590 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
591 if (current == nullptr) {
592 ZLOGE(LABEL, "%s:current process skeleton is nullptr", __func__);
593 return false;
594 }
595
596 std::shared_ptr<DBinderSessionObject> connectSession = current->QuerySessionByInfo(serviceName, peerID);
597 if (connectSession == nullptr) {
598 connectSession = std::make_shared<DBinderSessionObject>(nullptr, serviceName, peerID);
599 if (connectSession == nullptr) {
600 ZLOGE(LABEL, "new server session fail!");
601 return false;
602 }
603 }
604
605 if (!current->AttachHandleToIndex((uint32_t)handle, stubIndex)) {
606 ZLOGE(LABEL, "add stub index err stubIndex = %" PRIu64 ", handle = %d", stubIndex, handle);
607 return false;
608 }
609
610 if (!current->CreateSoftbusServer(localBusName)) {
611 ZLOGE(LABEL, "create bus server fail name = %s, localID = %s", localBusName.c_str(), localID.c_str());
612 return false;
613 }
614
615 bool result = invoker->UpdateClientSession(handle, connectSession);
616 if (!result) {
617 ZLOGE(LABEL, "update server session object fail!");
618 return false;
619 }
620
621 return true;
622 }
623
ReleaseDatabusProto()624 void IPCObjectProxy::ReleaseDatabusProto()
625 {
626 if (handle_ == 0) {
627 ZLOGI(LABEL, "%s:handle == 0, do nothing", __func__);
628 return;
629 }
630
631 if (proto_ != IRemoteObject::IF_PROT_DATABUS) {
632 ZLOGW(LABEL, "not databus dbinder, need do nothing");
633 return;
634 }
635
636 MessageParcel data, reply;
637 MessageOption option = { MessageOption::TF_ASYNC };
638 int32_t err = SendRequestInner(false, DBINDER_DECREFS_TRANSACTION, data, reply, option);
639 if (err != ERR_NONE) {
640 ZLOGW(LABEL, "DBINDER_DECREFS_TRANSACTION transact return error = %{public}d", err);
641 // do nothing
642 }
643 }
644
ReleaseBinderProto()645 void IPCObjectProxy::ReleaseBinderProto()
646 {
647 // do nothing
648 }
649 #endif
650 } // namespace OHOS
651