• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "ipc_debug.h"
24 #include "ipc_thread_skeleton.h"
25 #include "ipc_types.h"
26 #include "log_tags.h"
27 #include "process_skeleton.h"
28 #include "string_ex.h"
29 #include "sys_binder.h"
30 
31 #ifndef CONFIG_IPC_SINGLE
32 #include "databus_session_callback.h"
33 #include "softbus_bus_center.h"
34 #endif
35 
36 namespace OHOS {
37 #ifdef CONFIG_IPC_SINGLE
38 namespace IPC_SINGLE {
39 #endif
40 #ifndef CONFIG_IPC_SINGLE
41 using namespace Communication;
42 #endif
43 using namespace OHOS::HiviewDFX;
44 
45 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC_PROC_SKELETON, "IPCProcessSkeleton" };
46 #ifndef CONFIG_IPC_SINGLE
47 static constexpr int32_t DETACH_PROXY_REF_COUNT = 2;
48 #endif
49 std::mutex IPCProcessSkeleton::procMutex_;
50 IPCProcessSkeleton *IPCProcessSkeleton::instance_ = nullptr;
51 IPCProcessSkeleton::DestroyInstance IPCProcessSkeleton::destroyInstance_;
52 std::atomic<bool> IPCProcessSkeleton::exitFlag_ = false;
53 
GetCurrent()54 IPCProcessSkeleton *IPCProcessSkeleton::GetCurrent()
55 {
56     if ((instance_ == nullptr) && !exitFlag_) {
57         std::lock_guard<std::mutex> lockGuard(procMutex_);
58         if ((instance_ == nullptr) && !exitFlag_) {
59             IPCProcessSkeleton *temp = new (std::nothrow) IPCProcessSkeleton();
60             if (temp == nullptr) {
61                 ZLOGE(LOG_LABEL, "create IPCProcessSkeleton object failed");
62                 return nullptr;
63             }
64             if (temp->SetMaxWorkThread(DEFAULT_WORK_THREAD_NUM)) {
65                 temp->SpawnThread(IPCWorkThread::SPAWN_ACTIVE);
66             }
67             instance_ = temp;
68         }
69     }
70 
71     return instance_;
72 }
73 
IPCProcessSkeleton()74 IPCProcessSkeleton::IPCProcessSkeleton()
75 {
76 #ifndef CONFIG_IPC_SINGLE
77     std::random_device randDevice;
78     std::default_random_engine baseRand { randDevice() };
79     std::uniform_int_distribution<> range(1, DBINDER_HANDLE_COUNT * DBINDER_HANDLE_RANG);
80     int temp = range(baseRand);
81     randNum_ = static_cast<uint64_t>(temp);
82 #endif
83 }
84 
ConvertToSecureString(const std::string & str)85 std::string IPCProcessSkeleton::ConvertToSecureString(const std::string &str)
86 {
87     size_t len = str.size();
88     if (len <= ENCRYPT_LENGTH) {
89         return "****";
90     }
91     return str.substr(0, ENCRYPT_LENGTH) + "****" + str.substr(len - ENCRYPT_LENGTH);
92 }
93 
ConvertToSecureDesc(const std::string & str)94 std::string IPCProcessSkeleton::ConvertToSecureDesc(const std::string &str)
95 {
96     auto pos = str.find_last_of(".");
97     if (pos != std::string::npos) {
98         return "*" + str.substr(pos);
99     }
100     return str;
101 }
102 
103 #ifndef CONFIG_IPC_SINGLE
ClearDataResource()104 void IPCProcessSkeleton::ClearDataResource()
105 {
106     {
107         std::unique_lock<std::shared_mutex> lockGuard(rawDataMutex_);
108         rawData_.clear();
109     }
110     {
111         std::unique_lock<std::shared_mutex> lockGuard(threadLockMutex_);
112         threadLockInfo_.clear();
113     }
114     {
115         std::lock_guard<std::mutex> lockGuard(findThreadMutex_);
116         seqNumberToThread_.clear();
117     }
118     {
119         std::unique_lock<std::shared_mutex> lockGuard(stubObjectsMutex_);
120         stubObjects_.clear();
121     }
122     {
123         std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
124         proxyToSession_.clear();
125     }
126     {
127         std::unique_lock<std::shared_mutex> lockGuard(databusSessionMutex_);
128         dbinderSessionObjects_.clear();
129     }
130     {
131         std::unique_lock<std::shared_mutex> lockGuard(callbackStubMutex_);
132         noticeStub_.clear();
133     }
134     {
135         std::lock_guard<std::mutex> lockGuard(idleDataMutex_);
136         idleDataThreads_.clear();
137     }
138     {
139         std::lock_guard<std::mutex> lockGuard(dataQueueMutex_);
140         dataInfoQueue_.clear();
141     }
142     {
143         std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_);
144         appInfoToStubIndex_.clear();
145     }
146     {
147         std::unique_lock<std::shared_mutex> lockGuard(commAuthMutex_);
148         commAuth_.clear();
149     }
150     {
151         std::unique_lock<std::shared_mutex> lockGuard(dbinderSentMutex_);
152         dbinderSentCallback_.clear();
153     }
154 }
155 #endif
156 
~IPCProcessSkeleton()157 IPCProcessSkeleton::~IPCProcessSkeleton()
158 {
159     std::lock_guard<std::mutex> lockGuard(procMutex_);
160     exitFlag_ = true;
161     delete threadPool_;
162     threadPool_ = nullptr;
163 
164 #ifndef CONFIG_IPC_SINGLE
165     ClearDataResource();
166     std::shared_ptr<ISessionService> manager = ISessionService::GetInstance();
167     if (manager != nullptr) {
168         std::string pkgName = std::string(DBINDER_SERVER_PKG_NAME) + "_" + std::to_string(getpid());
169         (void)manager->RemoveSessionServer(pkgName, sessionName_);
170     }
171 #endif
172 }
173 
GetRegistryObject()174 sptr<IRemoteObject> IPCProcessSkeleton::GetRegistryObject()
175 {
176     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
177     auto current = ProcessSkeleton::GetInstance();
178     if (current == nullptr) {
179         ZLOGE(LOG_LABEL, "get process skeleton failed");
180         return nullptr;
181     }
182     sptr<IRemoteObject> object = current->GetRegistryObject();
183     if (object == nullptr) {
184         object = FindOrNewObject(REGISTRY_HANDLE);
185         if (object != nullptr) {
186             current->SetRegistryObject(object);
187         }
188     }
189     return object;
190 }
191 
MakeHandleDescriptor(int handle)192 std::u16string IPCProcessSkeleton::MakeHandleDescriptor(int handle)
193 {
194     std::string descriptor = "IPCObjectProxy" + std::to_string(handle);
195     return Str8ToStr16(descriptor);
196 }
197 
FindOrNewObject(int handle)198 sptr<IRemoteObject> IPCProcessSkeleton::FindOrNewObject(int handle)
199 {
200     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
201     bool newFlag = false;
202     sptr<IRemoteObject> result = GetProxyObject(handle, newFlag);
203     if (result == nullptr) {
204         ZLOGE(LOG_LABEL, "GetProxyObject failed, handle:%{public}d", handle);
205         return result;
206     }
207     sptr<IPCObjectProxy> proxy = reinterpret_cast<IPCObjectProxy *>(result.GetRefPtr());
208     proxy->WaitForInit();
209 #ifndef CONFIG_IPC_SINGLE
210     if (proxy->GetProto() == IRemoteObject::IF_PROT_ERROR) {
211         ZLOGE(LOG_LABEL, "init rpc proxy failed, handle:%{public}d", handle);
212         if (proxy->GetSptrRefCount() <= DETACH_PROXY_REF_COUNT) {
213             DetachObject(result.GetRefPtr());
214         }
215         return nullptr;
216     }
217 #endif
218     ZLOGD(LOG_LABEL, "handle:%{public}d proto:%{public}d new:%{public}d", handle, proxy->GetProto(), newFlag);
219     return result;
220 }
221 
GetProxyObject(int handle,bool & newFlag)222 sptr<IRemoteObject> IPCProcessSkeleton::GetProxyObject(int handle, bool &newFlag)
223 {
224     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
225     sptr<IRemoteObject> result = nullptr;
226     std::u16string descriptor = MakeHandleDescriptor(handle);
227     if (descriptor.length() == 0) {
228         ZLOGE(LOG_LABEL, "make handle descriptor failed");
229         return result;
230     }
231 
232     auto current = ProcessSkeleton::GetInstance();
233     if (current == nullptr) {
234         ZLOGE(LOG_LABEL, "get process skeleton failed");
235         return result;
236     }
237 
238     if (!current->LockObjectMutex()) {
239         ZLOGE(LOG_LABEL, "LockObjectMutex failed!");
240         return result;
241     }
242     result = QueryObject(descriptor, false);
243     if (result != nullptr) {
244         current->UnlockObjectMutex();
245         return result;
246     }
247     // Either this is a new handle or attemptIncStrong failed(strong refcount has been decreased to zero),
248     // we need to create a new proxy and initialize it. Meanwhile, the old proxy is destroying concurrently.
249     if (handle == REGISTRY_HANDLE) {
250         IRemoteInvoker *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DEFAULT);
251         if (invoker == nullptr) {
252             ZLOGE(LOG_LABEL, "failed to get invoker");
253             current->UnlockObjectMutex();
254             return result;
255         }
256         if (!invoker->PingService(REGISTRY_HANDLE)) {
257             current->UnlockObjectMutex();
258             return result;
259         }
260     }
261     // OnFirstStrongRef will be called.
262     result = new (std::nothrow) IPCObjectProxy(handle, descriptor);
263     if (result == nullptr) {
264         ZLOGE(LOG_LABEL, "new IPCObjectProxy failed!");
265         current->UnlockObjectMutex();
266         return result;
267     }
268     AttachObject(result.GetRefPtr(), false);
269     newFlag = true;
270     current->UnlockObjectMutex();
271     return result;
272 }
273 
SetRegistryObject(sptr<IRemoteObject> & object)274 bool IPCProcessSkeleton::SetRegistryObject(sptr<IRemoteObject> &object)
275 {
276     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
277     if (object == nullptr) {
278         ZLOGE(LOG_LABEL, "object is null");
279         return false;
280     }
281     auto current = ProcessSkeleton::GetInstance();
282     if (current == nullptr) {
283         ZLOGE(LOG_LABEL, "get process skeleton failed");
284         return false;
285     }
286     IRemoteInvoker *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DEFAULT);
287     if (invoker == nullptr) {
288         ZLOGE(LOG_LABEL, "fail to get invoker");
289         return false;
290     }
291     bool ret = invoker->SetRegistryObject(object);
292     if (ret) {
293         current->SetRegistryObject(object);
294         current->SetSamgrFlag(true);
295     }
296     ZLOGI(LOG_LABEL, "set registry result:%{public}d", ret);
297     return ret;
298 }
299 
SetMaxWorkThread(int maxThreadNum)300 bool IPCProcessSkeleton::SetMaxWorkThread(int maxThreadNum)
301 {
302     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
303     if (maxThreadNum <= 0) {
304         ZLOGE(LOG_LABEL, "Set Invalid thread Number:%{public}d", maxThreadNum);
305         return false;
306     }
307 
308     if (threadPool_ == nullptr) {
309         threadPool_ = new (std::nothrow) IPCWorkThreadPool(maxThreadNum);
310         if (threadPool_ == nullptr) {
311             ZLOGE(LOG_LABEL, "create IPCWorkThreadPool object failed");
312             return false;
313         }
314     }
315     threadPool_->UpdateMaxThreadNum(maxThreadNum);
316     IRemoteInvoker *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DEFAULT);
317     if (invoker != nullptr) {
318         return invoker->SetMaxWorkThread(maxThreadNum);
319     }
320 
321     return false;
322 }
323 
SpawnThread(int policy,int proto)324 bool IPCProcessSkeleton::SpawnThread(int policy, int proto)
325 {
326     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
327     if (threadPool_ != nullptr) {
328         return threadPool_->SpawnThread(policy, proto);
329     }
330 
331     /* can NOT reach here */
332     return false;
333 }
334 
OnThreadTerminated(const std::string & threadName)335 bool IPCProcessSkeleton::OnThreadTerminated(const std::string &threadName)
336 {
337     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
338     if (threadPool_ != nullptr) {
339         return threadPool_->RemoveThread(threadName);
340     }
341 
342     return true;
343 }
344 
IsContainsObject(IRemoteObject * object)345 bool IPCProcessSkeleton::IsContainsObject(IRemoteObject *object)
346 {
347     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
348     if (object == nullptr) {
349         ZLOGE(LOG_LABEL, "object is null");
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 size_t 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     if (getuid() != FOUNDATION_UID) {
430         return;
431     }
432     std::lock_guard<std::mutex> lockGuard(mutex_);
433     numExecuting_++;
434 }
435 
UnlockForNumExecuting()436 void IPCProcessSkeleton::UnlockForNumExecuting()
437 {
438     CHECK_INSTANCE_EXIT(exitFlag_);
439     if (getuid() != FOUNDATION_UID) {
440         return;
441     }
442     std::lock_guard<std::mutex> lockGuard(mutex_);
443     numExecuting_--;
444     if (numWaitingForThreads_ > 0) {
445         cv_.notify_all();
446     }
447 }
448 
449 #ifndef CONFIG_IPC_SINGLE
GetSAMgrObject()450 sptr<IRemoteObject> IPCProcessSkeleton::GetSAMgrObject()
451 {
452     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
453     IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
454     if (invoker == nullptr) {
455         return nullptr;
456     }
457     return invoker->GetSAMgrObject();
458 }
459 
460 /*
461  * databus return int64_t channel id, but high 32bit only use 1bit channel type, we convert to int
462  * convert to 24bit channelID and 7bit channel type
463  * |---1bit---|------7bit----| ------------------------24bit------|
464  * | reserved | channel type |    true channel id                 |
465  * don't care signed bit when convert,for we reserved high 1bit
466  */
ConvertChannelID2Int(int64_t databusChannelId)467 uint32_t IPCProcessSkeleton::ConvertChannelID2Int(int64_t databusChannelId)
468 {
469     if (databusChannelId < 0) {
470         return 0;
471     }
472     uint64_t databusChannel = static_cast<uint64_t>(databusChannelId);
473     uint32_t channelType = static_cast<uint32_t>((databusChannel >> 8) & 0X00000000FF000000ULL);
474     uint32_t channelID = static_cast<uint32_t>(databusChannel & 0X0000000000FFFFFFULL);
475     return (channelType | channelID);
476 }
477 
GetLocalDeviceID()478 std::string IPCProcessSkeleton::GetLocalDeviceID()
479 {
480     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, "");
481     std::lock_guard<std::mutex> lockGuard(databusProcMutex_);
482 
483     std::string pkgName = std::string(DBINDER_SERVER_PKG_NAME) + "_" + std::to_string(getpid());
484     NodeBasicInfo nodeBasicInfo;
485     if (GetLocalNodeDeviceInfo(pkgName.c_str(), &nodeBasicInfo) != 0) {
486         ZLOGE(LOG_LABEL, "Get local node device info failed");
487         return "";
488     }
489     std::string networkId(nodeBasicInfo.networkId);
490     return networkId;
491 }
492 
IsHandleMadeByUser(uint32_t handle)493 bool IPCProcessSkeleton::IsHandleMadeByUser(uint32_t handle)
494 {
495     if (handle >= DBINDER_HANDLE_BASE && handle <= (DBINDER_HANDLE_BASE + DBINDER_HANDLE_COUNT)) {
496         ZLOGD(LOG_LABEL, "handle:%{public}u is make by user, not kernel", handle);
497         return true;
498     }
499     return false;
500 }
501 
GetDBinderIdleHandle(std::shared_ptr<DBinderSessionObject> session)502 uint32_t IPCProcessSkeleton::GetDBinderIdleHandle(std::shared_ptr<DBinderSessionObject> session)
503 {
504     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0);
505     std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
506     uint32_t tempHandle = dBinderHandle_;
507     int count = DBINDER_HANDLE_COUNT;
508     bool insertResult = false;
509     do {
510         count--;
511         tempHandle++;
512         if (tempHandle > DBINDER_HANDLE_BASE + DBINDER_HANDLE_COUNT) {
513             tempHandle = DBINDER_HANDLE_BASE;
514         }
515         insertResult = proxyToSession_.insert(std::pair<uint32_t,
516             std::shared_ptr<DBinderSessionObject>>(tempHandle, session)).second;
517     } while (insertResult == false && count > 0);
518 
519     if (count == 0 && insertResult == false) {
520         return 0;
521     }
522     dBinderHandle_ = tempHandle;
523     return dBinderHandle_;
524 }
525 
ProxyDetachDBinderSession(uint32_t handle,IPCObjectProxy * proxy)526 std::shared_ptr<DBinderSessionObject> IPCProcessSkeleton::ProxyDetachDBinderSession(uint32_t handle,
527     IPCObjectProxy *proxy)
528 {
529     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
530     std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
531     std::shared_ptr<DBinderSessionObject> tmp = nullptr;
532     auto it = proxyToSession_.find(handle);
533     if (it != proxyToSession_.end() && it->second->GetProxy() == proxy) {
534         tmp = it->second;
535         proxyToSession_.erase(it);
536         ZLOGI(LOG_LABEL, "detach handle:%{public}u from session:%{public}" PRId64
537             " service:%{public}s stubIndex:%{public}" PRIu64, handle,
538             tmp->GetBusSession()->GetChannelId(), tmp->GetServiceName().c_str(),
539             tmp->GetStubIndex());
540     } else {
541         ZLOGW(LOG_LABEL, "detach handle:%{Public}u, not found", handle);
542     }
543 
544     return tmp;
545 }
546 
ProxyAttachDBinderSession(uint32_t handle,std::shared_ptr<DBinderSessionObject> object)547 bool IPCProcessSkeleton::ProxyAttachDBinderSession(uint32_t handle, std::shared_ptr<DBinderSessionObject> object)
548 {
549     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
550     std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
551     auto result = proxyToSession_.insert(std::pair<uint32_t, std::shared_ptr<DBinderSessionObject>>(handle, object));
552     ZLOGI(LOG_LABEL, "attach handle:%{public}u to session:%{public}" PRId64
553         " service:%{public}s stubIndex:%{public}" PRIu64 " result:%{public}d",
554         handle, object->GetBusSession()->GetChannelId(), object->GetServiceName().c_str(),
555         object->GetStubIndex(), result.second);
556     return result.second;
557 }
558 
ProxyQueryDBinderSession(uint32_t handle)559 std::shared_ptr<DBinderSessionObject> IPCProcessSkeleton::ProxyQueryDBinderSession(uint32_t handle)
560 {
561     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
562     std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
563     auto it = proxyToSession_.find(handle);
564     if (it != proxyToSession_.end()) {
565         return it->second;
566     }
567     return nullptr;
568 }
569 
ProxyMoveDBinderSession(uint32_t handle,IPCObjectProxy * proxy)570 bool IPCProcessSkeleton::ProxyMoveDBinderSession(uint32_t handle, IPCObjectProxy *proxy)
571 {
572     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
573     std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
574     auto it = proxyToSession_.find(handle);
575     if (it != proxyToSession_.end()) {
576         ZLOGI(LOG_LABEL, "move proxy of handle:%{public}u old==new:%{public}d", handle,
577             it->second->GetProxy() == proxy);
578         // moves ownership to this new proxy, so old proxy should not detach this session and stubIndex
579         // see QueryHandleByDatabusSession
580         it->second->SetProxy(proxy);
581         return true;
582     }
583     return false;
584 }
585 
QueryProxyBySessionHandle(uint32_t handle,std::vector<uint32_t> & proxyHandle)586 bool IPCProcessSkeleton::QueryProxyBySessionHandle(uint32_t handle, std::vector<uint32_t> &proxyHandle)
587 {
588     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
589     std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
590     for (auto it = proxyToSession_.begin(); it != proxyToSession_.end(); it++) {
591         std::shared_ptr<Session> session = it->second->GetBusSession();
592         if (session == nullptr) {
593             continue;
594         }
595         uint32_t sessionHandle = IPCProcessSkeleton::ConvertChannelID2Int(session->GetChannelId());
596         if (sessionHandle == handle) {
597             proxyHandle.push_back(it->first);
598         }
599     }
600     ZLOGD(LOG_LABEL, "query proxys of session handle:%{public}u size:%{public}zu", handle, proxyHandle.size());
601     return true;
602 }
603 
QueryHandleByDatabusSession(const std::string & name,const std::string & deviceId,uint64_t stubIndex)604 uint32_t IPCProcessSkeleton::QueryHandleByDatabusSession(const std::string &name, const std::string &deviceId,
605     uint64_t stubIndex)
606 {
607     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0);
608     std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
609 
610     for (auto it = proxyToSession_.begin(); it != proxyToSession_.end(); it++) {
611         if ((it->second->GetStubIndex() == stubIndex) && (it->second->GetDeviceId().compare(deviceId) == 0) &&
612             (it->second->GetServiceName().compare(name) == 0)) {
613             ZLOGI(LOG_LABEL, "found handle:%{public}u of session, stubIndex:%{public}" PRIu64, it->first, stubIndex);
614             // marks ownership not belong to the original proxy, In FindOrNewObject method,
615             // we will find the original proxy and take ownership again if the original proxy is still existed.
616             // Otherwise, if the original proxy is destroyed, it will not erase the session
617             // because we marks here. Later we will setProxy again with the new proxy in UpdateProto method
618             it->second->SetProxy(nullptr);
619             return it->first;
620         }
621     }
622     return 0;
623 }
624 
QuerySessionByInfo(const std::string & name,const std::string & deviceId)625 std::shared_ptr<DBinderSessionObject> IPCProcessSkeleton::QuerySessionByInfo(const std::string &name,
626     const std::string &deviceId)
627 {
628     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
629     std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
630 
631     for (auto it = proxyToSession_.begin(); it != proxyToSession_.end(); it++) {
632         if ((it->second->GetDeviceId().compare(deviceId) == 0) && (it->second->GetServiceName().compare(name) == 0)) {
633             return it->second;
634         }
635     }
636 
637     return nullptr;
638 }
639 
StubDetachDBinderSession(uint32_t handle,uint32_t & tokenId)640 bool IPCProcessSkeleton::StubDetachDBinderSession(uint32_t handle, uint32_t &tokenId)
641 {
642     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
643     std::unique_lock<std::shared_mutex> lockGuard(databusSessionMutex_);
644     auto it = dbinderSessionObjects_.find(handle);
645     if (it != dbinderSessionObjects_.end()) {
646         tokenId = it->second->GetTokenId();
647         ZLOGI(LOG_LABEL, "detach handle:%{public}u stubIndex:%{public}" PRIu64 " tokenId:%{public}u",
648             handle, it->second->GetStubIndex(), tokenId);
649         dbinderSessionObjects_.erase(it);
650         return true;
651     }
652     return false;
653 }
654 
StubAttachDBinderSession(uint32_t handle,std::shared_ptr<DBinderSessionObject> object)655 bool IPCProcessSkeleton::StubAttachDBinderSession(uint32_t handle, std::shared_ptr<DBinderSessionObject> object)
656 {
657     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
658     std::unique_lock<std::shared_mutex> lockGuard(databusSessionMutex_);
659     auto result =
660         dbinderSessionObjects_.insert(std::pair<uint32_t, std::shared_ptr<DBinderSessionObject>>(handle, object));
661     ZLOGI(LOG_LABEL, "attach handle:%{public}u stubIndex:%{public}" PRIu64 " tokenId:%{public}u result:%{public}u",
662         handle, object->GetStubIndex(), object->GetTokenId(), result.second);
663     return result.second;
664 }
665 
StubQueryDBinderSession(uint32_t handle)666 std::shared_ptr<DBinderSessionObject> IPCProcessSkeleton::StubQueryDBinderSession(uint32_t handle)
667 {
668     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
669     std::shared_lock<std::shared_mutex> lockGuard(databusSessionMutex_);
670 
671     auto it = dbinderSessionObjects_.find(handle);
672     if (it != dbinderSessionObjects_.end()) {
673         return it->second;
674     }
675 
676     return nullptr;
677 }
678 
DetachThreadLockInfo(const std::thread::id & threadId)679 bool IPCProcessSkeleton::DetachThreadLockInfo(const std::thread::id &threadId)
680 {
681     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
682     std::unique_lock<std::shared_mutex> lockGuard(threadLockMutex_);
683 
684     return (threadLockInfo_.erase(threadId) > 0);
685 }
686 
AttachThreadLockInfo(std::shared_ptr<SocketThreadLockInfo> object,const std::thread::id & threadId)687 bool IPCProcessSkeleton::AttachThreadLockInfo(std::shared_ptr<SocketThreadLockInfo> object,
688     const std::thread::id &threadId)
689 {
690     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
691     std::unique_lock<std::shared_mutex> lockGuard(threadLockMutex_);
692     auto result =
693         threadLockInfo_.insert(std::pair<std::thread::id, std::shared_ptr<SocketThreadLockInfo>>(threadId, object));
694     return result.second;
695 }
696 
QueryThreadLockInfo(const std::thread::id & threadId)697 std::shared_ptr<SocketThreadLockInfo> IPCProcessSkeleton::QueryThreadLockInfo(const std::thread::id &threadId)
698 {
699     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
700     std::shared_lock<std::shared_mutex> lockGuard(threadLockMutex_);
701 
702     auto it = threadLockInfo_.find(threadId);
703     if (it != threadLockInfo_.end()) {
704         return it->second;
705     }
706 
707     return nullptr;
708 }
709 
710 
AddDataThreadToIdle(const std::thread::id & threadId)711 bool IPCProcessSkeleton::AddDataThreadToIdle(const std::thread::id &threadId)
712 {
713     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
714     std::lock_guard<std::mutex> lockGuard(idleDataMutex_);
715 
716     idleDataThreads_.push_front(threadId);
717     return true;
718 }
719 
DeleteDataThreadFromIdle(const std::thread::id & threadId)720 bool IPCProcessSkeleton::DeleteDataThreadFromIdle(const std::thread::id &threadId)
721 {
722     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
723     std::lock_guard<std::mutex> lockGuard(idleDataMutex_);
724     for (auto it = idleDataThreads_.begin(); it != idleDataThreads_.end(); it++) {
725         if ((*it) == threadId) {
726             it = idleDataThreads_.erase(it);
727             return true;
728         }
729     }
730 
731     /* not in idle state, also return true */
732     return true;
733 }
734 
GetIdleDataThread()735 std::thread::id IPCProcessSkeleton::GetIdleDataThread()
736 {
737     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, std::thread::id());
738     std::lock_guard<std::mutex> lockGuard(idleDataMutex_);
739 
740     if (idleDataThreads_.size() == 0) {
741         return std::thread::id();
742     }
743 
744     std::thread::id threadId = idleDataThreads_.back();
745     return threadId;
746 }
747 
GetSocketIdleThreadNum() const748 int IPCProcessSkeleton::GetSocketIdleThreadNum() const
749 {
750     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0);
751     if (threadPool_ != nullptr) {
752         return threadPool_->GetSocketIdleThreadNum();
753     }
754 
755     return 0;
756 }
757 
GetSocketTotalThreadNum() const758 int IPCProcessSkeleton::GetSocketTotalThreadNum() const
759 {
760     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0);
761     if (threadPool_ != nullptr) {
762         return threadPool_->GetSocketTotalThreadNum();
763     }
764     return 0;
765 }
766 
AddDataInfoToThread(const std::thread::id & threadId,std::shared_ptr<ThreadProcessInfo> processInfo)767 void IPCProcessSkeleton::AddDataInfoToThread(const std::thread::id &threadId,
768     std::shared_ptr<ThreadProcessInfo> processInfo)
769 {
770     CHECK_INSTANCE_EXIT(exitFlag_);
771     std::lock_guard<std::mutex> lockGuard(dataQueueMutex_);
772 
773     (dataInfoQueue_[threadId]).push_back(processInfo);
774 }
775 
PopDataInfoFromThread(const std::thread::id & threadId)776 std::shared_ptr<ThreadProcessInfo> IPCProcessSkeleton::PopDataInfoFromThread(const std::thread::id &threadId)
777 {
778     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
779     std::lock_guard<std::mutex> lockGuard(dataQueueMutex_);
780 
781     if ((dataInfoQueue_[threadId]).size() == 0) {
782         return nullptr;
783     }
784 
785     std::shared_ptr<ThreadProcessInfo> processInfo = (dataInfoQueue_[threadId]).front();
786 
787     (dataInfoQueue_[threadId]).erase((dataInfoQueue_[threadId]).begin());
788     return processInfo;
789 }
790 
WakeUpDataThread(const std::thread::id & threadID)791 void IPCProcessSkeleton::WakeUpDataThread(const std::thread::id &threadID)
792 {
793     CHECK_INSTANCE_EXIT(exitFlag_);
794     if (threadID != std::thread::id()) {
795         std::shared_ptr<SocketThreadLockInfo> threadLockInfo = QueryThreadLockInfo(threadID);
796         if (threadLockInfo != nullptr) {
797             /* Wake up this IO thread to process socket stream
798              * Wake up the client processing thread
799              */
800             std::unique_lock<std::mutex> lock_unique(threadLockInfo->mutex);
801             threadLockInfo->ready = true;
802             threadLockInfo->condition.notify_one();
803         }
804     }
805 }
806 
AddDataThreadInWait(const std::thread::id & threadId)807 void IPCProcessSkeleton::AddDataThreadInWait(const std::thread::id &threadId)
808 {
809     CHECK_INSTANCE_EXIT(exitFlag_);
810     std::shared_ptr<SocketThreadLockInfo> threadLockInfo;
811 
812     threadLockInfo = QueryThreadLockInfo(threadId);
813     if (threadLockInfo == nullptr) {
814         threadLockInfo = std::make_shared<struct SocketThreadLockInfo>();
815         if (!AttachThreadLockInfo(threadLockInfo, threadId)) {
816             ZLOGE(LOG_LABEL, "thread has added lock info");
817             return;
818         }
819     }
820 
821     AddDataThreadToIdle(threadId);
822     std::unique_lock<std::mutex> lock_unique(threadLockInfo->mutex);
823     threadLockInfo->condition.wait(lock_unique, [&threadLockInfo] { return threadLockInfo->ready; });
824     threadLockInfo->ready = false;
825     /* corresponding thread will be waked up */
826     DeleteDataThreadFromIdle(threadId);
827 }
828 
GetSeqNumber()829 uint64_t IPCProcessSkeleton::GetSeqNumber()
830 {
831     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0);
832     std::lock_guard<std::mutex> lockGuard(seqNumberMutex_);
833     if (seqNumber_ == std::numeric_limits<uint64_t>::max()) {
834         seqNumber_ = 0;
835     }
836     seqNumber_++;
837     return seqNumber_;
838 }
839 
QueryThreadBySeqNumber(uint64_t seqNumber)840 std::shared_ptr<ThreadMessageInfo> IPCProcessSkeleton::QueryThreadBySeqNumber(uint64_t seqNumber)
841 {
842     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
843     std::lock_guard<std::mutex> lockGuard(findThreadMutex_);
844 
845     auto it = seqNumberToThread_.find(seqNumber);
846     if (it != seqNumberToThread_.end()) {
847         return it->second;
848     }
849 
850     return nullptr;
851 }
852 
EraseThreadBySeqNumber(uint64_t seqNumber)853 void IPCProcessSkeleton::EraseThreadBySeqNumber(uint64_t seqNumber)
854 {
855     CHECK_INSTANCE_EXIT(exitFlag_);
856     std::lock_guard<std::mutex> lockGuard(findThreadMutex_);
857     seqNumberToThread_.erase(seqNumber);
858 }
859 
860 
AddThreadBySeqNumber(uint64_t seqNumber,std::shared_ptr<ThreadMessageInfo> messageInfo)861 bool IPCProcessSkeleton::AddThreadBySeqNumber(uint64_t seqNumber, std::shared_ptr<ThreadMessageInfo> messageInfo)
862 {
863     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
864     std::lock_guard<std::mutex> lockGuard(findThreadMutex_);
865 
866     auto result =
867         seqNumberToThread_.insert(std::pair<uint64_t, std::shared_ptr<ThreadMessageInfo>>(seqNumber, messageInfo));
868 
869     return result.second;
870 }
871 
WakeUpThreadBySeqNumber(uint64_t seqNumber,uint32_t handle)872 void IPCProcessSkeleton::WakeUpThreadBySeqNumber(uint64_t seqNumber, uint32_t handle)
873 {
874     CHECK_INSTANCE_EXIT(exitFlag_);
875     std::shared_ptr<ThreadMessageInfo> messageInfo;
876 
877     messageInfo = QueryThreadBySeqNumber(seqNumber);
878     if (messageInfo == nullptr) {
879         ZLOGE(LOG_LABEL, "error! messageInfo is nullptr");
880         return;
881     }
882 
883     if (handle != messageInfo->socketId) {
884         ZLOGE(LOG_LABEL, "handle is not equal, handle:%{public}d socketId:%{public}u",
885             handle, messageInfo->socketId);
886         return;
887     }
888 
889     std::unique_lock<std::mutex> lock_unique(messageInfo->mutex);
890     messageInfo->ready = true;
891     messageInfo->condition.notify_one();
892 }
893 
AddSendThreadInWait(uint64_t seqNumber,std::shared_ptr<ThreadMessageInfo> messageInfo,int userWaitTime)894 bool IPCProcessSkeleton::AddSendThreadInWait(uint64_t seqNumber, std::shared_ptr<ThreadMessageInfo> messageInfo,
895     int userWaitTime)
896 {
897     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
898     if (!AddThreadBySeqNumber(seqNumber, messageInfo)) {
899         ZLOGE(LOG_LABEL, "add seqNumber:%{public}" PRIu64 " failed", seqNumber);
900         return false;
901     }
902 
903     std::unique_lock<std::mutex> lock_unique(messageInfo->mutex);
904     if (messageInfo->condition.wait_for(lock_unique, std::chrono::seconds(userWaitTime),
905         [&messageInfo] { return messageInfo->ready; }) == false) {
906         messageInfo->ready = false;
907         ZLOGE(LOG_LABEL, "thread timeout, seqNumber:%{public}" PRIu64 " waittime:%{public}d", seqNumber, userWaitTime);
908         return false;
909     }
910     messageInfo->ready = false;
911     return true;
912 }
913 
QueryStubByIndex(uint64_t stubIndex)914 IRemoteObject *IPCProcessSkeleton::QueryStubByIndex(uint64_t stubIndex)
915 {
916     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
917     if (stubIndex == 0) {
918         ZLOGE(LOG_LABEL, "stubIndex invalid");
919         return nullptr;
920     }
921     std::shared_lock<std::shared_mutex> lockGuard(stubObjectsMutex_);
922 
923     auto it = stubObjects_.find(stubIndex);
924     if (it != stubObjects_.end()) {
925         return it->second;
926     }
927 
928     return nullptr;
929 }
930 
AddStubByIndex(IRemoteObject * stubObject)931 uint64_t IPCProcessSkeleton::AddStubByIndex(IRemoteObject *stubObject)
932 {
933     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0);
934     std::unique_lock<std::shared_mutex> lockGuard(stubObjectsMutex_);
935 
936     /* if stub has its index, return it directly */
937     for (auto it = stubObjects_.begin(); it != stubObjects_.end(); it++) {
938         if (it->second == stubObject) {
939             return it->first;
940         }
941     }
942     uint64_t stubIndex = randNum_++;
943     auto result = stubObjects_.insert(std::pair<uint64_t, IRemoteObject *>(stubIndex, stubObject));
944     if (result.second) {
945         return stubIndex;
946     } else {
947         return 0;
948     }
949 }
950 
QueryStubIndex(IRemoteObject * stubObject)951 uint64_t IPCProcessSkeleton::QueryStubIndex(IRemoteObject *stubObject)
952 {
953     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0);
954     std::unique_lock<std::shared_mutex> lockGuard(stubObjectsMutex_);
955 
956     for (auto it = stubObjects_.begin(); it != stubObjects_.end(); it++) {
957         if (it->second == stubObject) {
958             return it->first;
959         }
960     }
961     return 0;
962 }
963 
EraseStubIndex(IRemoteObject * stubObject)964 uint64_t IPCProcessSkeleton::EraseStubIndex(IRemoteObject *stubObject)
965 {
966     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, 0);
967     std::unique_lock<std::shared_mutex> lockGuard(stubObjectsMutex_);
968 
969     for (auto it = stubObjects_.begin(); it != stubObjects_.end(); it++) {
970         if (it->second == stubObject) {
971             uint64_t stubIndex = it->first;
972             stubObjects_.erase(it);
973             return stubIndex;
974         }
975     }
976     return 0;
977 }
978 
UIntToString(uint32_t input)979 std::string IPCProcessSkeleton::UIntToString(uint32_t input)
980 {
981     // 12: convert to fixed string length
982     char str[12] = {0};
983     if (sprintf_s(str, sizeof(str) / sizeof(str[0]), "%011u", input) <= EOK) {
984         ZLOGE(LOG_LABEL, "sprintf_s fail");
985     }
986     return str;
987 }
988 
DetachAppInfoToStubIndex(uint32_t pid,uint32_t uid,uint32_t tokenId,const std::string & deviceId,uint64_t stubIndex,uint32_t listenFd)989 bool IPCProcessSkeleton::DetachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId,
990     const std::string &deviceId, uint64_t stubIndex, uint32_t listenFd)
991 {
992     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
993     std::string appInfo = deviceId + UIntToString(pid) + UIntToString(uid) + UIntToString(tokenId);
994 
995     std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_);
996     bool result = false;
997     auto it = appInfoToStubIndex_.find(appInfo);
998     if (it != appInfoToStubIndex_.end()) {
999         std::map<uint64_t, uint32_t> indexes = it->second;
1000         auto it2 = indexes.find(stubIndex);
1001         if (it2 != indexes.end() && it2->second == listenFd) {
1002             indexes.erase(it2);
1003             result = true;
1004         }
1005         if (indexes.empty()) {
1006             appInfoToStubIndex_.erase(it);
1007         }
1008     }
1009     ZLOGI(LOG_LABEL, "pid:%{public}u uid:%{public}u tokenId:%{public}u deviceId:%{public}s stubIndex:%{public}" PRIu64
1010         " listenFd:%{public}u result:%{public}d", pid, uid, tokenId, ConvertToSecureString(deviceId).c_str(),
1011         stubIndex, listenFd, result);
1012     return result;
1013 }
1014 
DetachAppInfoToStubIndex(uint32_t pid,uint32_t uid,uint32_t tokenId,const std::string & deviceId,uint32_t listenFd)1015 std::list<uint64_t> IPCProcessSkeleton::DetachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId,
1016     const std::string &deviceId, uint32_t listenFd)
1017 {
1018     std::list<uint64_t> indexes;
1019     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, indexes);
1020     std::string appInfo = deviceId + UIntToString(pid) + UIntToString(uid) + UIntToString(tokenId);
1021 
1022     std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_);
1023 
1024     uint32_t indexCnt = 0;
1025     bool appInfoErase = false;
1026     auto it = appInfoToStubIndex_.find(appInfo);
1027     if (it != appInfoToStubIndex_.end()) {
1028         std::map<uint64_t, uint32_t> stubIndexes = it->second;
1029         for (auto it2 = stubIndexes.begin(); it2 != stubIndexes.end();) {
1030             if (it2->second == listenFd) {
1031                 indexes.push_back(it2->first);
1032                 it2 = stubIndexes.erase(it2);
1033                 indexCnt++;
1034             } else {
1035                 it2++;
1036             }
1037         }
1038         if (stubIndexes.empty()) {
1039             appInfoToStubIndex_.erase(it);
1040             appInfoErase = true;
1041         }
1042     }
1043     ZLOGI(LOG_LABEL, "pid:%{public}u uid:%{public}u tokenId:%{public}u deviceId:%{public}s listenFd:%{public}u"
1044         " indexCnt:%{public}u appInfoErase:%{public}d",
1045         pid, uid, tokenId, ConvertToSecureString(deviceId).c_str(), listenFd, indexCnt, appInfoErase);
1046     return indexes;
1047 }
1048 
DetachAppInfoToStubIndex(uint64_t stubIndex)1049 void IPCProcessSkeleton::DetachAppInfoToStubIndex(uint64_t stubIndex)
1050 {
1051     CHECK_INSTANCE_EXIT(exitFlag_);
1052     std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_);
1053 
1054     for (auto it = appInfoToStubIndex_.begin(); it != appInfoToStubIndex_.end();) {
1055         if (it->second.erase(stubIndex) > 0) {
1056             ZLOGI(LOG_LABEL, "earse stubIndex:%{public}" PRIu64 " of appInfo:%{public}s",
1057                 stubIndex, ConvertToSecureString(it->first).c_str());
1058         }
1059         if (it->second.size() == 0) {
1060             it = appInfoToStubIndex_.erase(it);
1061         } else {
1062             it++;
1063         }
1064     }
1065 }
1066 
AttachAppInfoToStubIndex(uint32_t pid,uint32_t uid,uint32_t tokenId,const std::string & deviceId,uint64_t stubIndex,uint32_t listenFd)1067 bool IPCProcessSkeleton::AttachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId,
1068     const std::string &deviceId, uint64_t stubIndex, uint32_t listenFd)
1069 {
1070     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
1071     ZLOGI(LOG_LABEL, "pid:%{public}u uid:%{public}u tokenId:%{public}u deviceId:%{public}s stubIndex:%{public}" PRIu64
1072         " listenFd:%{public}u", pid, uid, tokenId, ConvertToSecureString(deviceId).c_str(), stubIndex, listenFd);
1073     std::string appInfo = deviceId + UIntToString(pid) + UIntToString(uid) + UIntToString(tokenId);
1074 
1075     std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_);
1076 
1077     auto it = appInfoToStubIndex_.find(appInfo);
1078     if (it != appInfoToStubIndex_.end()) {
1079         auto result = it->second.insert_or_assign(stubIndex, listenFd);
1080         return result.second;
1081     }
1082 
1083     std::map<uint64_t, uint32_t> mapItem { { stubIndex, listenFd } };
1084     auto result = appInfoToStubIndex_.insert(std::pair<std::string, std::map<uint64_t, uint32_t>>(appInfo, mapItem));
1085     return result.second;
1086 }
1087 
AttachAppInfoToStubIndex(uint32_t pid,uint32_t uid,uint32_t tokenId,const std::string & deviceId,uint32_t listenFd)1088 bool IPCProcessSkeleton::AttachAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId,
1089     const std::string &deviceId, uint32_t listenFd)
1090 {
1091     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
1092     ZLOGI(LOG_LABEL, "pid:%{public}u uid:%{public}u tokenId:%{public}u deviceId:%{public}s listenFd:%{public}u",
1093         pid, uid, tokenId, ConvertToSecureString(deviceId).c_str(), listenFd);
1094     std::string appInfo = deviceId + UIntToString(pid) + UIntToString(uid) + UIntToString(tokenId);
1095 
1096     std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_);
1097 
1098     auto it = appInfoToStubIndex_.find(appInfo);
1099     if (it != appInfoToStubIndex_.end()) {
1100         std::map<uint64_t, uint32_t> indexes = it->second;
1101         // OnSessionOpen update listenFd
1102         for (auto it2 = indexes.begin(); it2 != indexes.end(); it2++) {
1103             it2->second = listenFd;
1104         }
1105     }
1106     return true;
1107 }
1108 
QueryAppInfoToStubIndex(uint32_t pid,uint32_t uid,uint32_t tokenId,const std::string & deviceId,uint64_t stubIndex,uint32_t listenFd)1109 bool IPCProcessSkeleton::QueryAppInfoToStubIndex(uint32_t pid, uint32_t uid, uint32_t tokenId,
1110     const std::string &deviceId, uint64_t stubIndex, uint32_t listenFd)
1111 {
1112     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
1113     std::string appInfo = deviceId + UIntToString(pid) + UIntToString(uid) + UIntToString(tokenId);
1114 
1115     std::shared_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_);
1116 
1117     auto it = appInfoToStubIndex_.find(appInfo);
1118     if (it != appInfoToStubIndex_.end()) {
1119         auto it2 = it->second.find(stubIndex);
1120         // listenFd may be marked as 0
1121         if (it2 != it->second.end() && (it2->second == 0 || it2->second == listenFd)) {
1122             ZLOGD(LOG_LABEL, "found appInfo:%{public}s stubIndex:%{public}" PRIu64,
1123                 ConvertToSecureString(appInfo).c_str(), stubIndex);
1124             return true;
1125         }
1126     }
1127 
1128     return false;
1129 }
1130 
AttachCallbackStub(IPCObjectProxy * ipcProxy,sptr<IPCObjectStub> callbackStub)1131 bool IPCProcessSkeleton::AttachCallbackStub(IPCObjectProxy *ipcProxy, sptr<IPCObjectStub> callbackStub)
1132 {
1133     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
1134     std::unique_lock<std::shared_mutex> lockGuard(callbackStubMutex_);
1135     auto result = noticeStub_.insert(std::pair<IPCObjectProxy *, sptr<IPCObjectStub>>(ipcProxy, callbackStub));
1136     return result.second;
1137 }
1138 
DetachCallbackStub(IPCObjectProxy * ipcProxy)1139 sptr<IPCObjectStub> IPCProcessSkeleton::DetachCallbackStub(IPCObjectProxy *ipcProxy)
1140 {
1141     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
1142     sptr<IPCObjectStub> ret = nullptr;
1143     std::unique_lock<std::shared_mutex> lockGuard(callbackStubMutex_);
1144     auto it = noticeStub_.find(ipcProxy);
1145     if (it != noticeStub_.end()) {
1146         ret = it->second;
1147         noticeStub_.erase(it);
1148     }
1149     return ret;
1150 }
1151 
QueryCallbackStub(IPCObjectProxy * ipcProxy)1152 sptr<IPCObjectStub> IPCProcessSkeleton::QueryCallbackStub(IPCObjectProxy *ipcProxy)
1153 {
1154     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
1155     std::shared_lock<std::shared_mutex> lockGuard(callbackStubMutex_);
1156     auto it = noticeStub_.find(ipcProxy);
1157     if (it != noticeStub_.end()) {
1158         return it->second;
1159     }
1160 
1161     return nullptr;
1162 }
1163 
QueryCallbackProxy(IPCObjectStub * callbackStub)1164 sptr<IPCObjectProxy> IPCProcessSkeleton::QueryCallbackProxy(IPCObjectStub *callbackStub)
1165 {
1166     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
1167     sptr<IPCObjectProxy> ret = nullptr;
1168     std::shared_lock<std::shared_mutex> lockGuard(callbackStubMutex_);
1169     for (auto it = noticeStub_.begin(); it != noticeStub_.end(); it++) {
1170         if (it->second.GetRefPtr() == callbackStub) {
1171             ret = it->first;
1172         }
1173     }
1174 
1175     return ret;
1176 }
1177 
GetDatabusName()1178 std::string IPCProcessSkeleton::GetDatabusName()
1179 {
1180     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, "");
1181     std::lock_guard<std::mutex> lockGuard(sessionNameMutex_);
1182 
1183     return sessionName_;
1184 }
1185 
CreateSoftbusServer(const std::string & name)1186 bool IPCProcessSkeleton::CreateSoftbusServer(const std::string &name)
1187 {
1188     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
1189     std::lock_guard<std::mutex> lockGuard(sessionNameMutex_);
1190 
1191     if (name.empty()) {
1192         ZLOGE(LOG_LABEL, "get empty session name");
1193         return false;
1194     }
1195 
1196     std::shared_ptr<ISessionService> manager = ISessionService::GetInstance();
1197     if (manager == nullptr) {
1198         ZLOGE(LOG_LABEL, "fail to get softbus manager");
1199         return false;
1200     }
1201 
1202     std::shared_ptr<DatabusSessionCallback> callback = std::make_shared<DatabusSessionCallback>();
1203     if (callback == nullptr) {
1204         ZLOGE(LOG_LABEL, "fail to create softbus callbacks");
1205         return false;
1206     }
1207     std::string pkgName = std::string(DBINDER_SERVER_PKG_NAME) + "_" + std::to_string(getpid());
1208     int ret = manager->CreateSessionServer(pkgName, name, callback);
1209     if (ret != 0) {
1210         ZLOGE(LOG_LABEL, "CreateSessionServer fail, sessionName:%{public}s maybe created already", name.c_str());
1211     }
1212 
1213     if (name != sessionName_) {
1214         SpawnThread(IPCWorkThread::PROCESS_ACTIVE, IRemoteObject::IF_PROT_DATABUS);
1215     }
1216     sessionName_ = name;
1217     return true;
1218 }
1219 
AttachRawData(uint32_t fd,std::shared_ptr<InvokerRawData> rawData)1220 bool IPCProcessSkeleton::AttachRawData(uint32_t fd, std::shared_ptr<InvokerRawData> rawData)
1221 {
1222     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
1223     std::unique_lock<std::shared_mutex> lockGuard(rawDataMutex_);
1224     /* always discard the old one if exists */
1225     rawData_.erase(fd);
1226     auto result = rawData_.insert(std::pair<uint32_t, std::shared_ptr<InvokerRawData>>(fd, rawData));
1227     return result.second;
1228 }
1229 
DetachRawData(uint32_t fd)1230 bool IPCProcessSkeleton::DetachRawData(uint32_t fd)
1231 {
1232     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
1233     std::unique_lock<std::shared_mutex> lockGuard(rawDataMutex_);
1234     return (rawData_.erase(fd) > 0);
1235 }
1236 
QueryRawData(uint32_t fd)1237 std::shared_ptr<InvokerRawData> IPCProcessSkeleton::QueryRawData(uint32_t fd)
1238 {
1239     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
1240     std::shared_lock<std::shared_mutex> lockGuard(rawDataMutex_);
1241     auto it = rawData_.find(fd);
1242     if (it != rawData_.end()) {
1243         return it->second;
1244     }
1245     return nullptr;
1246 }
1247 
IsSameRemoteObject(IRemoteObject * stub,int pid,int uid,uint32_t tokenId,const std::string & deviceId,const std::shared_ptr<CommAuthInfo> & auth)1248 bool IPCProcessSkeleton::IsSameRemoteObject(IRemoteObject *stub, int pid, int uid, uint32_t tokenId,
1249     const std::string &deviceId, const std::shared_ptr<CommAuthInfo> &auth)
1250 {
1251     if ((auth->GetStubObject() == stub) && (auth->GetRemotePid() == pid) && (auth->GetRemoteUid() == uid) &&
1252         (auth->GetRemoteTokenId() == tokenId) && (auth->GetRemoteDeviceId().compare(deviceId) == 0)) {
1253         return true;
1254     } else {
1255         return false;
1256     }
1257 }
1258 
IsSameRemoteObject(int pid,int uid,const std::string & deviceId,const std::shared_ptr<CommAuthInfo> & auth)1259 bool IPCProcessSkeleton::IsSameRemoteObject(int pid, int uid, const std::string &deviceId,
1260     const std::shared_ptr<CommAuthInfo> &auth)
1261 {
1262     if ((auth->GetRemotePid() == pid) && (auth->GetRemoteUid() == uid) &&
1263         (auth->GetRemoteDeviceId().compare(deviceId) == 0)) {
1264         return true;
1265     } else {
1266         return false;
1267     }
1268 }
1269 
AttachCommAuthInfo(IRemoteObject * stub,int pid,int uid,uint32_t tokenId,const std::string & deviceId)1270 bool IPCProcessSkeleton::AttachCommAuthInfo(IRemoteObject *stub, int pid, int uid, uint32_t tokenId,
1271     const std::string &deviceId)
1272 {
1273     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
1274     auto check = [&stub, &pid, &uid, &tokenId, &deviceId, this](const std::shared_ptr<CommAuthInfo> &auth) {
1275         return IsSameRemoteObject(stub, pid, uid, tokenId, deviceId, auth);
1276     };
1277     std::unique_lock<std::shared_mutex> lockGuard(commAuthMutex_);
1278     auto it = std::find_if(commAuth_.begin(), commAuth_.end(), check);
1279     if (it != commAuth_.end()) {
1280         return false;
1281     }
1282 
1283     std::shared_ptr<CommAuthInfo> authObject = std::make_shared<CommAuthInfo>(stub, pid, uid, tokenId, deviceId);
1284     if (authObject == nullptr) {
1285         ZLOGE(LOG_LABEL, "make_share CommonAuthInfo fail, device:%{public}s pid:%{public}d uid:%{public}d",
1286             IPCProcessSkeleton::ConvertToSecureString(deviceId).c_str(), pid, uid);
1287         return false;
1288     }
1289     commAuth_.push_front(authObject);
1290     return true;
1291 }
1292 
DetachCommAuthInfo(IRemoteObject * stub,int pid,int uid,uint32_t tokenId,const std::string & deviceId)1293 bool IPCProcessSkeleton::DetachCommAuthInfo(IRemoteObject *stub, int pid, int uid, uint32_t tokenId,
1294     const std::string &deviceId)
1295 {
1296     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
1297     auto check = [&stub, &pid, &uid, &tokenId, &deviceId, this](const std::shared_ptr<CommAuthInfo> &auth) {
1298         return IsSameRemoteObject(stub, pid, uid, tokenId, deviceId, auth);
1299     };
1300     std::unique_lock<std::shared_mutex> lockGuard(commAuthMutex_);
1301     auto it = std::find_if(commAuth_.begin(), commAuth_.end(), check);
1302     if (it != commAuth_.end()) {
1303         commAuth_.erase(it);
1304         return true;
1305     }
1306     return false;
1307 }
1308 
QueryCommAuthInfo(int pid,int uid,uint32_t & tokenId,const std::string & deviceId)1309 bool IPCProcessSkeleton::QueryCommAuthInfo(int pid, int uid, uint32_t &tokenId, const std::string &deviceId)
1310 {
1311     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
1312     auto check = [&pid, &uid, &deviceId, this](const std::shared_ptr<CommAuthInfo> &auth) {
1313         return IsSameRemoteObject(pid, uid, deviceId, auth);
1314     };
1315 
1316     std::shared_lock<std::shared_mutex> lockGuard(commAuthMutex_);
1317     auto it = std::find_if(commAuth_.begin(), commAuth_.end(), check);
1318     if (it != commAuth_.end()) {
1319         if ((*it) == nullptr) {
1320             tokenId = 0;
1321             return false;
1322         }
1323         tokenId = (*it)->GetRemoteTokenId();
1324         return true;
1325     }
1326     ZLOGE(LOG_LABEL, "NOT exist, deviceId:%{public}s pid:%{public}u uid:%{public}u",
1327         IPCProcessSkeleton::ConvertToSecureString(deviceId).c_str(), pid, uid);
1328     tokenId = 0;
1329     return false;
1330 }
1331 
DetachCommAuthInfoByStub(IRemoteObject * stub)1332 void IPCProcessSkeleton::DetachCommAuthInfoByStub(IRemoteObject *stub)
1333 {
1334     CHECK_INSTANCE_EXIT(exitFlag_);
1335     auto check = [&stub](const std::shared_ptr<CommAuthInfo> &auth) {
1336         return (auth != nullptr) && (auth->GetStubObject() == stub);
1337     };
1338     std::unique_lock<std::shared_mutex> lockGuard(commAuthMutex_);
1339     commAuth_.erase(std::remove_if(commAuth_.begin(), commAuth_.end(), check), commAuth_.end());
1340 }
1341 
AttachDBinderCallbackStub(sptr<IRemoteObject> proxy,sptr<DBinderCallbackStub> stub)1342 bool IPCProcessSkeleton::AttachDBinderCallbackStub(sptr<IRemoteObject> proxy, sptr<DBinderCallbackStub> stub)
1343 {
1344     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
1345     std::unique_lock<std::shared_mutex> lockGuard(dbinderSentMutex_);
1346     auto result = dbinderSentCallback_.insert(std::pair<sptr<IRemoteObject>, wptr<DBinderCallbackStub>>(proxy, stub));
1347     return result.second;
1348 }
1349 
DetachDBinderCallbackStubByProxy(sptr<IRemoteObject> proxy)1350 bool IPCProcessSkeleton::DetachDBinderCallbackStubByProxy(sptr<IRemoteObject> proxy)
1351 {
1352     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
1353     std::unique_lock<std::shared_mutex> lockGuard(dbinderSentMutex_);
1354 
1355     return (dbinderSentCallback_.erase(proxy) > 0);
1356 }
1357 
DetachDBinderCallbackStub(DBinderCallbackStub * stub)1358 void IPCProcessSkeleton::DetachDBinderCallbackStub(DBinderCallbackStub *stub)
1359 {
1360     CHECK_INSTANCE_EXIT(exitFlag_);
1361     std::unique_lock<std::shared_mutex> lockGuard(dbinderSentMutex_);
1362     for (auto it = dbinderSentCallback_.begin(); it != dbinderSentCallback_.end(); it++) {
1363         if (it->second == stub) {
1364             dbinderSentCallback_.erase(it);
1365             break;
1366         }
1367     }
1368 }
1369 
QueryDBinderCallbackStub(sptr<IRemoteObject> proxy)1370 sptr<DBinderCallbackStub> IPCProcessSkeleton::QueryDBinderCallbackStub(sptr<IRemoteObject> proxy)
1371 {
1372     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
1373     std::shared_lock<std::shared_mutex> lockGuard(dbinderSentMutex_);
1374     auto it = dbinderSentCallback_.find(proxy);
1375     if (it != dbinderSentCallback_.end()) {
1376         wptr<DBinderCallbackStub> cache = it->second;
1377         return cache.promote();
1378     }
1379     return nullptr;
1380 }
1381 
QueryDBinderCallbackProxy(sptr<IRemoteObject> stub)1382 sptr<IRemoteObject> IPCProcessSkeleton::QueryDBinderCallbackProxy(sptr<IRemoteObject> stub)
1383 {
1384     CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, nullptr);
1385     std::shared_lock<std::shared_mutex> lockGuard(dbinderSentMutex_);
1386     for (auto it = dbinderSentCallback_.begin(); it != dbinderSentCallback_.end(); it++) {
1387         if (it->second.GetRefPtr() == stub.GetRefPtr() && it->second.promote() != nullptr) {
1388             return it->first;
1389         }
1390     }
1391 
1392     return nullptr;
1393 }
1394 #endif
1395 #ifdef CONFIG_IPC_SINGLE
1396 } // namespace IPC_SINGLE
1397 #endif
1398 } // namespace OHOS
1399