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