• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "dm_constants.h"
28 #include "system_ability_definition.h"
29 
30 #include "cast_engine_dfx.h"
31 #include "cast_engine_errors.h"
32 #include "cast_engine_log.h"
33 #include "cast_session_impl.h"
34 #include "cast_session_impl_class.h"
35 #include "connection_manager.h"
36 #include "discovery_manager.h"
37 #include "softbus_error_code.h"
38 #include "hisysevent.h"
39 #include "permission.h"
40 #include "utils.h"
41 #include "bundle_mgr_client.h"
42 
43 namespace OHOS {
44 namespace CastEngine {
45 namespace CastEngineService {
46 DEFINE_CAST_ENGINE_LABEL("Cast-Service");
47 
48 REGISTER_SYSTEM_ABILITY_BY_ID(CastSessionManagerService, CAST_ENGINE_SA_ID, false);
49 
50 namespace SessionServer {
51 
52 constexpr int ROLE_CLENT = 1;
53 constexpr int SOFTBUS_OK = 0;
54 constexpr char SESSION_NAME[] = "CastPlusSessionName";
55 
OnSessionOpened(int sessionId,int result)56 int OnSessionOpened(int sessionId, int result)
57 {
58     CLOGI("OnSessionOpened, session id = %{public}d, result is %{public}d", sessionId, result);
59     if (sessionId <= INVALID_ID || result != SOFTBUS_OK) {
60         auto device = CastDeviceDataManager::GetInstance().GetDeviceByTransId(sessionId);
61         if (device == std::nullopt) {
62             CLOGE("device is empty");
63             return result;
64         }
65         return result;
66     }
67     int role = GetSessionSide(sessionId);
68     if (role == ROLE_CLENT) {
69         ConnectionManager::GetInstance().OnConsultSessionOpened(sessionId, true);
70     } else {
71         ConnectionManager::GetInstance().OnConsultSessionOpened(sessionId, false);
72     }
73     return SOFTBUS_OK;
74 }
75 
OnSessionClosed(int sessionId)76 void OnSessionClosed(int sessionId)
77 {
78     CLOGI("OnSessionClosed, session id = %{public}d", sessionId);
79     if (sessionId <= INVALID_ID) {
80         return;
81     }
82 }
83 
OnBytesReceived(int sessionId,const void * data,unsigned int dataLen)84 void OnBytesReceived(int sessionId, const void *data, unsigned int dataLen)
85 {
86     CLOGI("OnBytesReceived,session id = %{public}d, len = %{public}u", sessionId, dataLen);
87     if (sessionId <= INVALID_ID || data == nullptr || dataLen == 0) {
88         return;
89     }
90     int role = GetSessionSide(sessionId);
91     if (role != ROLE_CLENT) {
92         ConnectionManager::GetInstance().OnConsultDataReceived(sessionId, data, dataLen);
93     }
94 }
95 
96 ISessionListener g_SessionListener = {
97     OnSessionOpened, OnSessionClosed, OnBytesReceived, nullptr, nullptr, nullptr
98 };
99 
100 // true: softbus service is up, and the session server has been created;
101 // false: softbus service is up, but the session server failed to create;
102 // nullopt: softbus service is down.
WaitSoftBusInit()103 std::optional<bool> WaitSoftBusInit()
104 {
105     constexpr int sleepTime = 50; // uint: ms
106     constexpr int retryTimes = 60 * 20; // total 60s
107     int ret = SoftBusErrNo::SOFTBUS_TRANS_SESSION_ADDPKG_FAILED;
108     int retryTime = 0;
109     while (ret == SoftBusErrNo::SOFTBUS_TRANS_SESSION_ADDPKG_FAILED && retryTime < retryTimes) {
110         CLOGI("create session server");
111         ret = CreateSessionServer(PKG_NAME, SessionServer::SESSION_NAME, &SessionServer::g_SessionListener);
112         if (ret == SOFTBUS_OK) {
113             return true;
114         }
115         retryTime++;
116         std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
117     }
118 
119     if (retryTime == retryTimes) {
120         CLOGE("softbus service is down.");
121         return std::nullopt;
122     }
123 
124     return false;
125 }
126 
SetupSessionServer()127 bool SetupSessionServer()
128 {
129     int32_t result = SoftBusErrNo::SOFTBUS_ERR;
130     int32_t retryTime = 0;
131     constexpr int32_t retryTimes = 20;
132     while (result != SessionServer::SOFTBUS_OK && retryTime < retryTimes) {
133         CLOGI("retry create session server");
134         result = CreateSessionServer(PKG_NAME, SessionServer::SESSION_NAME, &SessionServer::g_SessionListener);
135         retryTime++;
136     }
137     if (result != SessionServer::SOFTBUS_OK) {
138         CLOGE("CreateSessionServer failed, ret:%d", result);
139         return false;
140     }
141 
142     return true;
143 }
144 }
145 
146 namespace {
147 constexpr int DEVICE_MANAGER_SA_ID = 4802;
148 } // namespace
149 
CastSessionManagerService(int32_t saId,bool runOnCreate)150 CastSessionManagerService::CastSessionManagerService(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate)
151 {
152     CLOGD("construction in");
153     myPid_ = getpid();
154 };
155 
~CastSessionManagerService()156 CastSessionManagerService::~CastSessionManagerService()
157 {
158     CLOGD("destruction in");
159 }
160 
OnStart()161 void CastSessionManagerService::OnStart()
162 {
163     bool ret = Publish(this);
164     if (!ret) {
165         CLOGE("Failed to publish cast session manager service");
166         return;
167     }
168 
169     AddSystemAbilityListener(CAST_ENGINE_SA_ID);
170     auto result = SessionServer::WaitSoftBusInit();
171     if (result == std::nullopt) {
172         CastEngineDfx::WriteErrorEvent(SOURCE_CREATE_SESSION_SERVER_FAIL);
173         CLOGE("softbus service is down.");
174         return;
175     }
176 
177     if (result) {
178         hasServer_ = true;
179         return;
180     }
181 
182     if (!SessionServer::SetupSessionServer()) {
183         CastEngineDfx::WriteErrorEvent(SOURCE_CREATE_SESSION_SERVER_FAIL);
184         return;
185     }
186     hasServer_ = true;
187 }
188 
OnStop()189 void CastSessionManagerService::OnStop()
190 {
191     CLOGI("Stop in");
192     RemoveSessionServer(PKG_NAME, SessionServer::SESSION_NAME);
193 }
194 
OnActive(const SystemAbilityOnDemandReason & activeReason)195 void CastSessionManagerService::OnActive(const SystemAbilityOnDemandReason& activeReason)
196 {
197     CLOGI("OnActive in, reasonValue:%{public}s", activeReason.GetValue().c_str());
198     isUnloading_.store(false);
199 }
200 
201 namespace {
202 using namespace OHOS::DistributedHardware;
203 constexpr int AV_SESSION_UID = 6700;
204 
205 class DiscoveryManagerListener : public IDiscoveryManagerListener {
206 public:
DiscoveryManagerListener(sptr<CastSessionManagerService> service)207     DiscoveryManagerListener(sptr<CastSessionManagerService> service) : service_(service) {}
208 
OnDeviceFound(const std::vector<CastInnerRemoteDevice> & devices)209     void OnDeviceFound(const std::vector<CastInnerRemoteDevice> &devices) override
210     {
211         auto service = service_.promote();
212         if (!service) {
213             CLOGE("service is null");
214             return;
215         }
216 
217         std::vector<std::pair<CastRemoteDevice, bool>> remoteDevices;
218         for (const auto &device : devices) {
219             std::pair<CastRemoteDevice, bool> remoteDevice;
220             remoteDevice.first = CastRemoteDevice{ device.deviceId, device.deviceName, device.deviceType,
221                 device.subDeviceType, device.ipAddress, device.channelType, device.capability,
222                 device.capabilityInfo, device.networkId, "", 0, nullptr, device.isLeagacy, device.sessionId,
223                 device.drmCapabilities, device.mediumTypes };
224 
225             remoteDevice.second = (device.capabilityInfo & static_cast<uint32_t>(ProtocolType::CAST_PLUS_STREAM)) != 0;
226             if (device.deviceType == DeviceType::DEVICE_TYPE_2IN1) {
227                 remoteDevice.second = true;
228             }
229             remoteDevices.push_back(remoteDevice);
230         }
231         service->ReportDeviceFound(remoteDevices);
232     }
233 
234 private:
235     wptr<CastSessionManagerService> service_;
236 };
237 } // namespace
238 
NotifySessionIsReady()239 int ConnectionManagerListener::NotifySessionIsReady()
240 {
241     auto service = service_.promote();
242     if (!service) {
243         CLOGE("service is null");
244         return INVALID_ID;
245     }
246 
247     sptr<ICastSessionImpl> session;
248     service->CreateCastSession({}, session);
249     if (session == nullptr) {
250         return INVALID_ID;
251     }
252 
253     std::string sessionId{};
254     session->GetSessionId(sessionId);
255     return Utils::StringToInt((sessionId));
256 }
257 
ReportSessionCreate(int castSessionId)258 void ConnectionManagerListener::ReportSessionCreate(int castSessionId)
259 {
260     auto service = service_.promote();
261     if (!service) {
262         CLOGE("service is null");
263         return;
264     }
265 
266     sptr<ICastSessionImpl> castSession;
267     if (service->GetCastSession(std::to_string(castSessionId), castSession) == CAST_ENGINE_SUCCESS) {
268         service->ReportSessionCreate(castSession);
269         return;
270     }
271     CLOGE("Invalid castSessionId: %d.", castSessionId);
272 }
273 
NotifyRemoteDeviceIsReady(int castSessionId,const CastInnerRemoteDevice & device)274 bool ConnectionManagerListener::NotifyRemoteDeviceIsReady(int castSessionId, const CastInnerRemoteDevice &device)
275 {
276     auto service = service_.promote();
277     if (!service) {
278         CLOGE("service is null");
279         return false;
280     }
281 
282     sptr<ICastSessionImpl> session;
283     service->GetCastSession(std::to_string(castSessionId), session);
284     if (session == nullptr) {
285         CLOGE("Session is null when consultation data comes!");
286         return false;
287     }
288 
289     if (!session->AddDevice(device)) {
290         CLOGE("Session addDevice fail");
291         return false;
292     }
293 
294     ConnectionManager::GetInstance().NotifyConnectStage(device, ConnectStageResult::CONNECT_START);
295     return true;
296 }
297 
NotifyDeviceIsOffline(const std::string & deviceId)298 void ConnectionManagerListener::NotifyDeviceIsOffline(const std::string &deviceId)
299 {
300     auto service = service_.promote();
301     if (!service) {
302         CLOGE("service is null");
303         return;
304     }
305     service->ReportDeviceOffline(deviceId);
306     CLOGD("OnDeviceOffline out");
307 }
308 
GrabDevice(int32_t sessionId)309 void ConnectionManagerListener::GrabDevice(int32_t sessionId)
310 {
311     auto service = service_.promote();
312     if (!service) {
313         CLOGE("service is null");
314         return;
315     }
316 
317     sptr<ICastSessionImpl> session;
318     service->GetCastSession(std::to_string(sessionId), session);
319     if (!session) {
320         CLOGE("The session is null. Failed to obtain the session.");
321         return;
322     }
323     session->Release();
324 }
325 
GetSessionProtocolType(int sessionId,ProtocolType & protocolType)326 int32_t ConnectionManagerListener::GetSessionProtocolType(int sessionId, ProtocolType &protocolType)
327 {
328     CLOGI("GetSessionProtocolType in");
329 
330     auto service = service_.promote();
331     if (!service) {
332         CLOGE("service is null");
333         return CAST_ENGINE_ERROR;
334     }
335 
336     sptr<ICastSessionImpl> session;
337     service->GetCastSession(std::to_string(sessionId), session);
338     if (!session) {
339         CLOGE("The session is null. Failed to obtain the session.");
340         return CAST_ENGINE_ERROR;
341     }
342     return session->GetSessionProtocolType(protocolType);
343 }
344 
SetSessionProtocolType(int sessionId,ProtocolType protocolType)345 int32_t ConnectionManagerListener::SetSessionProtocolType(int sessionId, ProtocolType protocolType)
346 {
347     CLOGI("SetSessionProtocolType in");
348 
349     auto service = service_.promote();
350     if (!service) {
351         CLOGE("service is null");
352         return CAST_ENGINE_ERROR;
353     }
354 
355     sptr<ICastSessionImpl> session;
356     service->GetCastSession(std::to_string(sessionId), session);
357     if (!session) {
358         CLOGE("The session is null. Failed to obtain the session.");
359         return CAST_ENGINE_ERROR;
360     }
361     session->SetSessionProtocolType(protocolType);
362     return CAST_ENGINE_SUCCESS;
363 }
364 
LoadSinkSA(const std::string & networkId)365 bool ConnectionManagerListener::LoadSinkSA(const std::string &networkId)
366 {
367     auto service = service_.promote();
368     if (!service) {
369         CLOGE("service is null");
370         return false;
371     }
372     return service->LoadSinkSA(networkId);
373 }
374 
RegisterListener(sptr<ICastServiceListenerImpl> listener)375 int32_t CastSessionManagerService::RegisterListener(sptr<ICastServiceListenerImpl> listener)
376 {
377     CLOGI("RegisterListener in");
378     HiSysEventWrite(CAST_ENGINE_DFX_DOMAIN_NAME, "CAST_ENGINE_EVE", HiviewDFX::HiSysEvent::EventType::STATISTIC,
379         "SEQUENTIAL_ID", CastEngineDfx::GetSequentialId(), "BIZ_PACKAGE_NAME", CastEngineDfx::GetBizPackageName());
380 
381     SharedWLock lock(mutex_);
382     if (listener == nullptr) {
383         CLOGE("RegisterListener failed, listener is null");
384         return CAST_ENGINE_ERROR;
385     }
386 
387     bool needInitMore = !HasListenerLocked();
388     if (!AddListenerLocked(listener)) {
389         return CAST_ENGINE_ERROR;
390     }
391 
392     if (needInitMore) {
393         if (!CheckAndWaitDevieManagerServiceInit()) {
394             CLOGE("Wait DM SA load timeout");
395             ReleaseLocked();
396             return CAST_ENGINE_ERROR;
397         }
398 
399         DiscoveryManager::GetInstance().Init(std::make_shared<DiscoveryManagerListener>(this));
400         ConnectionManager::GetInstance().Init(std::make_shared<ConnectionManagerListener>(this));
401         sessionMap_.clear();
402     }
403 
404     serviceStatus_ = ServiceStatus::CONNECTED;
405     CLOGI("RegisterListener out");
406     return CAST_ENGINE_SUCCESS;
407 }
408 
UnregisterListener()409 int32_t CastSessionManagerService::UnregisterListener()
410 {
411     SharedWLock lock(mutex_);
412     CLOGI("UnregisterListener in");
413 
414     return RemoveListenerLocked(IPCSkeleton::GetCallingPid());
415 }
416 
Release()417 int32_t CastSessionManagerService::Release()
418 {
419     SharedWLock lock(mutex_);
420     CLOGI("Release in");
421     if (!Permission::CheckPidPermission()) {
422         return ERR_NO_PERMISSION;
423     }
424 
425     return ReleaseLocked();
426 }
427 
ReleaseLocked()428 int32_t CastSessionManagerService::ReleaseLocked()
429 {
430     CLOGI("ReleaseLocked in");
431     serviceStatus_ = ServiceStatus::DISCONNECTED;
432     ReportServiceDieLocked();
433 
434     ClearListenersLocked();
435     DiscoveryManager::GetInstance().Deinit();
436     ConnectionManager::GetInstance().Deinit();
437     sessionMap_.clear();
438     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
439     if (samgr == nullptr) {
440         CLOGE("get samgr failed");
441         return CAST_ENGINE_ERROR;
442     }
443     int32_t ret = samgr->UnloadSystemAbility(CAST_ENGINE_SA_ID);
444     if (ret != ERR_OK) {
445         CLOGE("remove system ability failed");
446         return CAST_ENGINE_ERROR;
447     }
448     CLOGI("Release success done");
449     return CAST_ENGINE_SUCCESS;
450 }
451 
SetLocalDevice(const CastLocalDevice & localDevice)452 int32_t CastSessionManagerService::SetLocalDevice(const CastLocalDevice &localDevice)
453 {
454     CLOGD("SetLocalDevice in");
455     SharedWLock lock(mutex_);
456     if (!Permission::CheckPidPermission()) {
457         return ERR_NO_PERMISSION;
458     }
459     localDevice_ = localDevice;
460     return CAST_ENGINE_SUCCESS;
461 }
462 
GetCastSession(std::string sessionId,sptr<ICastSessionImpl> & castSession)463 int32_t CastSessionManagerService::GetCastSession(std::string sessionId, sptr<ICastSessionImpl> &castSession)
464 {
465     SharedRLock lock(mutex_);
466     if (!Permission::CheckPidPermission()) {
467         return ERR_NO_PERMISSION;
468     }
469 
470     auto session = GetCastSessionInner(sessionId);
471     if (session == nullptr) {
472         return ERR_SESSION_NOT_EXIST;
473     }
474     castSession = session;
475     return CAST_ENGINE_SUCCESS;
476 }
477 
GetCastSessionInner(std::string sessionId)478 sptr<ICastSessionImpl> CastSessionManagerService::GetCastSessionInner(std::string sessionId)
479 {
480     auto innerSessionId = Utils::StringToInt(sessionId);
481     auto it = sessionMap_.find(innerSessionId);
482     if (it == sessionMap_.end()) {
483         CLOGE("No sessionId=%{public}d session.", innerSessionId);
484         return nullptr;
485     }
486     return it->second;
487 }
488 
CreateCastSession(const CastSessionProperty & property,sptr<ICastSessionImpl> & castSession)489 int32_t CastSessionManagerService::CreateCastSession(const CastSessionProperty &property,
490     sptr<ICastSessionImpl> &castSession)
491 {
492     SharedWLock lock(mutex_);
493     CLOGI("CreateCastSession in, protocol:%{public}d, endType:%{public}d.", property.protocolType, property.endType);
494     if (serviceStatus_ != ServiceStatus::CONNECTED) {
495         CLOGE("not connected");
496         return ERR_SERVICE_STATE_NOT_MATCH;
497     }
498 
499     if (localDevice_.deviceId.empty()) {
500         CastLocalDevice local;
501         int32_t ret = ConnectionManager::GetInstance().GetLocalDeviceInfo(local);
502         if (ret != DM_OK) {
503             return ret;
504         }
505         localDevice_ = local;
506     }
507 
508     for (auto it = sessionMap_.begin(); it != sessionMap_.end();) {
509         ProtocolType protocolType;
510         if (it->second->GetSessionProtocolType(protocolType) == CAST_ENGINE_ERROR) {
511             CLOGE("GetSessionProtocolType failed");
512             return CAST_ENGINE_ERROR;
513         }
514         auto curSessionState = it->second->GetSessionState();
515         if (protocolType == ProtocolType::CAST_PLUS_MIRROR &&
516             property.protocolType == ProtocolType::CAST_PLUS_STREAM &&
517             curSessionState == static_cast<uint8_t>(SessionState::PLAYING)) {
518             CLOGI("MirrorSession exits, return mirrorSession.");
519             castSession = it->second;
520             return CAST_ENGINE_SUCCESS;
521         }
522         it++;
523     }
524 
525     return CAST_ENGINE_SUCCESS;
526 }
527 
DestroyCastSession(int32_t sessionId)528 bool CastSessionManagerService::DestroyCastSession(int32_t sessionId)
529 {
530     CLOGD("DestroyCastSession in");
531     sptr<ICastSessionImpl> session;
532     {
533         SharedWLock lock(mutex_);
534         auto it = sessionMap_.find(sessionId);
535         if (it == sessionMap_.end()) {
536             CLOGE("Cast session(%d) has gone.", sessionId);
537             return true;
538         }
539         session = it->second;
540         sessionMap_.erase(it);
541     }
542 
543     ConnectionManager::GetInstance().RemoveSessionListener(sessionId);
544     ConnectionManager::GetInstance().UpdateGrabState(false, -1);
545     session->Stop();
546     CLOGD("Session refcount is %d, session count:%zu", session->GetSptrRefCount(), sessionMap_.size());
547     return true;
548 }
549 
SetSinkSessionCapacity(int sessionCapacity)550 int32_t CastSessionManagerService::SetSinkSessionCapacity(int sessionCapacity)
551 {
552     CLOGD("SetSinkSessionCapacity in, sessionCapacity = %d", sessionCapacity);
553     SharedRLock lock(mutex_);
554     if (!Permission::CheckPidPermission()) {
555         return ERR_NO_PERMISSION;
556     }
557     sessionCapacity_ = sessionCapacity;
558     return CAST_ENGINE_SUCCESS;
559 }
560 
StartDiscovery(int protocols,std::vector<std::string> drmSchemes)561 int32_t CastSessionManagerService::StartDiscovery(int protocols, std::vector<std::string> drmSchemes)
562 {
563     CLOGI("StartDiscovery in, protocolType = %{public}d, drm shcheme size = %{public}zu", protocols, drmSchemes.size());
564 
565     DiscoveryManager::GetInstance().StartDiscovery(protocols, drmSchemes);
566     return CAST_ENGINE_SUCCESS;
567 }
568 
StopDiscovery()569 int32_t CastSessionManagerService::StopDiscovery()
570 {
571     CLOGI("StopDiscovery in");
572     SharedRLock lock(mutex_);
573     if (!Permission::CheckPidPermission()) {
574         return ERR_NO_PERMISSION;
575     }
576     DiscoveryManager::GetInstance().StopDiscovery();
577     return CAST_ENGINE_SUCCESS;
578 }
579 
StartDeviceLogging(int32_t fd,uint32_t maxSize)580 int32_t CastSessionManagerService::StartDeviceLogging(int32_t fd, uint32_t maxSize)
581 {
582     CLOGI("StartDeviceLogging in");
583     if (IPCSkeleton::GetCallingUid() != AV_SESSION_UID) {
584         if (fd >= 0) {
585             close(fd);
586         }
587         return static_cast<int32_t>(LogCodeId::UID_MISMATCH);
588     }
589 
590     // 待实现 DfxCastEngineStartDeviceLogging
591     return CAST_ENGINE_ERROR;
592 }
593 
SetDiscoverable(bool enable)594 int32_t CastSessionManagerService::SetDiscoverable(bool enable)
595 {
596     CLOGI("SetDiscoverable in, enable = %{public}d", enable);
597     SharedRLock lock(mutex_);
598     if (!Permission::CheckPidPermission()) {
599         return ERR_NO_PERMISSION;
600     }
601 
602     if (enable) {
603         if (ConnectionManager::GetInstance().EnableDiscoverable() &&
604             DiscoveryManager::GetInstance().StartAdvertise()) {
605             return CAST_ENGINE_SUCCESS;
606         }
607     } else {
608         if (ConnectionManager::GetInstance().DisableDiscoverable() &&
609             DiscoveryManager::GetInstance().StopAdvertise()) {
610             return CAST_ENGINE_SUCCESS;
611         }
612     }
613     return CAST_ENGINE_ERROR;
614 }
615 
ReleaseServiceResources(pid_t pid,uid_t uid)616 void CastSessionManagerService::ReleaseServiceResources(pid_t pid, uid_t uid)
617 {
618     {
619         SharedWLock lock(mutex_);
620         RemoveListenerLocked(pid);
621 
622         CLOGI("Release service resources");
623         for (auto it = sessionMap_.begin(); it != sessionMap_.end();) {
624             if (it->second->ReleaseSessionResources(pid, uid)) {
625                 sessionMap_.erase(it++);
626                 continue;
627             }
628             it++;
629         }
630         if (HasListenerLocked()) {
631             return;
632         }
633     }
634 
635     if (Release() != CAST_ENGINE_SUCCESS) {
636         CLOGE("Release service resources failed");
637     }
638 }
639 
AddClientDeathRecipientLocked(pid_t pid,uid_t uid,sptr<ICastServiceListenerImpl> listener)640 void CastSessionManagerService::AddClientDeathRecipientLocked(pid_t pid, uid_t uid,
641     sptr<ICastServiceListenerImpl> listener)
642 {
643     sptr<CastEngineClientDeathRecipient> deathRecipient(
644         new (std::nothrow) CastEngineClientDeathRecipient(wptr<CastSessionManagerService>(this), pid, uid));
645     if (deathRecipient == nullptr) {
646         CLOGE("Alloc death recipient filed");
647         return;
648     }
649     if (!listener->AsObject()->AddDeathRecipient(deathRecipient)) {
650         CLOGE("Add cast client death recipient failed");
651         return;
652     }
653     CLOGD("add death recipient pid:%d", pid);
654     deathRecipientMap_[pid] = deathRecipient;
655 }
656 
RemoveClientDeathRecipientLocked(pid_t pid,sptr<ICastServiceListenerImpl> listener)657 void CastSessionManagerService::RemoveClientDeathRecipientLocked(pid_t pid, sptr<ICastServiceListenerImpl> listener)
658 {
659     auto it = deathRecipientMap_.find(pid);
660     if (it != deathRecipientMap_.end()) {
661         listener->AsObject()->RemoveDeathRecipient(it->second);
662         deathRecipientMap_.erase(it);
663         CLOGD("remove death recipient pid:%d", pid);
664     }
665 }
666 
AddListenerLocked(sptr<ICastServiceListenerImpl> listener)667 bool CastSessionManagerService::AddListenerLocked(sptr<ICastServiceListenerImpl> listener)
668 {
669     pid_t pid = IPCSkeleton::GetCallingPid();
670     uid_t uid = static_cast<uid_t>(IPCSkeleton::GetCallingUid());
671     Permission::SavePid(pid);
672     if (listeners_.count(pid) == 0) {
673         listeners_[pid] = std::make_pair(listener, uid);
674         AddClientDeathRecipientLocked(pid, uid, listener);
675         return true;
676     }
677 
678     CLOGE("Listener of process(%u) has been registered.", pid);
679     return false;
680 }
681 
RemoveListenerLocked(pid_t pid)682 int32_t CastSessionManagerService::RemoveListenerLocked(pid_t pid)
683 {
684     Permission::RemovePid(pid);
685     int32_t ret = CAST_ENGINE_ERROR;
686     if (listeners_.count(pid) == 1) {
687         RemoveClientDeathRecipientLocked(pid, listeners_[pid].first);
688         listeners_.erase(pid);
689         ret = CAST_ENGINE_SUCCESS;
690     }
691 
692     if (listeners_.empty()) {
693         ReleaseLocked();
694     }
695 
696     return ret;
697 }
698 
ClearListenersLocked()699 void CastSessionManagerService::ClearListenersLocked()
700 {
701     listeners_.clear();
702     Permission::ClearPids();
703 }
704 
HasListenerLocked()705 bool CastSessionManagerService::HasListenerLocked()
706 {
707     return listeners_.size() > 0;
708 }
709 
ReportServiceDieLocked()710 void CastSessionManagerService::ReportServiceDieLocked()
711 {
712     pid_t pid = IPCSkeleton::GetCallingPid();
713     if (pid == myPid_) {
714         for (const auto &listener : listeners_) {
715             listener.second.first->OnServiceDied();
716         }
717         return;
718     }
719 
720     if (listeners_.count(pid) == 1) {
721         listeners_[pid].first->OnServiceDied();
722         return;
723     }
724 }
725 
ReportDeviceFound(const std::vector<std::pair<CastRemoteDevice,bool>> & deviceList)726 void CastSessionManagerService::ReportDeviceFound(const std::vector<std::pair<CastRemoteDevice, bool>> &deviceList)
727 {
728     CLOGI("ReportDeviceFound in");
729 
730     SharedRLock lock(mutex_);
731     for (const auto &listener : listeners_) {
732         std::vector<CastRemoteDevice> deviceInfo;
733         for (const auto &device : deviceList) {
734             if (listener.second.second == AV_SESSION_UID && !device.second) {
735                 CLOGI("device don't support stream capability, device name is %s", device.first.deviceName.c_str());
736                 continue;
737             }
738             if (listener.second.second != AV_SESSION_UID && device.first.deviceType == DeviceType::DEVICE_TYPE_2IN1) {
739                 CLOGI("No need to report hwcast , device name is %s", device.first.deviceName.c_str());
740                 continue;
741             }
742             deviceInfo.push_back(device.first);
743         }
744 
745         listener.second.first->OnDeviceFound(deviceInfo);
746     }
747 }
748 
ReportSessionCreate(const sptr<ICastSessionImpl> & castSession)749 void CastSessionManagerService::ReportSessionCreate(const sptr<ICastSessionImpl> &castSession)
750 {
751     SharedRLock lock(mutex_);
752     for (const auto &listener : listeners_) {
753         listener.second.first->OnSessionCreated(castSession);
754     }
755 }
756 
ReportDeviceOffline(const std::string & deviceId)757 void CastSessionManagerService::ReportDeviceOffline(const std::string &deviceId)
758 {
759     SharedRLock lock(mutex_);
760     for (const auto &listener : listeners_) {
761         listener.second.first->OnDeviceOffline(deviceId);
762     }
763 }
764 
LoadSinkSA(const std::string & networkId)765 bool CastSessionManagerService::LoadSinkSA(const std::string &networkId)
766 {
767     CLOGI("LoadSinkSA in");
768     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
769     if (samgr == nullptr) {
770         CLOGE("Failed to get SA manager");
771         return false;
772     }
773     sptr<CastServiceLoadCallback> loadCallback = new (std::nothrow) CastServiceLoadCallback();
774     if (loadCallback == nullptr) {
775         CLOGE("Failed to new object");
776         return false;
777     }
778 
779     constexpr int32_t sleepTimeMs = 30;
780     constexpr int32_t retryTimeMax = 150; // The service startup timeout interval is 4s.
781     int32_t result = samgr->LoadSystemAbility(CAST_ENGINE_SA_ID, networkId, loadCallback);
782     for (int32_t retryTime = 1; (result != ERR_OK) && (retryTime < retryTimeMax); ++retryTime) {
783         std::this_thread::sleep_for(std::chrono::milliseconds(sleepTimeMs));
784         result = samgr->LoadSystemAbility(CAST_ENGINE_SA_ID, networkId, loadCallback);
785         CLOGD("Attemp to reLoad SA for the %d time.", retryTime);
786     }
787 
788     if (result != ERR_OK) {
789         CLOGE("systemAbilityId: %d load failed, result code: %d", CAST_ENGINE_SA_ID, result);
790         return false;
791     } else {
792         CLOGI("Load sink SA success!");
793         return true;
794     }
795 }
796 
CheckAndWaitDevieManagerServiceInit()797 bool CastSessionManagerService::CheckAndWaitDevieManagerServiceInit()
798 {
799     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
800     if (samgr == nullptr) {
801         CLOGE("get samgr failed");
802         return false;
803     }
804     constexpr int32_t sleepTimeMs = 50;
805     constexpr int32_t retryTimes = 200;
806     int32_t retryTime = 0;
807 
808     while (samgr->CheckSystemAbility(DEVICE_MANAGER_SA_ID) == nullptr && (retryTime < retryTimes)) {
809         std::this_thread::sleep_for(std::chrono::milliseconds(sleepTimeMs));
810         retryTime++;
811     }
812     CLOGI("retryTime:%{public}d", retryTime);
813 
814     return retryTime < retryTimes;
815 }
816 
OnRemoteDied(const wptr<IRemoteObject> & object)817 void CastSessionManagerService::CastEngineClientDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
818 {
819     CLOGI("Client died, need release resources, client pid_: %{public}d", pid_);
820     sptr<CastSessionManagerService> service = service_.promote();
821     std::string bundleName;
822     AppExecFwk::BundleMgrClient client;
823     if (client.GetNameForUid(uid_, bundleName) != ERR_OK) {
824         CLOGE("GetBundleNameByUid failed");
825     }
826 
827     if (service == nullptr) {
828         CLOGE("ServiceStub is nullptr");
829         return;
830     }
831     service->ReleaseServiceResources(pid_, uid_);
832 }
833 
OnLoadSystemAbilitySuccess(int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)834 void CastSessionManagerService::CastServiceLoadCallback::OnLoadSystemAbilitySuccess(
835     int32_t systemAbilityId, const sptr<IRemoteObject> &remoteObject)
836 {
837     CLOGI("In systemAbilityId: %d", systemAbilityId);
838 
839     if (systemAbilityId != CAST_ENGINE_SA_ID) {
840         CLOGE("Start aystemabilityId is not sinkSAId!");
841         return;
842     }
843 
844     if (remoteObject == nullptr) {
845         CLOGE("RemoteObject is nullptr.");
846         return;
847     }
848 }
849 
OnLoadSystemAbilityFail(int32_t systemAbilityId)850 void CastSessionManagerService::CastServiceLoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId)
851 {
852     CLOGI("In systemAbilityId: %d.", systemAbilityId);
853 
854     if (systemAbilityId != CAST_ENGINE_SA_ID) {
855         CLOGE("Start aystemabilityId is not sinkSAId!");
856         return;
857     }
858 }
859 } // namespace CastEngineService
860 } // namespace CastEngine
861 } // namespace OHOS
862