/* * Copyright (c) 2023-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "avrouter_impl.h" #include "ipc_skeleton.h" #include "avsession_errors.h" #include "avsession_log.h" #include "avsession_trace.h" #include "permission_checker.h" #include "avcast_provider_manager.h" #include "avsession_sysevent.h" #include "collaboration_manager_urlcasting.h" #include "collaboration_manager_hiplay.h" #include "cJSON.h" #ifdef DEVICE_MANAGER_ENABLE #include "device_manager.h" #endif namespace OHOS::AVSession { AVRouterImpl::AVRouterImpl() { SLOGD("AVRouter construct"); } AVRouterImpl::~AVRouterImpl() { SLOGD("AVRouter destruct"); } int32_t AVRouterImpl::GetLocalDeviceType() { int32_t deviceType = -1; #ifdef DEVICE_MANAGER_ENABLE int32_t ret = DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceType("av_session", deviceType); CHECK_AND_RETURN_RET_LOG(ret == 0, deviceType, "get local device type failed with ret:%{public}d", ret); #endif return deviceType; } int32_t AVRouterImpl::Init(IAVSessionServiceListener *servicePtr) { SLOGI("Start init AVRouter"); deviceType_ = GetLocalDeviceType(); { std::lock_guard lockGuard(servicePtrLock_); servicePtr_ = servicePtr; } castSessionListener_ = std::make_shared(this); auto hwProvider = std::make_shared(); if (hwProvider != nullptr && hwProvider->Init() != AVSESSION_ERROR) { SLOGI("init pvd success"); } else { SLOGE("init with null pvd to init"); return AVSESSION_ERROR; } providerNumber_ = providerNumberEnableDefault_; std::shared_ptr avCastProviderManager = std::make_shared(); if (avCastProviderManager == nullptr) { SLOGE("init with null manager"); return AVSESSION_ERROR; } avCastProviderManager->Init(providerNumber_, hwProvider); { std::lock_guard lockGuard(providerManagerLock_); hwProvider_ = hwProvider; providerManagerMap_[providerNumber_] = avCastProviderManager; } hwProvider->RegisterCastStateListener(avCastProviderManager); std::lock_guard lockGuard(providerManagerLock_); if (cacheStartDiscovery_) { SLOGI("cacheStartDiscovery check do discovery"); StartCastDiscovery(cacheCastDeviceCapability_, cacheDrmSchemes_); cacheStartDiscovery_ = false; } SLOGI("init AVRouter done"); return AVSESSION_SUCCESS; } bool AVRouterImpl::Release() { SLOGI("Start Release AVRouter"); std::shared_ptr hwProvider; { std::lock_guard lockGuard(providerManagerLock_); if (hwProvider_ == nullptr) { SLOGE("Start Release AVRouter err for no provider"); return false; } SLOGI("repeat check for pvd alive"); hwProvider = hwProvider_; hwProvider_ = nullptr; providerNumber_ = providerNumberDisable_; providerManagerMap_.clear(); } hwProvider->Release(); { std::lock_guard castHandleLockGuard(castHandleToInfoMapLock_); castHandleToInfoMap_.clear(); } SLOGD("Release AVRouter done"); return false; } std::shared_ptr AVRouterImpl::GetCastProvider(int32_t providerNumber) { std::lock_guard lockGuard(providerManagerLock_); auto iter = providerManagerMap_.find(providerNumber); CHECK_AND_RETURN_RET_LOG(iter != providerManagerMap_.end() && iter->second != nullptr && iter->second->provider_ != nullptr, nullptr, "providerNumber %{public}d is invalid", providerNumber); return iter->second->provider_; } std::shared_ptr AVRouterImpl::GetHwProvider() { std::lock_guard lockGuard(providerManagerLock_); return hwProvider_; } int32_t AVRouterImpl::StartDeviceLogging(int32_t fd, uint32_t maxSize) { SLOGI("AVRouterImpl StartDeviceLogging"); std::lock_guard lockGuard(providerManagerLock_); if (providerManagerMap_.empty()) { cacheStartDeviceLogging_ = true; return AVSESSION_SUCCESS; } for (const auto& [number, providerManager] : providerManagerMap_) { CHECK_AND_RETURN_RET_LOG(providerManager != nullptr && providerManager->provider_ != nullptr, AVSESSION_ERROR, "provider is nullptr"); providerManager->provider_->StartDeviceLogging(fd, maxSize); } return AVSESSION_SUCCESS; } int32_t AVRouterImpl::StopDeviceLogging() { SLOGI("AVRouterImpl StopDeviceLogging"); std::lock_guard lockGuard(providerManagerLock_); if (cacheStartDeviceLogging_) { SLOGI("clear cacheStartDeviceLogging_ when stop discovery"); cacheStartDeviceLogging_ = false; } for (const auto& [number, providerManager] : providerManagerMap_) { CHECK_AND_RETURN_RET_LOG(providerManager != nullptr && providerManager->provider_ != nullptr, AVSESSION_ERROR, "provider is nullptr"); providerManager->provider_->StopDeviceLogging(); } return AVSESSION_SUCCESS; } int32_t AVRouterImpl::StartCastDiscovery(int32_t castDeviceCapability, std::vector drmSchemes) { SLOGI("AVRouterImpl StartCastDiscovery"); std::lock_guard lockGuard(providerManagerLock_); auto pid = IPCSkeleton::GetCallingPid(); cacheStartDiscoveryPids_.insert(pid); cacheCastDeviceCapability_ = castDeviceCapability; cacheDrmSchemes_ = drmSchemes; if (providerManagerMap_.empty()) { SLOGI("set cacheStartDiscovery with no element with cap %{public}d", static_cast(castDeviceCapability)); cacheStartDiscovery_ = true; return AVSESSION_SUCCESS; } for (const auto& [number, providerManager] : providerManagerMap_) { CHECK_AND_RETURN_RET_LOG(providerManager != nullptr && providerManager->provider_ != nullptr, AVSESSION_ERROR, "provider is nullptr"); providerManager->provider_->StartDiscovery(castDeviceCapability, drmSchemes); } return AVSESSION_SUCCESS; } int32_t AVRouterImpl::StopCastDiscovery() { SLOGI("AVRouterImpl StopCastDiscovery"); std::lock_guard lockGuard(providerManagerLock_); auto pid = IPCSkeleton::GetCallingPid(); CHECK_AND_RETURN_RET_LOG(IsStopCastDiscovery(pid), AVSESSION_SUCCESS, "StartCastDiscovery is still in use, no need to stop"); if (cacheStartDiscovery_) { SLOGI("clear cacheStartDiscovery when stop discovery"); cacheStartDiscovery_ = false; } for (const auto& [number, providerManager] : providerManagerMap_) { CHECK_AND_RETURN_RET_LOG(providerManager != nullptr && providerManager->provider_ != nullptr, AVSESSION_ERROR, "provider is nullptr"); providerManager->provider_->StopDiscovery(); } return AVSESSION_SUCCESS; } bool AVRouterImpl::IsStopCastDiscovery(pid_t pid) { std::lock_guard lockGuard(providerManagerLock_); if (cacheStartDiscoveryPids_.find(pid) != cacheStartDiscoveryPids_.end()) { cacheStartDiscoveryPids_.erase(pid); if (cacheStartDiscoveryPids_.empty()) { return true; } else { SLOGI("other pid is not calling StopCastDiscovery"); } } else { SLOGI("pid:%{public}d is not include in cacheStartDiscoveryPids", static_cast(pid)); } return false; } int32_t AVRouterImpl::SetDiscoverable(const bool enable) { SLOGI("AVRouterImpl SetDiscoverable %{public}d", enable); std::lock_guard lockGuard(providerManagerLock_); for (const auto& [number, providerManager] : providerManagerMap_) { CHECK_AND_RETURN_RET_LOG(providerManager != nullptr && providerManager->provider_ != nullptr, AVSESSION_ERROR, "provider is nullptr"); providerManager->provider_->SetDiscoverable(enable); } return AVSESSION_SUCCESS; } int32_t AVRouterImpl::OnDeviceAvailable(OutputDeviceInfo& castOutputDeviceInfo) { SLOGI("AVRouterImpl received OnDeviceAvailable event"); std::lock_guard lockGuard(servicePtrLock_); if (servicePtr_ == nullptr) { return ERR_SERVICE_NOT_EXIST; } std::lock_guard validDeviceInfoMapLockGuard(validDeviceInfoMapLock_); for (const DeviceInfo& deviceInfo : castOutputDeviceInfo.deviceInfos_) { validDeviceInfoMap_[deviceInfo.deviceId_] = deviceInfo; } servicePtr_->NotifyDeviceAvailable(castOutputDeviceInfo); return AVSESSION_SUCCESS; } int32_t AVRouterImpl::OnDeviceLogEvent(const DeviceLogEventCode eventId, const int64_t param) { SLOGI("AVRouterImpl received OnDeviceLogEvent event"); std::lock_guard lockGuard(servicePtrLock_); if (servicePtr_ == nullptr) { return ERR_SERVICE_NOT_EXIST; } servicePtr_->NotifyDeviceLogEvent(eventId, param); return AVSESSION_SUCCESS; } void AVRouterImpl::ReleaseCurrentCastSession() { SLOGI("Start ReleaseCurrentCastSession"); std::lock_guard lockGuard(servicePtrLock_); CHECK_AND_RETURN_LOG(servicePtr_ != nullptr, "servicePtr_ is nullptr"); servicePtr_->ReleaseCastSession(); } int32_t AVRouterImpl::OnCastSessionCreated(const int32_t castId) { SLOGI("AVRouterImpl On cast session created, cast id is %{public}d", castId); int64_t castHandle = -1; CHECK_AND_RETURN_RET_LOG(GetCastProvider(providerNumberEnableDefault_) != nullptr, castHandle, "provider is nullptr"); int64_t tempId = 1; // The first 32 bits are providerId, the last 32 bits are castId castHandle = static_cast((static_cast(tempId) << 32) | static_cast(castId)); CastHandleInfo castHandleInfo; OutputDeviceInfo outputDeviceInfo; castHandleInfo.outputDeviceInfo_ = outputDeviceInfo; { std::lock_guard lockGuard(castHandleToInfoMapLock_); castHandleToInfoMap_.clear(); castHandleToInfoMap_[castHandle] = castHandleInfo; } { std::lock_guard lockGuard(servicePtrLock_); servicePtr_->CreateSessionByCast(castHandle); } return AVSESSION_SUCCESS; } int32_t AVRouterImpl::OnDeviceOffline(const std::string& deviceId) { SLOGI("AVRouterImpl received OnDeviceOffline event"); std::lock_guard lockGuard(servicePtrLock_); if (servicePtr_ == nullptr) { return ERR_SERVICE_NOT_EXIST; } std::lock_guard validDeviceInfoMapLockGuard(validDeviceInfoMapLock_); validDeviceInfoMap_.erase(deviceId); servicePtr_->NotifyDeviceOffline(deviceId); return AVSESSION_SUCCESS; } int32_t AVRouterImpl::OnSystemCommonEvent(const std::string& commonEvent, const std::string& args) { SLOGI("AVRouterImpl received OnSystemCommonEvent event"); std::lock_guard lockGuard(servicePtrLock_); if (servicePtr_ == nullptr) { return ERR_SERVICE_NOT_EXIST; } servicePtr_->NotifySystemCommonEvent(commonEvent, args); return AVSESSION_SUCCESS; } int32_t AVRouterImpl::OnDeviceStateChange(const DeviceState& deviceState) { SLOGI("AVRouterImpl received OnDeviceStateChange event"); std::lock_guard lockGuard(servicePtrLock_); if (servicePtr_ == nullptr) { return ERR_SERVICE_NOT_EXIST; } servicePtr_->NotifyDeviceStateChange(deviceState); return AVSESSION_SUCCESS; } int32_t AVRouterImpl::OnCastServerDied(int32_t providerNumber) { SLOGI("AVRouterImpl received OnCastServerDied event %{public}d", providerNumber); { std::lock_guard lockGuard(servicePtrLock_); if (servicePtr_ == nullptr) { return ERR_SERVICE_NOT_EXIST; } servicePtr_->setInCast(false); std::lock_guard validDeviceInfoMapLockGuard(validDeviceInfoMapLock_); for (const auto& [deviceId, deviceInfo] : validDeviceInfoMap_) { servicePtr_->NotifyDeviceOffline(deviceId); } validDeviceInfoMap_.clear(); } #ifdef DEVICE_MANAGER_ENABLE { std::lock_guard lockGuard(providerManagerLock_); providerNumber_ = providerNumberDisable_; providerManagerMap_.clear(); } DeviceInfo deviceInfo(AVCastCategory::CATEGORY_LOCAL, "-1", "RemoteCast"); OnCastStateChange(disconnectStateFromCast_, deviceInfo, noReasonCode_); { std::lock_guard castHandleLockGuard(castHandleToInfoMapLock_); castHandleToInfoMap_.clear(); } CHECK_AND_RETURN_RET(deviceType_ == DistributedHardware::DmDeviceType::DEVICE_TYPE_PHONE, AVSESSION_SUCCESS); std::this_thread::sleep_for(std::chrono::milliseconds(castEngineServiceRestartWaitTime)); StartCastDiscovery(cacheCastDeviceCapability_, cacheDrmSchemes_); { std::lock_guard lockGuard(servicePtrLock_); if (servicePtr_ != nullptr) { servicePtr_->checkEnableCast(true); } } #endif return AVSESSION_SUCCESS; } std::shared_ptr AVRouterImpl::GetRemoteController(const int64_t castHandle) { SLOGI("AVRouterImpl start get remote controller process"); // The first 32 bits are providerId, the last 32 bits are castId int32_t providerNumber = static_cast(static_cast(castHandle) >> 32); SLOGD("Get remote controller of provider %{public}d", providerNumber); // The first 32 bits are providerId, the last 32 bits are castId int32_t castId = static_cast((static_cast(castHandle) << 32) >> 32); std::shared_ptr provider = GetCastProvider(providerNumber); CHECK_AND_RETURN_RET_LOG(provider != nullptr, nullptr, "provider is nullptr"); { std::lock_guard lockGuard(castHandleToInfoMapLock_); for (const auto& [number, castHandleInfo] : castHandleToInfoMap_) { if (number == castHandle && castHandleInfo.avCastControllerProxy_ != nullptr) { return castHandleInfo.avCastControllerProxy_; } } if (castHandleToInfoMap_.find(castHandle) != castHandleToInfoMap_.end()) { castHandleToInfoMap_[castHandle].avCastControllerProxy_ = provider->GetRemoteController(castId); } } return provider->GetRemoteController(castId); } int64_t AVRouterImpl::StartCast(const OutputDeviceInfo& outputDeviceInfo, std::pair& serviceNameStatePair, std::string sessionId) { castSide_ = CAST_SIDE::CAST_SOURCE; SLOGI("AVRouterImpl start cast process"); castServiceNameStatePair_ = serviceNameStatePair; int64_t castHandle = -1; std::shared_ptr provider = GetCastProvider(outputDeviceInfo.deviceInfos_[0].providerId_); CHECK_AND_RETURN_RET_LOG(provider != nullptr, castHandle, "provider is nullptr"); { std::lock_guard lockGuard(castHandleToInfoMapLock_); for (const auto& [number, castHandleInfo] : castHandleToInfoMap_) { if (castHandleInfo.sessionId_ != sessionId && castHandleInfo.outputDeviceInfo_.deviceInfos_.size() > 0 && castHandleInfo.outputDeviceInfo_.deviceInfos_[0].deviceId_ == outputDeviceInfo.deviceInfos_[0].deviceId_) { castHandleToInfoMap_[number].sessionId_ = sessionId; return number; } } } bool isPcm = sessionId == pcmCastSession; int32_t castId = provider->StartCastSession( static_cast(outputDeviceInfo.deviceInfos_[0].supportedProtocols_), isPcm); CHECK_AND_RETURN_RET_LOG(castId != AVSESSION_ERROR, AVSESSION_ERROR, "StartCast failed"); int64_t tempId = outputDeviceInfo.deviceInfos_[0].providerId_; // The first 32 bits are providerId, the last 32 bits are castId castHandle = static_cast((static_cast(tempId) << 32) | static_cast(castId)); CastHandleInfo castHandleInfo; castHandleInfo.sessionId_ = sessionId; OutputDeviceInfo localDevice; DeviceInfo localInfo; localInfo.castCategory_ = AVCastCategory::CATEGORY_LOCAL; localInfo.deviceId_ = "-1"; localInfo.deviceName_ = "LocalDevice"; localDevice.deviceInfos_.emplace_back(localInfo); castHandleInfo.outputDeviceInfo_ = localDevice; { std::lock_guard lockGuard(castHandleToInfoMapLock_); castHandleToInfoMap_[castHandle] = castHandleInfo; } return castHandle; } int32_t AVRouterImpl::AddDevice(const int32_t castId, const OutputDeviceInfo& outputDeviceInfo, uint32_t spid) { SLOGI("AVRouterImpl AddDevice process"); int64_t tempId = outputDeviceInfo.deviceInfos_[0].providerId_; int64_t castHandle = static_cast((static_cast(tempId) << 32) | static_cast(castId)); { std::lock_guard lockGuard(castHandleToInfoMapLock_); for (const auto& [number, castHandleInfo] : castHandleToInfoMap_) { if (castHandle == number && castHandleInfo.outputDeviceInfo_.deviceInfos_.size() > 0 && castHandleInfo.outputDeviceInfo_.deviceInfos_[0].deviceId_ == outputDeviceInfo.deviceInfos_[0].deviceId_) { return AVSESSION_SUCCESS; } } } std::shared_ptr provider = GetCastProvider(outputDeviceInfo.deviceInfos_[0].providerId_); CHECK_AND_RETURN_RET_LOG(provider != nullptr, AVSESSION_ERROR, "provider is nullptr"); bool ret = provider->AddCastDevice(castId, outputDeviceInfo.deviceInfos_[0], spid); HILOG_COMM_INFO("AVRouterImpl AddDevice process with ret %{public}d", static_cast(ret)); std::lock_guard lockGuard(castHandleToInfoMapLock_); if (ret && castHandleToInfoMap_.find(castHandle) != castHandleToInfoMap_.end()) { castHandleToInfoMap_[castHandle].outputDeviceInfo_ = outputDeviceInfo; } return ret ? AVSESSION_SUCCESS : ERR_DEVICE_CONNECTION_FAILED; } int32_t AVRouterImpl::AddDeviceWithConnectionConfig(const int32_t castId, const OutputDeviceInfo& outputDeviceInfo, uint32_t spid, CastEngine::ConnectionConfig connectionConfig) { SLOGI("AVRouterImpl AddDeviceWithConnectionConfig process"); int64_t tempId = outputDeviceInfo.deviceInfos_[0].providerId_; int64_t castHandle = static_cast((static_cast(tempId) << 32) | static_cast(castId)); { std::lock_guard lockGuard(castHandleToInfoMapLock_); for (const auto& [number, castHandleInfo] : castHandleToInfoMap_) { if (castHandle == number && castHandleInfo.outputDeviceInfo_.deviceInfos_.size() > 0 && castHandleInfo.outputDeviceInfo_.deviceInfos_[0].deviceId_ == outputDeviceInfo.deviceInfos_[0].deviceId_) { return AVSESSION_SUCCESS; } } } std::shared_ptr provider = GetCastProvider(outputDeviceInfo.deviceInfos_[0].providerId_); CHECK_AND_RETURN_RET_LOG(provider != nullptr, AVSESSION_ERROR, "provider is nullptr"); bool ret = provider->AddCastDeviceWithConnectionConfig(castId, outputDeviceInfo.deviceInfos_[0], spid, connectionConfig); SLOGI("AVRouterImpl AddDeviceWithConnectionConfig process with ret %{public}d", static_cast(ret)); std::lock_guard lockGuard(castHandleToInfoMapLock_); if (ret && castHandleToInfoMap_.find(castHandle) != castHandleToInfoMap_.end()) { castHandleToInfoMap_[castHandle].outputDeviceInfo_ = outputDeviceInfo; } return ret ? AVSESSION_SUCCESS : ERR_DEVICE_CONNECTION_FAILED; } int32_t AVRouterImpl::StopCast(const int64_t castHandle, const DeviceRemoveAction deviceRemoveAction) { SLOGI("AVRouterImpl stop cast process"); int32_t providerNumber = static_cast(static_cast(castHandle) >> 32); SLOGI("Stop cast, the provider number is %{public}d", providerNumber); // The first 32 bits are providerId, the last 32 bits are castId int32_t castId = static_cast((static_cast(castHandle) << 32) >> 32); SLOGI("Stop cast, the castId is %{public}d", castId); std::shared_ptr provider = GetCastProvider(providerNumber); CHECK_AND_RETURN_RET_LOG(provider != nullptr, castHandle, "provider is nullptr"); DeviceInfo deviceInfo; { std::lock_guard lockGuard(castHandleToInfoMapLock_); CHECK_AND_RETURN_RET_LOG(castHandleToInfoMap_.find(castHandle) != castHandleToInfoMap_.end(), AVSESSION_ERROR, "Can not find corresponding castHandle"); CHECK_AND_RETURN_RET_LOG(castHandleToInfoMap_[castHandle].outputDeviceInfo_.deviceInfos_.size() > 0, AVSESSION_ERROR, "deviceInfos is empty"); deviceInfo = castHandleToInfoMap_[castHandle].outputDeviceInfo_.deviceInfos_[0]; } provider->RemoveCastDevice(castId, deviceInfo, deviceRemoveAction); SLOGI("AVRouterImpl stop cast process remove device done"); { std::lock_guard lockGuard(castHandleToInfoMapLock_); if (castHandleToInfoMap_.find(castHandle) != castHandleToInfoMap_.end()) { OutputDeviceInfo localDevice; DeviceInfo localInfo; localInfo.castCategory_ = AVCastCategory::CATEGORY_LOCAL; localInfo.deviceId_ = "-1"; localInfo.deviceName_ = "LocalDevice"; localDevice.deviceInfos_.emplace_back(localInfo); castHandleToInfoMap_[castHandle].outputDeviceInfo_ = localDevice; } } return AVSESSION_SUCCESS; } int32_t AVRouterImpl::StopCastSession(const int64_t castHandle) { SLOGI("AVRouterImpl stop cast session"); isInMirrorToStream_ = false; isRemoteCasting_ = false; castSide_ = CAST_SIDE::DEFAULT; int32_t providerNumber = static_cast(static_cast(castHandle) >> 32); std::shared_ptr provider = GetCastProvider(providerNumber); CHECK_AND_RETURN_RET_LOG(provider != nullptr, castHandle, "provider is nullptr"); // The first 32 bits are providerId, the last 32 bits are castId int32_t castId = static_cast((static_cast(castHandle) << 32) >> 32); provider->StopCastSession(castId); { std::lock_guard castHandleLockGuard(castHandleToInfoMapLock_); CHECK_AND_RETURN_RET_LOG(castHandleToInfoMap_.find(castHandle) != castHandleToInfoMap_.end(), AVSESSION_ERROR, "Can not find corresponding castHandle"); for (const auto& [number, castHandleInfo] : castHandleToInfoMap_) { if (number == castHandle) { castHandleToInfoMap_[number].avCastControllerProxy_ = nullptr; } } } return AVSESSION_SUCCESS; } int32_t AVRouterImpl::SetServiceAllConnectState(int64_t castHandle, DeviceInfo deviceInfo) { int64_t realCastHandle = castHandle == noMirrorCastHandle_ ? GetMirrorCastHandle() : castHandle; { std::lock_guard lockGuard(castHandleToInfoMapLock_); if (castHandleToInfoMap_.find(realCastHandle) != castHandleToInfoMap_.end()) { OutputDeviceInfo device; device.deviceInfos_.emplace_back(deviceInfo); castHandleToInfoMap_[realCastHandle].outputDeviceInfo_ = device; } } std::shared_ptr provider = GetCastProvider(providerNumberEnableDefault_); CHECK_AND_RETURN_RET_LOG(provider != nullptr, AVSESSION_ERROR, "provider is nullptr"); provider->SetStreamState(castHandle, deviceInfo); return AVSESSION_SUCCESS; } int32_t AVRouterImpl::GetRemoteNetWorkId(int64_t castHandle, std::string deviceId, std::string &networkId) { int32_t providerNumber = static_cast(static_cast(castHandle) >> 32); int32_t castId = static_cast((static_cast(castHandle) << 32) >> 32); std::shared_ptr provider = GetCastProvider(providerNumber); CHECK_AND_RETURN_RET_LOG(provider != nullptr, AVSESSION_ERROR, "provider is nullptr"); provider->GetRemoteNetWorkId(castId, deviceId, networkId); return AVSESSION_SUCCESS; } int32_t AVRouterImpl::GetRemoteDrmCapabilities(int64_t castHandle, std::string deviceId, std::vector &drmCapabilities) { int32_t providerNumber = static_cast(static_cast(castHandle) >> 32); int32_t castId = static_cast((static_cast(castHandle) << 32) >> 32); std::shared_ptr provider = GetCastProvider(providerNumber); CHECK_AND_RETURN_RET_LOG(provider != nullptr, AVSESSION_ERROR, "provider is nullptr"); provider->GetRemoteDrmCapabilities(castId, deviceId, drmCapabilities); return AVSESSION_SUCCESS; } void AVRouterImpl::RegisterStashCallback(int64_t castHandle, const std::shared_ptr callback, std::string sessionId) { SLOGI("AVRouterImpl register stash callback to provider"); std::lock_guard lockGuard(castHandleToInfoMapLock_); castHandleToInfoMap_[castHandle].avRouterListener_ = callback; castHandleToInfoMap_[castHandle].sessionId_ = sessionId; } int32_t AVRouterImpl::RegisterCallback(int64_t castHandle, const std::shared_ptr callback, std::string sessionId, DeviceInfo deviceInfo) { SLOGI("AVRouterImpl register IAVRouterListener callback to provider"); // The first 32 bits are providerId, the last 32 bits are castId int32_t providerNumber = static_cast(static_cast(castHandle) >> 32); // The first 32 bits are providerId, the last 32 bits are castId int32_t castId = static_cast((static_cast(castHandle) << 32) >> 32); std::shared_ptr provider = GetCastProvider(providerNumber); CHECK_AND_RETURN_RET_LOG(provider != nullptr, AVSESSION_ERROR, "provider is nullptr"); if (GetMirrorCastHandle() == noMirrorCastHandle_) { std::lock_guard lockGuard(castHandleToInfoMapLock_); for (const auto& [number, castHandleInfo] : castHandleToInfoMap_) { if (number == castHandle && castHandleInfo.outputDeviceInfo_.deviceInfos_.size() > 0 && castHandleInfo.avRouterListener_ != nullptr) { SLOGI("trigger the OnCastStateChange for disconnected/connected avRouterListener"); castHandleInfo.avRouterListener_->OnCastStateChange(disconnectStateFromCast_, castHandleInfo.outputDeviceInfo_.deviceInfos_[0], false, noReasonCode_); castHandleToInfoMap_[castHandle].avRouterListener_ = callback; callback->OnCastStateChange(connectStateFromCast_, castHandleInfo.outputDeviceInfo_.deviceInfos_[0], false, noReasonCode_); return AVSESSION_SUCCESS; } } if (castHandleToInfoMap_.find(castHandle) != castHandleToInfoMap_.end()) { castHandleToInfoMap_[castHandle].avRouterListener_ = callback; castHandleToInfoMap_[castHandle].sessionId_ = sessionId; } provider->RegisterCastSessionStateListener(castId, castSessionListener_); } else { std::lock_guard lockGuard(castHandleToInfoMapLock_); if (castHandleToInfoMap_.find(castHandle) != castHandleToInfoMap_.end() && castHandleToInfoMap_[castHandle].avRouterListener_ == nullptr) { provider->RegisterCastSessionStateListener(castId, castSessionListener_); OutputDeviceInfo outputDevice; outputDevice.deviceInfos_.emplace_back(deviceInfo); castHandleToInfoMap_[castHandle].outputDeviceInfo_ = outputDevice; castHandleToInfoMap_[castHandle].avRouterListener_ = callback; castHandleToInfoMap_[castHandle].sessionId_ = sessionId; } else { mirrorSessionMap_[sessionId] = callback; } callback->OnCastStateChange(connectStateFromCast_, deviceInfo, false, noReasonCode_); } SLOGD("AVRouter impl register callback finished"); return AVSESSION_SUCCESS; } int32_t AVRouterImpl::UnRegisterCallback(int64_t castHandle, const std::shared_ptr callback, std::string sessionId) { SLOGI("AVRouterImpl UnRegisterCallback IAVRouterListener callback to provider"); // The first 32 bits are providerId, the last 32 bits are castId int32_t providerNumber = static_cast(static_cast(castHandle)) >> 32; // The first 32 bits are providerId, the last 32 bits are castId int32_t castId = static_cast((static_cast(castHandle) << 32) >> 32); std::shared_ptr provider = GetCastProvider(providerNumber); CHECK_AND_RETURN_RET_LOG(provider != nullptr, AVSESSION_ERROR, "provider is nullptr"); { std::lock_guard lockGuard(castHandleToInfoMapLock_); for (const auto& [number, castHandleInfo] : castHandleToInfoMap_) { if (castHandleInfo.sessionId_ == sessionId && number == castHandle) { provider->UnRegisterCastSessionStateListener(castId, castSessionListener_); castHandleToInfoMap_[number].avRouterListener_ = nullptr; } } if (mirrorSessionMap_.find(sessionId) != mirrorSessionMap_.end()) { mirrorSessionMap_.erase(sessionId); } } return AVSESSION_SUCCESS; } int64_t AVRouterImpl::GetMirrorCastHandle() { std::lock_guard lockGuard(providerManagerLock_); CHECK_AND_RETURN_RET_LOG(providerManagerMap_.find(providerNumberEnableDefault_) != providerManagerMap_.end(), providerNumberEnableDefault_, "providerNull"); CHECK_AND_RETURN_RET_LOG(providerManagerMap_[providerNumberEnableDefault_] != nullptr && providerManagerMap_[providerNumberEnableDefault_]->provider_ != nullptr, AVSESSION_ERROR, "provider is nullptr"); return providerManagerMap_[providerNumberEnableDefault_]->provider_->GetMirrorCastHandle(); } bool AVRouterImpl::IsInMirrorToStreamState() { return isInMirrorToStream_; } void AVRouterImpl::SetMirrorCastHandle(int64_t castHandle) { std::shared_ptr hwProvider = GetHwProvider(); CHECK_AND_RETURN_LOG(hwProvider != nullptr, "hwProvider_ is nullptr"); hwProvider->SetMirrorCastHandle(castHandle); } std::string AVRouterImpl::GetMirrorDeviceId() { std::string castHandleDeviceId = "-100"; int64_t mirrorCastHandle = GetMirrorCastHandle(); std::lock_guard lockGuard(castHandleToInfoMapLock_); if (castHandleToInfoMap_.find(mirrorCastHandle) != castHandleToInfoMap_.end() && castHandleToInfoMap_[mirrorCastHandle].outputDeviceInfo_.deviceInfos_.size() > 0) { castHandleDeviceId = castHandleToInfoMap_[mirrorCastHandle].outputDeviceInfo_.deviceInfos_[0].deviceId_; } return castHandleDeviceId; } void AVRouterImpl::SetSinkCastSessionInfo(const AAFwk::Want &want) { std::string deviceInfoStr = want.GetStringParam("deviceInfo"); cJSON* deviceInfo = cJSON_Parse(deviceInfoStr.c_str()); bool deviceInfoFlag = (deviceInfo == nullptr) || cJSON_IsInvalid(deviceInfo) || cJSON_IsNull(deviceInfo); if (deviceInfoFlag) { SLOGE("deviceInfo parse is not valid json"); cJSON_Delete(deviceInfo); return; } cJSON* deviceIdItem = cJSON_GetObjectItem(deviceInfo, "deviceId"); CHECK_AND_PRINT_LOG(deviceIdItem != nullptr, "deviceIdItem is nullptr"); bool deviceIdItemFlag = (deviceIdItem != nullptr) && !cJSON_IsInvalid(deviceIdItem) && !cJSON_IsNull(deviceIdItem) && cJSON_IsString(deviceIdItem) && deviceIdItem->valuestring != nullptr; sourceDeviceId_ = deviceIdItemFlag ? std::string(deviceIdItem->valuestring) : ""; cJSON* protocolTypeItem = cJSON_GetObjectItem(deviceInfo, "protocolType"); CHECK_AND_PRINT_LOG(protocolTypeItem != nullptr, "protocolTypeItem is nullptr"); bool protocolTypeItemFlag = (protocolTypeItem != nullptr) && !cJSON_IsInvalid(protocolTypeItem) && !cJSON_IsNull(protocolTypeItem) && cJSON_IsNumber(protocolTypeItem); sourceProtocols_ = protocolTypeItemFlag ? static_cast(protocolTypeItem->valueint) : ProtocolType::TYPE_LOCAL; sinkCastSessionId_ = want.GetStringParam("sessionId"); SLOGI("Cast Session Create success with sessionId length %{public}d and deviceId length %{public}d", static_cast(sinkCastSessionId_.size()), static_cast(sourceDeviceId_.size())); cJSON_Delete(deviceInfo); #ifdef CAR_FEATURE_ENABLE std::string userId = want.GetStringParam("userId"); #endif } void AVRouterImpl::NotifyCastSessionCreated() { CHECK_AND_RETURN_LOG(!sinkCastSessionId_.empty(), "sinkCastSessionId_ is empty"); std::shared_ptr hwProvider = GetHwProvider(); CHECK_AND_RETURN_LOG(hwProvider != nullptr, "hwProvider_ is nullptr"); if (deviceType_ == DistributedHardware::DmDeviceType::DEVICE_TYPE_2IN1) { DeviceInfo deviceInfo; deviceInfo.deviceId_ = sourceDeviceId_; deviceInfo.realDeviceId_ = sourceDeviceId_; deviceInfo.supportedProtocols_ = sourceProtocols_; SLOGI("sourceProtocols_ is %{public}d", sourceProtocols_); castSide_ = CAST_SIDE::CAST_SINK; // prohibit cast preempt mirror toast disconnect sinkAllConnectResult_ = CollaborationManagerURLCasting::GetInstance().CastAddToCollaboration(deviceInfo); } castSide_ = CAST_SIDE::CAST_SINK; hwProvider->NotifyCastSessionCreated(sinkCastSessionId_); } void AVRouterImpl::DestroyCastSessionCreated() { CHECK_AND_RETURN_LOG(!sinkCastSessionId_.empty(), "sinkCastSessionId_ is empty"); std::shared_ptr hwProvider = GetHwProvider(); CHECK_AND_RETURN_LOG(hwProvider != nullptr, "hwProvider_ is nullptr"); hwProvider->DestroyCastSessionCreated(sinkCastSessionId_); } void AVRouterImpl::SetCastSide(CAST_SIDE castSide) { castSide_.store(castSide); } CAST_SIDE AVRouterImpl::GetCastSide() { return castSide_.load(); } void AVRouterImpl::SetCastingDeviceName(std::string deviceName) { sinkDeviceName_ = deviceName; } std::string AVRouterImpl::GetCastingDeviceName() { return sinkDeviceName_; } bool AVRouterImpl::IsHiPlayCasting() { if (servicePtr_ == nullptr) { SLOGE("servicePtr is NULL"); return false; } return servicePtr_->IsHiPlayCasting(); } bool AVRouterImpl::IsRemoteCasting() { return isRemoteCasting_; } void AVRouterImpl::UpdateConnectState(int32_t castState) { if (castState == static_cast(CastEngine::DeviceState::MIRROR_TO_STREAM) || castState == static_cast(CastEngine::DeviceState::STREAM_TO_MIRROR)) { isInMirrorToStream_ = (castState == static_cast(CastEngine::DeviceState::MIRROR_TO_STREAM)); } if (castState == static_cast(CastEngine::DeviceState::STREAM) || castState == static_cast(CastEngine::DeviceState::DISCONNECTED) || castState == static_cast(CastEngine::DeviceState::STREAM_TO_MIRROR)) { isRemoteCasting_ = (castState == static_cast(CastEngine::DeviceState::STREAM)); SLOGI("isRemoteCasting_ is %{public}d", isRemoteCasting_.load()); } } void AVRouterImpl::OnCastStateChange(int32_t castState, DeviceInfo deviceInfo, int32_t reasonCode) { UpdateConnectState(castState); switch (castState) { case static_cast(CastEngine::DeviceState::STREAM): connectedDeviceInfo_ = deviceInfo; if (sinkAllConnectResult_ != AVSESSION_SUCCESS) { sinkAllConnectResult_ = AVSESSION_SUCCESS; DestroyCastSessionCreated(); return; } break; case static_cast(CastEngine::DeviceState::DISCONNECTED): sinkAllConnectResult_ = AVSESSION_SUCCESS; castSide_ = CAST_SIDE::DEFAULT; { std::lock_guard lockGuard(servicePtrLock_); servicePtr_->SetIsSupportMirrorToStream(false); servicePtr_->checkEnableCast(false); } break; } std::lock_guard lockGuard(castHandleToInfoMapLock_); for (const auto& [number, castHandleInfo] : castHandleToInfoMap_) { if (castHandleInfo.avRouterListener_ != nullptr) { SLOGI("trigger the OnCastStateChange for registered avRouterListener"); std::shared_ptr listener = castHandleInfo.avRouterListener_; AVSessionEventHandler::GetInstance().AVSessionPostTask([listener, castState, deviceInfo, reasonCode]() { CHECK_AND_RETURN_LOG(listener != nullptr, "listener is nullptr"); listener->OnCastStateChange(castState, deviceInfo, true, reasonCode); }, "OnCastStateChange", 0); if (castState == disconnectStateFromCast_) { OutputDeviceInfo localDevice; DeviceInfo localInfo; localInfo.castCategory_ = AVCastCategory::CATEGORY_LOCAL; localInfo.deviceId_ = "-1"; localInfo.deviceName_ = "LocalDevice"; localDevice.deviceInfos_.emplace_back(localInfo); castHandleToInfoMap_[number].outputDeviceInfo_ = localDevice; } if (number == INT64_MAX) { castHandleToInfoMap_[number].avRouterListener_ = nullptr; } } } } void AVRouterImpl::OnCastEventRecv(int32_t errorCode, std::string& errorMsg) { if (errorCode == static_cast(CastEngine::EventId::STREAM_TO_MIRROR_FROM_SINK)) { HandleStreamToMirrorFromSinkEvent(); } std::lock_guard lockGuard(castHandleToInfoMapLock_); for (const auto& [number, castHandleInfo] : castHandleToInfoMap_) { if (castHandleInfo.avRouterListener_ != nullptr) { SLOGI("trigger the OnCastEventRecv for registered avRouterListener"); castHandleInfo.avRouterListener_->OnCastEventRecv(errorCode, errorMsg); } } } void AVRouterImpl::HandleStreamToMirrorFromSinkEvent() { SetStreamToMirrorFromSink(true); UpdateConnectState(disconnectStateFromCast_); int32_t disconnectState; DeviceInfo connectedDeviceInfo; int32_t noReasonCode; { std::lock_guard lockGuard(servicePtrLock_); CHECK_AND_RETURN_LOG(servicePtr_ != nullptr, "servicePtr_ is nullptr"); disconnectState = disconnectStateFromCast_; connectedDeviceInfo = connectedDeviceInfo_; noReasonCode = noReasonCode_; servicePtr_->SetIsSupportMirrorToStream(false); } std::lock_guard lockGuard(castHandleToInfoMapLock_); for (const auto& [number, castHandleInfo] : castHandleToInfoMap_) { CHECK_AND_CONTINUE(castHandleInfo.avRouterListener_ != nullptr); SLOGI("trigger the OnCastStateChange for registered avRouterListener"); std::shared_ptr listener = castHandleInfo.avRouterListener_; AVSessionEventHandler::GetInstance().AVSessionPostTask([listener, disconnectState, connectedDeviceInfo, noReasonCode]() { CHECK_AND_RETURN_LOG(listener != nullptr, "listener is nullptr"); listener->OnCastStateChange(disconnectState, connectedDeviceInfo, false, noReasonCode); }, "OnCastStateChange", 0); } } void AVRouterImpl::SetStreamToMirrorFromSink(bool fromSink) { SLOGI("SetStreamToMirrorFromSink: %{public}d", fromSink); streamToMirrorFromSink_.store(fromSink); } bool AVRouterImpl::IsStreamToMirrorFromSink() { return streamToMirrorFromSink_.load(); } bool AVRouterImpl::IsDisconnectingOtherSession() { return disconnectOtherSession_.load(); } void AVRouterImpl::SendCommandArgsToCast(const int64_t castHandle, const int32_t commandType, const std::string& params) { SLOGI("AVRouterImpl start send commandArgs to cast"); // the first 32 bits are providerId, the last 32 bits are castId int32_t providerNumber = static_cast(static_cast(castHandle) >> 32); SLOGI("Get hwcastprovider of provider %{public}d", providerNumber); int32_t castId = static_cast((static_cast(castHandle) << 32) >> 32); std::shared_ptr provider = GetCastProvider(providerNumber); CHECK_AND_RETURN_LOG(provider != nullptr, "provider is nullptr"); provider->SendCommandArgsToCast(castId, commandType, params); } std::string AVRouterImpl::QueryCastSessionId(const int64_t castHandle) { SLOGI("AVRouterImpl start query castsessionid"); // the first 32 bits are providerId, the last 32 bits are castId int32_t providerNumber = static_cast(static_cast(castHandle) >> 32); SLOGI("Get hwcastprovider of provider %{public}d", providerNumber); int32_t castId = static_cast((static_cast(castHandle) << 32) >> 32); std::shared_ptr provider = GetCastProvider(providerNumber); CHECK_AND_RETURN_RET_LOG(provider != nullptr, "", "provider is nullptr"); return provider->QueryCastSessionId(castId); } int32_t AVRouterImpl::PcmCastSessionReleasePlayer() { CHECK_AND_RETURN_RET_LOG(servicePtr_ != nullptr, AVSESSION_ERROR, "servicePtr_ is nullptr"); return servicePtr_->PcmCastSessionReleasePlayer(); } void AVRouterImpl::DisconnectOtherSession(std::string sessionId, DeviceInfo deviceInfo) { disconnectOtherSession_.store(true); std::vector> listenersToNotify; { std::lock_guard lockGuard(castHandleToInfoMapLock_); for (const auto& [string, avRouterListener] : mirrorSessionMap_) { if (string != sessionId && avRouterListener != nullptr) { listenersToNotify.push_back(avRouterListener); } } for (auto& [number, castHandleInfo] : castHandleToInfoMap_) { CHECK_AND_CONTINUE(castHandleInfo.sessionId_ != sessionId); CHECK_AND_CONTINUE(castHandleInfo.avRouterListener_ != nullptr); CHECK_AND_CONTINUE(mirrorSessionMap_[sessionId] != nullptr); listenersToNotify.push_back(castHandleInfo.avRouterListener_); castHandleInfo.sessionId_ = sessionId; castHandleInfo.avRouterListener_ = mirrorSessionMap_[sessionId]; } mirrorSessionMap_.clear(); } for (auto& listener : listenersToNotify) { listener->OnCastStateChange(disconnectStateFromCast_, deviceInfo, false, noReasonCode_); } disconnectOtherSession_.store(false); } } // namespace OHOS::AVSession