• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "rpc_feature_set.h"
47 #endif
48 
49 namespace OHOS {
50 #ifdef CONFIG_IPC_SINGLE
51 using namespace IPC_SINGLE;
52 #endif
53 
54 static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC, "IPCObjectProxy" };
55 
IPCObjectProxy(int handle,std::u16string descriptor,int proto)56 IPCObjectProxy::IPCObjectProxy(int handle, std::u16string descriptor, int proto)
57     : IRemoteObject(std::move(descriptor)), handle_(handle), proto_(proto), isFinishInit_(false), isRemoteDead_(false)
58 {
59 }
60 
~IPCObjectProxy()61 IPCObjectProxy::~IPCObjectProxy()
62 {
63 }
64 
GetObjectRefCount()65 int32_t IPCObjectProxy::GetObjectRefCount()
66 {
67     MessageParcel dummy, reply;
68     MessageOption option;
69     option.SetFlags(MessageOption::TF_SYNC);
70     if (SendRequestInner(false, SYNCHRONIZE_REFERENCE, dummy, 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, "%s: null invoker, type = %d", __func__, 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     int32_t err = SendRequestInner(false, INTERFACE_TRANSACTION, data, reply, option);
138     if (err != ERR_NONE) {
139         ZLOGE(LABEL, "INTERFACE_TRANSACTION transact return error = %{public}d", err);
140         return std::u16string();
141     }
142     remoteDescriptor_ = reply.ReadString16();
143 
144     return remoteDescriptor_;
145 }
146 
GetPidAndUidInfo(int32_t systemAbilityId)147 std::string IPCObjectProxy::GetPidAndUidInfo(int32_t systemAbilityId)
148 {
149     MessageParcel data, reply;
150     MessageOption option;
151 
152     data.WriteInt32(systemAbilityId);
153     int32_t err = SendRequestInner(false, GET_UIDPID_INFO, data, reply, option);
154     if (err != ERR_NONE) {
155         ZLOGE(LABEL, "GetPidAndUidInfo SendRequestInner return error = %{public}d", err);
156         return std::string("");
157     }
158     return reply.ReadString();
159 }
160 
GetDataBusName(int32_t systemAbilityId)161 std::string IPCObjectProxy::GetDataBusName(int32_t systemAbilityId)
162 {
163     MessageParcel data, reply;
164     MessageOption option;
165 
166     data.WriteInt32(systemAbilityId);
167     int32_t err = SendRequestInner(false, GRANT_DATABUS_NAME, data, reply, option);
168     if (err != ERR_NONE) {
169         ZLOGE(LABEL, "GetDataBusName transact return error = %{public}d", err);
170         return std::string("");
171     }
172 
173     if (reply.ReadUint32() != IRemoteObject::IF_PROT_DATABUS) {
174         ZLOGE(LABEL, "GetDataBusName normal binder");
175         return std::string("");
176     }
177 
178     return reply.ReadString();
179 }
180 
TransDataBusName(uint32_t uid,uint32_t pid)181 std::string IPCObjectProxy::TransDataBusName(uint32_t uid, uint32_t pid)
182 {
183     if (pid == static_cast<uint32_t>(getpid())) {
184         ZLOGE(LABEL, "TransDataBusName can't write local pid. my/remotePid = %{public}u/%{public}u", getpid(), pid);
185         return std::string("");
186     }
187 
188     MessageParcel data, reply;
189     MessageOption option;
190     if (!data.WriteUint32(pid) || !data.WriteUint32(uid)) {
191         ZLOGE(LABEL, "TransDataBusName write pid/uid = %{public}u/%{public}u failed", pid, uid);
192         return std::string("");
193     }
194     int32_t err = SendRequestInner(false, TRANS_DATABUS_NAME, data, reply, option);
195     if (err != ERR_NONE) {
196         ZLOGE(LABEL, "TransDataBusName transact return error = %{public}d", err);
197         return std::string("");
198     }
199 
200     if (reply.ReadUint32() != IRemoteObject::IF_PROT_DATABUS) {
201         ZLOGE(LABEL, "TransDataBusName normal binder");
202         return std::string("");
203     }
204 
205     return reply.ReadString();
206 }
207 
OnFirstStrongRef(const void * objectId)208 void IPCObjectProxy::OnFirstStrongRef(const void *objectId)
209 {
210     IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
211     if (invoker != nullptr) {
212         invoker->AcquireHandle(handle_);
213     }
214 }
215 
WaitForInit()216 void IPCObjectProxy::WaitForInit()
217 {
218     {
219         std::lock_guard<std::mutex> lockGuard(initMutex_);
220         if (IsObjectDead()) {
221             ZLOGW(LABEL, "check a dead proxy, init again");
222             isRemoteDead_ = false;
223             isFinishInit_ = false;
224         }
225 
226         // check again is this object been initialized
227         if (isFinishInit_) {
228 #ifndef CONFIG_IPC_SINGLE
229             if (proto_ == IRemoteObject::IF_PROT_DATABUS) {
230                 if (!CheckHaveSession()) {
231                     SetProto(IRemoteObject::IF_PROT_ERROR);
232                     isRemoteDead_ = true;
233                 }
234             }
235 #endif
236             return;
237         }
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     }
246 #ifndef CONFIG_IPC_SINGLE
247     if (proto_ == IRemoteObject::IF_PROT_DATABUS) {
248         int32_t errcode = IncRefToRemote();
249         if (errcode != ERR_NONE) {
250             SetProto(IRemoteObject::IF_PROT_ERROR);
251             isRemoteDead_ = true;
252         }
253     }
254 #endif
255 }
256 
OnLastStrongRef(const void * objectId)257 void IPCObjectProxy::OnLastStrongRef(const void *objectId)
258 {
259     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
260     if (current == nullptr) {
261         ZLOGE(LABEL, "OnLastStrongRef current is null");
262         return;
263     }
264     if (current->DetachObject(this) == false) { // if detach successfully, this proxy will be destroyed
265         return;
266     }
267 #ifndef CONFIG_IPC_SINGLE
268     ReleaseProto();
269     std::shared_ptr<DBinderSessionObject> session = nullptr;
270     session = current->ProxyQueryDBinderSession(handle_);
271     (void)current->ProxyDetachDBinderSession(handle_);
272     (void)current->DetachHandleToIndex(handle_);
273 #endif
274     IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
275     if (invoker != nullptr) {
276         invoker->ReleaseHandle(handle_);
277     }
278 }
279 
280 
281 /* mutex_ should be called before set or get isRemoteDead_ status */
MarkObjectDied()282 void IPCObjectProxy::MarkObjectDied()
283 {
284     isRemoteDead_ = true;
285 }
286 
IsObjectDead() const287 bool IPCObjectProxy::IsObjectDead() const
288 {
289     return isRemoteDead_;
290 }
291 
AddDeathRecipient(const sptr<DeathRecipient> & recipient)292 bool IPCObjectProxy::AddDeathRecipient(const sptr<DeathRecipient> &recipient)
293 {
294     std::lock_guard<std::recursive_mutex> lock(mutex_);
295     if (IsObjectDead()) {
296         ZLOGW(LABEL, "%s: proxy is already dead", __func__);
297         return false;
298     }
299 
300     bool registerRecipient = false;
301     if (recipients_.empty()) {
302         registerRecipient = true;
303     }
304     recipients_.push_back(recipient);
305 
306     if (!registerRecipient || handle_ >= IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
307         return true;
308     }
309 
310     IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
311     if (invoker == nullptr) {
312         ZLOGE(LABEL, "%s : invoker is null", __func__);
313         return false;
314     }
315 
316     /* 1. Subscribe to death notifications, whether the stub comes from kernel or remote;
317      * 2. Subscribe to additional death notifications, if remote object.
318      * If step 1 is failed, do not execute step 2 and return false directly.
319      * If step 1 is successful but step 2 is failed, return false.
320      */
321     bool status = invoker->AddDeathRecipient(handle_, this);
322     if (!status) {
323         ZLOGE(LABEL, "%s: fail to add binder death recipient, status = %d", __func__, status);
324 #ifndef BUILD_PUBLIC_VERSION
325         ReportDriverEvent(DbinderErrorCode::COMMON_DRIVER_ERROR, DbinderErrorCode::ERROR_TYPE,
326             DbinderErrorCode::IPC_DRIVER, DbinderErrorCode::ERROR_CODE, DbinderErrorCode::SET_DEATH_RECIPIENT_FAILURE);
327 #endif
328         return status;
329     }
330 #ifndef CONFIG_IPC_SINGLE
331     if (proto_ == IRemoteObject::IF_PROT_DATABUS) {
332         status = AddDbinderDeathRecipient();
333 #ifndef BUILD_PUBLIC_VERSION
334         if (!status) {
335             ZLOGE(LABEL, "failed to add dbinder death recipient");
336             ReportDriverEvent(DbinderErrorCode::COMMON_DRIVER_ERROR, DbinderErrorCode::ERROR_TYPE,
337                 DbinderErrorCode::RPC_DRIVER, DbinderErrorCode::ERROR_CODE,
338                 DbinderErrorCode::SET_DEATH_RECIPIENT_FAILURE);
339         }
340 #endif
341     }
342 #endif
343     return status;
344 }
345 
RemoveDeathRecipient(const sptr<DeathRecipient> & recipient)346 bool IPCObjectProxy::RemoveDeathRecipient(const sptr<DeathRecipient> &recipient)
347 {
348     std::lock_guard<std::recursive_mutex> lock(mutex_);
349 
350     bool removeRecipient = false;
351 
352     if (!IsObjectDead()) {
353         auto it = find(recipients_.begin(), recipients_.end(), recipient);
354         if (it != recipients_.end()) {
355             recipients_.erase(it);
356             removeRecipient = true;
357         }
358 
359         if (!recipients_.empty()) {
360             removeRecipient = false;
361         }
362     }
363 
364     if ((handle_ >= IPCProcessSkeleton::DBINDER_HANDLE_BASE) && (removeRecipient == true)) {
365         ZLOGD(LABEL, "%s: death recipient is already unregistered", __func__);
366         return true;
367     }
368 
369     if (removeRecipient) {
370         IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
371         if (invoker == nullptr) {
372             ZLOGE(LABEL, "%s : invoker is null", __func__);
373             return false;
374         }
375 
376         bool dbinderStatus = true;
377         bool binderStatus = invoker->RemoveDeathRecipient(handle_, this);
378 #ifndef CONFIG_IPC_SINGLE
379         if (proto_ == IRemoteObject::IF_PROT_DATABUS) {
380             dbinderStatus = RemoveDbinderDeathRecipient();
381         }
382 #endif
383         if (binderStatus && dbinderStatus) {
384             return true;
385         }
386     }
387 
388     return false;
389 }
390 
SendObituary()391 void IPCObjectProxy::SendObituary()
392 {
393     std::vector<sptr<DeathRecipient>> deathCallback;
394     {
395         std::lock_guard<std::recursive_mutex> lock(mutex_);
396         ZLOGW(LABEL, "%{public}s: enter, handle: %{public}d", __func__, handle_);
397         MarkObjectDied();
398         deathCallback = recipients_;
399         IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
400         if (recipients_.size() > 0 && invoker != nullptr) {
401             invoker->RemoveDeathRecipient(handle_, this);
402         }
403         recipients_.clear();
404     }
405     for (auto &deathRecipient : deathCallback) {
406         ZLOGW(LABEL, "%{public}s: handle = %{public}u call OnRemoteDied", __func__, handle_);
407         if (deathRecipient != nullptr) {
408             deathRecipient->OnRemoteDied(this);
409         }
410     }
411 #ifndef CONFIG_IPC_SINGLE
412     if (proto_ == IRemoteObject::IF_PROT_DATABUS) {
413         IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
414         if (current == nullptr) {
415             ZLOGE(LABEL, "%s: get current fail", __func__);
416             return;
417         }
418 
419         current->DetachCallbackStubByProxy(this);
420     }
421 #endif
422 }
423 
GetProto() const424 int IPCObjectProxy::GetProto() const
425 {
426     return proto_;
427 }
428 
NoticeServiceDie()429 int32_t IPCObjectProxy::NoticeServiceDie()
430 {
431     ZLOGW(LABEL, "%{public}s: handle: %{public}d", __func__, handle_);
432     MessageParcel data;
433     MessageParcel reply;
434     MessageOption option(MessageOption::TF_SYNC);
435     data.WriteInt32(IRemoteObject::DeathRecipient::NOTICE_DEATH_RECIPIENT);
436 
437     int status = SendLocalRequest(DBINDER_OBITUARY_TRANSACTION, data, reply, option);
438     if (status != ERR_NONE || reply.ReadInt32() != ERR_NONE) {
439         ZLOGE(LABEL, "%s: send local request fail, status = %d", __func__, status);
440         return IPC_PROXY_TRANSACTION_ERR;
441     }
442 
443     return ERR_NONE;
444 }
445 
InvokeListenThread(MessageParcel & data,MessageParcel & reply)446 int IPCObjectProxy::InvokeListenThread(MessageParcel &data, MessageParcel &reply)
447 {
448     MessageOption option;
449     return SendRequestInner(false, INVOKE_LISTEN_THREAD, data, reply, option);
450 }
451 
452 #ifndef CONFIG_IPC_SINGLE
UpdateProto()453 int IPCObjectProxy::UpdateProto()
454 {
455     int type = GetSessionFromDBinderService();
456     SetProto(type);
457     return type;
458 }
459 
IncRefToRemote()460 int32_t IPCObjectProxy::IncRefToRemote()
461 {
462     MessageParcel data, reply;
463     MessageOption option;
464 
465     int32_t err = SendRequestInner(false, DBINDER_INCREFS_TRANSACTION, data, reply, option);
466     if (err != ERR_NONE) {
467         ZLOGE(LABEL, "DBINDER_INCREFS_TRANSACTION transact return error = %{public}d", err);
468     }
469     return err;
470 }
471 
472 
ReleaseProto()473 void IPCObjectProxy::ReleaseProto()
474 {
475     ReleaseDatabusProto();
476 }
477 
SetProto(int proto)478 void IPCObjectProxy::SetProto(int proto)
479 {
480     proto_ = proto;
481 }
482 
GetSessionFromDBinderService()483 int IPCObjectProxy::GetSessionFromDBinderService()
484 {
485     MessageParcel data, reply;
486     MessageOption option;
487 
488     if (CheckHaveSession()) {
489         ZLOGE(LABEL, "GetSessionFromDBinderService CheckHaveSession success");
490         return IRemoteObject::IF_PROT_DATABUS;
491     }
492     if (handle_ >= IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
493         ZLOGE(LABEL, "cannot find session for handle:%{public}u", handle_);
494         return IRemoteObject::IF_PROT_ERROR;
495     }
496 
497     int32_t err = SendRequestInner(true, GET_PROTO_INFO, data, reply, option);
498     if (err != ERR_NONE) {
499         ZLOGE(LABEL, "GET_PROTO_INFO transact return error = %{public}d", err);
500         return IRemoteObject::IF_PROT_ERROR;
501     }
502 
503     switch (reply.ReadUint32()) {
504         case IRemoteObject::IF_PROT_BINDER: {
505             break;
506         }
507         case IRemoteObject::IF_PROT_DATABUS: {
508             if (UpdateDatabusClientSession(handle_, reply)) {
509                 ZLOGW(LABEL, "it is dbinder, not binder");
510                 return IRemoteObject::IF_PROT_DATABUS;
511             } else {
512                 ZLOGE(LABEL, "UpdateDatabusClientSession failed");
513                 return IRemoteObject::IF_PROT_ERROR;
514             }
515             break;
516         }
517         default: {
518             ZLOGE(LABEL, "GetSessionFromDBinderService Invalid Type");
519             return IRemoteObject::IF_PROT_ERROR;
520             break;
521         }
522     }
523 
524     return IRemoteObject::IF_PROT_BINDER;
525 }
526 
AddDbinderDeathRecipient()527 bool IPCObjectProxy::AddDbinderDeathRecipient()
528 {
529     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
530     if (current == nullptr) {
531         ZLOGE(LABEL, "%s: get current fail", __func__);
532         return false;
533     }
534 
535     if (current->QueryCallbackStub(this) != nullptr) {
536         ZLOGW(LABEL, "%s: already attach callback stub", __func__);
537         return true;
538     }
539 
540     sptr<IPCObjectStub> callbackStub = new (std::nothrow) IPCObjectStub(descriptor_);
541     if (callbackStub == nullptr) {
542         ZLOGE(LABEL, "create IPCObjectStub object failed");
543         return false;
544     }
545     if (!current->AttachCallbackStub(this, callbackStub)) {
546         ZLOGW(LABEL, "%s: already attach new callback stub", __func__);
547         return false;
548     }
549 
550     MessageParcel data;
551     MessageParcel reply;
552     MessageOption option(MessageOption::TF_SYNC);
553     data.WriteInt32(IRemoteObject::DeathRecipient::ADD_DEATH_RECIPIENT);
554     data.WriteRemoteObject(callbackStub);
555     data.WriteString(current->GetDatabusName());
556 
557     int err = SendLocalRequest(DBINDER_OBITUARY_TRANSACTION, data, reply, option);
558     if (err != ERR_NONE || reply.ReadInt32() != ERR_NONE) {
559         ZLOGE(LABEL, "%s: send local request fail, err = %d", __func__, err);
560         (void)current->DetachCallbackStubByProxy(this);
561         return false;
562     }
563 
564     return true;
565 }
566 
RemoveDbinderDeathRecipient()567 bool IPCObjectProxy::RemoveDbinderDeathRecipient()
568 {
569     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
570     if (current == nullptr) {
571         ZLOGE(LABEL, "%s: get current fail", __func__);
572         return false;
573     }
574 
575     sptr<IPCObjectStub> callbackStub = current->QueryCallbackStub(this);
576     if (callbackStub == nullptr) {
577         ZLOGE(LABEL, "%s: get callbackStub fail", __func__);
578         return false;
579     }
580 
581     MessageParcel data;
582     MessageParcel reply;
583     MessageOption option(MessageOption::TF_SYNC);
584     data.WriteInt32(IRemoteObject::DeathRecipient::REMOVE_DEATH_RECIPIENT);
585     data.WriteRemoteObject(callbackStub);
586 
587     int err = SendLocalRequest(DBINDER_OBITUARY_TRANSACTION, data, reply, option);
588     if (err != ERR_NONE || reply.ReadInt32() != ERR_NONE) {
589         ZLOGE(LABEL, "%s: send local request fail, err = %d", __func__, err);
590         // do nothing, even send request failed
591     }
592 
593     return current->DetachCallbackStubByProxy(this);
594 }
595 
CheckHaveSession()596 bool IPCObjectProxy::CheckHaveSession()
597 {
598     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
599     if (current == nullptr) {
600         ZLOGE(LABEL, "IPCProcessSkeleton is null, set type as binder");
601         return false;
602     }
603 
604     std::shared_ptr<DBinderSessionObject> session = current->ProxyQueryDBinderSession(handle_);
605     if (session == nullptr) {
606         return false;
607     }
608 
609     return true;
610 }
611 
UpdateDatabusClientSession(int handle,MessageParcel & reply)612 bool IPCObjectProxy::UpdateDatabusClientSession(int handle, MessageParcel &reply)
613 {
614     DBinderDatabusInvoker *invoker =
615         reinterpret_cast<DBinderDatabusInvoker *>(IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS));
616     if (invoker == nullptr) {
617         ZLOGE(LABEL, "%s: invoker null", __func__);
618         return false;
619     }
620 
621     uint64_t stubIndex = reply.ReadUint64();
622     std::string serviceName = reply.ReadString();
623     std::string peerID = reply.ReadString();
624     std::string localID = reply.ReadString();
625     std::string localBusName = reply.ReadString();
626     uint32_t rpcFeatureSet = reply.ReadUint32();
627     uint32_t tokenId = 0;
628     if (IsATEnable(rpcFeatureSet) == true) {
629         tokenId = RpcGetSelfTokenID();
630     }
631     std::shared_ptr<FeatureSetData> featureSet = nullptr;
632     featureSet.reset(reinterpret_cast<FeatureSetData *>(::operator new(sizeof(FeatureSetData))));
633     if (featureSet == nullptr) {
634         ZLOGE(LABEL, "%s: featureSet null", __func__);
635         return false;
636     }
637     featureSet->featureSet = rpcFeatureSet;
638     featureSet->tokenId = tokenId;
639 
640     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
641     if (current == nullptr) {
642         ZLOGE(LABEL, "%s:current process skeleton is nullptr", __func__);
643         return false;
644     }
645 
646     std::shared_ptr<DBinderSessionObject> connectSession = current->QuerySessionByInfo(serviceName, peerID);
647     if (connectSession == nullptr) {
648         connectSession = std::make_shared<DBinderSessionObject>(nullptr, serviceName, peerID);
649         if (connectSession == nullptr) {
650             ZLOGE(LABEL, "new server session fail!");
651             return false;
652         }
653     }
654     connectSession->SetFeatureSet(featureSet);
655 
656     if (!current->AttachHandleToIndex((uint32_t)handle, stubIndex)) {
657         ZLOGE(LABEL, "add stub index err stubIndex = %" PRIu64 ", handle = %d", stubIndex, handle);
658         return false;
659     }
660 
661     if (!current->CreateSoftbusServer(localBusName)) {
662         ZLOGE(LABEL, "create bus server fail name = %s, localID = %s", localBusName.c_str(), localID.c_str());
663         return false;
664     }
665 
666     bool result = invoker->UpdateClientSession(handle, connectSession);
667     return result;
668 }
669 
ReleaseDatabusProto()670 void IPCObjectProxy::ReleaseDatabusProto()
671 {
672     if (handle_ == 0) {
673         ZLOGD(LABEL, "%s:handle == 0, do nothing", __func__);
674         return;
675     }
676 
677     if (proto_ != IRemoteObject::IF_PROT_DATABUS) {
678         return;
679     }
680 
681     MessageParcel data, reply;
682     MessageOption option = { MessageOption::TF_ASYNC };
683     int32_t err = SendRequestInner(false, DBINDER_DECREFS_TRANSACTION, data, reply, option);
684     if (err != ERR_NONE) {
685         ZLOGW(LABEL, "DBINDER_DECREFS_TRANSACTION transact return error = %{public}d", err);
686         // do nothing
687     }
688 
689     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
690     if (current == nullptr) {
691         ZLOGE(LABEL, "release proto current is null");
692         return;
693     }
694     std::shared_ptr<DBinderSessionObject> toBeDelete = current->ProxyQueryDBinderSession(handle_);
695     if (toBeDelete != nullptr &&
696         current->QuerySessionByInfo(toBeDelete->GetServiceName(), toBeDelete->GetDeviceId()) != nullptr) {
697             toBeDelete->CloseDatabusSession();
698         }
699 }
700 
ReleaseBinderProto()701 void IPCObjectProxy::ReleaseBinderProto()
702 {
703     // do nothing
704 }
705 #endif
706 } // namespace OHOS
707