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