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