• 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 <unistd.h>
19 #include <random>
20 #include <sys/epoll.h>
21 #include "string_ex.h"
22 #include "ipc_debug.h"
23 #include "ipc_types.h"
24 
25 #include "ipc_thread_skeleton.h"
26 #include "sys_binder.h"
27 #include "log_tags.h"
28 
29 #ifndef CONFIG_IPC_SINGLE
30 #include "databus_session_callback.h"
31 #include "softbus_bus_center.h"
32 #endif
33 
34 namespace OHOS {
35 #ifdef CONFIG_IPC_SINGLE
36 namespace IPC_SINGLE {
37 #endif
38 
39 #ifndef CONFIG_IPC_SINGLE
40 using namespace Communication;
41 #endif
42 using namespace OHOS::HiviewDFX;
43 
44 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC, "IPCProcessSkeleton" };
45 
46 std::mutex IPCProcessSkeleton::procMutex_;
47 IPCProcessSkeleton *IPCProcessSkeleton::instance_ = nullptr;
48 
GetCurrent()49 IPCProcessSkeleton *IPCProcessSkeleton::GetCurrent()
50 {
51     if (instance_ == nullptr) {
52         std::lock_guard<std::mutex> lockGuard(procMutex_);
53         if (instance_ == nullptr) {
54             IPCProcessSkeleton *temp = new (std::nothrow) IPCProcessSkeleton();
55             if (temp == nullptr) {
56                 ZLOGE(LOG_LABEL, "create IPCProcessSkeleton object failed");
57                 return nullptr;
58             }
59             if (temp->SetMaxWorkThread(DEFAULT_WORK_THREAD_NUM)) {
60                 temp->SpawnThread(IPCWorkThread::SPAWN_ACTIVE);
61             }
62             instance_ = temp;
63         }
64     }
65 
66     return instance_;
67 }
68 
IPCProcessSkeleton()69 IPCProcessSkeleton::IPCProcessSkeleton()
70 {
71 #ifndef CONFIG_IPC_SINGLE
72     std::random_device randDevice;
73     std::default_random_engine baseRand { randDevice() };
74     std::uniform_int_distribution<> range(1, DBINDER_HANDLE_BASE * DBINDER_HANDLE_RANG);
75     randNum_ = static_cast<uint64_t>(range(baseRand));
76 #endif
77 }
78 
~IPCProcessSkeleton()79 IPCProcessSkeleton::~IPCProcessSkeleton()
80 {
81     std::lock_guard<std::mutex> lockGuard(procMutex_);
82     delete threadPool_;
83     threadPool_ = nullptr;
84 
85     objects_.clear();
86     isContainStub_.clear();
87     rawData_.clear();
88 #ifndef CONFIG_IPC_SINGLE
89     listenThreadReady_.reset();
90     threadLockInfo_.clear();
91     seqNumberToThread_.clear();
92     stubObjects_.clear();
93     proxyToSession_.clear();
94     dbinderSessionObjects_.clear();
95     noticeStub_.clear();
96     transTimes_.clear();
97 
98     std::shared_ptr<ISessionService> manager = ISessionService::GetInstance();
99     if (manager != nullptr) {
100         std::string pkgName = DBINDER_SERVER_PKG_NAME + "_" + std::to_string(getpid());
101         (void)manager->RemoveSessionServer(pkgName, sessionName_);
102     }
103 #endif
104 }
105 
GetRegistryObject()106 sptr<IRemoteObject> IPCProcessSkeleton::GetRegistryObject()
107 {
108     if (registryObject_ == nullptr) {
109         registryObject_ = FindOrNewObject(REGISTRY_HANDLE);
110     }
111 
112     return registryObject_;
113 }
114 
MakeHandleDescriptor(int handle)115 std::u16string IPCProcessSkeleton::MakeHandleDescriptor(int handle)
116 {
117     std::string descriptor = "IPCObjectProxy" + std::to_string(handle);
118     return Str8ToStr16(descriptor);
119 }
120 
FindOrNewObject(int handle)121 sptr<IRemoteObject> IPCProcessSkeleton::FindOrNewObject(int handle)
122 {
123     sptr<IRemoteObject> result = nullptr;
124     std::u16string descriptor = MakeHandleDescriptor(handle);
125     if (descriptor.length() == 0) {
126         ZLOGE(LOG_LABEL, "make handle descriptor failed");
127         return nullptr;
128     }
129     {
130         std::lock_guard<std::recursive_mutex> lock(mutex_);
131 
132         IRemoteObject *remoteObject = QueryObjectInner(descriptor);
133         if (remoteObject == nullptr) {
134             if (handle == REGISTRY_HANDLE) {
135                 IRemoteInvoker *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DEFAULT);
136                 if (invoker == nullptr) {
137                     ZLOGE(LOG_LABEL, "failed to get invoker");
138                     return nullptr;
139                 }
140                 if (!invoker->PingService(REGISTRY_HANDLE)) {
141                     ZLOGE(LOG_LABEL, "Registry is not exist");
142                     return nullptr;
143                 }
144             }
145 
146             auto proxy = new (std::nothrow) IPCObjectProxy(handle, descriptor);
147             if (proxy == nullptr) {
148                 return nullptr;
149             }
150             remoteObject = reinterpret_cast<IRemoteObject *>(proxy);
151             if (!AttachObjectInner(remoteObject)) {
152                 delete proxy;
153                 return nullptr;
154             }
155         }
156         result = remoteObject;
157     }
158 
159     sptr<IPCObjectProxy> remoteProxy = reinterpret_cast<IPCObjectProxy *>(result.GetRefPtr());
160     remoteProxy->WaitForInit();
161 #ifndef CONFIG_IPC_SINGLE
162     if (remoteProxy->GetProto() == IRemoteObject::IF_PROT_ERROR) {
163         ZLOGE(LOG_LABEL, "init rpc proxy:%{public}d failed", handle);
164         return nullptr;
165     }
166 #endif
167     return result;
168 }
169 
SetMaxWorkThread(int maxThreadNum)170 bool IPCProcessSkeleton::SetMaxWorkThread(int maxThreadNum)
171 {
172     if (maxThreadNum <= 0) {
173         ZLOGE(LOG_LABEL, "Set Invalid thread Number %d", maxThreadNum);
174         return false;
175     }
176 
177     if (threadPool_ == nullptr) {
178         threadPool_ = new (std::nothrow) IPCWorkThreadPool(maxThreadNum);
179         if (threadPool_ == nullptr) {
180             ZLOGE(LOG_LABEL, "create IPCWorkThreadPool object failed");
181             return false;
182         }
183     }
184     threadPool_->UpdateMaxThreadNum(maxThreadNum);
185     IRemoteInvoker *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DEFAULT);
186     if (invoker != nullptr) {
187         return invoker->SetMaxWorkThread(maxThreadNum);
188     }
189 
190     return false;
191 }
192 
SetRegistryObject(sptr<IRemoteObject> & object)193 bool IPCProcessSkeleton::SetRegistryObject(sptr<IRemoteObject> &object)
194 {
195     if (object == nullptr) {
196         ZLOGE(LOG_LABEL, "object is null");
197         return false;
198     }
199 
200     IRemoteInvoker *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DEFAULT);
201     if (invoker == nullptr) {
202         ZLOGE(LOG_LABEL, "fail to get invoker");
203         return false;
204     }
205 
206     bool ret = invoker->SetRegistryObject(object);
207     if (ret) {
208         registryObject_ = object;
209     }
210     ZLOGI(LOG_LABEL, "%{public}s set registry result is %{public}d", __func__, ret);
211     return ret;
212 }
213 
SpawnThread(int policy,int proto)214 bool IPCProcessSkeleton::SpawnThread(int policy, int proto)
215 {
216     if (threadPool_ != nullptr) {
217         return threadPool_->SpawnThread(policy, proto);
218     }
219 
220     /* can NOT reach here */
221     return false;
222 }
223 
OnThreadTerminated(const std::string & threadName)224 bool IPCProcessSkeleton::OnThreadTerminated(const std::string &threadName)
225 {
226     if (threadPool_ != nullptr) {
227         return threadPool_->RemoveThread(threadName);
228     }
229 
230     return true;
231 }
232 
IsContainsObject(IRemoteObject * object)233 bool IPCProcessSkeleton::IsContainsObject(IRemoteObject *object)
234 {
235     /* don't care mutex result even object is deleted */
236     std::lock_guard<std::recursive_mutex> lock(mutex_);
237     auto it = isContainStub_.find(object);
238     if (it != isContainStub_.end()) {
239         return it->second;
240     }
241 
242     return false;
243 }
244 
DetachObject(IRemoteObject * object)245 bool IPCProcessSkeleton::DetachObject(IRemoteObject *object)
246 {
247     std::lock_guard<std::recursive_mutex> lock(mutex_);
248     return DetachObjectInner(object);
249 }
250 
DetachObjectInner(IRemoteObject * object)251 bool IPCProcessSkeleton::DetachObjectInner(IRemoteObject *object)
252 {
253     int strongRef = object->GetSptrRefCount();
254     if (strongRef > 0) {
255         ZLOGI(LOG_LABEL, "proxy is still strong referenced:%{public}d", strongRef);
256         return false;
257     }
258 
259     // If it fails, clear it in the destructor.
260     (void)isContainStub_.erase(object);
261     std::u16string descriptor = object->GetObjectDescriptor();
262     if (descriptor.empty()) {
263         return false;
264     }
265 
266     return (objects_.erase(descriptor) > 0);
267 }
268 
AttachObject(IRemoteObject * object)269 bool IPCProcessSkeleton::AttachObject(IRemoteObject *object)
270 {
271     std::lock_guard<std::recursive_mutex> lock(mutex_);
272     return AttachObjectInner(object);
273 }
274 
AttachObjectInner(IRemoteObject * object)275 bool IPCProcessSkeleton::AttachObjectInner(IRemoteObject *object)
276 {
277     // If it fails, it means it was added before.
278     (void)isContainStub_.insert(std::pair<IRemoteObject *, bool>(object, true));
279     std::u16string descriptor = object->GetObjectDescriptor();
280     if (descriptor.empty()) {
281         return false;
282     }
283 
284     auto result = objects_.insert(std::pair<std::u16string, wptr<IRemoteObject>>(descriptor, object));
285     return result.second;
286 }
287 
QueryObject(const std::u16string & descriptor)288 IRemoteObject *IPCProcessSkeleton::QueryObject(const std::u16string &descriptor)
289 {
290     if (descriptor.empty()) {
291         return nullptr;
292     }
293 
294     std::lock_guard<std::recursive_mutex> lock(mutex_);
295     return QueryObjectInner(descriptor);
296 }
297 
QueryObjectInner(const std::u16string & descriptor)298 IRemoteObject *IPCProcessSkeleton::QueryObjectInner(const std::u16string &descriptor)
299 {
300     auto it = objects_.find(descriptor);
301     if (it != objects_.end()) {
302         return it->second.GetRefPtr();
303     }
304     return nullptr;
305 }
306 
307 
308 #ifndef CONFIG_IPC_SINGLE
GetSAMgrObject()309 sptr<IRemoteObject> IPCProcessSkeleton::GetSAMgrObject()
310 {
311     IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
312     if (invoker == nullptr) {
313         return nullptr;
314     }
315     return invoker->GetSAMgrObject();
316 }
317 
318 /*
319  * databus return int64_t channel id, but high 32bit only use 1bit channel type, we convert to int
320  * convert to 24bit channelID and 7bit channel type
321  * |---1bit---|------7bit----| ------------------------24bit------|
322  * | reserved | channel type |    true channel id                 |
323  * don't care signed bit when convert,for we reserved high 1bit
324  */
ConvertChannelID2Int(int64_t databusChannelId)325 uint32_t IPCProcessSkeleton::ConvertChannelID2Int(int64_t databusChannelId)
326 {
327     if (databusChannelId < 0) {
328         return 0;
329     }
330     uint64_t databusChannel = static_cast<uint64_t>(databusChannelId);
331     uint32_t channelType = static_cast<uint32_t>((databusChannel >> 8) & 0X00000000FF000000ULL);
332     uint32_t channelID = static_cast<uint32_t>(databusChannel & 0X0000000000FFFFFFULL);
333     return (channelType | channelID);
334 }
335 
GetLocalDeviceID()336 std::string IPCProcessSkeleton::GetLocalDeviceID()
337 {
338     std::lock_guard<std::mutex> lockGuard(databusProcMutex_);
339 
340     std::string pkgName = DBINDER_SERVER_PKG_NAME + "_" + std::to_string(getpid());
341     NodeBasicInfo nodeBasicInfo;
342     if (GetLocalNodeDeviceInfo(pkgName.c_str(), &nodeBasicInfo) != 0) {
343         ZLOGE(LOG_LABEL, "Get local node device info failed");
344         return "";
345     }
346     std::string networkId(nodeBasicInfo.networkId);
347     return networkId;
348 }
349 
IsHandleMadeByUser(uint32_t handle)350 bool IPCProcessSkeleton::IsHandleMadeByUser(uint32_t handle)
351 {
352     if (handle > DBINDER_HANDLE_BASE && handle < (DBINDER_HANDLE_BASE + DBINDER_HANDLE_BASE)) {
353         ZLOGE(LOG_LABEL, "handle = %{public}u is make by user, not kernel", handle);
354         return true;
355     }
356     return false;
357 }
358 
GetDBinderIdleHandle(uint64_t stubIndex)359 uint32_t IPCProcessSkeleton::GetDBinderIdleHandle(uint64_t stubIndex)
360 {
361     std::unique_lock<std::shared_mutex> lockGuard(handleToIndexMutex_);
362 
363     if (dBinderHandle_ < DBINDER_HANDLE_BASE || dBinderHandle_ > DBINDER_HANDLE_BASE + DBINDER_HANDLE_BASE) {
364         dBinderHandle_ = DBINDER_HANDLE_BASE;
365     }
366     uint32_t tempHandle = dBinderHandle_;
367     uint32_t count = DBINDER_HANDLE_BASE;
368     bool insertResult = false;
369     do {
370         count--;
371         tempHandle++;
372         if (tempHandle > DBINDER_HANDLE_BASE + DBINDER_HANDLE_BASE) {
373             tempHandle = DBINDER_HANDLE_BASE;
374         }
375         insertResult = handleToStubIndex_.insert(std::pair<uint32_t, uint64_t>(tempHandle, stubIndex)).second;
376     } while (insertResult == false && count > 0);
377 
378     if (count == 0 && insertResult == false) {
379         return 0;
380     }
381     dBinderHandle_ = tempHandle;
382     return dBinderHandle_;
383 }
384 
DetachHandleToIndex(uint32_t handle)385 bool IPCProcessSkeleton::DetachHandleToIndex(uint32_t handle)
386 {
387     std::unique_lock<std::shared_mutex> lockGuard(handleToIndexMutex_);
388 
389     return (handleToStubIndex_.erase(handle) > 0);
390 }
391 
AttachHandleToIndex(uint32_t handle,uint64_t stubIndex)392 bool IPCProcessSkeleton::AttachHandleToIndex(uint32_t handle, uint64_t stubIndex)
393 {
394     std::unique_lock<std::shared_mutex> lockGuard(handleToIndexMutex_);
395     auto result = handleToStubIndex_.insert(std::pair<uint32_t, uint64_t>(handle, stubIndex));
396     return result.second;
397 }
398 
QueryHandleToIndex(uint32_t handle)399 uint64_t IPCProcessSkeleton::QueryHandleToIndex(uint32_t handle)
400 {
401     std::shared_lock<std::shared_mutex> lockGuard(handleToIndexMutex_);
402 
403     auto it = handleToStubIndex_.find(handle);
404     if (it != handleToStubIndex_.end()) {
405         return it->second;
406     }
407 
408     return 0;
409 }
410 
QueryHandleToIndex(std::list<uint32_t> & handleList,uint32_t & handle)411 uint64_t IPCProcessSkeleton::QueryHandleToIndex(std::list<uint32_t> &handleList, uint32_t &handle)
412 {
413     std::shared_lock<std::shared_mutex> lockGuard(handleToIndexMutex_);
414     for (auto it = handleList.begin(); it != handleList.end(); it++) {
415         auto mapIndex = handleToStubIndex_.find(*it);
416         if (mapIndex != handleToStubIndex_.end()) {
417             handle = mapIndex->first;
418             return mapIndex->second;
419         }
420     }
421     return 0;
422 }
423 
424 
ProxyDetachDBinderSession(uint32_t handle)425 bool IPCProcessSkeleton::ProxyDetachDBinderSession(uint32_t handle)
426 {
427     std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
428 
429     return (proxyToSession_.erase(handle) > 0);
430 }
431 
ProxyAttachDBinderSession(uint32_t handle,std::shared_ptr<DBinderSessionObject> object)432 bool IPCProcessSkeleton::ProxyAttachDBinderSession(uint32_t handle, std::shared_ptr<DBinderSessionObject> object)
433 {
434     std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
435     auto result = proxyToSession_.insert(std::pair<uint32_t, std::shared_ptr<DBinderSessionObject>>(handle, object));
436     return result.second;
437 }
438 
ProxyQueryDBinderSession(uint32_t handle)439 std::shared_ptr<DBinderSessionObject> IPCProcessSkeleton::ProxyQueryDBinderSession(uint32_t handle)
440 {
441     std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
442 
443     auto it = proxyToSession_.find(handle);
444     if (it != proxyToSession_.end()) {
445         return it->second;
446     }
447 
448     return nullptr;
449 }
450 
QueryProxyBySessionHandle(uint32_t handle,std::vector<uint32_t> & proxyHandle)451 bool IPCProcessSkeleton::QueryProxyBySessionHandle(uint32_t handle, std::vector<uint32_t> &proxyHandle)
452 {
453     std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
454 
455     for (auto it = proxyToSession_.begin(); it != proxyToSession_.end(); it++) {
456         std::shared_ptr<Session> session = it->second->GetBusSession();
457         if (session == nullptr) {
458             ZLOGE(LOG_LABEL, "session is null, handle = %{public}u", handle);
459             return false;
460         }
461         uint32_t sessionHandle = IPCProcessSkeleton::ConvertChannelID2Int(session->GetChannelId());
462         if (sessionHandle == handle) {
463             proxyHandle.push_back(it->first);
464         }
465     }
466     return true;
467 }
468 
QueryHandleByDatabusSession(const std::string & name,const std::string & deviceId,uint64_t index)469 uint32_t IPCProcessSkeleton::QueryHandleByDatabusSession(const std::string &name, const std::string &deviceId,
470     uint64_t index)
471 {
472     std::list<uint32_t> handleList;
473     bool found = false;
474     {
475         std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
476 
477         for (auto it = proxyToSession_.begin(); it != proxyToSession_.end(); it++) {
478             if ((it->second->GetDeviceId().compare(deviceId) == 0) &&
479                 (it->second->GetServiceName().compare(name) == 0)) {
480                 handleList.push_front(it->first);
481                 found = true; // found one at the least
482             }
483         }
484     }
485     uint32_t handleFound = 0;
486     if (found == true && QueryHandleToIndex(handleList, handleFound) == index) {
487         return handleFound;
488     }
489 
490     return 0;
491 }
492 
QuerySessionByInfo(const std::string & name,const std::string & deviceId)493 std::shared_ptr<DBinderSessionObject> IPCProcessSkeleton::QuerySessionByInfo(const std::string &name,
494     const std::string &deviceId)
495 {
496     std::lock_guard<std::recursive_mutex> lockGuard(proxyToSessionMutex_);
497 
498     for (auto it = proxyToSession_.begin(); it != proxyToSession_.end(); it++) {
499         if ((it->second->GetDeviceId().compare(deviceId) == 0) && (it->second->GetServiceName().compare(name) == 0)) {
500             return it->second;
501         }
502     }
503 
504     return nullptr;
505 }
506 
StubDetachDBinderSession(uint32_t handle)507 bool IPCProcessSkeleton::StubDetachDBinderSession(uint32_t handle)
508 {
509     std::unique_lock<std::shared_mutex> lockGuard(databusSessionMutex_);
510 
511     return (dbinderSessionObjects_.erase(handle) > 0);
512 }
513 
StubAttachDBinderSession(uint32_t handle,std::shared_ptr<DBinderSessionObject> object)514 bool IPCProcessSkeleton::StubAttachDBinderSession(uint32_t handle, std::shared_ptr<DBinderSessionObject> object)
515 {
516     std::unique_lock<std::shared_mutex> lockGuard(databusSessionMutex_);
517     auto result =
518         dbinderSessionObjects_.insert(std::pair<uint32_t, std::shared_ptr<DBinderSessionObject>>(handle, object));
519 
520     return result.second;
521 }
522 
StubQueryDBinderSession(uint32_t handle)523 std::shared_ptr<DBinderSessionObject> IPCProcessSkeleton::StubQueryDBinderSession(uint32_t handle)
524 {
525     std::shared_lock<std::shared_mutex> lockGuard(databusSessionMutex_);
526 
527     auto it = dbinderSessionObjects_.find(handle);
528     if (it != dbinderSessionObjects_.end()) {
529         return it->second;
530     }
531 
532     return nullptr;
533 }
534 
DetachThreadLockInfo(const std::thread::id & threadId)535 bool IPCProcessSkeleton::DetachThreadLockInfo(const std::thread::id &threadId)
536 {
537     std::unique_lock<std::shared_mutex> lockGuard(threadLockMutex_);
538 
539     return (threadLockInfo_.erase(threadId) > 0);
540 }
541 
AttachThreadLockInfo(std::shared_ptr<SocketThreadLockInfo> object,const std::thread::id & threadId)542 bool IPCProcessSkeleton::AttachThreadLockInfo(std::shared_ptr<SocketThreadLockInfo> object,
543     const std::thread::id &threadId)
544 {
545     std::unique_lock<std::shared_mutex> lockGuard(threadLockMutex_);
546     auto result =
547         threadLockInfo_.insert(std::pair<std::thread::id, std::shared_ptr<SocketThreadLockInfo>>(threadId, object));
548     return result.second;
549 }
550 
QueryThreadLockInfo(const std::thread::id & threadId)551 std::shared_ptr<SocketThreadLockInfo> IPCProcessSkeleton::QueryThreadLockInfo(const std::thread::id &threadId)
552 {
553     std::shared_lock<std::shared_mutex> lockGuard(threadLockMutex_);
554 
555     auto it = threadLockInfo_.find(threadId);
556     if (it != threadLockInfo_.end()) {
557         return it->second;
558     }
559 
560     return nullptr;
561 }
562 
563 
AddDataThreadToIdle(const std::thread::id & threadId)564 bool IPCProcessSkeleton::AddDataThreadToIdle(const std::thread::id &threadId)
565 {
566     std::lock_guard<std::mutex> lockGuard(idleDataMutex_);
567 
568     idleDataThreads_.push_front(threadId);
569     return true;
570 }
571 
DeleteDataThreadFromIdle(const std::thread::id & threadId)572 bool IPCProcessSkeleton::DeleteDataThreadFromIdle(const std::thread::id &threadId)
573 {
574     std::lock_guard<std::mutex> lockGuard(idleDataMutex_);
575     for (auto it = idleDataThreads_.begin(); it != idleDataThreads_.end(); it++) {
576         if ((*it) == threadId) {
577             it = idleDataThreads_.erase(it);
578             return true;
579         }
580     }
581 
582     /* not in idle state, also return true */
583     return true;
584 }
585 
GetIdleDataThread()586 std::thread::id IPCProcessSkeleton::GetIdleDataThread()
587 {
588     std::lock_guard<std::mutex> lockGuard(idleDataMutex_);
589 
590     if (idleDataThreads_.size() == 0) {
591         return std::thread::id();
592     }
593 
594     std::thread::id threadId = idleDataThreads_.back();
595     return threadId;
596 }
597 
GetSocketIdleThreadNum() const598 int IPCProcessSkeleton::GetSocketIdleThreadNum() const
599 {
600     if (threadPool_ != nullptr) {
601         return threadPool_->GetSocketIdleThreadNum();
602     }
603 
604     return 0;
605 }
GetSocketTotalThreadNum() const606 int IPCProcessSkeleton::GetSocketTotalThreadNum() const
607 {
608     if (threadPool_ != nullptr) {
609         return threadPool_->GetSocketTotalThreadNum();
610     }
611 
612     return 0;
613 }
614 
AddDataInfoToThread(const std::thread::id & threadId,std::shared_ptr<ThreadProcessInfo> processInfo)615 void IPCProcessSkeleton::AddDataInfoToThread(const std::thread::id &threadId,
616     std::shared_ptr<ThreadProcessInfo> processInfo)
617 {
618     std::lock_guard<std::mutex> lockGuard(dataQueueMutex_);
619 
620     (dataInfoQueue_[threadId]).push_back(processInfo);
621 }
622 
PopDataInfoFromThread(const std::thread::id & threadId)623 std::shared_ptr<ThreadProcessInfo> IPCProcessSkeleton::PopDataInfoFromThread(const std::thread::id &threadId)
624 {
625     std::lock_guard<std::mutex> lockGuard(dataQueueMutex_);
626 
627     if ((dataInfoQueue_[threadId]).size() == 0) {
628         return nullptr;
629     }
630 
631     std::shared_ptr<ThreadProcessInfo> processInfo = (dataInfoQueue_[threadId]).front();
632 
633     (dataInfoQueue_[threadId]).erase((dataInfoQueue_[threadId]).begin());
634     return processInfo;
635 }
636 
WakeUpDataThread(const std::thread::id & threadID)637 void IPCProcessSkeleton::WakeUpDataThread(const std::thread::id &threadID)
638 {
639     if (threadID != std::thread::id()) {
640         std::shared_ptr<SocketThreadLockInfo> threadLockInfo = QueryThreadLockInfo(threadID);
641         if (threadLockInfo != nullptr) {
642             /* Wake up this IO thread to process socket stream
643              * Wake up the client processing thread
644              */
645             std::unique_lock<std::mutex> lock_unique(threadLockInfo->mutex);
646             threadLockInfo->ready = true;
647             threadLockInfo->condition.notify_one();
648         }
649     }
650 }
651 
AddDataThreadInWait(const std::thread::id & threadId)652 void IPCProcessSkeleton::AddDataThreadInWait(const std::thread::id &threadId)
653 {
654     std::shared_ptr<SocketThreadLockInfo> threadLockInfo;
655 
656     threadLockInfo = QueryThreadLockInfo(threadId);
657     if (threadLockInfo == nullptr) {
658         threadLockInfo = std::make_shared<struct SocketThreadLockInfo>();
659         if (!AttachThreadLockInfo(threadLockInfo, threadId)) {
660             ZLOGE(LOG_LABEL, "thread has added lock info");
661             return;
662         }
663     }
664 
665     AddDataThreadToIdle(threadId);
666     std::unique_lock<std::mutex> lock_unique(threadLockInfo->mutex);
667     threadLockInfo->condition.wait(lock_unique, [&threadLockInfo] { return threadLockInfo->ready; });
668     threadLockInfo->ready = false;
669     /* corresponding thread will be waked up */
670     DeleteDataThreadFromIdle(threadId);
671 }
672 
GetSeqNumber()673 uint64_t IPCProcessSkeleton::GetSeqNumber()
674 {
675     std::lock_guard<std::mutex> lockGuard(seqNumberMutex_);
676     seqNumber_++; // can be overflow, and seqNumber do not use 0
677     if (seqNumber_ == 0) {
678         seqNumber_++;
679     }
680     return seqNumber_;
681 }
682 
QueryThreadBySeqNumber(uint64_t seqNumber)683 std::shared_ptr<ThreadMessageInfo> IPCProcessSkeleton::QueryThreadBySeqNumber(uint64_t seqNumber)
684 {
685     std::lock_guard<std::mutex> lockGuard(findThreadMutex_);
686 
687     auto it = seqNumberToThread_.find(seqNumber);
688     if (it != seqNumberToThread_.end()) {
689         return it->second;
690     }
691 
692     return nullptr;
693 }
694 
EraseThreadBySeqNumber(uint64_t seqNumber)695 void IPCProcessSkeleton::EraseThreadBySeqNumber(uint64_t seqNumber)
696 {
697     std::lock_guard<std::mutex> lockGuard(findThreadMutex_);
698     seqNumberToThread_.erase(seqNumber);
699 }
700 
701 
AddThreadBySeqNumber(uint64_t seqNumber,std::shared_ptr<ThreadMessageInfo> messageInfo)702 bool IPCProcessSkeleton::AddThreadBySeqNumber(uint64_t seqNumber, std::shared_ptr<ThreadMessageInfo> messageInfo)
703 {
704     std::lock_guard<std::mutex> lockGuard(findThreadMutex_);
705 
706     auto result =
707         seqNumberToThread_.insert(std::pair<uint64_t, std::shared_ptr<ThreadMessageInfo>>(seqNumber, messageInfo));
708 
709     return result.second;
710 }
711 
WakeUpThreadBySeqNumber(uint64_t seqNumber,uint32_t handle)712 void IPCProcessSkeleton::WakeUpThreadBySeqNumber(uint64_t seqNumber, uint32_t handle)
713 {
714     std::shared_ptr<ThreadMessageInfo> messageInfo;
715 
716     messageInfo = QueryThreadBySeqNumber(seqNumber);
717     if (messageInfo == nullptr) {
718         ZLOGE(LOG_LABEL, "error! messageInfo is nullptr");
719         return;
720     }
721 
722     if (handle != messageInfo->socketId) {
723         ZLOGE(LOG_LABEL, "error! handle is not equal messageInfo, handle = %{public}d, messageFd = %{public}u", handle,
724             messageInfo->socketId);
725         return;
726     }
727 
728     if (messageInfo->threadId != std::thread::id()) {
729         std::shared_ptr<SocketThreadLockInfo> threadLockInfo = QueryThreadLockInfo(messageInfo->threadId);
730         if (threadLockInfo != nullptr) {
731             /* wake up this IO thread to process socket stream
732              * Wake up the client processing thread
733              */
734             std::unique_lock<std::mutex> lock_unique(threadLockInfo->mutex);
735             threadLockInfo->ready = true;
736             threadLockInfo->condition.notify_one();
737         }
738     }
739 }
740 
AddSendThreadInWait(uint64_t seqNumber,std::shared_ptr<ThreadMessageInfo> messageInfo,int userWaitTime)741 bool IPCProcessSkeleton::AddSendThreadInWait(uint64_t seqNumber, std::shared_ptr<ThreadMessageInfo> messageInfo,
742     int userWaitTime)
743 {
744     std::shared_ptr<SocketThreadLockInfo> threadLockInfo;
745 
746     if (!AddThreadBySeqNumber(seqNumber, messageInfo)) {
747         ZLOGE(LOG_LABEL, "add seqNumber = %" PRIu64 " failed", seqNumber);
748         return false;
749     }
750 
751     threadLockInfo = QueryThreadLockInfo(messageInfo->threadId);
752     if (threadLockInfo == nullptr) {
753         threadLockInfo = std::make_shared<struct SocketThreadLockInfo>();
754         bool ret = AttachThreadLockInfo(threadLockInfo, messageInfo->threadId);
755         if (!ret) {
756             ZLOGE(LOG_LABEL, "AttachThreadLockInfo fail");
757             return false;
758         }
759     }
760 
761     std::unique_lock<std::mutex> lock_unique(threadLockInfo->mutex);
762     if (threadLockInfo->condition.wait_for(lock_unique, std::chrono::seconds(userWaitTime),
763         [&threadLockInfo] { return threadLockInfo->ready; }) == false) {
764         threadLockInfo->ready = false;
765         ZLOGE(LOG_LABEL, "socket thread timeout, seqNumber = %{public}" PRIu64
766             ", ipc wait time = %{public}d", seqNumber, userWaitTime);
767         return false;
768     }
769     threadLockInfo->ready = false;
770     return true;
771 }
772 
QueryStubByIndex(uint64_t stubIndex)773 IRemoteObject *IPCProcessSkeleton::QueryStubByIndex(uint64_t stubIndex)
774 {
775     std::shared_lock<std::shared_mutex> lockGuard(stubObjectsMutex_);
776 
777     auto it = stubObjects_.find(stubIndex);
778     if (it != stubObjects_.end()) {
779         return it->second;
780     }
781 
782     return nullptr;
783 }
784 
AddStubByIndex(IRemoteObject * stubObject)785 uint64_t IPCProcessSkeleton::AddStubByIndex(IRemoteObject *stubObject)
786 {
787     std::unique_lock<std::shared_mutex> lockGuard(stubObjectsMutex_);
788 
789     /* if stub has its index, return it directly */
790     for (auto it = stubObjects_.begin(); it != stubObjects_.end(); it++) {
791         if (it->second == stubObject) {
792             return it->first;
793         }
794     }
795     uint64_t stubIndex = randNum_++;
796     auto result = stubObjects_.insert(std::pair<uint64_t, IRemoteObject *>(stubIndex, stubObject));
797     if (result.second) {
798         return stubIndex;
799     } else {
800         return 0;
801     }
802 }
803 
EraseStubIndex(IRemoteObject * stubObject)804 uint64_t IPCProcessSkeleton::EraseStubIndex(IRemoteObject *stubObject)
805 {
806     std::unique_lock<std::shared_mutex> lockGuard(stubObjectsMutex_);
807 
808     for (auto it = stubObjects_.begin(); it != stubObjects_.end(); it++) {
809         if (it->second == stubObject) {
810             uint64_t stubIndex = it->first;
811             stubObjects_.erase(it);
812             return stubIndex;
813         }
814     }
815     return 0;
816 }
817 
DetachAppInfoToStubIndex(uint32_t pid,uint32_t uid,const std::string & deviceId,uint64_t stubIndex)818 bool IPCProcessSkeleton::DetachAppInfoToStubIndex(uint32_t pid, uint32_t uid, const std::string &deviceId,
819     uint64_t stubIndex)
820 {
821     std::string appInfo = deviceId + std::to_string(pid) + std::to_string(uid);
822 
823     std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_);
824 
825     auto it = appInfoToStubIndex_.find(appInfo);
826     if (it != appInfoToStubIndex_.end()) {
827         bool result = it->second.erase(stubIndex) > 0;
828         if (it->second.size() == 0) {
829             appInfoToStubIndex_.erase(it);
830         }
831         return result;
832     }
833 
834     return false;
835 }
836 
DetachAppInfoToStubIndex(uint64_t stubIndex)837 void IPCProcessSkeleton::DetachAppInfoToStubIndex(uint64_t stubIndex)
838 {
839     std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_);
840 
841     for (auto it = appInfoToStubIndex_.begin(); it != appInfoToStubIndex_.end();) {
842         (void)it->second.erase(stubIndex);
843         if (it->second.size() == 0) {
844             it = appInfoToStubIndex_.erase(it);
845         } else {
846             it++;
847         }
848     }
849 }
850 
AttachAppInfoToStubIndex(uint32_t pid,uint32_t uid,const std::string & deviceId,uint64_t stubIndex)851 bool IPCProcessSkeleton::AttachAppInfoToStubIndex(uint32_t pid, uint32_t uid, const std::string &deviceId,
852     uint64_t stubIndex)
853 {
854     std::string appInfo = deviceId + std::to_string(pid) + std::to_string(uid);
855 
856     std::unique_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_);
857 
858     auto it = appInfoToStubIndex_.find(appInfo);
859     if (it != appInfoToStubIndex_.end()) {
860         auto result = it->second.insert(std::pair<uint64_t, bool>(stubIndex, true));
861         return result.second;
862     }
863 
864     std::map<uint64_t, bool> mapItem { { stubIndex, true } };
865     auto result = appInfoToStubIndex_.insert(std::pair<std::string, std::map<uint64_t, bool>>(appInfo, mapItem));
866     return result.second;
867 }
868 
QueryAppInfoToStubIndex(uint32_t pid,uint32_t uid,const std::string & deviceId,uint64_t stubIndex)869 bool IPCProcessSkeleton::QueryAppInfoToStubIndex(uint32_t pid, uint32_t uid, const std::string &deviceId,
870     uint64_t stubIndex)
871 {
872     std::string appInfo = deviceId + std::to_string(pid) + std::to_string(uid);
873 
874     std::shared_lock<std::shared_mutex> lockGuard(appInfoToIndexMutex_);
875 
876     auto it = appInfoToStubIndex_.find(appInfo);
877     if (it != appInfoToStubIndex_.end()) {
878         auto it2 = it->second.find(stubIndex);
879         if (it2 != it->second.end()) {
880             return true;
881         }
882     }
883 
884     return false;
885 }
886 
GetListenThreadLockInfo()887 std::shared_ptr<SocketThreadLockInfo> IPCProcessSkeleton::GetListenThreadLockInfo()
888 {
889     return listenThreadReady_;
890 }
891 
AttachCallbackStub(IPCObjectProxy * ipcProxy,sptr<IPCObjectStub> callbackStub)892 bool IPCProcessSkeleton::AttachCallbackStub(IPCObjectProxy *ipcProxy, sptr<IPCObjectStub> callbackStub)
893 {
894     std::unique_lock<std::shared_mutex> lockGuard(callbackStubMutex_);
895     auto result = noticeStub_.insert(std::pair<IPCObjectProxy *, sptr<IPCObjectStub>>(ipcProxy, callbackStub));
896     return result.second;
897 }
898 
DetachCallbackStub(IPCObjectStub * callbackStub)899 bool IPCProcessSkeleton::DetachCallbackStub(IPCObjectStub *callbackStub)
900 {
901     std::unique_lock<std::shared_mutex> lockGuard(callbackStubMutex_);
902     for (auto it = noticeStub_.begin(); it != noticeStub_.end(); it++) {
903         if (it->second.GetRefPtr() == callbackStub) {
904             noticeStub_.erase(it);
905             return true;
906         }
907     }
908     return false;
909 }
910 
DetachCallbackStubByProxy(IPCObjectProxy * ipcProxy)911 bool IPCProcessSkeleton::DetachCallbackStubByProxy(IPCObjectProxy *ipcProxy)
912 {
913     std::unique_lock<std::shared_mutex> lockGuard(callbackStubMutex_);
914 
915     return (noticeStub_.erase(ipcProxy) > 0);
916 }
917 
QueryCallbackStub(IPCObjectProxy * ipcProxy)918 sptr<IPCObjectStub> IPCProcessSkeleton::QueryCallbackStub(IPCObjectProxy *ipcProxy)
919 {
920     std::shared_lock<std::shared_mutex> lockGuard(callbackStubMutex_);
921     auto it = noticeStub_.find(ipcProxy);
922     if (it != noticeStub_.end()) {
923         return it->second;
924     }
925 
926     return nullptr;
927 }
928 
QueryCallbackProxy(IPCObjectStub * callbackStub)929 IPCObjectProxy *IPCProcessSkeleton::QueryCallbackProxy(IPCObjectStub *callbackStub)
930 {
931     std::shared_lock<std::shared_mutex> lockGuard(callbackStubMutex_);
932     for (auto it = noticeStub_.begin(); it != noticeStub_.end(); it++) {
933         if (it->second.GetRefPtr() == callbackStub) {
934             return it->first;
935         }
936     }
937 
938     return nullptr;
939 }
940 
GetDatabusName()941 std::string IPCProcessSkeleton::GetDatabusName()
942 {
943     std::lock_guard<std::mutex> lockGuard(sessionNameMutex_);
944 
945     return sessionName_;
946 }
947 
CreateSoftbusServer(const std::string & name)948 bool IPCProcessSkeleton::CreateSoftbusServer(const std::string &name)
949 {
950     std::lock_guard<std::mutex> lockGuard(sessionNameMutex_);
951 
952     if (name.empty()) {
953         ZLOGE(LOG_LABEL, "get wrong session name = %s", name.c_str());
954         return false;
955     }
956 
957     std::shared_ptr<ISessionService> manager = ISessionService::GetInstance();
958     if (manager == nullptr) {
959         ZLOGE(LOG_LABEL, "fail to get softbus manager");
960         return false;
961     }
962 
963     std::shared_ptr<DatabusSessionCallback> callback = std::make_shared<DatabusSessionCallback>();
964     if (callback == nullptr) {
965         ZLOGE(LOG_LABEL, "fail to create softbus callbacks");
966         return false;
967     }
968     std::string pkgName = DBINDER_SERVER_PKG_NAME + "_" + std::to_string(getpid());
969     int ret = manager->CreateSessionServer(pkgName, name, callback);
970     if (ret != 0) {
971         ZLOGE(LOG_LABEL, "fail to create softbus server");
972         return false;
973     }
974 
975     sessionName_ = name;
976     SpawnThread(IPCWorkThread::PROCESS_ACTIVE, IRemoteObject::IF_PROT_DATABUS);
977 
978     return true;
979 }
980 
AttachRawData(uint32_t fd,std::shared_ptr<InvokerRawData> rawData)981 bool IPCProcessSkeleton::AttachRawData(uint32_t fd, std::shared_ptr<InvokerRawData> rawData)
982 {
983     std::unique_lock<std::shared_mutex> lockGuard(rawDataMutex_);
984     /* always discard the old one if exists */
985     rawData_.erase(fd);
986     auto result = rawData_.insert(std::pair<uint32_t, std::shared_ptr<InvokerRawData>>(fd, rawData));
987     return result.second;
988 }
989 
DetachRawData(uint32_t fd)990 bool IPCProcessSkeleton::DetachRawData(uint32_t fd)
991 {
992     std::unique_lock<std::shared_mutex> lockGuard(rawDataMutex_);
993     return (rawData_.erase(fd) > 0);
994 }
995 
QueryRawData(uint32_t fd)996 std::shared_ptr<InvokerRawData> IPCProcessSkeleton::QueryRawData(uint32_t fd)
997 {
998     std::shared_lock<std::shared_mutex> lockGuard(rawDataMutex_);
999     auto it = rawData_.find(fd);
1000     if (it != rawData_.end()) {
1001         return it->second;
1002     }
1003     return nullptr;
1004 }
1005 
AttachStubRecvRefInfo(IRemoteObject * stub,int pid,const std::string & deviceId)1006 bool IPCProcessSkeleton::AttachStubRecvRefInfo(IRemoteObject *stub, int pid, const std::string &deviceId)
1007 {
1008     auto check = [&stub, &pid, &deviceId](const std::shared_ptr<StubRefCountObject> &stubRef) {
1009         return stubRef->GetRemotePid() == pid && stubRef->GetDeviceId().compare(deviceId) == 0 &&
1010             stubRef->GetStubObject() == stub;
1011     };
1012 
1013     std::unique_lock<std::shared_mutex> lockGuard(stubRecvRefMutex_);
1014     auto it = std::find_if(stubRecvRefs_.begin(), stubRecvRefs_.end(), check);
1015     if (it != stubRecvRefs_.end()) {
1016         ZLOGE(LOG_LABEL, "fail to attach stub recv ref info, already in");
1017         return false;
1018     }
1019 
1020     std::shared_ptr<StubRefCountObject> refCount = std::make_shared<StubRefCountObject>(stub, pid, deviceId);
1021     stubRecvRefs_.push_front(refCount);
1022     return true;
1023 }
1024 
DetachStubRecvRefInfo(int pid,const std::string & deviceId)1025 void IPCProcessSkeleton::DetachStubRecvRefInfo(int pid, const std::string &deviceId)
1026 {
1027     auto check = [&pid, &deviceId](const std::shared_ptr<StubRefCountObject> &stubRef) {
1028         return stubRef->GetRemotePid() == pid && stubRef->GetDeviceId().compare(deviceId) == 0;
1029     };
1030 
1031     std::unique_lock<std::shared_mutex> lockGuard(stubRecvRefMutex_);
1032     stubRecvRefs_.remove_if(check);
1033 }
1034 
DetachStubRecvRefInfo(const IRemoteObject * stub,int pid,const std::string & deviceId)1035 bool IPCProcessSkeleton::DetachStubRecvRefInfo(const IRemoteObject *stub, int pid, const std::string &deviceId)
1036 {
1037     std::unique_lock<std::shared_mutex> lockGuard(stubRecvRefMutex_);
1038     for (auto it = stubRecvRefs_.begin(); it != stubRecvRefs_.end(); it++) {
1039         std::shared_ptr<StubRefCountObject> object = (*it);
1040         if ((object->GetRemotePid() == pid) && (object->GetDeviceId().compare(deviceId) == 0) &&
1041             (object->GetStubObject() == stub)) {
1042             stubRecvRefs_.erase(it);
1043             return true;
1044         }
1045     }
1046     return false;
1047 }
1048 
DetachStubRecvRefInfo(const IRemoteObject * stub)1049 void IPCProcessSkeleton::DetachStubRecvRefInfo(const IRemoteObject *stub)
1050 {
1051     auto check = [&stub](const std::shared_ptr<StubRefCountObject> &stubRef) {
1052         return stubRef->GetStubObject() == stub;
1053     };
1054 
1055     std::unique_lock<std::shared_mutex> lockGuard(stubRecvRefMutex_);
1056     stubRecvRefs_.remove_if(check);
1057 }
1058 
QueryStubRecvRefInfo(int pid,const std::string & deviceId)1059 std::list<IRemoteObject *> IPCProcessSkeleton::QueryStubRecvRefInfo(int pid, const std::string &deviceId)
1060 {
1061     std::shared_lock<std::shared_mutex> lockGuard(stubRecvRefMutex_);
1062     std::list<IRemoteObject *> stubList;
1063     for (auto it = stubRecvRefs_.begin(); it != stubRecvRefs_.end(); it++) {
1064         std::shared_ptr<StubRefCountObject> object = (*it);
1065         if ((object->GetRemotePid() == pid) && (object->GetDeviceId().compare(deviceId) == 0)) {
1066             stubList.push_back(object->GetStubObject());
1067         }
1068     }
1069 
1070     return stubList;
1071 }
1072 
DetachStubRefInfo(int pid,const std::string & deviceId)1073 void IPCProcessSkeleton::DetachStubRefInfo(int pid, const std::string &deviceId)
1074 {
1075     std::list<IRemoteObject *> stubList = QueryStubRecvRefInfo(pid, deviceId);
1076     if (!stubList.empty()) {
1077         for (auto it = stubList.begin(); it != stubList.end(); it++) {
1078             (*it)->DecStrongRef(this);
1079         }
1080     }
1081     DetachStubRecvRefInfo(pid, deviceId);
1082     DetachStubSendRefInfo(pid, deviceId);
1083 }
1084 
DetachStubRefInfo(IRemoteObject * stub,int pid,const std::string & deviceId)1085 void IPCProcessSkeleton::DetachStubRefInfo(IRemoteObject *stub, int pid, const std::string &deviceId)
1086 {
1087     if (DetachStubRecvRefInfo(stub, pid, deviceId) == true) {
1088         stub->DecStrongRef(this);
1089     }
1090     DetachStubSendRefInfo(stub, pid, deviceId);
1091 }
1092 
IncStubRefTimes(IRemoteObject * stub)1093 bool IPCProcessSkeleton::IncStubRefTimes(IRemoteObject *stub)
1094 {
1095     std::lock_guard<std::mutex> lockGuard(transTimesMutex_);
1096 
1097     auto it = transTimes_.find(stub);
1098     if (it != transTimes_.end()) {
1099         it->second++;
1100         return true;
1101     }
1102 
1103     auto result = transTimes_.insert(std::pair<IRemoteObject *, uint32_t>(stub, TRANS_TIME_INIT_VALUE));
1104     return result.second;
1105 }
1106 
DecStubRefTimes(IRemoteObject * stub)1107 bool IPCProcessSkeleton::DecStubRefTimes(IRemoteObject *stub)
1108 {
1109     std::lock_guard<std::mutex> lockGuard(transTimesMutex_);
1110 
1111     auto it = transTimes_.find(stub);
1112     if (it != transTimes_.end()) {
1113         if (it->second > 0) {
1114             it->second--;
1115             return true;
1116         }
1117     }
1118     return false;
1119 }
1120 
DetachStubRefTimes(IRemoteObject * stub)1121 bool IPCProcessSkeleton::DetachStubRefTimes(IRemoteObject *stub)
1122 {
1123     std::lock_guard<std::mutex> lockGuard(transTimesMutex_);
1124     return (transTimes_.erase(stub) > 0);
1125 }
1126 
AttachStubSendRefInfo(IRemoteObject * stub,int pid,const std::string & deviceId)1127 bool IPCProcessSkeleton::AttachStubSendRefInfo(IRemoteObject *stub, int pid, const std::string &deviceId)
1128 {
1129     auto check = [&stub, &pid, &deviceId](const std::shared_ptr<StubRefCountObject> &stubRef) {
1130         return stubRef->GetRemotePid() == pid && stubRef->GetDeviceId().compare(deviceId) == 0 &&
1131             stubRef->GetStubObject() == stub;
1132     };
1133 
1134     std::lock_guard<std::mutex> lockGuard(stubSendRefMutex_);
1135     auto it = std::find_if(stubSendRefs_.begin(), stubSendRefs_.end(), check);
1136     if (it != stubSendRefs_.end()) {
1137         ZLOGE(LOG_LABEL, "fail to attach stub sender ref info, already in");
1138         return false;
1139     }
1140     std::shared_ptr<StubRefCountObject> refCount = std::make_shared<StubRefCountObject>(stub, pid, deviceId);
1141     stubSendRefs_.push_front(refCount);
1142 
1143     return true;
1144 }
1145 
DetachStubSendRefInfo(IRemoteObject * stub)1146 void IPCProcessSkeleton::DetachStubSendRefInfo(IRemoteObject *stub)
1147 {
1148     auto check = [&stub](const std::shared_ptr<StubRefCountObject> &stubRef) {
1149         return stubRef->GetStubObject() == stub;
1150     };
1151 
1152     std::lock_guard<std::mutex> lockGuard(stubSendRefMutex_);
1153     stubSendRefs_.remove_if(check);
1154 }
1155 
DetachStubSendRefInfo(int pid,const std::string & deviceId)1156 void IPCProcessSkeleton::DetachStubSendRefInfo(int pid, const std::string &deviceId)
1157 {
1158     auto check = [&pid, &deviceId](const std::shared_ptr<StubRefCountObject> &stubRef) {
1159         return stubRef->GetRemotePid() == pid && stubRef->GetDeviceId().compare(deviceId) == 0;
1160     };
1161 
1162     std::lock_guard<std::mutex> lockGuard(stubSendRefMutex_);
1163     stubSendRefs_.remove_if(check);
1164 }
1165 
DetachStubSendRefInfo(IRemoteObject * stub,int pid,const std::string & deviceId)1166 void IPCProcessSkeleton::DetachStubSendRefInfo(IRemoteObject *stub, int pid, const std::string &deviceId)
1167 {
1168     auto check = [&pid, &deviceId, &stub](const std::shared_ptr<StubRefCountObject> &stubRef) {
1169         return stubRef->GetRemotePid() == pid && stubRef->GetDeviceId().compare(deviceId) == 0 &&
1170             stubRef->GetStubObject() == stub;
1171     };
1172 
1173     std::lock_guard<std::mutex> lockGuard(stubSendRefMutex_);
1174     stubSendRefs_.remove_if(check);
1175 }
1176 
IsSameRemoteObject(IRemoteObject * stub,int pid,int uid,const std::string & deviceId,const std::shared_ptr<CommAuthInfo> & auth)1177 bool IPCProcessSkeleton::IsSameRemoteObject(IRemoteObject *stub, int pid, int uid, const std::string &deviceId,
1178     const std::shared_ptr<CommAuthInfo> &auth)
1179 {
1180     if ((auth->GetStubObject() == stub) && (auth->GetRemotePid() == pid) && (auth->GetRemoteUid() == uid) &&
1181         (auth->GetRemoteDeviceId().compare(deviceId) == 0)) {
1182         return true;
1183     } else {
1184         return false;
1185     }
1186 }
1187 
IsSameRemoteObject(int pid,int uid,const std::string & deviceId,const std::shared_ptr<CommAuthInfo> & auth)1188 bool IPCProcessSkeleton::IsSameRemoteObject(int pid, int uid, const std::string &deviceId,
1189     const std::shared_ptr<CommAuthInfo> &auth)
1190 {
1191     if ((auth->GetRemotePid() == pid) && (auth->GetRemoteUid() == uid) &&
1192         (auth->GetRemoteDeviceId().compare(deviceId) == 0)) {
1193         return true;
1194     } else {
1195         return false;
1196     }
1197 }
1198 
AttachCommAuthInfo(IRemoteObject * stub,int pid,int uid,const std::string & deviceId,std::shared_ptr<FeatureSetData> featureSet)1199 bool IPCProcessSkeleton::AttachCommAuthInfo(IRemoteObject *stub, int pid, int uid,
1200     const std::string &deviceId, std::shared_ptr<FeatureSetData> featureSet)
1201 {
1202     auto check = [&stub, &pid, &uid, &deviceId, this](const std::shared_ptr<CommAuthInfo> &auth) {
1203         return IsSameRemoteObject(stub, pid, uid, deviceId, auth);
1204     };
1205     std::unique_lock<std::shared_mutex> lockGuard(commAuthMutex_);
1206     auto it = std::find_if(commAuth_.begin(), commAuth_.end(), check);
1207     if (it != commAuth_.end()) {
1208         ZLOGI(LOG_LABEL, "AttachCommAuthInfo already");
1209         return true;
1210     }
1211 
1212     std::shared_ptr<CommAuthInfo> authObject = std::make_shared<CommAuthInfo>(stub, pid, uid, deviceId, featureSet);
1213     commAuth_.push_front(authObject);
1214     return true;
1215 }
1216 
DetachCommAuthInfo(IRemoteObject * stub,int pid,int uid,const std::string & deviceId)1217 void IPCProcessSkeleton::DetachCommAuthInfo(IRemoteObject *stub, int pid, int uid, const std::string &deviceId)
1218 {
1219     auto check = [&stub, &pid, &uid, &deviceId, this](const std::shared_ptr<CommAuthInfo> &auth) {
1220         return IsSameRemoteObject(stub, pid, uid, deviceId, auth);
1221     };
1222     std::unique_lock<std::shared_mutex> lockGuard(commAuthMutex_);
1223     commAuth_.remove_if(check);
1224 }
1225 
QueryIsAuth(int pid,int uid,const std::string & deviceId)1226 std::shared_ptr<FeatureSetData> IPCProcessSkeleton::QueryIsAuth(int pid, int uid, const std::string &deviceId)
1227 {
1228     auto check = [&pid, &uid, &deviceId, this](const std::shared_ptr<CommAuthInfo> &auth) {
1229         return IsSameRemoteObject(pid, uid, deviceId, auth);
1230     };
1231     std::shared_lock<std::shared_mutex> lockGuard(commAuthMutex_);
1232     auto it = std::find_if(commAuth_.begin(), commAuth_.end(), check);
1233     if (it != commAuth_.end()) {
1234         return (*it)->GetFeatureSet();
1235     }
1236     ZLOGE(LOG_LABEL, "Query Comm Auth Fail");
1237     return nullptr;
1238 }
1239 
DetachCommAuthInfoByStub(IRemoteObject * stub)1240 void IPCProcessSkeleton::DetachCommAuthInfoByStub(IRemoteObject *stub)
1241 {
1242     auto check = [&stub](const std::shared_ptr<CommAuthInfo> &auth) { return auth->GetStubObject() == stub; };
1243     std::unique_lock<std::shared_mutex> lockGuard(commAuthMutex_);
1244     commAuth_.remove_if(check);
1245 }
1246 
AttachDBinderCallbackStub(sptr<IRemoteObject> proxy,sptr<DBinderCallbackStub> stub)1247 bool IPCProcessSkeleton::AttachDBinderCallbackStub(sptr<IRemoteObject> proxy, sptr<DBinderCallbackStub> stub)
1248 {
1249     std::unique_lock<std::shared_mutex> lockGuard(dbinderSentMutex_);
1250     auto result = dbinderSentCallback.insert(std::pair<sptr<IRemoteObject>, sptr<DBinderCallbackStub>>(proxy, stub));
1251     return result.second;
1252 }
1253 
DetachDBinderCallbackStubByProxy(sptr<IRemoteObject> proxy)1254 bool IPCProcessSkeleton::DetachDBinderCallbackStubByProxy(sptr<IRemoteObject> proxy)
1255 {
1256     std::unique_lock<std::shared_mutex> lockGuard(dbinderSentMutex_);
1257 
1258     return (dbinderSentCallback.erase(proxy) > 0);
1259 }
1260 
QueryDBinderCallbackStub(sptr<IRemoteObject> proxy)1261 sptr<DBinderCallbackStub> IPCProcessSkeleton::QueryDBinderCallbackStub(sptr<IRemoteObject> proxy)
1262 {
1263     std::shared_lock<std::shared_mutex> lockGuard(dbinderSentMutex_);
1264     auto it = dbinderSentCallback.find(proxy);
1265     if (it != dbinderSentCallback.end()) {
1266         return it->second;
1267     }
1268     return nullptr;
1269 }
1270 
QueryDBinderCallbackProxy(sptr<IRemoteObject> stub)1271 sptr<IRemoteObject> IPCProcessSkeleton::QueryDBinderCallbackProxy(sptr<IRemoteObject> stub)
1272 {
1273     std::shared_lock<std::shared_mutex> lockGuard(dbinderSentMutex_);
1274     for (auto it = dbinderSentCallback.begin(); it != dbinderSentCallback.end(); it++) {
1275         if (it->second.GetRefPtr() == stub.GetRefPtr()) {
1276             return it->first;
1277         }
1278     }
1279 
1280     return nullptr;
1281 }
1282 
1283 #endif
1284 #ifdef CONFIG_IPC_SINGLE
1285 } // namespace IPC_SINGLE
1286 #endif
1287 } // namespace OHOS