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