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