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