1 /*
2 * Copyright (C) 2023-2023 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 * Description: cast session manager service class
15 * Author: zhangge
16 * Create: 2022-06-15
17 */
18
19 #include "cast_session_manager_service.h"
20
21 #include <algorithm>
22 #include <atomic>
23
24 #include <ipc_skeleton.h>
25 #include "if_system_ability_manager.h"
26 #include "iservice_registry.h"
27 #include "system_ability_definition.h"
28
29 #include "cast_engine_dfx.h"
30 #include "cast_engine_errors.h"
31 #include "cast_engine_log.h"
32 #include "cast_session_impl.h"
33 #include "connection_manager.h"
34 #include "discovery_manager.h"
35 #include "softbus_error_code.h"
36 #include "hisysevent.h"
37 #include "permission.h"
38 #include "utils.h"
39
40 namespace OHOS {
41 namespace CastEngine {
42 namespace CastEngineService {
43 DEFINE_CAST_ENGINE_LABEL("Cast-Service");
44
45 REGISTER_SYSTEM_ABILITY_BY_ID(CastSessionManagerService, CAST_ENGINE_SA_ID, false);
46
47 namespace SessionServer {
48 constexpr char SESSION_NAME[] = "CastPlusSessionName";
49 constexpr int ROLE_CLENT = 1;
50 constexpr int SOFTBUS_OK = 0;
51
OnSessionOpened(int sessionId, int result)52 int OnSessionOpened(int sessionId, int result)
53 {
54 CLOGI("OnSessionOpened, session id = %{public}d, result is %{public}d", sessionId, result);
55 if (sessionId <= INVALID_ID || result != SOFTBUS_OK) {
56 auto device = CastDeviceDataManager::GetInstance().GetDeviceByTransId(sessionId);
57 if (device == std::nullopt) {
58 CLOGE("device is empty");
59 return result;
60 }
61 ConnectionManager::GetInstance().NotifySessionEvent(device->deviceId, ConnectEvent::DISCONNECT_START);
62 return result;
63 }
64 int role = GetSessionSide(sessionId);
65 if (role == ROLE_CLENT) {
66 ConnectionManager::GetInstance().OnConsultSessionOpened(sessionId, true);
67 } else {
68 ConnectionManager::GetInstance().OnConsultSessionOpened(sessionId, false);
69 }
70 return SOFTBUS_OK;
71 }
72
OnSessionClosed(int sessionId)73 void OnSessionClosed(int sessionId)
74 {
75 CLOGI("OnSessionClosed, session id = %{public}d", sessionId);
76 if (sessionId <= INVALID_ID) {
77 return;
78 }
79 }
80
OnBytesReceived(int sessionId, const void *data, unsigned int dataLen)81 void OnBytesReceived(int sessionId, const void *data, unsigned int dataLen)
82 {
83 CLOGI("OnBytesReceived,session id = %{public}d, len = %{public}u", sessionId, dataLen);
84 if (sessionId <= INVALID_ID || data == nullptr || dataLen == 0) {
85 return;
86 }
87 int role = GetSessionSide(sessionId);
88 if (role != ROLE_CLENT) {
89 ConnectionManager::GetInstance().OnConsultDataReceived(sessionId, data, dataLen);
90 }
91 }
92
93 ISessionListener g_SessionListener = {
94 OnSessionOpened, OnSessionClosed, OnBytesReceived, nullptr, nullptr, nullptr
95 };
96
97 // true: softbus service is up, and the session server has been created;
98 // false: softbus service is up, but the session server failed to create;
99 // nullopt: softbus service is down.
WaitSoftBusInit()100 std::optional<bool> WaitSoftBusInit()
101 {
102 constexpr int sleepTime = 50; // uint: ms
103 constexpr int retryTimes = 60 * 20; // total 60s
104 int ret = SoftBusErrNo::SOFTBUS_TRANS_SESSION_ADDPKG_FAILED;
105 int retryTime = 0;
106 while (ret == SoftBusErrNo::SOFTBUS_TRANS_SESSION_ADDPKG_FAILED && retryTime < retryTimes) {
107 CLOGI("create session server");
108 ret = CreateSessionServer(PKG_NAME, SessionServer::SESSION_NAME, &SessionServer::g_SessionListener);
109 if (ret == SOFTBUS_OK) {
110 return true;
111 }
112 retryTime++;
113 std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
114 }
115
116 if (retryTime == retryTimes) {
117 CLOGE("softbus service is down.");
118 return std::nullopt;
119 }
120
121 return false;
122 }
123
SetupSessionServer()124 bool SetupSessionServer()
125 {
126 int32_t result = SoftBusErrNo::SOFTBUS_ERR;
127 int32_t retryTime = 0;
128 constexpr int32_t retryTimes = 20;
129 while (result != SessionServer::SOFTBUS_OK && retryTime < retryTimes) {
130 CLOGI("retry create session server");
131 result = CreateSessionServer(PKG_NAME, SessionServer::SESSION_NAME, &SessionServer::g_SessionListener);
132 retryTime++;
133 }
134 if (result != SessionServer::SOFTBUS_OK) {
135 CLOGE("CreateSessionServer failed, ret:%d", result);
136 return false;
137 }
138
139 return true;
140 }
141 }
142
CastSessionManagerService(int32_t saId, bool runOnCreate)143 CastSessionManagerService::CastSessionManagerService(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate)
144 {
145 CLOGD("construction in");
146 myPid_ = getpid();
147 };
148
~CastSessionManagerService()149 CastSessionManagerService::~CastSessionManagerService()
150 {
151 CLOGD("destruction in");
152 }
153
OnStart()154 void CastSessionManagerService::OnStart()
155 {
156 bool ret = Publish(this);
157 if (!ret) {
158 CLOGE("Failed to publish cast session manager service");
159 return;
160 }
161
162 AddSystemAbilityListener(CAST_ENGINE_SA_ID);
163 auto result = SessionServer::WaitSoftBusInit();
164 if (result == std::nullopt) {
165 CastEngineDfx::WriteErrorEvent(SOURCE_CREATE_SESSION_SERVER_FAIL);
166 CLOGE("softbus service is down.");
167 return;
168 }
169
170 if (result) {
171 hasServer_ = true;
172 return;
173 }
174
175 if (!SessionServer::SetupSessionServer()) {
176 CastEngineDfx::WriteErrorEvent(SOURCE_CREATE_SESSION_SERVER_FAIL);
177 return;
178 }
179 hasServer_ = true;
180 }
181
OnStop()182 void CastSessionManagerService::OnStop()
183 {
184 CLOGI("Stop in");
185 RemoveSessionServer(PKG_NAME, SessionServer::SESSION_NAME);
186 }
187
188 namespace {
189 using namespace OHOS::DistributedHardware;
190
191 class DiscoveryManagerListener : public IDiscoveryManagerListener {
192 public:
DiscoveryManagerListener(sptr<CastSessionManagerService> service)193 DiscoveryManagerListener(sptr<CastSessionManagerService> service) : service_(service) {}
194
195 void OnDeviceFound(const std::vector<CastInnerRemoteDevice> &devices) override
196 {
197 auto service = service_.promote();
198 if (!service) {
199 CLOGE("service is null");
200 return;
201 }
202
203 std::vector<CastRemoteDevice> remoteDevices;
204 for (const auto &device : devices) {
205 remoteDevices.push_back(CastRemoteDevice{ device.deviceId, device.deviceName, device.deviceType,
206 device.subDeviceType, device.ipAddress, device.channelType,
207 CapabilityType::CAST_PLUS, device.networkId, "", 0, nullptr});
208 }
209 service->ReportDeviceFound(remoteDevices);
210 }
211
212 private:
213 wptr<CastSessionManagerService> service_;
214 };
215
216 class ConnectionManagerListener : public IConnectionManagerListener {
217 public:
ConnectionManagerListener(sptr<CastSessionManagerService> service)218 ConnectionManagerListener(sptr<CastSessionManagerService> service) : service_(service) {}
219
220 int NotifySessionIsReady() override
221 {
222 auto service = service_.promote();
223 if (!service) {
224 CLOGE("service is null");
225 return INVALID_ID;
226 }
227
228 sptr<ICastSessionImpl> session;
229 service->CreateCastSession({}, session);
230 if (session == nullptr) {
231 return INVALID_ID;
232 }
233
234 service->ReportSessionCreate(session);
235 std::string sessionId{};
236 session->GetSessionId(sessionId);
237 return Utils::StringToInt((sessionId));
238 }
239
240 bool NotifyRemoteDeviceIsReady(int castSessionId, const CastInnerRemoteDevice &device) override
241 {
242 auto service = service_.promote();
243 if (!service) {
244 CLOGE("service is null");
245 return false;
246 }
247 sptr<ICastSessionImpl> session;
248 service->GetCastSession(std::to_string(castSessionId), session);
249 if (session == nullptr) {
250 CLOGE("Session is null when consultation data comes!");
251 return false;
252 }
253 if (!session->AddDevice(device)) {
254 CLOGE("Session addDevice fail");
255 return false;
256 }
257 ConnectionManager::GetInstance().NotifySessionEvent(device.deviceId, ConnectEvent::CONNECT_START);
258 return true;
259 }
260
261 void NotifyDeviceIsOffline(const std::string &deviceId) override
262 {
263 auto service = service_.promote();
264 if (!service) {
265 CLOGE("service is null");
266 return;
267 }
268 service->ReportDeviceOffline(deviceId);
269 CLOGD("OnDeviceOffline out");
270 }
271
272 void OnEvent(const std::string &deviceId, EventCode currentEventCode) override
273 {
274 auto service = service_.promote();
275 if (!service) {
276 CLOGE("service is null");
277 return;
278 }
279 int sessionId = CastDeviceDataManager::GetInstance().GetSessionIdByDeviceId(deviceId);
280 if (sessionId == INVALID_ID) {
281 CLOGE("The obtained sessionId is null");
282 return;
283 }
284 sptr<ICastSessionImpl> session;
285 service->GetCastSession(std::to_string(sessionId), session);
286 if (!session) {
287 CLOGE("The session is null. Failed to obtain the session.");
288 return;
289 }
290 session->OnSessionEvent(deviceId, currentEventCode);
291 }
292
293 void GrabDevice(int32_t sessionId) override
294 {
295 auto service = service_.promote();
296 if (!service) {
297 CLOGE("service is null");
298 return;
299 }
300
301 sptr<ICastSessionImpl> session;
302 service->GetCastSession(std::to_string(sessionId), session);
303 if (!session) {
304 CLOGE("The session is null. Failed to obtain the session.");
305 return;
306 }
307 session->Release();
308 }
309
310 int32_t GetSessionProtocolType(int sessionId, ProtocolType &protocolType) override
311 {
312 CLOGI("GetSessionProtocolType in");
313 auto service = service_.promote();
314 if (!service) {
315 CLOGE("service is null");
316 return CAST_ENGINE_ERROR;
317 }
318 sptr<ICastSessionImpl> session;
319 service->GetCastSession(std::to_string(sessionId), session);
320 if (!session) {
321 CLOGE("The session is null. Failed to obtain the session.");
322 return CAST_ENGINE_ERROR;
323 }
324 return session->GetSessionProtocolType(protocolType);
325 }
326
327 int32_t SetSessionProtocolType(int sessionId, ProtocolType protocolType) override
328 {
329 CLOGI("SetSessionProtocolType in");
330 auto service = service_.promote();
331 if (!service) {
332 CLOGE("service is null");
333 return CAST_ENGINE_ERROR;
334 }
335 sptr<ICastSessionImpl> session;
336 service->GetCastSession(std::to_string(sessionId), session);
337 if (!session) {
338 CLOGE("The session is null. Failed to obtain the session.");
339 return CAST_ENGINE_ERROR;
340 }
341 session->SetSessionProtocolType(protocolType);
342 return CAST_ENGINE_SUCCESS;
343 }
344
345 private:
346 wptr<CastSessionManagerService> service_;
347 };
348 } // namespace
349
RegisterListener(sptr<ICastServiceListenerImpl> listener)350 int32_t CastSessionManagerService::RegisterListener(sptr<ICastServiceListenerImpl> listener)
351 {
352 CLOGI("RegisterListener in");
353 HiSysEventWrite(CAST_ENGINE_DFX_DOMAIN_NAME, "CAST_ENGINE_EVE", HiviewDFX::HiSysEvent::EventType::STATISTIC,
354 "SEQUENTIAL_ID", CastEngineDfx::GetSequentialId(), "BIZ_PACKAGE_NAME", CastEngineDfx::GetBizPackageName());
355 SharedWLock lock(mutex_);
356 if (listener == nullptr) {
357 CLOGE("RegisterListener failed, listener is null");
358 return CAST_ENGINE_ERROR;
359 }
360 bool needInitMore = !HasListenerLocked();
361 if (!AddListenerLocked(listener)) {
362 return CAST_ENGINE_ERROR;
363 }
364
365 if (needInitMore) {
366 DiscoveryManager::GetInstance().Init(std::make_shared<DiscoveryManagerListener>(this));
367 ConnectionManager::GetInstance().Init(std::make_shared<ConnectionManagerListener>(this));
368 sessionMap_.clear();
369 }
370
371 serviceStatus_ = ServiceStatus::CONNECTED;
372 CLOGI("RegisterListener out");
373 return CAST_ENGINE_SUCCESS;
374 }
375
UnregisterListener()376 int32_t CastSessionManagerService::UnregisterListener()
377 {
378 SharedWLock lock(mutex_);
379 CLOGI("UnregisterListener in");
380
381 return RemoveListenerLocked(IPCSkeleton::GetCallingPid());
382 }
383
Release()384 int32_t CastSessionManagerService::Release()
385 {
386 SharedWLock lock(mutex_);
387 CLOGI("Release in");
388 if (!Permission::CheckPidPermission()) {
389 return ERR_NO_PERMISSION;
390 }
391
392 return ReleaseLocked();
393 }
394
ReleaseLocked()395 int32_t CastSessionManagerService::ReleaseLocked()
396 {
397 CLOGI("ReleaseLocked in");
398 serviceStatus_ = ServiceStatus::DISCONNECTED;
399 ReportServiceDieLocked();
400
401 ClearListenersLocked();
402 DiscoveryManager::GetInstance().Deinit();
403 ConnectionManager::GetInstance().Deinit();
404 sessionMap_.clear();
405 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
406 if (samgr == nullptr) {
407 CLOGE("get samgr failed");
408 return CAST_ENGINE_ERROR;
409 }
410 int32_t ret = samgr->UnloadSystemAbility(CAST_ENGINE_SA_ID);
411 if (ret != ERR_OK) {
412 CLOGE("remove system ability failed");
413 return CAST_ENGINE_ERROR;
414 }
415 CLOGI("Release success done");
416 return CAST_ENGINE_SUCCESS;
417 }
418
SetLocalDevice(const CastLocalDevice &localDevice)419 int32_t CastSessionManagerService::SetLocalDevice(const CastLocalDevice &localDevice)
420 {
421 CLOGD("SetLocalDevice in");
422 SharedWLock lock(mutex_);
423 if (!Permission::CheckPidPermission()) {
424 return ERR_NO_PERMISSION;
425 }
426 localDevice_ = localDevice;
427 return CAST_ENGINE_SUCCESS;
428 }
429
GetCastSession(std::string sessionId, sptr<ICastSessionImpl> &castSession)430 int32_t CastSessionManagerService::GetCastSession(std::string sessionId, sptr<ICastSessionImpl> &castSession)
431 {
432 SharedRLock lock(mutex_);
433 if (!Permission::CheckPidPermission()) {
434 return ERR_NO_PERMISSION;
435 }
436
437 auto session = GetCastSessionInner(sessionId);
438 if (session == nullptr) {
439 return ERR_SESSION_NOT_EXIST;
440 }
441 castSession = session;
442 return CAST_ENGINE_SUCCESS;
443 }
444
GetCastSessionInner(std::string sessionId)445 sptr<ICastSessionImpl> CastSessionManagerService::GetCastSessionInner(std::string sessionId)
446 {
447 auto innerSessionId = Utils::StringToInt(sessionId);
448 auto it = sessionMap_.find(innerSessionId);
449 if (it == sessionMap_.end()) {
450 CLOGE("No sessionId=%{public}d session.", innerSessionId);
451 return nullptr;
452 }
453 return it->second;
454 }
455
CreateCastSession(const CastSessionProperty &property, sptr<ICastSessionImpl> &castSession)456 int32_t CastSessionManagerService::CreateCastSession(const CastSessionProperty &property,
457 sptr<ICastSessionImpl> &castSession)
458 {
459 SharedWLock lock(mutex_);
460 if (!Permission::CheckPidPermission()) {
461 return ERR_NO_PERMISSION;
462 }
463 CLOGD("CreateCastSession in, protocol:%{public}d, endType:%{public}d.", property.protocolType, property.endType);
464 if (serviceStatus_ != ServiceStatus::CONNECTED) {
465 CLOGE("not connected");
466 return ERR_SERVICE_STATE_NOT_MATCH;
467 }
468
469 if (localDevice_.deviceId.empty()) {
470 auto local = ConnectionManager::GetInstance().GetLocalDeviceInfo();
471 if (local == nullptr) {
472 return CAST_ENGINE_ERROR;
473 }
474 localDevice_ = *local;
475 }
476
477 auto tmp = new (std::nothrow) CastSessionImpl(property, localDevice_);
478 if (tmp == nullptr) {
479 CLOGE("CastSessionImpl is null");
480 return ERR_NO_MEMORY;
481 }
482 sptr<ICastSessionImpl> session(static_cast<ICastSessionImpl *>(tmp));
483 tmp->Init();
484 tmp->SetServiceCallbackForRelease([this](int32_t sessionId) { DestroyCastSession(sessionId); });
485
486 sessionIndex_++;
487 std::string sessionId{};
488 session->GetSessionId(sessionId);
489 sessionMap_.insert({ Utils::StringToInt(sessionId), session });
490
491 CLOGD("CreateCastSession success, session(%{public}d) count:%{public}zu",
492 Utils::StringToInt(sessionId), sessionMap_.size());
493 castSession = session;
494 ConnectionManager::GetInstance().UpdateGrabState(true, Utils::StringToInt(sessionId));
495 return CAST_ENGINE_SUCCESS;
496 }
497
DestroyCastSession(int32_t sessionId)498 bool CastSessionManagerService::DestroyCastSession(int32_t sessionId)
499 {
500 CLOGD("DestroyCastSession in");
501 sptr<ICastSessionImpl> session;
502 {
503 SharedWLock lock(mutex_);
504 auto it = sessionMap_.find(sessionId);
505 if (it == sessionMap_.end()) {
506 CLOGE("Cast session(%d) has gone.", sessionId);
507 return true;
508 }
509 session = it->second;
510 sessionMap_.erase(it);
511 }
512
513 ConnectionManager::GetInstance().UpdateGrabState(false, -1);
514 session->Stop();
515 CLOGD("Session refcount is %d, session count:%zu", session->GetSptrRefCount(), sessionMap_.size());
516 return true;
517 }
518
SetSinkSessionCapacity(int sessionCapacity)519 int32_t CastSessionManagerService::SetSinkSessionCapacity(int sessionCapacity)
520 {
521 CLOGD("SetSinkSessionCapacity in, sessionCapacity = %d", sessionCapacity);
522 SharedRLock lock(mutex_);
523 if (!Permission::CheckPidPermission()) {
524 return ERR_NO_PERMISSION;
525 }
526 sessionCapacity_ = sessionCapacity;
527 return CAST_ENGINE_SUCCESS;
528 }
529
StartDiscovery(int protocols)530 int32_t CastSessionManagerService::StartDiscovery(int protocols)
531 {
532 static_cast<void>(protocols);
533 CLOGD("StartDiscovery in, protocolType = %d", protocols);
534 SharedRLock lock(mutex_);
535 if (!Permission::CheckPidPermission()) {
536 return ERR_NO_PERMISSION;
537 }
538 DiscoveryManager::GetInstance().StartDiscovery();
539 return CAST_ENGINE_SUCCESS;
540 }
541
StopDiscovery()542 int32_t CastSessionManagerService::StopDiscovery()
543 {
544 CLOGD("StopDiscovery in");
545 SharedRLock lock(mutex_);
546 if (!Permission::CheckPidPermission()) {
547 return ERR_NO_PERMISSION;
548 }
549 DiscoveryManager::GetInstance().StopDiscovery();
550 return CAST_ENGINE_SUCCESS;
551 }
552
SetDiscoverable(bool enable)553 int32_t CastSessionManagerService::SetDiscoverable(bool enable)
554 {
555 CLOGD("SetDiscoverable in, enable = %{public}d", enable);
556 SharedRLock lock(mutex_);
557 if (!Permission::CheckPidPermission()) {
558 return ERR_NO_PERMISSION;
559 }
560
561 if (enable) {
562 if (ConnectionManager::GetInstance().EnableDiscoverable() &&
563 DiscoveryManager::GetInstance().StartAdvertise()) {
564 return CAST_ENGINE_SUCCESS;
565 }
566 } else {
567 if (ConnectionManager::GetInstance().DisableDiscoverable() &&
568 DiscoveryManager::GetInstance().StopAdvertise()) {
569 return CAST_ENGINE_SUCCESS;
570 }
571 }
572 return CAST_ENGINE_ERROR;
573 }
574
ReleaseServiceResources(pid_t pid)575 void CastSessionManagerService::ReleaseServiceResources(pid_t pid)
576 {
577 {
578 SharedWLock lock(mutex_);
579 RemoveListenerLocked(pid);
580 for (auto it = sessionMap_.begin(); it != sessionMap_.end();) {
581 if (it->second->ReleaseSessionResources(pid)) {
582 sessionMap_.erase(it++);
583 continue;
584 }
585 it++;
586 }
587 if (HasListenerLocked()) {
588 return;
589 }
590 }
591 CLOGD("Release service resources");
592 if (Release() != CAST_ENGINE_SUCCESS) {
593 CLOGE("Release service resources failed");
594 }
595 }
596
AddClientDeathRecipientLocked(pid_t pid, sptr<ICastServiceListenerImpl> listener)597 void CastSessionManagerService::AddClientDeathRecipientLocked(pid_t pid, sptr<ICastServiceListenerImpl> listener)
598 {
599 sptr<CastEngineClientDeathRecipient> deathRecipient(
600 new (std::nothrow) CastEngineClientDeathRecipient(wptr<CastSessionManagerService>(this), pid));
601 if (deathRecipient == nullptr) {
602 CLOGE("Alloc death recipient filed");
603 return;
604 }
605 if (!listener->AsObject()->AddDeathRecipient(deathRecipient)) {
606 CLOGE("Add cast client death recipient failed");
607 return;
608 }
609 CLOGD("add death recipient pid:%d", pid);
610 deathRecipientMap_[pid] = deathRecipient;
611 }
612
RemoveClientDeathRecipientLocked(pid_t pid, sptr<ICastServiceListenerImpl> listener)613 void CastSessionManagerService::RemoveClientDeathRecipientLocked(pid_t pid, sptr<ICastServiceListenerImpl> listener)
614 {
615 auto it = deathRecipientMap_.find(pid);
616 if (it != deathRecipientMap_.end()) {
617 listener->AsObject()->RemoveDeathRecipient(it->second);
618 deathRecipientMap_.erase(it);
619 CLOGD("remove death recipient pid:%d", pid);
620 }
621 }
622
AddListenerLocked(sptr<ICastServiceListenerImpl> listener)623 bool CastSessionManagerService::AddListenerLocked(sptr<ICastServiceListenerImpl> listener)
624 {
625 pid_t pid = IPCSkeleton::GetCallingPid();
626 Permission::SavePid(pid);
627 if (std::find_if(listeners_.begin(), listeners_.end(),
628 [pid](std::pair<pid_t, sptr<ICastServiceListenerImpl>> member) { return member.first == pid; }) ==
629 listeners_.end()) {
630 listeners_.push_back({ pid, listener });
631 AddClientDeathRecipientLocked(pid, listener);
632 return true;
633 }
634
635 CLOGE("The process(%u) has register the listener", pid);
636 return false;
637 }
638
RemoveListenerLocked(pid_t pid)639 int32_t CastSessionManagerService::RemoveListenerLocked(pid_t pid)
640 {
641 Permission::RemovePid(pid);
642 auto iter = std::find_if(listeners_.begin(), listeners_.end(),
643 [pid](std::pair<pid_t, sptr<ICastServiceListenerImpl>> element) { return element.first == pid; });
644 if (iter != listeners_.end()) {
645 RemoveClientDeathRecipientLocked(pid, (*iter).second);
646 listeners_.erase(iter);
647 if (listeners_.size() == 0) {
648 ReleaseLocked();
649 }
650 return CAST_ENGINE_SUCCESS;
651 }
652 return CAST_ENGINE_ERROR;
653 }
654
ClearListenersLocked()655 void CastSessionManagerService::ClearListenersLocked()
656 {
657 listeners_.clear();
658 Permission::ClearPids();
659 }
660
HasListenerLocked()661 bool CastSessionManagerService::HasListenerLocked()
662 {
663 return listeners_.size() > 0;
664 }
665
ReportServiceDieLocked()666 void CastSessionManagerService::ReportServiceDieLocked()
667 {
668 pid_t pid = IPCSkeleton::GetCallingPid();
669 if (pid == myPid_) {
670 for (const auto &listener : listeners_) {
671 listener.second->OnServiceDied();
672 }
673 return;
674 }
675
676 auto it = std::find_if(listeners_.begin(), listeners_.end(),
677 [pid](std::pair<pid_t, sptr<ICastServiceListenerImpl>> element) { return element.first == pid; });
678 if (it != listeners_.end()) {
679 it->second->OnServiceDied();
680 return;
681 }
682 }
683
ReportDeviceFound(const std::vector<CastRemoteDevice> &deviceList)684 void CastSessionManagerService::ReportDeviceFound(const std::vector<CastRemoteDevice> &deviceList)
685 {
686 SharedRLock lock(mutex_);
687 for (const auto &listener : listeners_) {
688 listener.second->OnDeviceFound(deviceList);
689 }
690 }
691
ReportSessionCreate(const sptr<ICastSessionImpl> &castSession)692 void CastSessionManagerService::ReportSessionCreate(const sptr<ICastSessionImpl> &castSession)
693 {
694 SharedRLock lock(mutex_);
695 for (const auto &listener : listeners_) {
696 listener.second->OnSessionCreated(castSession);
697 }
698 }
699
ReportDeviceOffline(const std::string &deviceId)700 void CastSessionManagerService::ReportDeviceOffline(const std::string &deviceId)
701 {
702 SharedRLock lock(mutex_);
703 for (const auto &listener : listeners_) {
704 listener.second->OnDeviceOffline(deviceId);
705 }
706 }
707
OnRemoteDied(const wptr<IRemoteObject> &object)708 void CastSessionManagerService::CastEngineClientDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
709 {
710 CLOGD("Client died, need release resources, client pid_: %d", pid_);
711 sptr<CastSessionManagerService> service = service_.promote();
712 if (service == nullptr) {
713 CLOGE("ServiceStub is nullptr");
714 return;
715 }
716 service->ReleaseServiceResources(pid_);
717 }
718 } // namespace CastEngineService
719 } // namespace CastEngine
720 } // namespace OHOS
721