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