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