1 /* 2 * Copyright (C) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "ipc_process_skeleton.h" 17 18 #include <random> 19 #include <securec.h> 20 #include <sys/epoll.h> 21 #include <unistd.h> 22 23 #include "check_instance_exit.h" 24 #include "ipc_debug.h" 25 #include "ipc_thread_skeleton.h" 26 #include "ipc_types.h" 27 #include "log_tags.h" 28 #include "process_skeleton.h" 29 #include "string_ex.h" 30 #include "sys_binder.h" 31 32 #ifndef CONFIG_IPC_SINGLE 33 #include "databus_socket_listener.h" 34 #endif 35 36 namespace OHOS { 37 #ifdef CONFIG_IPC_SINGLE 38 namespace IPC_SINGLE { 39 #endif 40 using namespace OHOS::HiviewDFX; 41 42 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC_PROC_SKELETON, "IPCProcessSkeleton" }; 43 #ifndef CONFIG_IPC_SINGLE 44 static constexpr int32_t DETACH_PROXY_REF_COUNT = 2; 45 #endif 46 47 std::mutex IPCProcessSkeleton::procMutex_; 48 IPCProcessSkeleton *IPCProcessSkeleton::instance_ = nullptr; 49 IPCProcessSkeleton::DestroyInstance IPCProcessSkeleton::destroyInstance_; 50 std::atomic<bool> IPCProcessSkeleton::exitFlag_ = false; 51 static constexpr int32_t INT_MIDMAX = INT_MAX / 2; 52 GetCurrent()53 IPCProcessSkeleton *IPCProcessSkeleton::GetCurrent() 54 { 55 if ((instance_ == nullptr) && !exitFlag_) { 56 std::lock_guard<std::mutex> lockGuard(procMutex_); 57 if ((instance_ == nullptr) && !exitFlag_) { 58 IPCProcessSkeleton *temp = new (std::nothrow) IPCProcessSkeleton(); 59 if (temp == nullptr) { 60 ZLOGE(LOG_LABEL, "create IPCProcessSkeleton object failed"); 61 return nullptr; 62 } 63 if (temp->SetMaxWorkThread(DEFAULT_WORK_THREAD_NUM)) { 64 temp->SpawnThread(IPCWorkThread::SPAWN_ACTIVE); 65 #ifdef CONFIG_ACTV_BINDER 66 temp->SpawnThread(IPCWorkThread::ACTV_ACTIVE); 67 #endif 68 } 69 instance_ = temp; 70 } 71 } 72 73 return instance_; 74 } 75 IPCProcessSkeleton()76 IPCProcessSkeleton::IPCProcessSkeleton() 77 { 78 #ifndef CONFIG_IPC_SINGLE 79 std::random_device randDevice; 80 std::default_random_engine baseRand { randDevice() }; 81 std::uniform_int_distribution<> range(1, DBINDER_HANDLE_COUNT * DBINDER_HANDLE_RANG); 82 int temp = range(baseRand); 83 randNum_ = static_cast<uint64_t>(temp); 84 #endif 85 } 86 ConvertToSecureString(const std::string & str)87 std::string IPCProcessSkeleton::ConvertToSecureString(const std::string &str) 88 { 89 size_t len = str.size(); 90 if (len <= ENCRYPT_LENGTH) { 91 return "****"; 92 } 93 return str.substr(0, ENCRYPT_LENGTH) + "****" + str.substr(len - ENCRYPT_LENGTH); 94 } 95 96 #ifndef CONFIG_IPC_SINGLE ClearDataResource()97 void IPCProcessSkeleton::ClearDataResource() 98 { 99 { 100 std::unique_lock<std::shared_mutex> lockGuard(rawDataMutex_); 101 rawData_.clear(); 102 } 103 { 104 std::unique_lock<std::shared_mutex> lockGuard(threadLockMutex_); 105 threadLockInfo_.clear(); 106 } 107 { 108 std::lock_guard<std::mutex> lockGuard(findThreadMutex_); 109 seqNumberToThread_.clear(); 110 } 111 { 112 std::unique_lock<std::shared_mutex> lockGuard(stubObjectsMutex_); 113 stubObjects_.clear(); 114 } 115 { 116 std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_); 117 proxyToSession_.clear(); 118 } 119 { 120 std::unique_lock<std::shared_mutex> lockGuard(databusSessionMutex_); 121 dbinderSessionObjects_.clear(); 122 } 123 { 124 std::unique_lock<std::shared_mutex> lockGuard(callbackStubMutex_); 125 noticeStub_.clear(); 126 } 127 { 128 std::lock_guard<std::mutex> lockGuard(idleDataMutex_); 129 idleDataThreads_.clear(); 130 } 131 { 132 std::lock_guard<std::mutex> lockGuard(dataQueueMutex_); 133 dataInfoQueue_.clear(); 134 } 135 { 136 std::unique_lock<std::shared_mutex> lockGuard(appAuthMutex_); 137 appInfoToStubIndex_.clear(); 138 commAuth_.clear(); 139 } 140 { 141 std::unique_lock<std::shared_mutex> lockGuard(dbinderSentMutex_); 142 dbinderSentCallback_.clear(); 143 } 144 } 145 #endif 146 ~IPCProcessSkeleton()147 IPCProcessSkeleton::~IPCProcessSkeleton() 148 { 149 ZLOGI(LOG_LABEL, "enter"); 150 std::lock_guard<std::mutex> lockGuard(procMutex_); 151 exitFlag_ = true; 152 delete threadPool_; 153 threadPool_ = nullptr; 154 155 #ifndef CONFIG_IPC_SINGLE 156 ClearDataResource(); 157 if (listenSocketId_ > 0) { 158 DBinderSoftbusClient::GetInstance().Shutdown(listenSocketId_); 159 listenSocketId_ = 0; 160 } 161 #endif 162 } 163 GetRegistryObject()164 sptr<IRemoteObject> IPCProcessSkeleton::GetRegistryObject() 165 { 166 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 167 auto current = ProcessSkeleton::GetInstance(); 168 if (current == nullptr) { 169 ZLOGE(LOG_LABEL, "get process skeleton failed"); 170 return nullptr; 171 } 172 sptr<IRemoteObject> object = current->GetRegistryObject(); 173 if (object == nullptr) { 174 object = FindOrNewObject(REGISTRY_HANDLE); 175 if (object != nullptr) { 176 current->SetRegistryObject(object); 177 } 178 } 179 return object; 180 } 181 MakeHandleDescriptor(int handle)182 std::u16string IPCProcessSkeleton::MakeHandleDescriptor(int handle) 183 { 184 std::string descriptor = "IPCObjectProxy" + std::to_string(handle); 185 return Str8ToStr16(descriptor); 186 } 187 FindOrNewObject(int handle,const dbinder_negotiation_data * dbinderData)188 sptr<IRemoteObject> IPCProcessSkeleton::FindOrNewObject(int handle, const dbinder_negotiation_data *dbinderData) 189 { 190 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 191 bool newFlag = false; 192 sptr<IRemoteObject> result = GetProxyObject(handle, newFlag); 193 if (result == nullptr) { 194 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>( 195 std::chrono::steady_clock::now().time_since_epoch()).count()); 196 if (ProcessSkeleton::IsPrint(handle, lastErrHandle_, lastErrCnt_)) { 197 ZLOGE(LOG_LABEL, "GetProxyObject failed, handle:%{public}d time:%{public}" PRIu64, handle, curTime); 198 } 199 return result; 200 } 201 sptr<IPCObjectProxy> proxy = reinterpret_cast<IPCObjectProxy *>(result.GetRefPtr()); 202 proxy->WaitForInit(dbinderData); 203 #ifndef CONFIG_IPC_SINGLE 204 if (proxy->GetProto() == IRemoteObject::IF_PROT_ERROR) { 205 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>( 206 std::chrono::steady_clock::now().time_since_epoch()).count()); 207 ZLOGE(LOG_LABEL, "init rpc proxy failed, handle:%{public}d %{public}u, time:%{public}" PRIu64, handle, 208 ProcessSkeleton::ConvertAddr(result.GetRefPtr()), curTime); 209 if (proxy->GetSptrRefCount() <= DETACH_PROXY_REF_COUNT) { 210 DetachObject(result.GetRefPtr()); 211 } 212 return nullptr; 213 } 214 #endif 215 ZLOGD(LOG_LABEL, "handle:%{public}d proto:%{public}d new:%{public}d", handle, proxy->GetProto(), newFlag); 216 return result; 217 } 218 GetProxyObject(int handle,bool & newFlag)219 sptr<IRemoteObject> IPCProcessSkeleton::GetProxyObject(int handle, bool &newFlag) 220 { 221 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 222 sptr<IRemoteObject> result = nullptr; 223 std::u16string descriptor = MakeHandleDescriptor(handle); 224 if (descriptor.length() == 0) { 225 ZLOGE(LOG_LABEL, "make handle descriptor failed"); 226 return result; 227 } 228 229 auto current = ProcessSkeleton::GetInstance(); 230 if (current == nullptr) { 231 ZLOGE(LOG_LABEL, "get process skeleton failed"); 232 return result; 233 } 234 235 if (!current->LockObjectMutex()) { 236 ZLOGE(LOG_LABEL, "LockObjectMutex failed!"); 237 return result; 238 } 239 result = QueryObject(descriptor, false); 240 if (result != nullptr) { 241 current->UnlockObjectMutex(); 242 return result; 243 } 244 // Either this is a new handle or attemptIncStrong failed(strong refcount has been decreased to zero), 245 // we need to create a new proxy and initialize it. Meanwhile, the old proxy is destroying concurrently. 246 if (handle == REGISTRY_HANDLE) { 247 IRemoteInvoker *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DEFAULT); 248 if (invoker == nullptr) { 249 ZLOGE(LOG_LABEL, "failed to get invoker"); 250 current->UnlockObjectMutex(); 251 return result; 252 } 253 if (!invoker->PingService(REGISTRY_HANDLE)) { 254 current->UnlockObjectMutex(); 255 return result; 256 } 257 } 258 // OnFirstStrongRef will be called. 259 result = new (std::nothrow) IPCObjectProxy(handle, descriptor); 260 if (result == nullptr) { 261 ZLOGE(LOG_LABEL, "new IPCObjectProxy failed!"); 262 current->UnlockObjectMutex(); 263 return result; 264 } 265 if (!AttachObject(result.GetRefPtr(), false)) { 266 ZLOGE(LOG_LABEL, "AttachObject failed!"); 267 current->UnlockObjectMutex(); 268 return nullptr; 269 } 270 newFlag = true; 271 current->UnlockObjectMutex(); 272 return result; 273 } 274 SetRegistryObject(sptr<IRemoteObject> & object)275 bool IPCProcessSkeleton::SetRegistryObject(sptr<IRemoteObject> &object) 276 { 277 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 278 if (object == nullptr) { 279 ZLOGE(LOG_LABEL, "object is null"); 280 return false; 281 } 282 auto current = ProcessSkeleton::GetInstance(); 283 if (current == nullptr) { 284 ZLOGE(LOG_LABEL, "get process skeleton failed"); 285 return false; 286 } 287 IRemoteInvoker *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DEFAULT); 288 if (invoker == nullptr) { 289 ZLOGE(LOG_LABEL, "fail to get invoker"); 290 return false; 291 } 292 bool ret = invoker->SetRegistryObject(object); 293 if (ret) { 294 current->SetRegistryObject(object); 295 current->SetSamgrFlag(true); 296 } 297 ZLOGI(LOG_LABEL, "set registry result:%{public}d", ret); 298 return ret; 299 } 300 SetMaxWorkThread(int maxThreadNum)301 bool IPCProcessSkeleton::SetMaxWorkThread(int maxThreadNum) 302 { 303 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 304 if (maxThreadNum <= 0 || maxThreadNum >= INT_MIDMAX) { 305 ZLOGE(LOG_LABEL, "Set Invalid thread Number:%{public}d", maxThreadNum); 306 return false; 307 } 308 309 if (threadPool_ == nullptr) { 310 threadPool_ = new (std::nothrow) IPCWorkThreadPool(maxThreadNum); 311 if (threadPool_ == nullptr) { 312 ZLOGE(LOG_LABEL, "create IPCWorkThreadPool object failed"); 313 return false; 314 } 315 } 316 threadPool_->UpdateMaxThreadNum(maxThreadNum); 317 IRemoteInvoker *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DEFAULT); 318 if (invoker != nullptr) { 319 return invoker->SetMaxWorkThread(maxThreadNum); 320 } 321 322 return false; 323 } 324 SpawnThread(int policy,int proto)325 bool IPCProcessSkeleton::SpawnThread(int policy, int proto) 326 { 327 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 328 if (threadPool_ != nullptr) { 329 return threadPool_->SpawnThread(policy, proto); 330 } 331 332 /* can NOT reach here */ 333 return false; 334 } 335 OnThreadTerminated(const std::string & threadName)336 bool IPCProcessSkeleton::OnThreadTerminated(const std::string &threadName) 337 { 338 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 339 if (threadPool_ != nullptr) { 340 return threadPool_->RemoveThread(threadName); 341 } 342 343 return true; 344 } 345 IsContainsObject(IRemoteObject * object)346 bool IPCProcessSkeleton::IsContainsObject(IRemoteObject *object) 347 { 348 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 349 if (object == nullptr) { 350 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>( 351 std::chrono::steady_clock::now().time_since_epoch()).count()); 352 ZLOGD(LOG_LABEL, "object is null, time:%{public}" PRIu64, curTime); 353 return false; 354 } 355 auto current = ProcessSkeleton::GetInstance(); 356 if (current == nullptr) { 357 ZLOGE(LOG_LABEL, "get process skeleton failed"); 358 return false; 359 } 360 return current->IsContainsObject(object); 361 } 362 DetachObject(IRemoteObject * object)363 bool IPCProcessSkeleton::DetachObject(IRemoteObject *object) 364 { 365 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 366 if (object == nullptr) { 367 ZLOGE(LOG_LABEL, "object is null"); 368 return false; 369 } 370 std::u16string descriptor = object->GetObjectDescriptor(); 371 if (descriptor.empty()) { 372 return false; 373 } 374 auto current = ProcessSkeleton::GetInstance(); 375 if (current == nullptr) { 376 ZLOGE(LOG_LABEL, "get process skeleton failed"); 377 return false; 378 } 379 return current->DetachObject(object, descriptor); 380 } 381 AttachObject(IRemoteObject * object,bool lockFlag)382 bool IPCProcessSkeleton::AttachObject(IRemoteObject *object, bool lockFlag) 383 { 384 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 385 if (object == nullptr) { 386 ZLOGE(LOG_LABEL, "object is null"); 387 return false; 388 } 389 std::u16string descriptor = object->GetObjectDescriptor(); 390 391 auto current = ProcessSkeleton::GetInstance(); 392 if (current == nullptr) { 393 ZLOGE(LOG_LABEL, "get process skeleton failed"); 394 return false; 395 } 396 return current->AttachObject(object, descriptor, lockFlag); 397 } 398 QueryObject(const std::u16string & descriptor,bool lockFlag)399 sptr<IRemoteObject> IPCProcessSkeleton::QueryObject(const std::u16string &descriptor, bool lockFlag) 400 { 401 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 402 if (descriptor.length() == 0) { 403 ZLOGE(LOG_LABEL, "enter descriptor is empty"); 404 return nullptr; 405 } 406 auto current = ProcessSkeleton::GetInstance(); 407 if (current == nullptr) { 408 ZLOGE(LOG_LABEL, "get process skeleton failed"); 409 return nullptr; 410 } 411 return current->QueryObject(descriptor, lockFlag); 412 } 413 BlockUntilThreadAvailable()414 void IPCProcessSkeleton::BlockUntilThreadAvailable() 415 { 416 CHECK_INSTANCE_EXIT(exitFlag_); 417 std::unique_lock<std::mutex> lock(mutex_); 418 numWaitingForThreads_++; 419 constexpr int maxIPCThreadNum = 10; 420 if (numExecuting_ > maxIPCThreadNum) { 421 ZLOGE(LOG_LABEL, "numExecuting_++ is %{public}d", numExecuting_); 422 } 423 while (numExecuting_ >= threadPool_->GetMaxThreadNum()) { 424 cv_.wait(lock); 425 } 426 numWaitingForThreads_--; 427 } 428 LockForNumExecuting()429 void IPCProcessSkeleton::LockForNumExecuting() 430 { 431 CHECK_INSTANCE_EXIT(exitFlag_); 432 if (getuid() != FOUNDATION_UID) { 433 return; 434 } 435 std::lock_guard<std::mutex> lockGuard(mutex_); 436 numExecuting_++; 437 } 438 UnlockForNumExecuting()439 void IPCProcessSkeleton::UnlockForNumExecuting() 440 { 441 CHECK_INSTANCE_EXIT(exitFlag_); 442 if (getuid() != FOUNDATION_UID) { 443 return; 444 } 445 std::lock_guard<std::mutex> lockGuard(mutex_); 446 numExecuting_--; 447 if (numWaitingForThreads_ > 0) { 448 cv_.notify_all(); 449 } 450 } 451 SetIPCProxyLimit(uint64_t num,std::function<void (uint64_t num)> callback)452 bool IPCProcessSkeleton::SetIPCProxyLimit(uint64_t num, std::function<void (uint64_t num)> callback) 453 { 454 auto current = ProcessSkeleton::GetInstance(); 455 if (current == nullptr) { 456 ZLOGE(LOG_LABEL, "get process skeleton failed"); 457 return false; 458 } 459 return current->SetIPCProxyLimit(num, callback); 460 } 461 462 #ifndef CONFIG_IPC_SINGLE GetSAMgrObject()463 sptr<IRemoteObject> IPCProcessSkeleton::GetSAMgrObject() 464 { 465 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 466 IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker(); 467 if (invoker == nullptr) { 468 return nullptr; 469 } 470 return invoker->GetSAMgrObject(); 471 } 472 473 /* 474 * databus return int64_t channel id, but high 32bit only use 1bit channel type, we convert to int 475 * convert to 24bit channelID and 7bit channel type 476 * |---1bit---|------7bit----| ------------------------24bit------| 477 * | reserved | channel type | true channel id | 478 * don't care signed bit when convert,for we reserved high 1bit 479 */ ConvertChannelID2Int(int64_t databusChannelId)480 uint32_t IPCProcessSkeleton::ConvertChannelID2Int(int64_t databusChannelId) 481 { 482 if (databusChannelId < 0) { 483 return 0; 484 } 485 uint64_t databusChannel = static_cast<uint64_t>(databusChannelId); 486 uint32_t channelType = static_cast<uint32_t>((databusChannel >> 8) & 0X00000000FF000000ULL); 487 uint32_t channelID = static_cast<uint32_t>(databusChannel & 0X0000000000FFFFFFULL); 488 return (channelType | channelID); 489 } 490 GetLocalDeviceID()491 std::string IPCProcessSkeleton::GetLocalDeviceID() 492 { 493 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, ""); 494 std::lock_guard<std::mutex> lockGuard(databusProcMutex_); 495 496 std::string pkgName = std::string(DBINDER_PKG_NAME) + "_" + std::to_string(getpid()); 497 std::string networkId; 498 499 if (DBinderSoftbusClient::GetInstance().GetLocalNodeDeviceId( 500 pkgName.c_str(), networkId) != SOFTBUS_CLIENT_SUCCESS) { 501 ZLOGE(LOG_LABEL, "Get local node device id failed"); 502 } 503 504 return networkId; 505 } 506 IsHandleMadeByUser(uint32_t handle)507 bool IPCProcessSkeleton::IsHandleMadeByUser(uint32_t handle) 508 { 509 if (handle >= DBINDER_HANDLE_BASE && handle <= (DBINDER_HANDLE_BASE + DBINDER_HANDLE_COUNT)) { 510 ZLOGD(LOG_LABEL, "handle:%{public}u is make by user, not kernel", handle); 511 return true; 512 } 513 return false; 514 } 515 GetDBinderIdleHandle(std::shared_ptr<DBinderSessionObject> session)516 uint32_t IPCProcessSkeleton::GetDBinderIdleHandle(std::shared_ptr<DBinderSessionObject> session) 517 { 518 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0); 519 std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_); 520 uint32_t tempHandle = dBinderHandle_; 521 int count = DBINDER_HANDLE_COUNT; 522 bool insertResult = false; 523 do { 524 count--; 525 tempHandle++; 526 if (tempHandle > DBINDER_HANDLE_BASE + DBINDER_HANDLE_COUNT) { 527 tempHandle = DBINDER_HANDLE_BASE; 528 } 529 insertResult = proxyToSession_.insert(std::pair<uint32_t, 530 std::shared_ptr<DBinderSessionObject>>(tempHandle, session)).second; 531 } while (insertResult == false && count > 0); 532 533 if (count == 0 && insertResult == false) { 534 return 0; 535 } 536 dBinderHandle_ = tempHandle; 537 return dBinderHandle_; 538 } 539 ProxyDetachDBinderSession(uint32_t handle,IPCObjectProxy * proxy)540 std::shared_ptr<DBinderSessionObject> IPCProcessSkeleton::ProxyDetachDBinderSession(uint32_t handle, 541 IPCObjectProxy *proxy) 542 { 543 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 544 std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_); 545 std::shared_ptr<DBinderSessionObject> tmp = nullptr; 546 auto it = proxyToSession_.find(handle); 547 if (it != proxyToSession_.end() && it->second != nullptr && it->second->GetProxy() == proxy) { 548 tmp = it->second; 549 proxyToSession_.erase(it); 550 ZLOGI(LOG_LABEL, "detach handle:%{public}u from SocketId:%{public}d" 551 " service:%{public}s stubIndex:%{public}" PRIu64, handle, 552 tmp->GetSocketId(), tmp->GetServiceName().c_str(), 553 tmp->GetStubIndex()); 554 } else { 555 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>( 556 std::chrono::steady_clock::now().time_since_epoch()).count()); 557 ZLOGW(LOG_LABEL, "detach handle: %{public}u, not found, time: %{public}" PRIu64, handle, curTime); 558 } 559 560 return tmp; 561 } 562 ProxyAttachDBinderSession(uint32_t handle,std::shared_ptr<DBinderSessionObject> object)563 bool IPCProcessSkeleton::ProxyAttachDBinderSession(uint32_t handle, std::shared_ptr<DBinderSessionObject> object) 564 { 565 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 566 std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_); 567 auto result = proxyToSession_.insert(std::pair<uint32_t, std::shared_ptr<DBinderSessionObject>>(handle, object)); 568 ZLOGI(LOG_LABEL, "attach handle:%{public}u to socketId:%{public}d" 569 " service:%{public}s stubIndex:%{public}" PRIu64 " result:%{public}d", 570 handle, object->GetSocketId(), object->GetServiceName().c_str(), 571 object->GetStubIndex(), result.second); 572 return result.second; 573 } 574 ProxyQueryDBinderSession(uint32_t handle)575 std::shared_ptr<DBinderSessionObject> IPCProcessSkeleton::ProxyQueryDBinderSession(uint32_t handle) 576 { 577 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 578 std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_); 579 auto it = proxyToSession_.find(handle); 580 if (it != proxyToSession_.end()) { 581 return it->second; 582 } 583 return nullptr; 584 } 585 ProxyMoveDBinderSession(uint32_t handle,IPCObjectProxy * proxy)586 bool IPCProcessSkeleton::ProxyMoveDBinderSession(uint32_t handle, IPCObjectProxy *proxy) 587 { 588 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 589 std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_); 590 auto it = proxyToSession_.find(handle); 591 if (it != proxyToSession_.end()) { 592 if (it->second == nullptr) { 593 ZLOGE(LOG_LABEL, "find object is null"); 594 return false; 595 } 596 ZLOGI(LOG_LABEL, "move proxy of handle:%{public}u old==new:%{public}d", handle, 597 it->second->GetProxy() == proxy); 598 // moves ownership to this new proxy, so old proxy should not detach this session and stubIndex 599 // see QueryHandleByDatabusSession 600 it->second->SetProxy(proxy); 601 return true; 602 } 603 return false; 604 } 605 QueryProxyBySocketId(int32_t socketId,std::vector<uint32_t> & proxyHandle)606 bool IPCProcessSkeleton::QueryProxyBySocketId(int32_t socketId, std::vector<uint32_t> &proxyHandle) 607 { 608 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 609 std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_); 610 for (auto it = proxyToSession_.begin(); it != proxyToSession_.end(); it++) { 611 if (it->second == nullptr) { 612 ZLOGE(LOG_LABEL, "find object is null"); 613 return false; 614 } 615 if (socketId == it->second->GetSocketId()) { 616 proxyHandle.push_back(it->first); 617 } 618 } 619 ZLOGD(LOG_LABEL, "query proxys of session handle:%{public}d size:%{public}zu", socketId, proxyHandle.size()); 620 return true; 621 } 622 QueryHandleByDatabusSession(const std::string & name,const std::string & deviceId,uint64_t stubIndex)623 uint32_t IPCProcessSkeleton::QueryHandleByDatabusSession(const std::string &name, const std::string &deviceId, 624 uint64_t stubIndex) 625 { 626 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0); 627 std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_); 628 629 for (auto it = proxyToSession_.begin(); it != proxyToSession_.end(); it++) { 630 if (it->second == nullptr) { 631 ZLOGE(LOG_LABEL, "find object is null"); 632 return 0; 633 } 634 if ((it->second->GetStubIndex() == stubIndex) && (it->second->GetDeviceId().compare(deviceId) == 0) && 635 (it->second->GetServiceName().compare(name) == 0)) { 636 ZLOGI(LOG_LABEL, "found handle:%{public}u of session, stubIndex:%{public}" PRIu64, it->first, stubIndex); 637 // marks ownership not belong to the original proxy, In FindOrNewObject method, 638 // we will find the original proxy and take ownership again if the original proxy is still existed. 639 // Otherwise, if the original proxy is destroyed, it will not erase the session 640 // because we marks here. Later we will setProxy again with the new proxy in UpdateProto method 641 it->second->SetProxy(nullptr); 642 return it->first; 643 } 644 } 645 return 0; 646 } 647 QuerySessionByInfo(const std::string & name,const std::string & deviceId)648 std::shared_ptr<DBinderSessionObject> IPCProcessSkeleton::QuerySessionByInfo(const std::string &name, 649 const std::string &deviceId) 650 { 651 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 652 std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_); 653 654 for (auto it = proxyToSession_.begin(); it != proxyToSession_.end(); it++) { 655 if (it->second == nullptr) { 656 ZLOGE(LOG_LABEL, "find object is null"); 657 return nullptr; 658 } 659 if ((it->second->GetDeviceId().compare(deviceId) == 0) && (it->second->GetServiceName().compare(name) == 0)) { 660 return it->second; 661 } 662 } 663 664 return nullptr; 665 } 666 StubDetachDBinderSession(uint32_t handle,uint32_t & tokenId)667 bool IPCProcessSkeleton::StubDetachDBinderSession(uint32_t handle, uint32_t &tokenId) 668 { 669 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 670 std::unique_lock<std::shared_mutex> lockGuard(databusSessionMutex_); 671 auto it = dbinderSessionObjects_.find(handle); 672 if (it != dbinderSessionObjects_.end()) { 673 if (it->second == nullptr) { 674 ZLOGE(LOG_LABEL, "find object is null"); 675 return false; 676 } 677 tokenId = it->second->GetTokenId(); 678 ZLOGI(LOG_LABEL, "detach handle:%{public}u stubIndex:%{public}" PRIu64 " tokenId:%{public}u", 679 handle, it->second->GetStubIndex(), tokenId); 680 dbinderSessionObjects_.erase(it); 681 return true; 682 } 683 return false; 684 } 685 StubAttachDBinderSession(uint32_t handle,std::shared_ptr<DBinderSessionObject> object)686 bool IPCProcessSkeleton::StubAttachDBinderSession(uint32_t handle, std::shared_ptr<DBinderSessionObject> object) 687 { 688 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 689 std::unique_lock<std::shared_mutex> lockGuard(databusSessionMutex_); 690 auto result = 691 dbinderSessionObjects_.insert(std::pair<uint32_t, std::shared_ptr<DBinderSessionObject>>(handle, object)); 692 ZLOGI(LOG_LABEL, "attach handle:%{public}u stubIndex:%{public}" PRIu64 " tokenId:%{public}u result:%{public}u", 693 handle, object->GetStubIndex(), object->GetTokenId(), result.second); 694 return result.second; 695 } 696 StubQueryDBinderSession(uint32_t handle)697 std::shared_ptr<DBinderSessionObject> IPCProcessSkeleton::StubQueryDBinderSession(uint32_t handle) 698 { 699 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 700 std::shared_lock<std::shared_mutex> lockGuard(databusSessionMutex_); 701 auto it = dbinderSessionObjects_.find(handle); 702 if (it != dbinderSessionObjects_.end()) { 703 return it->second; 704 } 705 706 return nullptr; 707 } 708 DetachThreadLockInfo(const std::thread::id & threadId)709 bool IPCProcessSkeleton::DetachThreadLockInfo(const std::thread::id &threadId) 710 { 711 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 712 std::unique_lock<std::shared_mutex> lockGuard(threadLockMutex_); 713 714 return (threadLockInfo_.erase(threadId) > 0); 715 } 716 AttachThreadLockInfo(std::shared_ptr<SocketThreadLockInfo> object,const std::thread::id & threadId)717 bool IPCProcessSkeleton::AttachThreadLockInfo(std::shared_ptr<SocketThreadLockInfo> object, 718 const std::thread::id &threadId) 719 { 720 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 721 std::unique_lock<std::shared_mutex> lockGuard(threadLockMutex_); 722 auto result = 723 threadLockInfo_.insert(std::pair<std::thread::id, std::shared_ptr<SocketThreadLockInfo>>(threadId, object)); 724 return result.second; 725 } 726 QueryThreadLockInfo(const std::thread::id & threadId)727 std::shared_ptr<SocketThreadLockInfo> IPCProcessSkeleton::QueryThreadLockInfo(const std::thread::id &threadId) 728 { 729 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 730 std::shared_lock<std::shared_mutex> lockGuard(threadLockMutex_); 731 732 auto it = threadLockInfo_.find(threadId); 733 if (it != threadLockInfo_.end()) { 734 return it->second; 735 } 736 737 return nullptr; 738 } 739 740 AddDataThreadToIdle(const std::thread::id & threadId)741 bool IPCProcessSkeleton::AddDataThreadToIdle(const std::thread::id &threadId) 742 { 743 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 744 std::lock_guard<std::mutex> lockGuard(idleDataMutex_); 745 746 idleDataThreads_.push_front(threadId); 747 return true; 748 } 749 DeleteDataThreadFromIdle(const std::thread::id & threadId)750 bool IPCProcessSkeleton::DeleteDataThreadFromIdle(const std::thread::id &threadId) 751 { 752 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 753 std::lock_guard<std::mutex> lockGuard(idleDataMutex_); 754 for (auto it = idleDataThreads_.begin(); it != idleDataThreads_.end(); it++) { 755 if ((*it) == threadId) { 756 it = idleDataThreads_.erase(it); 757 return true; 758 } 759 } 760 761 /* not in idle state, also return true */ 762 return true; 763 } 764 GetIdleDataThread()765 std::thread::id IPCProcessSkeleton::GetIdleDataThread() 766 { 767 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, std::thread::id()); 768 std::lock_guard<std::mutex> lockGuard(idleDataMutex_); 769 770 if (idleDataThreads_.size() == 0) { 771 return std::thread::id(); 772 } 773 774 std::thread::id threadId = idleDataThreads_.back(); 775 return threadId; 776 } 777 GetSocketIdleThreadNum() const778 int IPCProcessSkeleton::GetSocketIdleThreadNum() const 779 { 780 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0); 781 if (threadPool_ != nullptr) { 782 return threadPool_->GetSocketIdleThreadNum(); 783 } 784 785 return 0; 786 } 787 GetSocketTotalThreadNum() const788 int IPCProcessSkeleton::GetSocketTotalThreadNum() const 789 { 790 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0); 791 if (threadPool_ != nullptr) { 792 return threadPool_->GetSocketTotalThreadNum(); 793 } 794 return 0; 795 } 796 AddDataInfoToThread(const std::thread::id & threadId,std::shared_ptr<ThreadProcessInfo> processInfo)797 void IPCProcessSkeleton::AddDataInfoToThread(const std::thread::id &threadId, 798 std::shared_ptr<ThreadProcessInfo> processInfo) 799 { 800 CHECK_INSTANCE_EXIT(exitFlag_); 801 std::lock_guard<std::mutex> lockGuard(dataQueueMutex_); 802 803 (dataInfoQueue_[threadId]).push_back(processInfo); 804 } 805 PopDataInfoFromThread(const std::thread::id & threadId)806 std::shared_ptr<ThreadProcessInfo> IPCProcessSkeleton::PopDataInfoFromThread(const std::thread::id &threadId) 807 { 808 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 809 std::lock_guard<std::mutex> lockGuard(dataQueueMutex_); 810 811 if ((dataInfoQueue_[threadId]).size() == 0) { 812 return nullptr; 813 } 814 815 std::shared_ptr<ThreadProcessInfo> processInfo = (dataInfoQueue_[threadId]).front(); 816 817 (dataInfoQueue_[threadId]).erase((dataInfoQueue_[threadId]).begin()); 818 return processInfo; 819 } 820 WakeUpDataThread(const std::thread::id & threadID)821 void IPCProcessSkeleton::WakeUpDataThread(const std::thread::id &threadID) 822 { 823 CHECK_INSTANCE_EXIT(exitFlag_); 824 if (threadID != std::thread::id()) { 825 std::shared_ptr<SocketThreadLockInfo> threadLockInfo = QueryThreadLockInfo(threadID); 826 if (threadLockInfo != nullptr) { 827 /* Wake up this IO thread to process socket stream 828 * Wake up the client processing thread 829 */ 830 std::unique_lock<std::mutex> lock_unique(threadLockInfo->mutex); 831 threadLockInfo->ready = true; 832 threadLockInfo->condition.notify_one(); 833 } 834 } 835 } 836 AddDataThreadInWait(const std::thread::id & threadId)837 void IPCProcessSkeleton::AddDataThreadInWait(const std::thread::id &threadId) 838 { 839 CHECK_INSTANCE_EXIT(exitFlag_); 840 std::shared_ptr<SocketThreadLockInfo> threadLockInfo; 841 842 threadLockInfo = QueryThreadLockInfo(threadId); 843 if (threadLockInfo == nullptr) { 844 threadLockInfo = std::make_shared<struct SocketThreadLockInfo>(); 845 if (!AttachThreadLockInfo(threadLockInfo, threadId)) { 846 ZLOGE(LOG_LABEL, "thread has added lock info"); 847 return; 848 } 849 } 850 851 AddDataThreadToIdle(threadId); 852 std::unique_lock<std::mutex> lock_unique(threadLockInfo->mutex); 853 threadLockInfo->condition.wait(lock_unique, [&threadLockInfo] { return threadLockInfo->ready; }); 854 threadLockInfo->ready = false; 855 /* corresponding thread will be waked up */ 856 DeleteDataThreadFromIdle(threadId); 857 } 858 GetSeqNumber()859 uint64_t IPCProcessSkeleton::GetSeqNumber() 860 { 861 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0); 862 std::lock_guard<std::mutex> lockGuard(seqNumberMutex_); 863 if (seqNumber_ == std::numeric_limits<uint64_t>::max()) { 864 seqNumber_ = 0; 865 } 866 seqNumber_++; 867 return seqNumber_; 868 } 869 QueryThreadBySeqNumber(uint64_t seqNumber)870 std::shared_ptr<ThreadMessageInfo> IPCProcessSkeleton::QueryThreadBySeqNumber(uint64_t seqNumber) 871 { 872 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 873 std::lock_guard<std::mutex> lockGuard(findThreadMutex_); 874 875 auto it = seqNumberToThread_.find(seqNumber); 876 if (it != seqNumberToThread_.end()) { 877 return it->second; 878 } 879 880 return nullptr; 881 } 882 EraseThreadBySeqNumber(uint64_t seqNumber)883 void IPCProcessSkeleton::EraseThreadBySeqNumber(uint64_t seqNumber) 884 { 885 CHECK_INSTANCE_EXIT(exitFlag_); 886 std::lock_guard<std::mutex> lockGuard(findThreadMutex_); 887 seqNumberToThread_.erase(seqNumber); 888 } 889 890 AddThreadBySeqNumber(uint64_t seqNumber,std::shared_ptr<ThreadMessageInfo> messageInfo)891 bool IPCProcessSkeleton::AddThreadBySeqNumber(uint64_t seqNumber, std::shared_ptr<ThreadMessageInfo> messageInfo) 892 { 893 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 894 std::lock_guard<std::mutex> lockGuard(findThreadMutex_); 895 896 auto result = 897 seqNumberToThread_.insert(std::pair<uint64_t, std::shared_ptr<ThreadMessageInfo>>(seqNumber, messageInfo)); 898 899 return result.second; 900 } 901 WakeUpThreadBySeqNumber(uint64_t seqNumber,uint32_t handle)902 void IPCProcessSkeleton::WakeUpThreadBySeqNumber(uint64_t seqNumber, uint32_t handle) 903 { 904 CHECK_INSTANCE_EXIT(exitFlag_); 905 std::shared_ptr<ThreadMessageInfo> messageInfo; 906 907 messageInfo = QueryThreadBySeqNumber(seqNumber); 908 if (messageInfo == nullptr) { 909 ZLOGE(LOG_LABEL, "error! messageInfo is nullptr"); 910 return; 911 } 912 if (handle != messageInfo->socketId) { 913 ZLOGE(LOG_LABEL, "handle is not equal, handle:%{public}d socketId:%{public}u", 914 handle, messageInfo->socketId); 915 return; 916 } 917 918 std::unique_lock<std::mutex> lock_unique(messageInfo->mutex); 919 messageInfo->ready = true; 920 messageInfo->condition.notify_one(); 921 } 922 AddSendThreadInWait(uint64_t seqNumber,std::shared_ptr<ThreadMessageInfo> messageInfo,int userWaitTime)923 bool IPCProcessSkeleton::AddSendThreadInWait(uint64_t seqNumber, std::shared_ptr<ThreadMessageInfo> messageInfo, 924 int userWaitTime) 925 { 926 if (messageInfo == nullptr) { 927 ZLOGE(LOG_LABEL, "messageInfo is nullptr"); 928 return false; 929 } 930 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 931 if (!AddThreadBySeqNumber(seqNumber, messageInfo)) { 932 ZLOGE(LOG_LABEL, "add seqNumber:%{public}" PRIu64 " failed", seqNumber); 933 return false; 934 } 935 936 std::unique_lock<std::mutex> lock_unique(messageInfo->mutex); 937 if (messageInfo->condition.wait_for(lock_unique, std::chrono::seconds(userWaitTime), 938 [&messageInfo] { return messageInfo->ready; }) == false) { 939 messageInfo->ready = false; 940 ZLOGE(LOG_LABEL, "thread timeout, seqNumber:%{public}" PRIu64 " waittime:%{public}d", seqNumber, userWaitTime); 941 return false; 942 } 943 messageInfo->ready = false; 944 return true; 945 } 946 QueryStubByIndex(uint64_t stubIndex)947 IRemoteObject *IPCProcessSkeleton::QueryStubByIndex(uint64_t stubIndex) 948 { 949 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 950 if (stubIndex == 0) { 951 ZLOGE(LOG_LABEL, "stubIndex invalid"); 952 return nullptr; 953 } 954 std::shared_lock<std::shared_mutex> lockGuard(stubObjectsMutex_); 955 956 auto it = stubObjects_.find(stubIndex); 957 if (it != stubObjects_.end()) { 958 return it->second; 959 } 960 961 return nullptr; 962 } 963 AddStubByIndex(IRemoteObject * stubObject)964 uint64_t IPCProcessSkeleton::AddStubByIndex(IRemoteObject *stubObject) 965 { 966 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0); 967 std::unique_lock<std::shared_mutex> lockGuard(stubObjectsMutex_); 968 969 /* if stub has its index, return it directly */ 970 for (auto it = stubObjects_.begin(); it != stubObjects_.end(); it++) { 971 if (it->second == stubObject) { 972 return it->first; 973 } 974 } 975 uint64_t stubIndex = randNum_++; 976 auto result = stubObjects_.insert(std::pair<uint64_t, IRemoteObject *>(stubIndex, stubObject)); 977 if (result.second) { 978 return stubIndex; 979 } else { 980 return 0; 981 } 982 } 983 QueryStubIndex(IRemoteObject * stubObject)984 uint64_t IPCProcessSkeleton::QueryStubIndex(IRemoteObject *stubObject) 985 { 986 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0); 987 std::unique_lock<std::shared_mutex> lockGuard(stubObjectsMutex_); 988 989 for (auto it = stubObjects_.begin(); it != stubObjects_.end(); it++) { 990 if (it->second == stubObject) { 991 return it->first; 992 } 993 } 994 return 0; 995 } 996 EraseStubIndex(IRemoteObject * stubObject)997 uint64_t IPCProcessSkeleton::EraseStubIndex(IRemoteObject *stubObject) 998 { 999 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0); 1000 std::unique_lock<std::shared_mutex> lockGuard(stubObjectsMutex_); 1001 1002 for (auto it = stubObjects_.begin(); it != stubObjects_.end(); it++) { 1003 if (it->second == stubObject) { 1004 uint64_t stubIndex = it->first; 1005 stubObjects_.erase(it); 1006 return stubIndex; 1007 } 1008 } 1009 return 0; 1010 } 1011 UIntToString(uint32_t input)1012 std::string IPCProcessSkeleton::UIntToString(uint32_t input) 1013 { 1014 // 12: convert to fixed string length 1015 char str[12] = {0}; 1016 if (sprintf_s(str, sizeof(str) / sizeof(str[0]), "%011u", input) <= EOK) { 1017 ZLOGE(LOG_LABEL, "sprintf_s fail"); 1018 } 1019 return str; 1020 } 1021 DetachAppInfoToStubIndex(uint32_t pid,uint32_t uid,uint32_t tokenId,const std::string & deviceId,uint64_t stubIndex,int32_t listenFd)1022 bool IPCProcessSkeleton::DetachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, 1023 const std::string &deviceId, uint64_t stubIndex, int32_t listenFd) 1024 { 1025 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1026 std::string appInfo = deviceId + UIntToString(pid) + UIntToString(uid) + UIntToString(tokenId); 1027 1028 std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_); 1029 bool result = false; 1030 auto it = appInfoToStubIndex_.find(appInfo); 1031 if (it != appInfoToStubIndex_.end()) { 1032 std::map<uint64_t, int32_t> &indexes = it->second; 1033 auto it2 = indexes.find(stubIndex); 1034 if (it2 != indexes.end() && it2->second == listenFd) { 1035 indexes.erase(it2); 1036 result = true; 1037 } 1038 if (indexes.empty()) { 1039 appInfoToStubIndex_.erase(it); 1040 } 1041 } 1042 ZLOGI(LOG_LABEL, "pid:%{public}u uid:%{public}u tokenId:%{public}u deviceId:%{public}s stubIndex:%{public}" PRIu64 1043 " listenFd:%{public}u result:%{public}d", pid, uid, tokenId, ConvertToSecureString(deviceId).c_str(), 1044 stubIndex, listenFd, result); 1045 return result; 1046 } 1047 DetachAppInfoToStubIndex(uint32_t pid,uint32_t uid,uint32_t tokenId,const std::string & deviceId,int32_t listenFd)1048 std::list<uint64_t> IPCProcessSkeleton::DetachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, 1049 const std::string &deviceId, int32_t listenFd) 1050 { 1051 std::list<uint64_t> indexes; 1052 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, indexes); 1053 std::string appInfo = deviceId + UIntToString(pid) + UIntToString(uid) + UIntToString(tokenId); 1054 1055 std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_); 1056 1057 uint32_t indexCnt = 0; 1058 bool appInfoErase = false; 1059 auto it = appInfoToStubIndex_.find(appInfo); 1060 if (it != appInfoToStubIndex_.end()) { 1061 std::map<uint64_t, int32_t> &stubIndexes = it->second; 1062 for (auto it2 = stubIndexes.begin(); it2 != stubIndexes.end();) { 1063 if (it2->second == listenFd) { 1064 indexes.push_back(it2->first); 1065 it2 = stubIndexes.erase(it2); 1066 indexCnt++; 1067 } else { 1068 it2++; 1069 } 1070 } 1071 if (stubIndexes.empty()) { 1072 appInfoToStubIndex_.erase(it); 1073 appInfoErase = true; 1074 } 1075 } 1076 ZLOGI(LOG_LABEL, "pid:%{public}u uid:%{public}u tokenId:%{public}u deviceId:%{public}s listenFd:%{public}d" 1077 " indexCnt:%{public}u appInfoErase:%{public}d", 1078 pid, uid, tokenId, ConvertToSecureString(deviceId).c_str(), listenFd, indexCnt, appInfoErase); 1079 return indexes; 1080 } 1081 DetachAppInfoToStubIndex(uint64_t stubIndex)1082 void IPCProcessSkeleton::DetachAppInfoToStubIndex(uint64_t stubIndex) 1083 { 1084 CHECK_INSTANCE_EXIT(exitFlag_); 1085 std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_); 1086 1087 for (auto it = appInfoToStubIndex_.begin(); it != appInfoToStubIndex_.end();) { 1088 if (it->second.erase(stubIndex) > 0) { 1089 ZLOGI(LOG_LABEL, "earse stubIndex:%{public}" PRIu64 " of appInfo:%{public}s", 1090 stubIndex, ConvertToSecureString(it->first).c_str()); 1091 } 1092 if (it->second.size() == 0) { 1093 it = appInfoToStubIndex_.erase(it); 1094 } else { 1095 it++; 1096 } 1097 } 1098 } 1099 DetachAppInfoToStubIndex(int32_t listenFd)1100 std::list<uint64_t> IPCProcessSkeleton::DetachAppInfoToStubIndex(int32_t listenFd) 1101 { 1102 std::list<uint64_t> indexes; 1103 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, indexes); 1104 std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_); 1105 uint32_t indexCnt = 0; 1106 bool appInfoErase = false; 1107 for (auto it = appInfoToStubIndex_.begin(); it != appInfoToStubIndex_.end();) { 1108 std::map<uint64_t, int32_t> &mapItem = it->second; 1109 for (auto it2 = mapItem.begin(); it2 != mapItem.end();) { 1110 if (it2->second == listenFd) { 1111 indexes.push_back(it2->first); 1112 it2 = mapItem.erase(it2); 1113 indexCnt++; 1114 } else { 1115 it2++; 1116 } 1117 } 1118 if (mapItem.empty()) { 1119 it = appInfoToStubIndex_.erase(it); 1120 appInfoErase = true; 1121 } else { 1122 it++; 1123 } 1124 } 1125 ZLOGI(LOG_LABEL, "listenFd:%{public}d indexCnt:%{public}u appInfoErase:%{public}d", 1126 listenFd, indexCnt, appInfoErase); 1127 return indexes; 1128 } 1129 AttachAppInfoToStubIndex(uint32_t pid,uint32_t uid,uint32_t tokenId,const std::string & deviceId,uint64_t stubIndex,int32_t listenFd)1130 bool IPCProcessSkeleton::AttachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, 1131 const std::string &deviceId, uint64_t stubIndex, int32_t listenFd) 1132 { 1133 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1134 ZLOGI(LOG_LABEL, "pid:%{public}u uid:%{public}u tokenId:%{public}u deviceId:%{public}s stubIndex:%{public}" PRIu64 1135 " listenFd:%{public}d", pid, uid, tokenId, ConvertToSecureString(deviceId).c_str(), stubIndex, listenFd); 1136 std::string appInfo = deviceId + UIntToString(pid) + UIntToString(uid) + UIntToString(tokenId); 1137 1138 std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_); 1139 1140 auto it = appInfoToStubIndex_.find(appInfo); 1141 if (it != appInfoToStubIndex_.end()) { 1142 auto result = it->second.insert_or_assign(stubIndex, listenFd); 1143 return result.second; 1144 } 1145 1146 std::map<uint64_t, int32_t> mapItem { { stubIndex, listenFd } }; 1147 auto result = appInfoToStubIndex_.insert(std::pair<std::string, std::map<uint64_t, int32_t>>(appInfo, mapItem)); 1148 return result.second; 1149 } 1150 AttachAppInfoToStubIndex(uint32_t pid,uint32_t uid,uint32_t tokenId,const std::string & deviceId,int32_t listenFd)1151 bool IPCProcessSkeleton::AttachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, 1152 const std::string &deviceId, int32_t listenFd) 1153 { 1154 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1155 ZLOGI(LOG_LABEL, "pid:%{public}u uid:%{public}u tokenId:%{public}u deviceId:%{public}s listenFd:%{public}d", 1156 pid, uid, tokenId, ConvertToSecureString(deviceId).c_str(), listenFd); 1157 std::string appInfo = deviceId + UIntToString(pid) + UIntToString(uid) + UIntToString(tokenId); 1158 1159 std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_); 1160 1161 auto it = appInfoToStubIndex_.find(appInfo); 1162 if (it != appInfoToStubIndex_.end()) { 1163 std::map<uint64_t, int32_t> &indexes = it->second; 1164 // OnSessionOpen update listenFd 1165 for (auto it2 = indexes.begin(); it2 != indexes.end(); it2++) { 1166 it2->second = listenFd; 1167 } 1168 } 1169 return true; 1170 } 1171 QueryAppInfoToStubIndex(uint32_t pid,uint32_t uid,uint32_t tokenId,const std::string & deviceId,uint64_t stubIndex,int32_t listenFd)1172 bool IPCProcessSkeleton::QueryAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId, 1173 const std::string &deviceId, uint64_t stubIndex, int32_t listenFd) 1174 { 1175 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1176 std::string appInfo = deviceId + UIntToString(pid) + UIntToString(uid) + UIntToString(tokenId); 1177 1178 std::shared_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_); 1179 1180 auto it = appInfoToStubIndex_.find(appInfo); 1181 if (it != appInfoToStubIndex_.end()) { 1182 auto it2 = it->second.find(stubIndex); 1183 // listenFd may be marked as 0 1184 if (it2 != it->second.end() && (it2->second == 0 || it2->second == listenFd)) { 1185 ZLOGD(LOG_LABEL, "found appInfo:%{public}s stubIndex:%{public}" PRIu64, 1186 ConvertToSecureString(appInfo).c_str(), stubIndex); 1187 return true; 1188 } 1189 } 1190 1191 return false; 1192 } 1193 AttachCallbackStub(IPCObjectProxy * ipcProxy,sptr<IPCObjectStub> callbackStub)1194 bool IPCProcessSkeleton::AttachCallbackStub(IPCObjectProxy *ipcProxy, sptr<IPCObjectStub> callbackStub) 1195 { 1196 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1197 std::unique_lock<std::shared_mutex> lockGuard(callbackStubMutex_); 1198 auto result = noticeStub_.insert(std::pair<IPCObjectProxy *, sptr<IPCObjectStub>>(ipcProxy, callbackStub)); 1199 return result.second; 1200 } 1201 DetachCallbackStub(IPCObjectProxy * ipcProxy)1202 sptr<IPCObjectStub> IPCProcessSkeleton::DetachCallbackStub(IPCObjectProxy *ipcProxy) 1203 { 1204 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 1205 sptr<IPCObjectStub> ret = nullptr; 1206 std::unique_lock<std::shared_mutex> lockGuard(callbackStubMutex_); 1207 auto it = noticeStub_.find(ipcProxy); 1208 if (it != noticeStub_.end()) { 1209 ret = it->second; 1210 noticeStub_.erase(it); 1211 } 1212 return ret; 1213 } 1214 QueryCallbackStub(IPCObjectProxy * ipcProxy)1215 sptr<IPCObjectStub> IPCProcessSkeleton::QueryCallbackStub(IPCObjectProxy *ipcProxy) 1216 { 1217 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 1218 std::shared_lock<std::shared_mutex> lockGuard(callbackStubMutex_); 1219 auto it = noticeStub_.find(ipcProxy); 1220 if (it != noticeStub_.end()) { 1221 return it->second; 1222 } 1223 1224 return nullptr; 1225 } 1226 QueryCallbackProxy(IPCObjectStub * callbackStub)1227 sptr<IPCObjectProxy> IPCProcessSkeleton::QueryCallbackProxy(IPCObjectStub *callbackStub) 1228 { 1229 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 1230 sptr<IPCObjectProxy> ret = nullptr; 1231 std::shared_lock<std::shared_mutex> lockGuard(callbackStubMutex_); 1232 for (auto it = noticeStub_.begin(); it != noticeStub_.end(); it++) { 1233 if (it->second.GetRefPtr() == callbackStub) { 1234 ret = it->first; 1235 } 1236 } 1237 1238 return ret; 1239 } 1240 GetDatabusName()1241 std::string IPCProcessSkeleton::GetDatabusName() 1242 { 1243 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, ""); 1244 std::lock_guard<std::mutex> lockGuard(sessionNameMutex_); 1245 1246 return sessionName_; 1247 } 1248 CreateSoftbusServer(const std::string & name)1249 bool IPCProcessSkeleton::CreateSoftbusServer(const std::string &name) 1250 { 1251 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1252 if (name.empty()) { 1253 ZLOGE(LOG_LABEL, "server name is empty"); 1254 return false; 1255 } 1256 std::shared_ptr<DatabusSocketListener> listener = 1257 DelayedSingleton<DatabusSocketListener>::GetInstance(); 1258 if (listener == nullptr) { 1259 ZLOGE(LOG_LABEL, "fail to get socket listener"); 1260 return false; 1261 } 1262 1263 int32_t socketId = listener->StartServerListener(name); 1264 if (socketId <= 0) { 1265 ZLOGE(LOG_LABEL, "fail to start server listener"); 1266 return false; 1267 } 1268 listenSocketId_ = socketId; 1269 if (name != sessionName_) { 1270 SpawnThread(IPCWorkThread::PROCESS_ACTIVE, IRemoteObject::IF_PROT_DATABUS); 1271 } 1272 sessionName_ = name; 1273 return true; 1274 } 1275 AttachRawData(int32_t socketId,std::shared_ptr<InvokerRawData> rawData)1276 bool IPCProcessSkeleton::AttachRawData(int32_t socketId, std::shared_ptr<InvokerRawData> rawData) 1277 { 1278 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1279 std::unique_lock<std::shared_mutex> lockGuard(rawDataMutex_); 1280 /* always discard the old one if exists */ 1281 rawData_.erase(socketId); 1282 auto result = rawData_.insert(std::pair<uint32_t, std::shared_ptr<InvokerRawData>>(socketId, rawData)); 1283 return result.second; 1284 } 1285 DetachRawData(int32_t socketId)1286 bool IPCProcessSkeleton::DetachRawData(int32_t socketId) 1287 { 1288 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1289 std::unique_lock<std::shared_mutex> lockGuard(rawDataMutex_); 1290 return (rawData_.erase(socketId) > 0); 1291 } 1292 QueryRawData(int32_t socketId)1293 std::shared_ptr<InvokerRawData> IPCProcessSkeleton::QueryRawData(int32_t socketId) 1294 { 1295 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 1296 std::shared_lock<std::shared_mutex> lockGuard(rawDataMutex_); 1297 auto it = rawData_.find(socketId); 1298 if (it != rawData_.end()) { 1299 return it->second; 1300 } 1301 return nullptr; 1302 } 1303 IsSameRemoteObject(IRemoteObject * stub,int pid,int uid,uint32_t tokenId,const std::string & deviceId,const std::shared_ptr<CommAuthInfo> & auth)1304 bool IPCProcessSkeleton::IsSameRemoteObject(IRemoteObject *stub, int pid, int uid, uint32_t tokenId, 1305 const std::string &deviceId, const std::shared_ptr<CommAuthInfo> &auth) 1306 { 1307 if ((auth->GetStubObject() == stub) && (auth->GetRemotePid() == pid) && (auth->GetRemoteUid() == uid) && 1308 (auth->GetRemoteTokenId() == tokenId) && (auth->GetRemoteDeviceId().compare(deviceId) == 0)) { 1309 return true; 1310 } else { 1311 return false; 1312 } 1313 } 1314 IsSameRemoteObject(int pid,int uid,const std::string & deviceId,const std::shared_ptr<CommAuthInfo> & auth)1315 bool IPCProcessSkeleton::IsSameRemoteObject(int pid, int uid, const std::string &deviceId, 1316 const std::shared_ptr<CommAuthInfo> &auth) 1317 { 1318 if ((auth->GetRemotePid() == pid) && (auth->GetRemoteUid() == uid) && 1319 (auth->GetRemoteDeviceId().compare(deviceId) == 0)) { 1320 return true; 1321 } else { 1322 return false; 1323 } 1324 } 1325 AttachCommAuthInfo(IRemoteObject * stub,int pid,int uid,uint32_t tokenId,const std::string & deviceId)1326 bool IPCProcessSkeleton::AttachCommAuthInfo(IRemoteObject *stub, int pid, int uid, uint32_t tokenId, 1327 const std::string &deviceId) 1328 { 1329 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1330 auto check = [&stub, &pid, &uid, &tokenId, &deviceId, this](const std::shared_ptr<CommAuthInfo> &auth) { 1331 return IsSameRemoteObject(stub, pid, uid, tokenId, deviceId, auth); 1332 }; 1333 std::unique_lock<std::shared_mutex> lockGuard(commAuthMutex_); 1334 auto it = std::find_if(commAuth_.begin(), commAuth_.end(), check); 1335 if (it != commAuth_.end()) { 1336 return false; 1337 } 1338 1339 std::shared_ptr<CommAuthInfo> authObject = std::make_shared<CommAuthInfo>(stub, pid, uid, tokenId, deviceId); 1340 if (authObject == nullptr) { 1341 ZLOGE(LOG_LABEL, "make_share CommonAuthInfo fail, device:%{public}s pid:%{public}d uid:%{public}d", 1342 IPCProcessSkeleton::ConvertToSecureString(deviceId).c_str(), pid, uid); 1343 return false; 1344 } 1345 commAuth_.push_front(authObject); 1346 return true; 1347 } 1348 DetachCommAuthInfo(IRemoteObject * stub,int pid,int uid,uint32_t tokenId,const std::string & deviceId)1349 bool IPCProcessSkeleton::DetachCommAuthInfo(IRemoteObject *stub, int pid, int uid, uint32_t tokenId, 1350 const std::string &deviceId) 1351 { 1352 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1353 auto check = [&stub, &pid, &uid, &tokenId, &deviceId, this](const std::shared_ptr<CommAuthInfo> &auth) { 1354 return IsSameRemoteObject(stub, pid, uid, tokenId, deviceId, auth); 1355 }; 1356 std::unique_lock<std::shared_mutex> lockGuard(commAuthMutex_); 1357 auto it = std::find_if(commAuth_.begin(), commAuth_.end(), check); 1358 if (it != commAuth_.end()) { 1359 commAuth_.erase(it); 1360 return true; 1361 } 1362 return false; 1363 } 1364 DetachCommAuthInfoBySocketId(int32_t socketId)1365 void IPCProcessSkeleton::DetachCommAuthInfoBySocketId(int32_t socketId) 1366 { 1367 CHECK_INSTANCE_EXIT(exitFlag_); 1368 auto check = [&socketId](const std::shared_ptr<CommAuthInfo> &auth) { 1369 ZLOGI(LOG_LABEL, "socketId:%{public}d", socketId); 1370 return (auth != nullptr) && (auth->GetRemoteSocketId() == socketId); 1371 }; 1372 1373 std::unique_lock<std::shared_mutex> lockGuard(commAuthMutex_); 1374 commAuth_.erase(std::remove_if(commAuth_.begin(), commAuth_.end(), check), commAuth_.end()); 1375 } 1376 QueryCommAuthInfo(int pid,int uid,uint32_t & tokenId,const std::string & deviceId)1377 bool IPCProcessSkeleton::QueryCommAuthInfo(int pid, int uid, uint32_t &tokenId, const std::string &deviceId) 1378 { 1379 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1380 auto check = [&pid, &uid, &deviceId, this](const std::shared_ptr<CommAuthInfo> &auth) { 1381 return IsSameRemoteObject(pid, uid, deviceId, auth); 1382 }; 1383 1384 std::shared_lock<std::shared_mutex> lockGuard(commAuthMutex_); 1385 auto it = std::find_if(commAuth_.begin(), commAuth_.end(), check); 1386 if (it != commAuth_.end()) { 1387 if ((*it) == nullptr) { 1388 tokenId = 0; 1389 return false; 1390 } 1391 tokenId = (*it)->GetRemoteTokenId(); 1392 return true; 1393 } 1394 ZLOGE(LOG_LABEL, "NOT exist, deviceId:%{public}s pid:%{public}u uid:%{public}u", 1395 IPCProcessSkeleton::ConvertToSecureString(deviceId).c_str(), pid, uid); 1396 tokenId = 0; 1397 return false; 1398 } 1399 UpdateCommAuthSocketInfo(int pid,int uid,uint32_t & tokenId,const std::string & deviceId,int32_t socketId)1400 void IPCProcessSkeleton::UpdateCommAuthSocketInfo(int pid, int uid, uint32_t &tokenId, const std::string &deviceId, 1401 int32_t socketId) 1402 { 1403 CHECK_INSTANCE_EXIT(exitFlag_); 1404 auto check = [&pid, &uid, &deviceId, this](const std::shared_ptr<CommAuthInfo> &auth) { 1405 return IsSameRemoteObject(pid, uid, deviceId, auth); 1406 }; 1407 std::unique_lock<std::shared_mutex> lockGuard(commAuthMutex_); 1408 auto it = std::find_if(commAuth_.begin(), commAuth_.end(), check); 1409 if (it != commAuth_.end()) { 1410 (*it)->SetRemoteSocketId(socketId); 1411 } 1412 } 1413 AttachOrUpdateAppAuthInfo(const AppAuthInfo & appAuthInfo)1414 bool IPCProcessSkeleton::AttachOrUpdateAppAuthInfo(const AppAuthInfo &appAuthInfo) 1415 { 1416 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1417 ZLOGI(LOG_LABEL, "pid:%{public}u uid:%{public}u tokenId:%{public}u deviceId:%{public}s stubIndex:%{public}" PRIu64 1418 " socketId:%{public}d", appAuthInfo.pid, appAuthInfo.uid, appAuthInfo.tokenId, 1419 ConvertToSecureString(appAuthInfo.deviceId).c_str(), appAuthInfo.stubIndex, appAuthInfo.socketId); 1420 1421 std::unique_lock<std::shared_mutex> lockGuard(appAuthMutex_); 1422 std::string appInfo = appAuthInfo.deviceId + UIntToString(appAuthInfo.pid) + 1423 UIntToString(appAuthInfo.uid) + UIntToString(appAuthInfo.tokenId); 1424 auto it = appInfoToStubIndex_.find(appInfo); 1425 if (it != appInfoToStubIndex_.end()) { 1426 if (appAuthInfo.stubIndex != 0) { 1427 it->second.insert_or_assign(appAuthInfo.stubIndex, appAuthInfo.socketId); 1428 } else if (appAuthInfo.socketId != 0) { 1429 for (auto it2 = it->second.begin(); it2 != it->second.end(); it2++) { 1430 it2->second = appAuthInfo.socketId; 1431 } 1432 ZLOGW(LOG_LABEL, "app info already existed, update socketId:%{public}d", appAuthInfo.socketId); 1433 } else { 1434 ZLOGE(LOG_LABEL, "stubindex and socketid are both invalid"); 1435 } 1436 } else { 1437 appInfoToStubIndex_[appInfo].insert(std::make_pair(appAuthInfo.stubIndex, appAuthInfo.socketId)); 1438 } 1439 1440 if (appAuthInfo.stub == nullptr) { 1441 return false; 1442 } 1443 1444 auto check = [&appAuthInfo, this](const std::shared_ptr<CommAuthInfo> &auth) { 1445 return IsSameRemoteObject(appAuthInfo.stub, appAuthInfo.pid, appAuthInfo.uid, 1446 appAuthInfo.tokenId, appAuthInfo.deviceId, auth); 1447 }; 1448 auto iter = std::find_if(commAuth_.begin(), commAuth_.end(), check); 1449 if ((iter != commAuth_.end()) && (appAuthInfo.socketId != 0)) { 1450 (*iter)->SetRemoteSocketId(appAuthInfo.socketId); 1451 ZLOGW(LOG_LABEL, "comm auth info already existed, update socketId:%{public}d", appAuthInfo.socketId); 1452 return false; 1453 } 1454 1455 std::shared_ptr<CommAuthInfo> authObject = std::make_shared<CommAuthInfo>( 1456 appAuthInfo.stub, appAuthInfo.pid, appAuthInfo.uid, 1457 appAuthInfo.tokenId, appAuthInfo.deviceId, appAuthInfo.socketId); 1458 commAuth_.push_front(authObject); 1459 return true; 1460 } 1461 DetachAppAuthInfo(const AppAuthInfo & appAuthInfo)1462 bool IPCProcessSkeleton::DetachAppAuthInfo(const AppAuthInfo &appAuthInfo) 1463 { 1464 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1465 std::string appInfo = appAuthInfo.deviceId + UIntToString(appAuthInfo.pid) + 1466 UIntToString(appAuthInfo.uid) + UIntToString(appAuthInfo.tokenId); 1467 1468 std::unique_lock<std::shared_mutex> lockGuard(appAuthMutex_); 1469 bool result = false; 1470 auto it = appInfoToStubIndex_.find(appInfo); 1471 if (it != appInfoToStubIndex_.end()) { 1472 std::map<uint64_t, int32_t> &indexes = it->second; 1473 auto it2 = indexes.find(appAuthInfo.stubIndex); 1474 if (it2 != indexes.end() && it2->second == appAuthInfo.socketId) { 1475 indexes.erase(it2); 1476 result = true; 1477 } 1478 if (indexes.empty()) { 1479 appInfoToStubIndex_.erase(it); 1480 } 1481 } 1482 if (!result) { 1483 return false; 1484 } 1485 1486 auto check = [&appAuthInfo, this](const std::shared_ptr<CommAuthInfo> &auth) { 1487 return IsSameRemoteObject(appAuthInfo.stub, appAuthInfo.pid, appAuthInfo.uid, 1488 appAuthInfo.tokenId, appAuthInfo.deviceId, auth); 1489 }; 1490 1491 auto iter = std::find_if(commAuth_.begin(), commAuth_.end(), check); 1492 if (iter != commAuth_.end()) { 1493 commAuth_.erase(iter); 1494 } 1495 ZLOGI(LOG_LABEL, "pid:%{public}u uid:%{public}u tokenId:%{public}u deviceId:%{public}s" 1496 " stubIndex:%{public}" PRIu64 " socketId:%{public}u result:%{public}d", 1497 appAuthInfo.pid, appAuthInfo.uid, appAuthInfo.tokenId, ConvertToSecureString(appAuthInfo.deviceId).c_str(), 1498 appAuthInfo.stubIndex, appAuthInfo.socketId, result); 1499 1500 return true; 1501 } 1502 DetachAppAuthInfoByStub(IRemoteObject * stub,uint64_t stubIndex)1503 void IPCProcessSkeleton::DetachAppAuthInfoByStub(IRemoteObject *stub, uint64_t stubIndex) 1504 { 1505 CHECK_INSTANCE_EXIT(exitFlag_); 1506 auto check = [&stub](const std::shared_ptr<CommAuthInfo> &auth) { 1507 return (auth != nullptr) && (auth->GetStubObject() == stub); 1508 }; 1509 std::unique_lock<std::shared_mutex> lockGuard(appAuthMutex_); 1510 commAuth_.erase(std::remove_if(commAuth_.begin(), commAuth_.end(), check), commAuth_.end()); 1511 1512 for (auto it = appInfoToStubIndex_.begin(); it != appInfoToStubIndex_.end();) { 1513 if (it->second.erase(stubIndex) > 0) { 1514 ZLOGI(LOG_LABEL, "earse stubIndex:%{public}" PRIu64 " of appInfo:%{public}s", 1515 stubIndex, ConvertToSecureString(it->first).c_str()); 1516 } 1517 if (it->second.size() == 0) { 1518 it = appInfoToStubIndex_.erase(it); 1519 } else { 1520 ++it; 1521 } 1522 } 1523 } 1524 DetachAppAuthInfoBySocketId(int32_t socketId)1525 std::list<uint64_t> IPCProcessSkeleton::DetachAppAuthInfoBySocketId(int32_t socketId) 1526 { 1527 std::list<uint64_t> indexes; 1528 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, indexes); 1529 auto check = [&socketId](const std::shared_ptr<CommAuthInfo> &auth) { 1530 return (auth != nullptr) && (auth->GetRemoteSocketId() == socketId); 1531 }; 1532 1533 std::unique_lock<std::shared_mutex> lockGuard(appAuthMutex_); 1534 commAuth_.erase(std::remove_if(commAuth_.begin(), commAuth_.end(), check), commAuth_.end()); 1535 1536 uint32_t indexCnt = 0; 1537 bool appInfoErase = false; 1538 for (auto it = appInfoToStubIndex_.begin(); it != appInfoToStubIndex_.end();) { 1539 std::map<uint64_t, int32_t> &mapItem = it->second; 1540 for (auto it2 = mapItem.begin(); it2 != mapItem.end();) { 1541 if (it2->second == socketId) { 1542 indexes.push_back(it2->first); 1543 it2 = mapItem.erase(it2); 1544 indexCnt++; 1545 } else { 1546 ++it2; 1547 } 1548 } 1549 if (mapItem.empty()) { 1550 it = appInfoToStubIndex_.erase(it); 1551 appInfoErase = true; 1552 } else { 1553 ++it; 1554 } 1555 } 1556 ZLOGI(LOG_LABEL, "socketId:%{public}d, indexCnt:%{public}u appInfoErase:%{public}d", 1557 socketId, indexCnt, appInfoErase); 1558 return indexes; 1559 } 1560 QueryCommAuthInfo(AppAuthInfo & appAuthInfo)1561 bool IPCProcessSkeleton::QueryCommAuthInfo(AppAuthInfo &appAuthInfo) 1562 { 1563 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1564 auto check = [&appAuthInfo, this](const std::shared_ptr<CommAuthInfo> &auth) { 1565 return IsSameRemoteObject(appAuthInfo.pid, appAuthInfo.uid, appAuthInfo.deviceId, auth); 1566 }; 1567 1568 std::shared_lock<std::shared_mutex> lockGuard(appAuthMutex_); 1569 auto it = std::find_if(commAuth_.begin(), commAuth_.end(), check); 1570 if (it != commAuth_.end()) { 1571 if ((*it) == nullptr) { 1572 ZLOGE(LOG_LABEL, "CommAuthInfo is nullptr"); 1573 return false; 1574 } 1575 appAuthInfo.tokenId = (*it)->GetRemoteTokenId(); 1576 return true; 1577 } 1578 ZLOGE(LOG_LABEL, "NOT exist, deviceId:%{public}s pid:%{public}u uid:%{public}u", 1579 IPCProcessSkeleton::ConvertToSecureString(appAuthInfo.deviceId).c_str(), appAuthInfo.pid, appAuthInfo.uid); 1580 return false; 1581 } 1582 QueryAppInfoToStubIndex(const AppAuthInfo & appAuthInfo)1583 bool IPCProcessSkeleton::QueryAppInfoToStubIndex(const AppAuthInfo &appAuthInfo) 1584 { 1585 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1586 std::string appInfo = appAuthInfo.deviceId + UIntToString(appAuthInfo.pid) + 1587 UIntToString(appAuthInfo.uid) + UIntToString(appAuthInfo.tokenId); 1588 1589 std::shared_lock<std::shared_mutex> lockGuard(appAuthMutex_); 1590 auto it = appInfoToStubIndex_.find(appInfo); 1591 if (it != appInfoToStubIndex_.end()) { 1592 auto it2 = it->second.find(appAuthInfo.stubIndex); 1593 // listenFd may be marked as 0 1594 if (it2 != it->second.end() && (it2->second == 0 || it2->second == appAuthInfo.socketId)) { 1595 ZLOGD(LOG_LABEL, "found appInfo:%{public}s stubIndex:%{public}" PRIu64, 1596 ConvertToSecureString(appInfo).c_str(), appAuthInfo.stubIndex); 1597 return true; 1598 } 1599 } 1600 1601 return false; 1602 } 1603 DetachCommAuthInfoByStub(IRemoteObject * stub)1604 void IPCProcessSkeleton::DetachCommAuthInfoByStub(IRemoteObject *stub) 1605 { 1606 CHECK_INSTANCE_EXIT(exitFlag_); 1607 auto check = [&stub](const std::shared_ptr<CommAuthInfo> &auth) { 1608 return (auth != nullptr) && (auth->GetStubObject() == stub); 1609 }; 1610 std::unique_lock<std::shared_mutex> lockGuard(commAuthMutex_); 1611 commAuth_.erase(std::remove_if(commAuth_.begin(), commAuth_.end(), check), commAuth_.end()); 1612 } 1613 AttachDBinderCallbackStub(sptr<IRemoteObject> proxy,sptr<DBinderCallbackStub> stub)1614 bool IPCProcessSkeleton::AttachDBinderCallbackStub(sptr<IRemoteObject> proxy, sptr<DBinderCallbackStub> stub) 1615 { 1616 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1617 std::unique_lock<std::shared_mutex> lockGuard(dbinderSentMutex_); 1618 auto result = dbinderSentCallback_.insert(std::pair<sptr<IRemoteObject>, wptr<DBinderCallbackStub>>(proxy, stub)); 1619 return result.second; 1620 } 1621 DetachDBinderCallbackStubByProxy(sptr<IRemoteObject> proxy)1622 bool IPCProcessSkeleton::DetachDBinderCallbackStubByProxy(sptr<IRemoteObject> proxy) 1623 { 1624 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false); 1625 std::unique_lock<std::shared_mutex> lockGuard(dbinderSentMutex_); 1626 1627 return (dbinderSentCallback_.erase(proxy) > 0); 1628 } 1629 DetachDBinderCallbackStub(DBinderCallbackStub * stub)1630 void IPCProcessSkeleton::DetachDBinderCallbackStub(DBinderCallbackStub *stub) 1631 { 1632 CHECK_INSTANCE_EXIT(exitFlag_); 1633 std::unique_lock<std::shared_mutex> lockGuard(dbinderSentMutex_); 1634 for (auto it = dbinderSentCallback_.begin(); it != dbinderSentCallback_.end(); it++) { 1635 if (it->second == stub) { 1636 dbinderSentCallback_.erase(it); 1637 break; 1638 } 1639 } 1640 } 1641 QueryDBinderCallbackStub(sptr<IRemoteObject> proxy)1642 sptr<DBinderCallbackStub> IPCProcessSkeleton::QueryDBinderCallbackStub(sptr<IRemoteObject> proxy) 1643 { 1644 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 1645 std::shared_lock<std::shared_mutex> lockGuard(dbinderSentMutex_); 1646 auto it = dbinderSentCallback_.find(proxy); 1647 if (it != dbinderSentCallback_.end()) { 1648 wptr<DBinderCallbackStub> cache = it->second; 1649 return cache.promote(); 1650 } 1651 return nullptr; 1652 } 1653 QueryDBinderCallbackProxy(sptr<IRemoteObject> stub)1654 sptr<IRemoteObject> IPCProcessSkeleton::QueryDBinderCallbackProxy(sptr<IRemoteObject> stub) 1655 { 1656 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr); 1657 std::shared_lock<std::shared_mutex> lockGuard(dbinderSentMutex_); 1658 for (auto it = dbinderSentCallback_.begin(); it != dbinderSentCallback_.end(); it++) { 1659 if (it->second.GetRefPtr() == stub.GetRefPtr() && it->second.promote() != nullptr) { 1660 return it->first; 1661 } 1662 } 1663 1664 return nullptr; 1665 } 1666 #endif 1667 ~DestroyInstance()1668 IPCProcessSkeleton::DestroyInstance::~DestroyInstance() 1669 { 1670 if (instance_ == nullptr) { 1671 return; 1672 } 1673 1674 // notify other threads to stop running 1675 auto process = ProcessSkeleton::GetInstance(); 1676 if (process != nullptr) { 1677 process->NotifyChildThreadStop(); 1678 } 1679 1680 delete instance_; 1681 instance_ = nullptr; 1682 } 1683 #ifdef CONFIG_IPC_SINGLE 1684 } // namespace IPC_SINGLE 1685 #endif 1686 } // namespace OHOS 1687