Files
xuhy 0fc996fb20 revised
Co-Authored-By: Agent
Signed-off-by: xuhy <xuhuanyu2@huawei.com>
2026-08-08 15:14:14 +08:00

1023 lines
42 KiB
C++

/*
* 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<CastSessionListener>(this);
auto hwProvider = std::make_shared<HwCastProvider>();
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> avCastProviderManager = std::make_shared<AVCastProviderManager>();
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<HwCastProvider> 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<AVCastProvider> 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<HwCastProvider> 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<std::string> 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<int>(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<int>(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<int64_t>((static_cast<uint64_t>(tempId) << 32) |
static_cast<const uint32_t>(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<IAVCastControllerProxy> 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<int32_t>(static_cast<const uint64_t>(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<int32_t>((static_cast<const uint64_t>(castHandle) << 32) >> 32);
std::shared_ptr<AVCastProvider> 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<std::string, std::string>& serviceNameStatePair, std::string sessionId)
{
castSide_ = CAST_SIDE::CAST_SOURCE;
SLOGI("AVRouterImpl start cast process");
castServiceNameStatePair_ = serviceNameStatePair;
int64_t castHandle = -1;
std::shared_ptr<AVCastProvider> 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<uint32_t>(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<int64_t>((static_cast<uint64_t>(tempId) << 32) | static_cast<uint32_t>(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<int64_t>((static_cast<uint64_t>(tempId) << 32) |
static_cast<uint32_t>(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<AVCastProvider> 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<int32_t>(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<int64_t>((static_cast<uint64_t>(tempId) << 32) |
static_cast<uint32_t>(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<AVCastProvider> 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<int32_t>(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<int32_t>(static_cast<uint64_t>(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<int32_t>((static_cast<const uint64_t>(castHandle) << 32) >> 32);
SLOGI("Stop cast, the castId is %{public}d", castId);
std::shared_ptr<AVCastProvider> 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<int32_t>(static_cast<uint64_t>(castHandle) >> 32);
std::shared_ptr<AVCastProvider> 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<int32_t>((static_cast<uint64_t>(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<AVCastProvider> 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<int32_t>(static_cast<uint64_t>(castHandle) >> 32);
int32_t castId = static_cast<int32_t>((static_cast<uint64_t>(castHandle) << 32) >> 32);
std::shared_ptr<AVCastProvider> 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<std::string> &drmCapabilities)
{
int32_t providerNumber = static_cast<int32_t>(static_cast<uint64_t>(castHandle) >> 32);
int32_t castId = static_cast<int32_t>((static_cast<uint64_t>(castHandle) << 32) >> 32);
std::shared_ptr<AVCastProvider> 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<IAVRouterListener> 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<IAVRouterListener> 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<int32_t>(static_cast<uint64_t>(castHandle) >> 32);
// The first 32 bits are providerId, the last 32 bits are castId
int32_t castId = static_cast<int32_t>((static_cast<uint64_t>(castHandle) << 32) >> 32);
std::shared_ptr<AVCastProvider> 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<IAVRouterListener> 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<uint64_t>(static_cast<uint64_t>(castHandle)) >> 32;
// The first 32 bits are providerId, the last 32 bits are castId
int32_t castId = static_cast<int32_t>((static_cast<uint64_t>(castHandle) << 32) >> 32);
std::shared_ptr<AVCastProvider> 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<HwCastProvider> 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<ProtocolType>(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<int32_t>(sinkCastSessionId_.size()), static_cast<int32_t>(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<HwCastProvider> 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<HwCastProvider> 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<int32_t>(CastEngine::DeviceState::MIRROR_TO_STREAM) ||
castState == static_cast<int32_t>(CastEngine::DeviceState::STREAM_TO_MIRROR)) {
isInMirrorToStream_ = (castState == static_cast<int32_t>(CastEngine::DeviceState::MIRROR_TO_STREAM));
}
if (castState == static_cast<int32_t>(CastEngine::DeviceState::STREAM) ||
castState == static_cast<int32_t>(CastEngine::DeviceState::DISCONNECTED) ||
castState == static_cast<int32_t>(CastEngine::DeviceState::STREAM_TO_MIRROR)) {
isRemoteCasting_ = (castState == static_cast<int32_t>(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<int32_t>(CastEngine::DeviceState::STREAM):
connectedDeviceInfo_ = deviceInfo;
if (sinkAllConnectResult_ != AVSESSION_SUCCESS) {
sinkAllConnectResult_ = AVSESSION_SUCCESS;
DestroyCastSessionCreated();
return;
}
break;
case static_cast<int32_t>(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<IAVRouterListener> 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<int32_t>(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<IAVRouterListener> 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<int32_t>(static_cast<const uint64_t>(castHandle) >> 32);
SLOGI("Get hwcastprovider of provider %{public}d", providerNumber);
int32_t castId = static_cast<int32_t>((static_cast<const uint64_t>(castHandle) << 32) >> 32);
std::shared_ptr<AVCastProvider> 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<int32_t>(static_cast<const uint64_t>(castHandle) >> 32);
SLOGI("Get hwcastprovider of provider %{public}d", providerNumber);
int32_t castId = static_cast<int32_t>((static_cast<const uint64_t>(castHandle) << 32) >> 32);
std::shared_ptr<AVCastProvider> 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<std::shared_ptr<IAVRouterListener>> 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