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