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