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