• 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 "dbinder_service.h"
17 
18 #include <cinttypes>
19 #include "securec.h"
20 #include "string_ex.h"
21 #include "ipc_skeleton.h"
22 #include "ipc_thread_skeleton.h"
23 
24 #include "dbinder_log.h"
25 #include "dbinder_service_stub.h"
26 #include "dbinder_remote_listener.h"
27 #include "dbinder_error_code.h"
28 #include "dbinder_sa_death_recipient.h"
29 #include "ffrt.h"
30 #include "softbus_bus_center.h"
31 
32 namespace OHOS {
33 using namespace Communication;
34 
35 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC_DBINDER_SER, "DbinderService" };
36 
37 sptr<DBinderService> DBinderService::instance_ = nullptr;
38 bool DBinderService::mainThreadCreated_ = false;
39 std::mutex DBinderService::instanceMutex_;
40 std::shared_ptr<DBinderRemoteListener> DBinderService::remoteListener_ = nullptr;
41 constexpr unsigned int BINDER_MASK = 0xffff;
42 // DBinderServiceStub's reference count in a MakeRemoteBinder call.
43 constexpr int DBINDER_STUB_REF_COUNT = 2;
44 
DBinderService()45 DBinderService::DBinderService()
46 {
47     DBINDER_LOGI(LOG_LABEL, "create dbinder service");
48 }
49 
~DBinderService()50 DBinderService::~DBinderService()
51 {
52     StopRemoteListener();
53 
54     DBinderStubRegisted_.clear();
55     mapDBinderStubRegisters_.clear();
56     mapRemoteBinderObjects_.clear();
57     threadLockInfo_.clear();
58     proxyObject_.clear();
59     sessionObject_.clear();
60     noticeProxy_.clear();
61     deathRecipients_.clear();
62     loadSaReply_.clear();
63     dbinderCallback_ = nullptr;
64     DBINDER_LOGI(LOG_LABEL, "dbinder service died");
65 }
66 
GetLocalDeviceID()67 std::string DBinderService::GetLocalDeviceID()
68 {
69     std::string pkgName = "DBinderService";
70     NodeBasicInfo nodeBasicInfo;
71     if (GetLocalNodeDeviceInfo(pkgName.c_str(), &nodeBasicInfo) != 0) {
72         DBINDER_LOGE(LOG_LABEL, "Get local node device info failed");
73         return "";
74     }
75     std::string networkId(nodeBasicInfo.networkId);
76     return networkId;
77 }
78 
StartDBinderService(std::shared_ptr<RpcSystemAbilityCallback> & callbackImpl)79 bool DBinderService::StartDBinderService(std::shared_ptr<RpcSystemAbilityCallback> &callbackImpl)
80 {
81     if (mainThreadCreated_) {
82         return ReStartRemoteListener();
83     }
84 
85     bool result = StartRemoteListener();
86     if (!result) {
87         return false;
88     }
89     mainThreadCreated_ = true;
90     dbinderCallback_ = callbackImpl;
91 
92     return true;
93 }
94 
StartRemoteListener()95 bool DBinderService::StartRemoteListener()
96 {
97     if (remoteListener_ != nullptr) {
98         DBINDER_LOGI(LOG_LABEL, "remote listener started");
99         return true;
100     }
101 
102     remoteListener_ = std::make_shared<DBinderRemoteListener>(GetInstance());
103     if (remoteListener_ == nullptr) {
104         DBINDER_LOGE(LOG_LABEL, "failed to create remote listener");
105         return false;
106     }
107 
108     if (remoteListener_->StartListener(remoteListener_) != true) {
109         StopRemoteListener();
110         return false;
111     }
112 
113     DBINDER_LOGI(LOG_LABEL, "start remote listener ok");
114     return true;
115 }
116 
ReStartRemoteListener()117 bool DBinderService::ReStartRemoteListener()
118 {
119     if (remoteListener_ == nullptr) {
120         DBINDER_LOGE(LOG_LABEL, "restart remote listener got null");
121         return false;
122     }
123     if (remoteListener_->StartListener(remoteListener_) != true) {
124         DBINDER_LOGE(LOG_LABEL, "restart dbinder server failed");
125         StopRemoteListener();
126         return false;
127     }
128     return true;
129 }
130 
StopRemoteListener()131 void DBinderService::StopRemoteListener()
132 {
133     if (remoteListener_ != nullptr) {
134         remoteListener_->StopListener();
135         remoteListener_ = nullptr;
136     }
137 }
138 
GetRemoteListener()139 std::shared_ptr<DBinderRemoteListener> DBinderService::GetRemoteListener()
140 {
141     if (remoteListener_ == nullptr && !StartRemoteListener()) {
142         return nullptr;
143     }
144     return remoteListener_;
145 }
146 
GetInstance()147 sptr<DBinderService> DBinderService::GetInstance()
148 {
149     if (instance_ == nullptr) {
150         std::lock_guard<std::mutex> lockGuard(instanceMutex_);
151         if (instance_ == nullptr) {
152             sptr<DBinderService> temp = new DBinderService();
153             instance_ = temp;
154         }
155     }
156     return instance_;
157 }
158 
GetSeqNumber()159 uint32_t DBinderService::GetSeqNumber()
160 {
161     std::lock_guard<std::mutex> lockGuard(instanceMutex_);
162     if (seqNumber_ == std::numeric_limits<uint32_t>::max()) {
163         seqNumber_ = 0;
164     }
165     seqNumber_++;
166     return seqNumber_;
167 }
168 
IsDeviceIdIllegal(const std::string & deviceID)169 bool DBinderService::IsDeviceIdIllegal(const std::string &deviceID)
170 {
171     if (deviceID.empty() || deviceID.length() > DEVICEID_LENGTH) {
172         return true;
173     }
174     return false;
175 }
176 
AddStubByTag(binder_uintptr_t stub)177 binder_uintptr_t DBinderService::AddStubByTag(binder_uintptr_t stub)
178 {
179     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
180 
181     // the same stub needs add stubNum to mapDBinderStubRegisters_, the previous corresponding stubNum will be returned.
182     for (auto iter = mapDBinderStubRegisters_.begin(); iter != mapDBinderStubRegisters_.end(); iter++) {
183         if (iter->second == stub) {
184             return iter->first;
185         }
186     }
187     binder_uintptr_t stubTag = stubTagNum_++;
188     auto result = mapDBinderStubRegisters_.insert(
189         std::pair<binder_uintptr_t, binder_uintptr_t>(stubTag, stub));
190     if (result.second) {
191         return stubTag;
192     } else {
193         return 0;
194     }
195 }
196 
QueryStubPtr(binder_uintptr_t stubTag)197 binder_uintptr_t DBinderService::QueryStubPtr(binder_uintptr_t stubTag)
198 {
199     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
200 
201     auto iter = mapDBinderStubRegisters_.find(stubTag);
202     if (iter != mapDBinderStubRegisters_.end()) {
203         return iter->second;
204     }
205 
206     return 0;
207 }
208 
CheckBinderObject(const sptr<DBinderServiceStub> & stub,binder_uintptr_t stubPtr)209 bool DBinderService::CheckBinderObject(const sptr<DBinderServiceStub> &stub, binder_uintptr_t stubPtr)
210 {
211     if (stub == nullptr) {
212         return false;
213     }
214 
215     if (reinterpret_cast<binder_uintptr_t>(stub.GetRefPtr()) == stubPtr) {
216         DBINDER_LOGI(LOG_LABEL, "found registered stub");
217         return true;
218     }
219     return false;
220 }
221 
HasDBinderStub(binder_uintptr_t stubPtr)222 bool DBinderService::HasDBinderStub(binder_uintptr_t stubPtr)
223 {
224     auto checkStub = [&stubPtr, this](const sptr<DBinderServiceStub> &stub) {
225         return CheckBinderObject(stub, stubPtr);
226     };
227 
228     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
229     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
230     if (it != DBinderStubRegisted_.end()) {
231         return true;
232     }
233     return false;
234 }
235 
IsSameStubObject(const sptr<DBinderServiceStub> & stub,const std::u16string & service,const std::string & device)236 bool DBinderService::IsSameStubObject(const sptr<DBinderServiceStub> &stub, const std::u16string &service,
237     const std::string &device)
238 {
239     if (stub == nullptr) {
240         return false;
241     }
242     const std::string serviceStr8 = Str16ToStr8(service);
243     if (IsSameTextStr(stub->GetServiceName(), serviceStr8) && IsSameTextStr(stub->GetDeviceID(), device)) {
244         DBINDER_LOGI(LOG_LABEL, "found registered service, name:%{public}s device:%{public}s",
245             serviceStr8.c_str(), DBinderService::ConvertToSecureDeviceID(device).c_str());
246         return true;
247     }
248     return false;
249 }
250 
FindDBinderStub(const std::u16string & service,const std::string & device)251 sptr<DBinderServiceStub> DBinderService::FindDBinderStub(const std::u16string &service, const std::string &device)
252 {
253     auto checkStub = [&service, &device, this](const sptr<DBinderServiceStub> &stub) {
254         return IsSameStubObject(stub, service, device);
255     };
256 
257     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
258     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
259     if (it == DBinderStubRegisted_.end()) {
260         DBINDER_LOGW(LOG_LABEL, "not found, service:%{public}s device:%{public}s", Str16ToStr8(service).c_str(),
261             DBinderService::ConvertToSecureDeviceID(device).c_str());
262         return nullptr;
263     }
264     DBINDER_LOGD(LOG_LABEL, "found, service:%{public}s device:%{public}s", Str16ToStr8(service).c_str(),
265         DBinderService::ConvertToSecureDeviceID(device).c_str());
266     return (*it);
267 }
268 
DeleteDBinderStub(const std::u16string & service,const std::string & device)269 bool DBinderService::DeleteDBinderStub(const std::u16string &service, const std::string &device)
270 {
271     auto checkStub = [&service, &device, this](const sptr<DBinderServiceStub> &stub) {
272         return IsSameStubObject(stub, service, device);
273     };
274 
275     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
276     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
277     if (it == DBinderStubRegisted_.end()) {
278         DBINDER_LOGW(LOG_LABEL, "not found, service:%{public}s device:%{public}s", Str16ToStr8(service).c_str(),
279             DBinderService::ConvertToSecureDeviceID(device).c_str());
280         return false;
281     }
282 
283     for (auto mapIt = mapDBinderStubRegisters_.begin(); mapIt != mapDBinderStubRegisters_.end();) {
284         if (mapIt->second == reinterpret_cast<binder_uintptr_t>((*it).GetRefPtr())) {
285             mapIt = mapDBinderStubRegisters_.erase(mapIt);
286         } else {
287             ++mapIt;
288         }
289     }
290     DBinderStubRegisted_.erase(it);
291     DBINDER_LOGI(LOG_LABEL, "succ, service:%{public}s device:%{public}s", Str16ToStr8(service).c_str(),
292         DBinderService::ConvertToSecureDeviceID(device).c_str());
293     return true;
294 }
295 
FindOrNewDBinderStub(const std::u16string & service,const std::string & device,binder_uintptr_t binderObject)296 sptr<DBinderServiceStub> DBinderService::FindOrNewDBinderStub(const std::u16string &service, const std::string &device,
297     binder_uintptr_t binderObject)
298 {
299     auto checkStub = [&service, &device, this](const sptr<DBinderServiceStub> &stub) {
300         return IsSameStubObject(stub, service, device);
301     };
302 
303     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
304     const std::string serviceStr8 = Str16ToStr8(service);
305     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
306     if (it != DBinderStubRegisted_.end()) {
307         DBINDER_LOGD(LOG_LABEL, "found, service:%{public}s device:%{public}s", serviceStr8.c_str(),
308             DBinderService::ConvertToSecureDeviceID(device).c_str());
309         return (*it);
310     }
311 
312     sptr<DBinderServiceStub> dBinderServiceStub = new DBinderServiceStub(serviceStr8, device, binderObject);
313     DBinderStubRegisted_.push_back(dBinderServiceStub);
314     DBINDER_LOGD(LOG_LABEL, "create, service:%{public}s device:%{public}s", serviceStr8.c_str(),
315         DBinderService::ConvertToSecureDeviceID(device).c_str());
316     return dBinderServiceStub;
317 }
318 
MakeRemoteBinder(const std::u16string & serviceName,const std::string & deviceID,int32_t binderObject,uint32_t pid,uint32_t uid)319 sptr<DBinderServiceStub> DBinderService::MakeRemoteBinder(const std::u16string &serviceName,
320     const std::string &deviceID, int32_t binderObject, uint32_t pid, uint32_t uid)
321 {
322     if (IsDeviceIdIllegal(deviceID) || serviceName.length() == 0) {
323         DBINDER_LOGE(LOG_LABEL, "para is wrong, device length:%{public}zu, service length:%{public}zu",
324             deviceID.length(), serviceName.length());
325         return nullptr;
326     }
327     const std::string serviceNameStr8 = Str16ToStr8(serviceName);
328     DBINDER_LOGI(LOG_LABEL, "service:%{public}s device:%{public}s", serviceNameStr8.c_str(),
329         DBinderService::ConvertToSecureDeviceID(deviceID).c_str());
330 
331     sptr<DBinderServiceStub> dBinderServiceStub = FindOrNewDBinderStub(serviceName, deviceID,
332         static_cast<binder_uintptr_t>(binderObject));
333     if (dBinderServiceStub == nullptr) {
334         DBINDER_LOGE(LOG_LABEL, "FindOrNewDBinderStub fail, service:%{public}s", serviceNameStr8.c_str());
335         return nullptr;
336     }
337 
338     /* if not found dBinderServiceStub, should send msg to toDeviceID
339      * to invoker socket thread and add authentication info for create softbus session
340      */
341     int retryTimes = 0;
342     int32_t ret = -1;
343     do {
344         ret = InvokerRemoteDBinder(dBinderServiceStub, GetSeqNumber(), pid, uid);
345         retryTimes++;
346     } while (ret == WAIT_REPLY_TIMEOUT && (retryTimes < RETRY_TIMES));
347 
348     if (ret != DBINDER_OK) {
349         DBINDER_LOGE(LOG_LABEL, "fail to invoke service, service:%{public}s device:%{public}s "
350             "DBinderServiceStub refcount:%{public}d",
351             serviceNameStr8.c_str(), DBinderService::ConvertToSecureDeviceID(deviceID).c_str(),
352             dBinderServiceStub->GetSptrRefCount());
353         if (dBinderServiceStub->GetSptrRefCount() <= DBINDER_STUB_REF_COUNT) {
354             /* invoke fail, delete dbinder stub info */
355             (void)DeleteDBinderStub(serviceName, deviceID);
356             (void)DetachSessionObject(reinterpret_cast<binder_uintptr_t>(dBinderServiceStub.GetRefPtr()));
357         }
358         return nullptr;
359     }
360 
361     return dBinderServiceStub;
362 }
363 
SendEntryToRemote(const sptr<DBinderServiceStub> stub,uint32_t seqNumber,uint32_t pid,uint32_t uid)364 bool DBinderService::SendEntryToRemote(const sptr<DBinderServiceStub> stub, uint32_t seqNumber, uint32_t pid,
365     uint32_t uid)
366 {
367     const std::string deviceID = stub->GetDeviceID();
368     const std::string localDevID = GetLocalDeviceID();
369     if (IsDeviceIdIllegal(deviceID) || IsDeviceIdIllegal(localDevID)) {
370         DBINDER_LOGE(LOG_LABEL, "wrong device id length, remote:%{public}zu local:%{public}zu",
371             deviceID.length(), localDevID.length());
372         return false;
373     }
374 
375     std::shared_ptr<struct DHandleEntryTxRx> message = std::make_shared<struct DHandleEntryTxRx>();
376     message->head.len            = sizeof(DHandleEntryTxRx);
377     message->head.version        = RPC_TOKENID_SUPPORT_VERSION;
378     message->dBinderCode         = MESSAGE_AS_INVOKER;
379     message->transType           = GetRemoteTransType();
380     message->fromPort            = 0;
381     message->toPort              = 0;
382     message->stubIndex           = static_cast<uint64_t>(std::atoi(stub->GetServiceName().c_str()));
383     message->seqNumber           = seqNumber;
384     message->binderObject        = stub->GetBinderObject();
385     message->stub                = AddStubByTag(reinterpret_cast<binder_uintptr_t>(stub.GetRefPtr()));
386     message->deviceIdInfo.tokenId = IPCSkeleton::GetCallingTokenID();
387     message->pid                 = pid;
388     message->uid                 = uid;
389     if (memcpy_s(message->deviceIdInfo.fromDeviceId, DEVICEID_LENGTH, localDevID.data(), localDevID.length()) != 0 ||
390         memcpy_s(message->deviceIdInfo.toDeviceId, DEVICEID_LENGTH, deviceID.data(), deviceID.length()) != 0) {
391         DBINDER_LOGE(LOG_LABEL, "fail to copy memory, service:%{public}" PRIu64" seq:%{public}u",
392             message->stubIndex, message->seqNumber);
393         return false;
394     }
395     message->deviceIdInfo.fromDeviceId[localDevID.length()] = '\0';
396     message->deviceIdInfo.toDeviceId[deviceID.length()] = '\0';
397     DBINDER_LOGI(LOG_LABEL, "pid:%{public}u uid:%{public}u seq:%{public}u stub:%{public}llu"
398         " tokenId:%{public}u", message->pid, message->uid, message->seqNumber,
399         (message->stub & BINDER_MASK), message->deviceIdInfo.tokenId);
400 
401     std::shared_ptr<DBinderRemoteListener> remoteListener = GetRemoteListener();
402     if (remoteListener == nullptr) {
403         DBINDER_LOGE(LOG_LABEL, "remoteListener is null, service:%{public}" PRIu64 " seq:%{public}u",
404             message->stubIndex, message->seqNumber);
405         return false;
406     }
407     bool result = remoteListener->SendDataToRemote(deviceID, message.get());
408     if (result != true) {
409         DBINDER_LOGE(LOG_LABEL, "SendDataToRemote failed, service:%{public}" PRIu64" seq:%{public}u",
410             message->stubIndex, message->seqNumber);
411         return false;
412     }
413     return true;
414 }
415 
InvokerRemoteDBinder(const sptr<DBinderServiceStub> stub,uint32_t seqNumber,uint32_t pid,uint32_t uid)416 int32_t DBinderService::InvokerRemoteDBinder(const sptr<DBinderServiceStub> stub, uint32_t seqNumber,
417     uint32_t pid, uint32_t uid)
418 {
419     if (stub == nullptr) {
420         DBINDER_LOGE(LOG_LABEL, "stub is nullptr");
421         return STUB_INVALID;
422     }
423 
424     bool result = SendEntryToRemote(stub, seqNumber, pid, uid);
425     if (!result) {
426         DBINDER_LOGE(LOG_LABEL, "SendEntryToRemote fail, seq:%{public}u", seqNumber);
427         return SEND_MESSAGE_FAILED;
428     }
429 
430     /* pend to wait reply */
431     std::shared_ptr<struct ThreadLockInfo> threadLockInfo = std::make_shared<struct ThreadLockInfo>();
432     result = AttachThreadLockInfo(seqNumber, stub->GetDeviceID(), threadLockInfo);
433     if (result != true) {
434         DBINDER_LOGE(LOG_LABEL, "AttachThreadLockInfo fail, seq:%{public}u", seqNumber);
435         return MAKE_THREADLOCK_FAILED;
436     }
437 
438     std::unique_lock<std::mutex> lock(threadLockInfo->mutex);
439     if (threadLockInfo->condition.wait_for(lock, std::chrono::seconds(WAIT_FOR_REPLY_MAX_SEC),
440         [&threadLockInfo] { return threadLockInfo->ready; }) == false) {
441         DBINDER_LOGE(LOG_LABEL, "get remote data timeout, seq:%{public}u", seqNumber);
442         DetachThreadLockInfo(seqNumber);
443         threadLockInfo->ready = false;
444         return WAIT_REPLY_TIMEOUT;
445     }
446     /* if can not find session, means invoke failed or nothing in OnRemoteReplyMessage() */
447     auto session = QuerySessionObject(reinterpret_cast<binder_uintptr_t>(stub.GetRefPtr()));
448     if (session == nullptr) {
449         DBINDER_LOGE(LOG_LABEL, "client find session is null, seq:%{public}u", seqNumber);
450         return QUERY_REPLY_SESSION_FAILED;
451     }
452     return DBINDER_OK;
453 }
454 
CheckSystemAbilityId(int32_t systemAbilityId)455 bool DBinderService::CheckSystemAbilityId(int32_t systemAbilityId)
456 {
457     return systemAbilityId >= FIRST_SYS_ABILITY_ID && systemAbilityId <= LAST_SYS_ABILITY_ID;
458 }
459 
AllocFreeSocketPort()460 uint16_t DBinderService::AllocFreeSocketPort()
461 {
462     /* alloc port by system */
463     return 0;
464 }
465 
IsSameLoadSaItem(const std::string & srcNetworkId,int32_t systemAbilityId,std::shared_ptr<DHandleEntryTxRx> loadSaItem)466 bool DBinderService::IsSameLoadSaItem(const std::string& srcNetworkId, int32_t systemAbilityId,
467     std::shared_ptr<DHandleEntryTxRx> loadSaItem)
468 {
469     if (static_cast<int32_t>(loadSaItem->stubIndex) == systemAbilityId &&
470         loadSaItem->deviceIdInfo.fromDeviceId == srcNetworkId) {
471         DBINDER_LOGI(LOG_LABEL, "match succeed");
472         return true;
473     }
474     return false;
475 }
476 
PopLoadSaItem(const std::string & srcNetworkId,int32_t systemAbilityId)477 std::shared_ptr<DHandleEntryTxRx> DBinderService::PopLoadSaItem(const std::string& srcNetworkId,
478     int32_t systemAbilityId)
479 {
480     auto checkSaItem = [srcNetworkId, systemAbilityId, this](std::shared_ptr<DHandleEntryTxRx> loadSaItem) {
481         return IsSameLoadSaItem(srcNetworkId, systemAbilityId, loadSaItem);
482     };
483 
484     std::lock_guard<std::shared_mutex> lockGuard(loadSaMutex_);
485     auto it = std::find_if(loadSaReply_.begin(), loadSaReply_.end(), checkSaItem);
486     if (it == loadSaReply_.end()) {
487         DBINDER_LOGE(LOG_LABEL, "findSaItem failed saId:%{public}d, deviceId:%{public}s",
488             systemAbilityId, srcNetworkId.c_str());
489         return nullptr;
490     }
491     std::shared_ptr<DHandleEntryTxRx> replymsg = (*it);
492     it = loadSaReply_.erase(it);
493     return replymsg;
494 }
495 
LoadSystemAbilityComplete(const std::string & srcNetworkId,int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)496 void DBinderService::LoadSystemAbilityComplete(const std::string& srcNetworkId, int32_t systemAbilityId,
497     const sptr<IRemoteObject>& remoteObject)
498 {
499     while (true) {
500         std::shared_ptr<struct DHandleEntryTxRx> replyMessage = PopLoadSaItem(srcNetworkId, systemAbilityId);
501         if (replyMessage == nullptr) {
502             break;
503         }
504         if (remoteObject == nullptr) {
505             SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_NOT_FOUND, replyMessage);
506             DBINDER_LOGE(LOG_LABEL, "GetSystemAbility from samgr error, saId:%{public}d", systemAbilityId);
507             continue;
508         }
509         binder_uintptr_t binderObject = replyMessage->binderObject;
510         IPCObjectProxy *saProxy = reinterpret_cast<IPCObjectProxy *>(remoteObject.GetRefPtr());
511         if (QueryProxyObject(binderObject) == nullptr) {
512             /* When the stub object dies, you need to delete the corresponding busName information */
513             sptr<IRemoteObject::DeathRecipient> death(new DbinderSaDeathRecipient(binderObject));
514             if (!saProxy->AddDeathRecipient(death)) {
515                 SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_NOT_FOUND, replyMessage);
516                 DBINDER_LOGE(LOG_LABEL, "fail to add death recipient");
517                 continue;
518             }
519             if (!AttachProxyObject(remoteObject, binderObject)) {
520                 DBINDER_LOGW(LOG_LABEL, "attach proxy object is already existed");
521             }
522         }
523         std::string deviceId = replyMessage->deviceIdInfo.fromDeviceId;
524         if (replyMessage->transType != IRemoteObject::DATABUS_TYPE) {
525             SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_INVOKE_FAILED, replyMessage);
526             DBINDER_LOGE(LOG_LABEL, "Invalid Message Type");
527         } else {
528             // peer device rpc version == 1, not support thokenId and message->deviceIdInfo.tokenId is random value
529             uint32_t tokenId = (replyMessage->head.version < RPC_TOKENID_SUPPORT_VERSION) ?
530                 0 : replyMessage->deviceIdInfo.tokenId;
531             uint32_t result = OnRemoteInvokerDataBusMessage(saProxy, replyMessage.get(), deviceId,
532                 replyMessage->pid, replyMessage->uid, tokenId);
533             if (result != 0) {
534                 SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, result, replyMessage);
535                 continue;
536             }
537             SendReplyMessageToRemote(MESSAGE_AS_REPLY, 0, replyMessage);
538         }
539     }
540     DBINDER_LOGI(LOG_LABEL, "LoadSystemAbility complete");
541 }
542 
SendReplyMessageToRemote(uint32_t dBinderCode,uint32_t reason,std::shared_ptr<struct DHandleEntryTxRx> replyMessage)543 void DBinderService::SendReplyMessageToRemote(uint32_t dBinderCode, uint32_t reason,
544     std::shared_ptr<struct DHandleEntryTxRx> replyMessage)
545 {
546     std::shared_ptr<DBinderRemoteListener> remoteListener = GetRemoteListener();
547     if (remoteListener == nullptr) {
548         DBINDER_LOGE(LOG_LABEL, "remoteListener is null");
549         return;
550     }
551     replyMessage->dBinderCode = dBinderCode;
552     if (dBinderCode == MESSAGE_AS_REMOTE_ERROR) {
553         replyMessage->transType = reason; // reuse transType send back error code
554     }
555     if (!remoteListener->SendDataReply(replyMessage->deviceIdInfo.fromDeviceId, replyMessage.get())) {
556         DBINDER_LOGE(LOG_LABEL, "fail to send data from server DBS to client DBS");
557     }
558 }
559 
OnRemoteInvokerMessage(const struct DHandleEntryTxRx * message)560 bool DBinderService::OnRemoteInvokerMessage(const struct DHandleEntryTxRx *message)
561 {
562     DBINDER_LOGI(LOG_LABEL,
563         "invoke business service:%{public}d seq:%{public}u stub:%{public}llu tokenId:%{public}u",
564         static_cast<int32_t>(message->stubIndex), message->seqNumber,
565         (message->stub & BINDER_MASK), message->deviceIdInfo.tokenId);
566     std::shared_ptr<struct DHandleEntryTxRx> replyMessage = std::make_shared<struct DHandleEntryTxRx>();
567     if (memcpy_s(replyMessage.get(), sizeof(DHandleEntryTxRx), message, sizeof(DHandleEntryTxRx)) != 0) {
568         DBINDER_LOGE(LOG_LABEL, "memcpy DHandleEntryTxRx fail");
569         return false;
570     }
571 
572     {
573         std::lock_guard<std::shared_mutex> lockGuard(loadSaMutex_);
574         loadSaReply_.push_back(replyMessage);
575     }
576     bool isSaAvailable = dbinderCallback_->LoadSystemAbilityFromRemote(replyMessage->deviceIdInfo.fromDeviceId,
577         static_cast<int32_t>(replyMessage->stubIndex));
578     if (!isSaAvailable) {
579         DBINDER_LOGE(LOG_LABEL, "fail to call the system ability");
580         PopLoadSaItem(replyMessage->deviceIdInfo.fromDeviceId, static_cast<int32_t>(replyMessage->stubIndex));
581         return false;
582     }
583     return true;
584 }
585 
GetDatabusNameByProxy(IPCObjectProxy * proxy)586 std::string DBinderService::GetDatabusNameByProxy(IPCObjectProxy *proxy)
587 {
588     if (proxy == nullptr) {
589         DBINDER_LOGE(LOG_LABEL, "proxy can not be null");
590         return "";
591     }
592     std::string sessionName = proxy->GetSessionName();
593     if (sessionName.empty()) {
594         DBINDER_LOGE(LOG_LABEL, "grand session name failed");
595         return "";
596     }
597     DBINDER_LOGD(LOG_LABEL, "succ, handle:%{public}d sessionName:%{public}s",
598         proxy->GetHandle(), sessionName.c_str());
599     return sessionName;
600 }
601 
CreateDatabusName(int uid,int pid)602 std::string DBinderService::CreateDatabusName(int uid, int pid)
603 {
604     std::shared_ptr<ISessionService> softbusManager = ISessionService::GetInstance();
605     if (softbusManager == nullptr) {
606         DBINDER_LOGE(LOG_LABEL, "fail to get softbus service");
607         return "";
608     }
609 
610     std::string sessionName = "DBinder" + std::to_string(uid) + std::string("_") + std::to_string(pid);
611     if (softbusManager->GrantPermission(uid, pid, sessionName) != ERR_NONE) {
612         DBINDER_LOGE(LOG_LABEL, "fail to Grant Permission softbus name");
613         return "";
614     }
615 
616     return sessionName;
617 }
618 
OnRemoteInvokerDataBusMessage(IPCObjectProxy * proxy,struct DHandleEntryTxRx * replyMessage,std::string & remoteDeviceId,int pid,int uid,uint32_t tokenId)619 uint32_t DBinderService::OnRemoteInvokerDataBusMessage(IPCObjectProxy *proxy, struct DHandleEntryTxRx *replyMessage,
620     std::string &remoteDeviceId, int pid, int uid, uint32_t tokenId)
621 {
622     if (IsDeviceIdIllegal(remoteDeviceId)) {
623         DBINDER_LOGE(LOG_LABEL, "remote device id is error");
624         return DEVICEID_INVALID;
625     }
626     std::string sessionName = GetDatabusNameByProxy(proxy);
627     if (sessionName.empty()) {
628         DBINDER_LOGE(LOG_LABEL, "get bus name fail");
629         return SESSION_NAME_NOT_FOUND;
630     }
631 
632     MessageParcel data;
633     MessageParcel reply;
634     if (!data.WriteUint16(IRemoteObject::DATABUS_TYPE) || !data.WriteString(GetLocalDeviceID()) ||
635         !data.WriteUint32(pid) || !data.WriteUint32(uid) || !data.WriteString(remoteDeviceId) ||
636         !data.WriteString(sessionName) || !data.WriteUint32(tokenId)) {
637         DBINDER_LOGE(LOG_LABEL, "write to parcel fail, handle:%{public}d", proxy->GetHandle());
638         return WRITE_PARCEL_FAILED;
639     }
640     int err = proxy->InvokeListenThread(data, reply);
641     if (err != ERR_NONE) {
642         DBINDER_LOGE(LOG_LABEL, "start service listen error:%{public}d handle:%{public}d", err, proxy->GetHandle());
643         return INVOKE_STUB_THREAD_FAILED;
644     }
645     uint64_t stubIndex = reply.ReadUint64();
646     std::string serverSessionName = reply.ReadString();
647     std::string deviceId = reply.ReadString();
648     uint32_t selfTokenId = reply.ReadUint32();
649     if (stubIndex == 0 || serverSessionName.empty() || serverSessionName.length() > SERVICENAME_LENGTH) {
650         DBINDER_LOGE(LOG_LABEL, "stubindex:%{public}" PRIu64 " or sessionName:%{public}s is invalid"
651             " handle:%{public}d deviceId:%{public}s", stubIndex, serverSessionName.c_str(), proxy->GetHandle(),
652             DBinderService::ConvertToSecureDeviceID(deviceId).c_str());
653         return SESSION_NAME_INVALID;
654     }
655     replyMessage->dBinderCode = MESSAGE_AS_REPLY;
656     if (replyMessage->head.version >= RPC_TOKENID_SUPPORT_VERSION) {
657         replyMessage->dBinderCode = MESSAGE_AS_REPLY_TOKENID;
658     }
659     replyMessage->head.version = RPC_TOKENID_SUPPORT_VERSION;
660     replyMessage->stubIndex = stubIndex;
661     replyMessage->serviceNameLength = serverSessionName.length();
662     replyMessage->deviceIdInfo.tokenId = selfTokenId;
663     if (memcpy_s(replyMessage->serviceName, SERVICENAME_LENGTH, serverSessionName.data(),
664         replyMessage->serviceNameLength) != 0) {
665         DBINDER_LOGE(LOG_LABEL, "memcpy serviceName fail, handle:%{public}d", proxy->GetHandle());
666         return SESSION_NAME_INVALID;
667     }
668     replyMessage->serviceName[replyMessage->serviceNameLength] = '\0';
669     return 0;
670 }
671 
GetRegisterService(binder_uintptr_t binderObject)672 std::u16string DBinderService::GetRegisterService(binder_uintptr_t binderObject)
673 {
674     std::shared_lock<std::shared_mutex> lockGuard(remoteBinderMutex_);
675     for (auto it = mapRemoteBinderObjects_.begin(); it != mapRemoteBinderObjects_.end(); it++) {
676         if (it->second == binderObject) {
677             DBINDER_LOGI(LOG_LABEL, "get service:%{public}s", Str16ToStr8(it->first).c_str());
678             return it->first;
679         }
680     }
681     return std::u16string();
682 }
683 
RegisterRemoteProxy(std::u16string serviceName,sptr<IRemoteObject> binderObject)684 bool DBinderService::RegisterRemoteProxy(std::u16string serviceName, sptr<IRemoteObject> binderObject)
685 {
686     if (serviceName.length() == 0 || binderObject == nullptr) {
687         DBINDER_LOGE(LOG_LABEL, "serviceName length:%{public}zu", serviceName.length());
688         return false;
689     }
690 
691     DBINDER_LOGI(LOG_LABEL, "service name:%{public}s", Str16ToStr8(serviceName).c_str());
692     binder_uintptr_t binder = (binder_uintptr_t)binderObject.GetRefPtr();
693     return RegisterRemoteProxyInner(serviceName, binder);
694 }
695 
RegisterRemoteProxy(std::u16string serviceName,int32_t systemAbilityId)696 bool DBinderService::RegisterRemoteProxy(std::u16string serviceName, int32_t systemAbilityId)
697 {
698     if (serviceName.length() == 0 || systemAbilityId <= 0) {
699         DBINDER_LOGE(LOG_LABEL, "serviceName length:%{public}zu", serviceName.length());
700         return false;
701     }
702     DBINDER_LOGI(LOG_LABEL, "service name:%{public}s saId:%{public}d",
703         Str16ToStr8(serviceName).c_str(), systemAbilityId);
704     binder_uintptr_t binder = (binder_uintptr_t)systemAbilityId;
705     return RegisterRemoteProxyInner(serviceName, binder);
706 }
707 
RegisterRemoteProxyInner(std::u16string serviceName,binder_uintptr_t binder)708 bool DBinderService::RegisterRemoteProxyInner(std::u16string serviceName, binder_uintptr_t binder)
709 {
710     std::unique_lock<std::shared_mutex> lockGuard(remoteBinderMutex_);
711     // clear historical remnants, Don't care if it succeeds
712     (void)mapRemoteBinderObjects_.erase(serviceName);
713     auto result = mapRemoteBinderObjects_.insert(std::pair<std::u16string, binder_uintptr_t>(serviceName, binder));
714     return result.second;
715 }
716 
AddAsynMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message)717 void DBinderService::AddAsynMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message)
718 {
719     auto task = std::bind(&DBinderService::OnRemoteMessageTask, this, message);
720     ffrt::submit(task);
721 }
722 
OnRemoteMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message)723 bool DBinderService::OnRemoteMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message)
724 {
725     if (message == nullptr) {
726         DBINDER_LOGE(LOG_LABEL, "message is null");
727         return false;
728     }
729 
730     bool result = false;
731     switch (message->dBinderCode) {
732         case MESSAGE_AS_INVOKER: {
733             result = OnRemoteInvokerMessage(message.get());
734             break;
735         }
736         case MESSAGE_AS_REPLY:
737         case MESSAGE_AS_REPLY_TOKENID: {
738             result = OnRemoteReplyMessage(message.get());
739             break;
740         }
741         case MESSAGE_AS_REMOTE_ERROR: {
742             result = OnRemoteErrorMessage(message.get());
743             break;
744         }
745         default: {
746             DBINDER_LOGE(LOG_LABEL, "DbinderCode:%{public}u is not support", message->dBinderCode);
747             result = false;
748             break;
749         }
750     }
751     return result;
752 }
753 
ProcessOnSessionClosed(std::shared_ptr<Session> session)754 bool DBinderService::ProcessOnSessionClosed(std::shared_ptr<Session> session)
755 {
756     if (session == nullptr) {
757         DBINDER_LOGE(LOG_LABEL, "ERROR!Session is nullptr!");
758         return false;
759     }
760     std::lock_guard<std::mutex> lock(threadLockMutex_);
761     for (auto it = threadLockInfo_.begin(); it != threadLockInfo_.end();) {
762         if (it->second->networkId != session->GetPeerDeviceId()) {
763             it++;
764             continue;
765         }
766         std::unique_lock<std::mutex> lock(it->second->mutex);
767         it->second->ready = true;
768         it->second->condition.notify_all();
769         it = threadLockInfo_.erase(it);
770     }
771     return true;
772 }
773 
OnRemoteErrorMessage(const struct DHandleEntryTxRx * replyMessage)774 bool DBinderService::OnRemoteErrorMessage(const struct DHandleEntryTxRx *replyMessage)
775 {
776     DBINDER_LOGI(LOG_LABEL, "invoke remote stubIndex:%{public}d error, type:%{public}u seq:%{public}u",
777         static_cast<int32_t>(replyMessage->stubIndex), replyMessage->transType, replyMessage->seqNumber);
778     WakeupThreadByStub(replyMessage->seqNumber);
779     DetachThreadLockInfo(replyMessage->seqNumber);
780     return true;
781 }
782 
OnRemoteReplyMessage(const struct DHandleEntryTxRx * replyMessage)783 bool DBinderService::OnRemoteReplyMessage(const struct DHandleEntryTxRx *replyMessage)
784 {
785     DBINDER_LOGI(LOG_LABEL, "invoker remote stubIndex:%{public}d succ, seq:%{public}u stub:%{public}llu "
786         "tokenId:%{public}u dBinderCode:%{public}u", static_cast<int32_t>(replyMessage->stubIndex),
787         replyMessage->seqNumber, (replyMessage->stub & BINDER_MASK), replyMessage->deviceIdInfo.tokenId,
788         replyMessage->dBinderCode);
789     MakeSessionByReplyMessage(replyMessage);
790     WakeupThreadByStub(replyMessage->seqNumber);
791     DetachThreadLockInfo(replyMessage->seqNumber);
792     return true;
793 }
794 
IsSameSession(std::shared_ptr<struct SessionInfo> oldSession,std::shared_ptr<struct SessionInfo> newSession)795 bool DBinderService::IsSameSession(std::shared_ptr<struct SessionInfo> oldSession,
796     std::shared_ptr<struct SessionInfo> newSession)
797 {
798     if ((oldSession->stubIndex != newSession->stubIndex) || (oldSession->toPort != newSession->toPort)
799         || (oldSession->fromPort != newSession->fromPort) || (oldSession->type != newSession->type)
800         || (oldSession->serviceName != newSession->serviceName)) {
801         return false;
802     }
803     if (strncmp(oldSession->deviceIdInfo.fromDeviceId, newSession->deviceIdInfo.fromDeviceId, DEVICEID_LENGTH) != 0
804         || strncmp(oldSession->deviceIdInfo.toDeviceId, newSession->deviceIdInfo.toDeviceId, DEVICEID_LENGTH) != 0) {
805         return false;
806     }
807 
808     return true;
809 }
810 
MakeSessionByReplyMessage(const struct DHandleEntryTxRx * replyMessage)811 void DBinderService::MakeSessionByReplyMessage(const struct DHandleEntryTxRx *replyMessage)
812 {
813     if (HasDBinderStub(QueryStubPtr(replyMessage->stub)) == false) {
814         DBINDER_LOGE(LOG_LABEL, "invalid stub object");
815         return;
816     }
817 
818     std::shared_ptr<struct SessionInfo> session = std::make_shared<struct SessionInfo>();
819     if (session == nullptr) {
820         DBINDER_LOGE(LOG_LABEL, "new SessionInfo fail");
821         return;
822     }
823 
824     if (memcpy_s(&session->deviceIdInfo, sizeof(struct DeviceIdInfo), &replyMessage->deviceIdInfo,
825         sizeof(struct DeviceIdInfo)) != 0) {
826         DBINDER_LOGE(LOG_LABEL, "fail to copy memory");
827         return;
828     }
829     // remote device NOT support tokenId, clear random value
830     if (replyMessage->dBinderCode == MESSAGE_AS_REPLY) {
831         session->deviceIdInfo.tokenId = 0;
832     }
833     DBINDER_LOGI(LOG_LABEL, "stubIndex:%{public}d tokenId:%{public}u",
834         static_cast<int32_t>(replyMessage->stubIndex), session->deviceIdInfo.tokenId);
835     session->seqNumber   = replyMessage->seqNumber;
836     session->socketFd    = 0;
837     session->stubIndex   = replyMessage->stubIndex;
838     session->toPort      = replyMessage->toPort;
839     session->fromPort    = replyMessage->fromPort;
840     session->type        = replyMessage->transType;
841     session->serviceName = replyMessage->serviceName;
842 
843     if (session->stubIndex == 0) {
844         DBINDER_LOGE(LOG_LABEL, "get stubIndex == 0, it is invalid");
845         return;
846     }
847     // check whether need to update session
848     std::shared_ptr<struct SessionInfo> oldSession = QuerySessionObject(QueryStubPtr(replyMessage->stub));
849     if (oldSession != nullptr) {
850         if (IsSameSession(oldSession, session) == true) {
851             DBINDER_LOGI(LOG_LABEL, "invoker remote session already, do nothing");
852             return;
853         } else {
854             // ignore seqNumber overflow here, greater seqNumber means later request
855             if (oldSession->seqNumber < session->seqNumber) {
856                 // remote old session
857                 if (!DetachSessionObject(QueryStubPtr(replyMessage->stub))) {
858                     DBINDER_LOGE(LOG_LABEL, "failed to detach session object");
859                 }
860             } else {
861                 // do nothing, use old session, discard session got this time
862                 // in this case, old session is requested later, but it comes back earlier
863             }
864         }
865     }
866 
867     if (!AttachSessionObject(session, QueryStubPtr(replyMessage->stub))) {
868         DBINDER_LOGE(LOG_LABEL, "attach SessionInfo fail");
869         return;
870     }
871 }
872 
WakeupThreadByStub(uint32_t seqNumber)873 void DBinderService::WakeupThreadByStub(uint32_t seqNumber)
874 {
875     std::shared_ptr<struct ThreadLockInfo> threadLockInfo = QueryThreadLockInfo(seqNumber);
876     if (threadLockInfo == nullptr) {
877         DBINDER_LOGE(LOG_LABEL, "threadLockInfo is not exist");
878         return;
879     }
880     /* Wake up the client processing thread */
881     std::unique_lock<std::mutex> lock(threadLockInfo->mutex);
882     threadLockInfo->ready = true;
883     threadLockInfo->condition.notify_all();
884 }
885 
DetachThreadLockInfo(uint32_t seqNumber)886 void DBinderService::DetachThreadLockInfo(uint32_t seqNumber)
887 {
888     std::lock_guard<std::mutex> lock(threadLockMutex_);
889     threadLockInfo_.erase(seqNumber);
890 }
891 
AttachThreadLockInfo(uint32_t seqNumber,const std::string & networkId,std::shared_ptr<struct ThreadLockInfo> object)892 bool DBinderService::AttachThreadLockInfo(uint32_t seqNumber, const std::string &networkId,
893     std::shared_ptr<struct ThreadLockInfo> object)
894 {
895     std::lock_guard<std::mutex> lock(threadLockMutex_);
896     object->networkId = networkId;
897     auto result =
898         threadLockInfo_.insert(std::pair<uint32_t, std::shared_ptr<struct ThreadLockInfo>>(seqNumber, object));
899     return result.second;
900 }
901 
QueryThreadLockInfo(uint32_t seqNumber)902 std::shared_ptr<struct ThreadLockInfo> DBinderService::QueryThreadLockInfo(uint32_t seqNumber)
903 {
904     std::lock_guard<std::mutex> lock(threadLockMutex_);
905 
906     auto it = threadLockInfo_.find(seqNumber);
907     if (it != threadLockInfo_.end()) {
908         return it->second;
909     }
910     return nullptr;
911 }
912 
DetachProxyObject(binder_uintptr_t binderObject)913 bool DBinderService::DetachProxyObject(binder_uintptr_t binderObject)
914 {
915     std::unique_lock<std::shared_mutex> lock(proxyMutex_);
916 
917     return (proxyObject_.erase(binderObject) > 0);
918 }
919 
AttachProxyObject(sptr<IRemoteObject> object,binder_uintptr_t binderObject)920 bool DBinderService::AttachProxyObject(sptr<IRemoteObject> object, binder_uintptr_t binderObject)
921 {
922     std::unique_lock<std::shared_mutex> lock(proxyMutex_);
923 
924     auto result = proxyObject_.insert(std::pair<int, sptr<IRemoteObject>>(binderObject, object));
925     return result.second;
926 }
927 
QueryProxyObject(binder_uintptr_t binderObject)928 sptr<IRemoteObject> DBinderService::QueryProxyObject(binder_uintptr_t binderObject)
929 {
930     std::shared_lock<std::shared_mutex> lock(proxyMutex_);
931 
932     auto it = proxyObject_.find(binderObject);
933     if (it != proxyObject_.end()) {
934         return it->second;
935     }
936     return nullptr;
937 }
938 
DetachSessionObject(binder_uintptr_t stub)939 bool DBinderService::DetachSessionObject(binder_uintptr_t stub)
940 {
941     std::unique_lock<std::shared_mutex> lock(sessionMutex_);
942     return (sessionObject_.erase(stub) > 0);
943 }
944 
AttachSessionObject(std::shared_ptr<struct SessionInfo> object,binder_uintptr_t stub)945 bool DBinderService::AttachSessionObject(std::shared_ptr<struct SessionInfo> object, binder_uintptr_t stub)
946 {
947     std::unique_lock<std::shared_mutex> lock(sessionMutex_);
948 
949     auto ret = sessionObject_.insert(std::pair<binder_uintptr_t, std::shared_ptr<struct SessionInfo>>(stub, object));
950     return ret.second;
951 }
952 
QuerySessionObject(binder_uintptr_t stub)953 std::shared_ptr<struct SessionInfo> DBinderService::QuerySessionObject(binder_uintptr_t stub)
954 {
955     std::shared_lock<std::shared_mutex> lock(sessionMutex_);
956 
957     auto it = sessionObject_.find(stub);
958     if (it != sessionObject_.end()) {
959         return it->second;
960     }
961     return nullptr;
962 }
963 
DetachDeathRecipient(sptr<IRemoteObject> object)964 bool DBinderService::DetachDeathRecipient(sptr<IRemoteObject> object)
965 {
966     std::unique_lock<std::shared_mutex> lockGuard(deathRecipientMutex_);
967 
968     return (deathRecipients_.erase(object) > 0);
969 }
970 
AttachDeathRecipient(sptr<IRemoteObject> object,sptr<IRemoteObject::DeathRecipient> deathRecipient)971 bool DBinderService::AttachDeathRecipient(sptr<IRemoteObject> object,
972     sptr<IRemoteObject::DeathRecipient> deathRecipient)
973 {
974     std::unique_lock<std::shared_mutex> lockGuard(deathRecipientMutex_);
975 
976     auto ret = deathRecipients_.insert(
977         std::pair<sptr<IRemoteObject>, sptr<IRemoteObject::DeathRecipient>>(object, deathRecipient));
978 
979     return ret.second;
980 }
981 
QueryDeathRecipient(sptr<IRemoteObject> object)982 sptr<IRemoteObject::DeathRecipient> DBinderService::QueryDeathRecipient(sptr<IRemoteObject> object)
983 {
984     std::shared_lock<std::shared_mutex> lockGuard(deathRecipientMutex_);
985 
986     auto it = deathRecipients_.find(object);
987     if (it != deathRecipients_.end()) {
988         return it->second;
989     }
990 
991     return nullptr;
992 }
993 
994 
DetachCallbackProxy(sptr<IRemoteObject> object)995 bool DBinderService::DetachCallbackProxy(sptr<IRemoteObject> object)
996 {
997     std::lock_guard<std::mutex> lockGuard(callbackProxyMutex_);
998 
999     return (noticeProxy_.erase(object) > 0);
1000 }
1001 
AttachCallbackProxy(sptr<IRemoteObject> object,DBinderServiceStub * dbStub)1002 bool DBinderService::AttachCallbackProxy(sptr<IRemoteObject> object, DBinderServiceStub *dbStub)
1003 {
1004     std::lock_guard<std::mutex> lockGuard(callbackProxyMutex_);
1005 
1006     auto result = noticeProxy_.insert(std::pair<sptr<IRemoteObject>, DBinderServiceStub *>(object, dbStub));
1007 
1008     return result.second;
1009 }
1010 
NoticeCallbackProxy(sptr<DBinderServiceStub> dbStub)1011 bool DBinderService::NoticeCallbackProxy(sptr<DBinderServiceStub> dbStub)
1012 {
1013     DBINDER_LOGI(LOG_LABEL, "service:%{public}s devicId:%{public}s",
1014         dbStub->GetServiceName().c_str(), DBinderService::ConvertToSecureDeviceID(dbStub->GetDeviceID()).c_str());
1015     bool status = true;
1016     const binder_uintptr_t binderObject = reinterpret_cast<binder_uintptr_t>(dbStub.GetRefPtr());
1017     if (!DetachSessionObject(binderObject)) {
1018         DBINDER_LOGE(LOG_LABEL, "fail to detach session object");
1019         status = false;
1020     }
1021 
1022     if (!DeleteDBinderStub(Str8ToStr16(dbStub->GetServiceName()), dbStub->GetDeviceID())) {
1023         DBINDER_LOGE(LOG_LABEL, "fail to delete DBinder stub");
1024         status = false;
1025     }
1026 
1027     ProcessCallbackProxy(dbStub);
1028 
1029     return status;
1030 }
1031 
ProcessCallbackProxy(sptr<DBinderServiceStub> dbStub)1032 void DBinderService::ProcessCallbackProxy(sptr<DBinderServiceStub> dbStub)
1033 {
1034     std::lock_guard<std::mutex> lockGuard(callbackProxyMutex_);
1035     for (auto it = noticeProxy_.begin(); it != noticeProxy_.end();) {
1036         if (it->second == dbStub.GetRefPtr()) {
1037             IPCObjectProxy *callbackProxy = reinterpret_cast<IPCObjectProxy *>((it->first).GetRefPtr());
1038             int status = callbackProxy->NoticeServiceDie();
1039             if (status != ERR_NONE) {
1040                 DBINDER_LOGE(LOG_LABEL, "fail to notice service:%{public}s die, handle:%{public}d",
1041                     dbStub->GetServiceName().c_str(), callbackProxy->GetHandle());
1042                 // do nothing, Continue to clear subsequent data
1043             }
1044 
1045             sptr<IRemoteObject::DeathRecipient> death = QueryDeathRecipient((it->first));
1046             if (death != nullptr) {
1047                 // Continue to clear subsequent data
1048                 callbackProxy->RemoveDeathRecipient(death);
1049             }
1050 
1051             if (!DetachDeathRecipient((it->first))) {
1052                 DBINDER_LOGE(LOG_LABEL, "detaching death recipient is failed, service:%{public}s handle:%{public}d",
1053                     dbStub->GetServiceName().c_str(), callbackProxy->GetHandle());
1054             }
1055 
1056             it = noticeProxy_.erase(it);
1057         } else {
1058             it++;
1059         }
1060     }
1061 }
1062 
NoticeServiceDieInner(const std::u16string & serviceName,const std::string & deviceID)1063 int32_t DBinderService::NoticeServiceDieInner(const std::u16string &serviceName, const std::string &deviceID)
1064 {
1065     if (serviceName.empty() || IsDeviceIdIllegal(deviceID)) {
1066         DBINDER_LOGE(LOG_LABEL, "service name length:%{public}zu, deviceID length:%{public}zu",
1067             serviceName.length(), deviceID.length());
1068         return DBINDER_SERVICE_INVALID_DATA_ERR;
1069     }
1070 
1071     DBINDER_LOGI(LOG_LABEL, "service:%{public}s deviceId:%{public}s",
1072         Str16ToStr8(serviceName).c_str(), DBinderService::ConvertToSecureDeviceID(deviceID).c_str());
1073     sptr<DBinderServiceStub> dbStub = FindDBinderStub(serviceName, deviceID);
1074     if (dbStub == nullptr) {
1075         DBINDER_LOGE(LOG_LABEL, "find null stub, do not need notice death");
1076         return ERR_NONE;
1077     }
1078 
1079     if (!NoticeCallbackProxy(dbStub)) {
1080         DBINDER_LOGE(LOG_LABEL, "find null proxy");
1081         return DBINDER_SERVICE_NOTICE_DIE_ERR;
1082     }
1083     return ERR_NONE;
1084 }
1085 
NoticeServiceDie(const std::u16string & serviceName,const std::string & deviceID)1086 int32_t DBinderService::NoticeServiceDie(const std::u16string &serviceName, const std::string &deviceID)
1087 {
1088     std::lock_guard<std::mutex> lockGuard(deathNotificationMutex_);
1089     return NoticeServiceDieInner(serviceName, deviceID);
1090 }
1091 
NoticeDeviceDie(const std::string & deviceID)1092 int32_t DBinderService::NoticeDeviceDie(const std::string &deviceID)
1093 {
1094     if (IsDeviceIdIllegal(deviceID)) {
1095         DBINDER_LOGE(LOG_LABEL, "deviceID length:%{public}zu", deviceID.length());
1096         return DBINDER_SERVICE_INVALID_DATA_ERR;
1097     }
1098     DBINDER_LOGI(LOG_LABEL, "remote device:%{public}s is dead",
1099         DBinderService::ConvertToSecureDeviceID(deviceID).c_str());
1100 
1101     if (remoteListener_ == nullptr) {
1102         DBINDER_LOGE(LOG_LABEL, "remote listener is null");
1103         return DBINDER_SERVICE_NOTICE_DIE_ERR;
1104     }
1105 
1106     if (!remoteListener_->CloseDatabusSession(deviceID)) {
1107         DBINDER_LOGE(LOG_LABEL, "close databus session fail");
1108         // do nothing
1109     }
1110 
1111     std::list<std::u16string> serviceNames = FindServicesByDeviceID(deviceID);
1112     if (serviceNames.empty()) {
1113         DBINDER_LOGE(LOG_LABEL, "the device does not have any registered service");
1114         return ERR_NONE;
1115     }
1116 
1117     int status = ERR_NONE;
1118     std::lock_guard<std::mutex> lockGuard(deathNotificationMutex_);
1119 
1120     for (auto it = serviceNames.begin(); it != serviceNames.end(); it++) {
1121         status += NoticeServiceDieInner((*it), deviceID);
1122     }
1123 
1124     return status;
1125 }
1126 
FindServicesByDeviceID(const std::string & deviceID)1127 std::list<std::u16string> DBinderService::FindServicesByDeviceID(const std::string &deviceID)
1128 {
1129     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
1130     std::list<std::u16string> serviceNames;
1131     for (auto it = DBinderStubRegisted_.begin(); it != DBinderStubRegisted_.end(); it++) {
1132         if ((*it)->GetDeviceID() == deviceID) {
1133             serviceNames.push_back(Str8ToStr16((*it)->GetServiceName()));
1134         }
1135     }
1136 
1137     DBINDER_LOGI(LOG_LABEL, "deviceId:%{public}s, service size:%{public}zu",
1138         DBinderService::ConvertToSecureDeviceID(deviceID).c_str(), serviceNames.size());
1139     return serviceNames;
1140 }
1141 
GetRemoteTransType()1142 uint32_t DBinderService::GetRemoteTransType()
1143 {
1144     return IRemoteObject::DATABUS_TYPE;
1145 }
1146 
ConvertToSecureDeviceID(const std::string & str)1147 std::string DBinderService::ConvertToSecureDeviceID(const std::string &str)
1148 {
1149     size_t len = str.size();
1150     if (len <= ENCRYPT_LENGTH) {
1151         return "****";
1152     }
1153     return str.substr(0, ENCRYPT_LENGTH) + "****" + str.substr(len - ENCRYPT_LENGTH);
1154 }
1155 } // namespace OHOS
1156