Files
weixin_44014140 f94c4f4642 add moduleId && submoduleId
Signed-off-by: weixin_44014140 <chenyuming12@h-partners.com>
2026-08-17 20:44:48 +08:00

464 lines
19 KiB
C++

/*
* Copyright (c) 2023 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 "hw_cast_provider_session.h"
#include <thread>
#include "avsession_radar.h"
#include "avsession_utils.h"
#include "avsession_log.h"
#include "avsession_errors.h"
#include "av_router.h"
#include "avsession_sysevent.h"
using namespace OHOS::CastEngine;
namespace OHOS::AVSession {
static const std::set<SoftBusErrNo> SOFTBUS_CONN_PASSIVE_CONFLICT_CODE = {
SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_HML_NUM_LIMITED_CONFLICT,
SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_P2P_GO_GC_CONFLICT,
SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_STA_P2P_HML_555_CONFLICT,
SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_STA_P2P_HML_525_CONFLICT,
SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_STA_P2P_HML_255_CONFLICT,
SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_STA_P2P_HML_225_CONFLICT,
SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_STA_P2P_HML_55_CONFLICT,
SoftBusErrNo::SOFTBUS_CONN_PV2_PEER_GC_CONNECTED_TO_ANOTHER_DEVICE,
SoftBusErrNo::SOFTBUS_CONN_PV1_PEER_GC_CONNECTED_TO_ANOTHER_DEVICE,
};
HwCastProviderSession::~HwCastProviderSession()
{
SLOGI("destruct the HwCastProviderSession");
Release();
}
int32_t HwCastProviderSession::Init()
{
SLOGI("Init the HwCastProviderSession");
if (castSession_) {
return castSession_->RegisterListener(shared_from_this());
}
return AVSESSION_ERROR;
}
void HwCastProviderSession::SetProtocolType(CastEngine::ProtocolType protocolType)
{
SLOGI("SetProtocolType %{public}d", static_cast<int>(protocolType));
protocolType_ = protocolType;
}
void HwCastProviderSession::Release()
{
SLOGI("release the HwCastProviderSession");
if (!castSession_) {
SLOGE("castSession_ is not exist");
return;
}
avToastDeviceState_ = ConnectionState::STATE_DISCONNECTED;
castSession_->Release();
castSession_ = nullptr;
}
bool HwCastProviderSession::AddDevice(const DeviceInfo deviceInfo, uint32_t spid)
{
SLOGI("AddDevice in HwCastProviderSession");
if (!castSession_) {
SLOGE("castSession_ is not exist");
return false;
}
CastRemoteDevice castRemoteDevice = {};
castRemoteDevice.deviceId = deviceInfo.realDeviceId_;
castRemoteDevice.bleMac = deviceInfo.bleMac_;
castRemoteDevice.triggerType = static_cast<CastEngine::TriggerType>(deviceInfo.triggerType_);
castRemoteDevice.spid = spid;
std::vector<CastEngine::ServiceInfo> infos;
CastEngine::ServiceInfo serviceInfo;
serviceInfo.screenId = deviceInfo.screenId_;
infos.emplace_back(serviceInfo);
castRemoteDevice.serviceInfos = infos;
avToastDeviceState_ = ConnectionState::STATE_CONNECTING;
int32_t ret = castSession_->AddDevice(castRemoteDevice);
avToastDeviceState_ = (ret == 0) ? avToastDeviceState_ : ConnectionState::STATE_DISCONNECTED;
SLOGI("AddDevice in HwCastProviderSession with ret %{public}d", ret);
return (ret == 0) ? true : false;
}
bool HwCastProviderSession::AddDeviceWithConnectionConfig(const DeviceInfo deviceInfo, uint32_t spid,
CastEngine::ConnectionConfig connectionConfig)
{
SLOGI("AddDeviceWithConnectionConfig in HwCastProviderSession");
if (!castSession_) {
SLOGE("castSession_ is not exist");
return false;
}
CastRemoteDevice castRemoteDevice = {};
castRemoteDevice.deviceId = deviceInfo.deviceId_;
castRemoteDevice.deviceName = deviceInfo.deviceName_;
castRemoteDevice.bleMac = deviceInfo.bleMac_;
castRemoteDevice.triggerType = static_cast<CastEngine::TriggerType>(deviceInfo.triggerType_);
castRemoteDevice.spid = spid;
avToastDeviceState_ = ConnectionState::STATE_CONNECTING;
int32_t ret = castSession_->AddDevice(castRemoteDevice, connectionConfig);
avToastDeviceState_ = (ret == 0) ? avToastDeviceState_ : ConnectionState::STATE_DISCONNECTED;
SLOGI("AddDeviceWithConnectionConfig in HwCastProviderSession with ret %{public}d", ret);
return (ret == 0) ? true : false;
}
void HwCastProviderSession::SendCommandArgsToCast(const int32_t commandType, const std::string& params)
{
std::shared_ptr<CastEngine::ICastSession> sessionCopy;
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
if (!castSession_) {
SLOGE("castSession_ is nullptr");
return;
}
sessionCopy = castSession_;
}
std::string parStr = params;
switch (commandType) {
case CAST_MODE_CHANGE_COMMAND:
SLOGI("SendCommandArgsToCast: cast mode change");
sessionCopy->NotifyEvent(CastEngine::EventId::HIPLAY_CONFIG_MODE, parStr);
break;
case BYPASS_COMMAND_NUM:
sessionCopy->NotifyEvent(CastEngine::EventId::HIPLAY_BYPASS_DATA, parStr);
break;
case QUERY_COMMAND_NUM:
sessionCopy->NotifyEvent(CastEngine::EventId::HIPLAY_QUERY_REQUEST, parStr);
break;
case CONTROL_COMMAND_NUM:
sessionCopy->NotifyEvent(CastEngine::EventId::HIPLAY_MODE_CHANGE, parStr);
break;
default:
break;
}
}
std::string HwCastProviderSession::QueryCastSessionId()
{
std::string sessionId = "";
if (!castSession_) {
SLOGE("castSession_ is not exist");
return sessionId;
}
castSession_->GetSessionId(sessionId);
SLOGI("QueryCastSessionId is %{public}s", sessionId.c_str());
return sessionId;
}
bool HwCastProviderSession::RemoveDevice(std::string deviceId, const DeviceRemoveAction deviceRemoveAction)
{
SLOGI("RemoveDevice in HwCastProviderSession, device remove action %{public}d",
static_cast<int32_t>(deviceRemoveAction));
if (!castSession_) {
SLOGE("castSession_ is not exist");
return false;
}
avToastDeviceState_ = ConnectionState::STATE_DISCONNECTED;
return castSession_->RemoveDevice(deviceId, static_cast<CastEngine::DeviceRemoveAction>(deviceRemoveAction));
}
std::shared_ptr<CastEngine::IStreamPlayer> HwCastProviderSession::CreateStreamPlayer()
{
SLOGI("CreateStreamPlayer in HwCastProviderSession");
if (!castSession_) {
SLOGE("castSession_ is not exist");
return nullptr;
}
std::shared_ptr<CastEngine::IStreamPlayer> streamPlayerPtr = nullptr;
castSession_->CreateStreamPlayer(streamPlayerPtr);
return streamPlayerPtr;
}
bool HwCastProviderSession::GetRemoteDrmCapabilities(std::string deviceId, std::vector<std::string> &drmCapabilities)
{
SLOGI("enter GetRemoteDrmCapabilities");
if (!castSession_) {
SLOGE("castSession_ is not exist");
return false;
}
CastRemoteDevice castRemoteDevice = {};
castSession_->GetRemoteDeviceInfo(deviceId, castRemoteDevice);
drmCapabilities = castRemoteDevice.drmCapabilities;
return true;
}
bool HwCastProviderSession::GetRemoteNetWorkId(std::string deviceId, std::string &networkId)
{
SLOGI("enter GetRemoteNetWorkId");
if (!castSession_) {
SLOGE("castSession_ is not exist");
return false;
}
CastRemoteDevice castRemoteDevice = {};
castSession_->GetRemoteDeviceInfo(deviceId, castRemoteDevice);
networkId = castRemoteDevice.networkId;
return true;
}
bool HwCastProviderSession::SetStreamState(DeviceInfo deviceInfo)
{
std::vector<std::shared_ptr<IAVCastSessionStateListener>> tempListenerList;
{
std::lock_guard lockGuard(mutex_);
tempListenerList = castSessionStateListenerList_;
stashDeviceState_ = deviceStateConnection;
stashDeviceId_ = deviceInfo.deviceId_;
}
for (auto listener : tempListenerList) {
if (listener != nullptr) {
SLOGI("trigger the OnCastStateChange for registered listeners");
listener->OnCastStateChange(deviceStateConnection, deviceInfo, noReasonCode);
}
}
return true;
}
bool HwCastProviderSession::RegisterCastSessionStateListener(std::shared_ptr<IAVCastSessionStateListener> listener)
{
SLOGI("RegisterCastSessionStateListener");
if (listener == nullptr) {
SLOGE("RegisterCastSessionStateListener failed for the listener is nullptr");
return false;
}
{
std::lock_guard lockGuard(mutex_);
if (find(castSessionStateListenerList_.begin(), castSessionStateListenerList_.end(), listener)
!= castSessionStateListenerList_.end()) {
SLOGE("listener is already in castSessionStateListenerList_");
return false;
}
castSessionStateListenerList_.emplace_back(listener);
SLOGI("register listener finished with size %{public}d and check stash state %{public}d",
static_cast<int>(castSessionStateListenerList_.size()), static_cast<int32_t>(stashDeviceState_));
}
if (stashDeviceState_ > 0) {
DeviceInfo deviceInfo;
deviceInfo.deviceId_ = stashDeviceId_;
deviceInfo.deviceName_ = "RemoteCast";
deviceInfo.castCategory_ = AVCastCategory::CATEGORY_LOCAL;
if (listener != nullptr) {
SLOGI("retry trigger the OnCastStateChange for registered listeners");
listener->OnCastStateChange(static_cast<int>(stashDeviceState_), deviceInfo, noReasonCode);
}
}
return true;
}
bool HwCastProviderSession::UnRegisterCastSessionStateListener(std::shared_ptr<IAVCastSessionStateListener> listener)
{
if (listener == nullptr) {
SLOGE("UnRegisterCastSessionStateListener failed for the listener is nullptr");
return false;
}
std::lock_guard lockGuard(mutex_);
for (auto iter = castSessionStateListenerList_.begin(); iter != castSessionStateListenerList_.end();) {
if (*iter == listener) {
castSessionStateListenerList_.erase(iter);
SLOGI("unRegister finished with size %{public}d", static_cast<int>(castSessionStateListenerList_.size()));
return true;
} else {
++iter;
}
}
return false;
}
std::vector<AudioStreamInfo> HwCastProviderSession::BuildAudioStreamInfos(
const CastEngine::CastRemoteDevice &castRemoteDevice)
{
std::vector<AudioStreamInfo> streamInfos;
if (protocolType_ == CastEngine::ProtocolType::CAST_PLUS_AUDIO) {
SLOGI("OnDeviceState CAST_PLUS_AUDIO GetRemoteDeviceInfo");
AudioStreamInfo audioStreamInfo;
audioStreamInfo.samplingRate = static_cast<AudioSamplingRate>(castRemoteDevice.audioCapability.samplingRate);
audioStreamInfo.encoding = static_cast<AudioEncodingType>(castRemoteDevice.audioCapability.encoding);
audioStreamInfo.format = static_cast<AudioSampleFormat>(castRemoteDevice.audioCapability.format);
audioStreamInfo.channels = static_cast<AudioChannel>(castRemoteDevice.audioCapability.channels);
audioStreamInfo.channelLayout = static_cast<AudioChannelLayout>(castRemoteDevice.audioCapability.channelLayout);
streamInfos.push_back(audioStreamInfo);
}
return streamInfos;
}
void HwCastProviderSession::OnDeviceState(const CastEngine::DeviceStateInfo &stateInfo)
{
int32_t deviceState = static_cast<int32_t>(stateInfo.deviceState);
std::vector<std::shared_ptr<IAVCastSessionStateListener>> tempListenerList;
SLOGI("OnDeviceState from cast %{public}d", static_cast<int>(deviceState));
if (stashDeviceState_ == deviceState) {
SLOGI("duplicate devicestate");
return;
}
CastRemoteDevice castRemoteDevice;
castSession_ ? castSession_->GetRemoteDeviceInfo(stateInfo.deviceId, castRemoteDevice) : static_cast<int32_t>(0);
ComputeToastOnDeviceState(stateInfo, castRemoteDevice);
{
std::lock_guard lockGuard(mutex_);
if (castSessionStateListenerList_.size() == 0) {
SLOGI("current has not registered listener, stash state: %{public}d", deviceState);
stashDeviceState_ = deviceState;
stashDeviceId_ = GetDeviceId(stateInfo);
return;
}
stashDeviceState_ = -1;
tempListenerList = castSessionStateListenerList_;
}
auto streamInfos = BuildAudioStreamInfos(castRemoteDevice);
for (auto listener : tempListenerList) {
DeviceInfo deviceInfo;
deviceInfo.deviceId_ = GetDeviceId(stateInfo);
deviceInfo.deviceName_ = "RemoteCast";
deviceInfo.castCategory_ = AVCastCategory::CATEGORY_LOCAL;
deviceInfo.audioCapabilities_.streamInfos_ = streamInfos;
deviceInfo.supportedProtocols_ = GetProtocolType(castRemoteDevice.protocolCapabilities);
deviceInfo.realDeviceId_ = stateInfo.deviceId;
if (listener != nullptr) {
SLOGI("trigger the OnCastStateChange for ListSize %{public}d", static_cast<int>(tempListenerList.size()));
listener->OnCastStateChange(static_cast<int>(deviceState), deviceInfo,
static_cast<int32_t>(stateInfo.reasonCode));
OnDeviceStateChange(stateInfo);
}
}
}
void HwCastProviderSession::ComputeToastOnDeviceState(const CastEngine::DeviceStateInfo &stateInfo,
const CastEngine::CastRemoteDevice &castRemoteDevice)
{
CastEngine::DeviceState state = stateInfo.deviceState;
// device connected
if (state == CastEngine::DeviceState::STREAM) {
avToastDeviceState_ = ConnectionState::STATE_CONNECTED;
CHECK_AND_RETURN(AVRouter::GetInstance().GetCastSide() == CAST_SIDE::CAST_SINK);
std::string preSinkDeviceName = AVRouter::GetInstance().GetCastingDeviceName();
CHECK_AND_RETURN_LOG(!preSinkDeviceName.empty(), "preSinkDeviceName empty");
std::string curSourceDeviceName = castRemoteDevice.deviceName;
AVSessionUtils::PublishCommonEventWithDeviceName(MEDIA_SERIES_CAST_CONFLICT,
preSinkDeviceName, curSourceDeviceName);
AVRouter::GetInstance().SetCastingDeviceName("");
return;
}
// stream to mirror scene, session is not hold by avsession
if (state == CastEngine::DeviceState::STREAM_TO_MIRROR) {
avToastDeviceState_ = ConnectionState::STATE_DISCONNECTED;
AVRouter::GetInstance().SetCastingDeviceName("");
return;
}
if (state == CastEngine::DeviceState::CONNECTED || state == CastEngine::DeviceState::PLAYING) {
avToastDeviceState_ = prepareState;
AVRouter::GetInstance().SetCastingDeviceName("");
return;
}
if (state != CastEngine::DeviceState::DISCONNECTED) {
return;
}
// device disconnected after successful connection
if (avToastDeviceState_ == ConnectionState::STATE_CONNECTED) {
CHECK_AND_RETURN(AVRouter::GetInstance().GetCastSide() == CAST_SIDE::CAST_SOURCE);
AVSessionUtils::PublishCommonEvent(MEDIA_CAST_DISCONNECT);
return;
}
// device disconnected during connecting
if (avToastDeviceState_ == ConnectionState::STATE_CONNECTING) {
CHECK_AND_RETURN(AVRouter::GetInstance().GetCastSide() == CAST_SIDE::CAST_SOURCE);
SOFTBUS_CONN_PASSIVE_CONFLICT_CODE.count(static_cast<SoftBusErrNo>(stateInfo.radarErrCode)) ?
AVSessionUtils::PublishCommonEvent(MEDIA_SERIES_CAST_3VAP) :
AVSessionUtils::PublishCommonEvent(MEDIA_CAST_ERROR);
return;
}
}
void HwCastProviderSession::OnDeviceStateChange(const CastEngine::DeviceStateInfo &stateInfo)
{
HILOG_COMM_INFO("OnDeviceStateChange from cast with deviceId %{public}s, state %{public}d, reasonCode %{public}d",
AVSessionUtils::GetAnonyNetworkId(stateInfo.deviceId).c_str(),
static_cast<int32_t>(stateInfo.deviceState), static_cast<int32_t>(stateInfo.reasonCode));
DeviceState deviceState;
deviceState.deviceId = GetDeviceId(stateInfo);
deviceState.deviceState = static_cast<int32_t>(stateInfo.deviceState);
deviceState.reasonCode = static_cast<int32_t>(stateInfo.reasonCode);
deviceState.radarErrorCode = stateInfo.radarErrCode;
AVRouter::GetInstance().OnDeviceStateChange(deviceState);
}
void HwCastProviderSession::OnEvent(const CastEngine::EventId &eventId, const std::string &jsonParam)
{
SLOGI("OnEvent from cast with eventId %{public}d, %{public}s", eventId, jsonParam.c_str());
int32_t castEventId = static_cast<int>(eventId);
if (castEventId >= eventIdStart && castEventId <= eventIdEnd) {
std::lock_guard lockGuard(mutex_);
SLOGI("trigger the OnCastEventRecv for ListSize %{public}d",
static_cast<int>(castSessionStateListenerList_.size()));
for (auto listener : castSessionStateListenerList_) {
CHECK_AND_CONTINUE(listener != nullptr);
std::string param = jsonParam;
listener->OnCastEventRecv(castEventId, param);
}
} else if (castEventId >= hiplayEventIdStart && castEventId <= hiplayEventIdEnd) {
OnHiplayEventRecv(castEventId, jsonParam);
}
}
void HwCastProviderSession::OnHiplayEventRecv(const int32_t eventId, const std::string& jsonParam)
{
switch (eventId) {
case HIPLAY_CONFIG_MODE_RESULT:
AVRouter::GetInstance().OnSystemCommonEvent(HIPLAY_CONFIG_MODE_DATA, jsonParam);
break;
case HIPLAY_BYPASS_DATA_NUM:
AVRouter::GetInstance().OnSystemCommonEvent(HIPLAY_BYPASS_DATA, jsonParam);
break;
case HIPLAY_QUERY_RESPONSE_NUM:
AVRouter::GetInstance().OnSystemCommonEvent(HIPLAY_QUERY_RESPONSE, jsonParam);
break;
case HIPLAY_DEVICE_INFO:
AVRouter::GetInstance().OnSystemCommonEvent(HIPLAY_DEVICE_INFO_DATA, jsonParam);
break;
default:
break;
}
}
int32_t HwCastProviderSession::GetProtocolType(uint32_t castProtocolType)
{
int32_t protocolType = (castProtocolType & ProtocolType::TYPE_CAST_PLUS_STREAM) |
(castProtocolType & ProtocolType::TYPE_DLNA) |
((castProtocolType & static_cast<int>(CastEngine::ProtocolType::CAST_PLUS_AUDIO)) ?
ProtocolType::TYPE_CAST_PLUS_AUDIO : 0);
return protocolType;
}
std::string HwCastProviderSession::GetDeviceId(const CastEngine::DeviceStateInfo &stateInfo)
{
std::string deviceId = (stateInfo.screenId == noScreenId) ? stateInfo.deviceId :
(stateInfo.deviceId + std::to_string(stateInfo.screenId));
return deviceId;
}
}