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