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