Files
weixin_44014140 9034926149 修复腾讯视频低概率切换投屏断连
Signed-off-by: weixin_44014140 <chenyuming12@h-partners.com>
2026-08-18 09:47:14 +08:00

786 lines
32 KiB
C++

/*
* Copyright (c) 2025 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 "pcm_cast_session.h"
#include "avsession_log.h"
#include "avsession_utils.h"
#include "av_router.h"
#include "avsession_sysevent.h"
#include "cast_engine_common.h"
#include "collaboration_manager_hiplay.h"
#include "ipc_skeleton.h"
#include "string_wrapper.h"
#include "int_wrapper.h"
#include "avsession_errors.h"
#include "json_utils.h"
#include "avsession_service.h"
#include "avsession_event_handler.h"
#include <filesystem>
namespace OHOS::AVSession {
void PcmCastSession::OnCastStateChange(int32_t castState, DeviceInfo deviceInfo, bool isNeedRemove, int32_t reasonCode)
{
SLOGI("PcmCastSession OnCastStateChange state %{public}d id %{public}s reasonCode %{public}d", castState,
AVSessionUtils::GetAnonymousDeviceId(deviceInfo.deviceId_).c_str(), reasonCode);
if (castState == static_cast<int32_t>(CastEngine::DeviceState::DISCONNECTED)) {
HandleDeviceDisconnect();
}
UpdateDeviceInfo(deviceInfo);
OutputDeviceInfo outputDeviceInfo;
outputDeviceInfo.deviceInfos_.emplace_back(deviceInfo);
if (castState == static_cast<int32_t>(CastEngine::DeviceState::STREAM)) {
descriptor_.outputDeviceInfo_ = outputDeviceInfo;
castState_ = CastState::STREAM;
if (needStreamCasting_) {
needStreamCasting_ = false;
descriptor_.sessionId_ = streamCastingSessionId_;
FindSessionAndStreamCasting();
}
}
if (castState == static_cast<int32_t>(CastEngine::DeviceState::CONNECTED) ||
castState == static_cast<int32_t>(CastEngine::DeviceState::PLAYING)) {
descriptor_.outputDeviceInfo_ = outputDeviceInfo;
castState_ = CastState::PREPARE;
}
collaborationNeedDeviceId_ = deviceInfo.deviceId_;
if (isNeedRemove) { // same device cast exchange no publish when hostpot scene
DealCollaborationPublishState(castState, deviceInfo);
}
ReportSessionCast(castState, reasonCode);
std::weak_ptr<PcmCastSession> weakPtr = shared_from_this();
CollaborationManagerHiPlay::GetInstance().SendCollaborationOnStop([weakPtr](void) {
auto sharedPtr = weakPtr.lock();
CHECK_AND_RETURN_LOG(sharedPtr != nullptr, "PcmCastSession is null in SendCollaborationOnStop");
sharedPtr->StopCast();
});
if (needHandleTimer_) {
HandleTimerByCastState(castState);
}
}
void PcmCastSession::UpdateDeviceInfo(DeviceInfo& deviceInfo)
{
std::lock_guard lockGuard(castLock_);
deviceInfo.deviceName_ = tempDeviceInfo_.deviceName_;
deviceInfo.deviceType_ = tempDeviceInfo_.deviceType_;
deviceInfo.uuid_ = tempDeviceInfo_.uuid_;
deviceInfo.ipAddress_ = tempDeviceInfo_.ipAddress_;
deviceInfo.supportedProtocols_ = tempDeviceInfo_.supportedProtocols_;
deviceInfo.hiPlayDeviceInfo_.castMode_ = tempDeviceInfo_.hiPlayDeviceInfo_.castMode_;
deviceInfo.hiPlayDeviceInfo_.castUid_ = GetUid();
deviceInfo.hiPlayDeviceInfo_.supportCastMode_ = tempDeviceInfo_.hiPlayDeviceInfo_.supportCastMode_;
deviceInfo.hiPlayDeviceInfo_.moduleId_ = tempDeviceInfo_.hiPlayDeviceInfo_.moduleId_;
deviceInfo.hiPlayDeviceInfo_.submoduleId_ = tempDeviceInfo_.hiPlayDeviceInfo_.submoduleId_;
SLOGI("PcmCastSession OnCastStateChange castUid %{public}d", deviceInfo.hiPlayDeviceInfo_.castUid_);
}
void PcmCastSession::HandleDeviceDisconnect()
{
ReleaseStreamPlayer();
needHandleTimer_ = false;
AVRouter::GetInstance().UnRegisterCallback(castHandle_, shared_from_this(), "pcmCastSession");
AVRouter::GetInstance().StopCastSession(castHandle_);
castHandle_ = -1;
castState_ = CastState::DISCONNECTED;
castHandleDeviceId_ = "-100";
{
std::lock_guard lockGuard(castLock_);
descriptor_.uid_ = 0;
descriptor_.outputDeviceInfo_ = {};
}
if (multiDeviceState_ == MultiDeviceState::CASTING_SWITCH_DEVICE) {
multiDeviceState_ = MultiDeviceState::DEFAULT;
CHECK_AND_RETURN(newOutputDeviceInfo_.deviceInfos_.size() > 0);
if ((CollaborationManagerHiPlay::GetInstance().CastAddToCollaboration(
newOutputDeviceInfo_.deviceInfos_[0]) != AVSESSION_SUCCESS) ||
SubStartCast(newOutputDeviceInfo_, newServiceNameStatePair_, newSessionToken_) != AVSESSION_SUCCESS) {
OnCastStateChange(static_cast<int32_t>(CastEngine::DeviceState::DISCONNECTED),
newOutputDeviceInfo_.deviceInfos_[0], false, noReasonCode_);
AVSessionUtils::PublishCommonEvent(MEDIA_CAST_ERROR);
}
}
}
void PcmCastSession::HandleTimerByCastState(int32_t castState)
{
if (castState == static_cast<int32_t>(CastEngine::DeviceState::CONNECTED)) {
std::weak_ptr<PcmCastSession> weakPtr = shared_from_this();
AVSessionEventHandler::GetInstance().AVSessionPostTask(
[weakPtr]() {
auto sharedPtr = weakPtr.lock();
CHECK_AND_RETURN_LOG(sharedPtr != nullptr, "HandleTimerByCastState null");
AVRouter::GetInstance().OnSystemCommonEvent(sharedPtr->STOP_CAST, "");
}, "HandleHiPlayStreamCastStateChange", hiPlayHotelTimeoutMs);
}
if (castState == static_cast<int32_t>(CastEngine::DeviceState::DISCONNECTED) ||
castState == static_cast<int32_t>(CastEngine::DeviceState::PLAYING) ||
castState == static_cast<int32_t>(CastEngine::DeviceState::STREAM)) {
AVSessionEventHandler::GetInstance().AVSessionRemoveTask("HandleHiPlayStreamCastStateChange");
}
}
void PcmCastSession::ReportSessionCast(int32_t castState, int32_t reasonCode)
{
#ifdef ENABLE_AVSESSION_SYSEVENT_CONTROL
if (castState == static_cast<int32_t>(CastEngine::DeviceState::AUTHING) &&
reasonCode == reasonDeviceIsUntrusted_) {
SLOGI("OnCastStateChange: authing state with show pin, reset");
AVSessionSysEvent::GetInstance().clearCastControlInfo(PCM_CAST_SESSION);
}
if (castState == static_cast<int32_t>(CastEngine::DeviceState::STREAM)) {
AVSessionSysEvent::GetInstance().updateDeviceConnectTime(PCM_CAST_SESSION);
}
if (castState == static_cast<int32_t>(CastEngine::DeviceState::DISCONNECTED)) {
DeviceInfo localDeviceInfo;
{
std::lock_guard lockGuard(castLock_);
localDeviceInfo = tempDeviceInfo_;
}
CHECK_AND_RETURN(!localDeviceInfo.deviceId_.empty());
AVSessionSysEvent::GetInstance().ReportSessionCastControl(PCM_CAST_SESSION, PCM_CAST_SESSION, localDeviceInfo);
}
#endif
}
void PcmCastSession::DealCollaborationPublishState(int32_t castState, DeviceInfo deviceInfo)
{
SLOGI("enter DealCollaborationPublishState");
if (castState == static_cast<int32_t>(CastEngine::DeviceState::AUTHING)) {
CollaborationManagerHiPlay::GetInstance().PublishServiceState(collaborationNeedDeviceId_.c_str(),
ServiceCollaborationManagerBussinessStatus::SCM_CONNECTING);
}
if (castState == static_cast<int32_t>(CastEngine::DeviceState::STREAM) || // 6 is connected status (stream)
castState == static_cast<int32_t>(CastEngine::DeviceState::CONNECTED)) { // 1 is connected status (screen)
AVRouter::GetInstance().GetRemoteNetWorkId(
castHandle_, deviceInfo.deviceId_, collaborationNeedNetworkId_);
if (collaborationNeedNetworkId_.empty()) {
SLOGI("networkId is empty, try use deviceId:%{public}s",
AVSessionUtils::GetAnonyNetworkId(deviceInfo.deviceId_).c_str());
collaborationNeedNetworkId_ = deviceInfo.deviceId_;
}
CollaborationManagerHiPlay::GetInstance().PublishServiceState(collaborationNeedNetworkId_.c_str(),
ServiceCollaborationManagerBussinessStatus::SCM_CONNECTED, extraInfo_);
}
if (castState == static_cast<int32_t>(CastEngine::DeviceState::DISCONNECTED)) { // 5 is disconnected status
if (collaborationNeedNetworkId_.empty()) {
SLOGI("networkId is empty, try use deviceId:%{public}s",
AVSessionUtils::GetAnonyNetworkId(deviceInfo.deviceId_).c_str());
collaborationNeedNetworkId_ = deviceInfo.deviceId_;
}
CollaborationManagerHiPlay::GetInstance().PublishServiceState(collaborationNeedDeviceId_.c_str(),
ServiceCollaborationManagerBussinessStatus::SCM_IDLE);
CollaborationManagerHiPlay::GetInstance().PublishServiceState(collaborationNeedNetworkId_.c_str(),
ServiceCollaborationManagerBussinessStatus::SCM_IDLE);
}
}
void PcmCastSession::OnSystemCommonEvent(const std::string& args)
{
int32_t code = JsonUtils::GetIntParamFromJsonString(args, "code");
CHECK_AND_RETURN_RET_LOG(CheckIsCasting(), void(), "First connection, castState is 0.");
CHECK_AND_RETURN_RET_LOG(code == 0, void(), "Castmode changes fail, code is %{public}d", code);
int32_t castMode = JsonUtils::GetIntParamFromJsonString(args, "mode");
int32_t uid = JsonUtils::GetIntParamFromJsonString(args, "uid");
std::string deviceId = JsonUtils::GetStringParamFromJsonString(args, "deviceId");
SLOGI("Received HIPLAY_CONFIG_MODE_DATA: castMode=%{public}d, uid=%{public}d, deviceId:%{public}s",
castMode, uid, AVSessionUtils::GetAnonymousDeviceId(deviceId).c_str());
{
std::lock_guard lockGuard(castLock_);
CHECK_AND_RETURN_RET_LOG(!descriptor_.outputDeviceInfo_.deviceInfos_.empty(), void(),
"DeviceInfos is empty");
if (castMode == HiPlayCastMode::DEVICE_LEVEL) {
tempDeviceInfo_.hiPlayDeviceInfo_.castMode_ = HiPlayCastMode::DEVICE_LEVEL;
descriptor_.uid_ = 0;
descriptor_.outputDeviceInfo_.deviceInfos_[0].hiPlayDeviceInfo_.castUid_ = 0;
descriptor_.outputDeviceInfo_.deviceInfos_[0].hiPlayDeviceInfo_.castMode_ = HiPlayCastMode::DEVICE_LEVEL;
} else if (castMode == HiPlayCastMode::APP_LEVEL) {
tempDeviceInfo_.hiPlayDeviceInfo_.castMode_ = HiPlayCastMode::APP_LEVEL;
descriptor_.uid_ = uid;
descriptor_.outputDeviceInfo_.deviceInfos_[0].hiPlayDeviceInfo_.castUid_ = uid;
descriptor_.outputDeviceInfo_.deviceInfos_[0].hiPlayDeviceInfo_.castMode_ = HiPlayCastMode::APP_LEVEL;
}
}
WriteCastPairToFile(deviceId, castMode);
}
void PcmCastSession::OnDeviceInfoCommonEvent(const std::string& args)
{
std::string moduleId = JsonUtils::GetStringParamFromJsonString(args, "modelId");
std::string submoduleId = JsonUtils::GetStringParamFromJsonString(args, "subModelId");
SLOGI("Received UpdateDeviceModuleId: moduleId:%{public}s, submoduleId:%{public}s",
moduleId.c_str(), submoduleId.c_str());
{
std::lock_guard lockGuard(castLock_);
tempDeviceInfo_.hiPlayDeviceInfo_.moduleId_ = moduleId;
tempDeviceInfo_.hiPlayDeviceInfo_.submoduleId_ = submoduleId;
}
}
void PcmCastSession::OnDeviceNameSystemCommonEvent(const std::string& args)
{
std::string deviceName = JsonUtils::GetStringParamFromJsonString(args, "DEVICE_NAME");
SLOGI("Received UPDATE_DEVICE_NAME: deviceName:%{public}s", AVSessionUtils::GetAnonyDeviceName(deviceName).c_str());
std::lock_guard lockGuard(castLock_);
CHECK_AND_RETURN_RET_LOG(!descriptor_.outputDeviceInfo_.deviceInfos_.empty(), void(),
"DeviceInfos is empty");
tempDeviceInfo_.deviceName_ = deviceName;
CHECK_AND_RETURN_LOG(!descriptor_.outputDeviceInfo_.deviceInfos_.empty(), "deviceInfos is empty");
descriptor_.outputDeviceInfo_.deviceInfos_[0].deviceName_ = deviceName;
}
void PcmCastSession::OnCastEventRecv(int32_t errorCode, std::string& errorMsg)
{
SLOGI("PcmCastSession OnCastEventRecv errorCode %{public}d errorMsg %{public}s", errorCode, errorMsg.c_str());
}
int32_t PcmCastSession::StartCast(const OutputDeviceInfo& outputDeviceInfo,
std::pair<std::string, std::string>& serviceNameStatePair, const SessionToken& sessionToken)
{
SLOGI("PcmCastSession StartCast");
CHECK_AND_RETURN_RET_LOG(outputDeviceInfo.deviceInfos_.size() > 0, ERR_INVALID_PARAM, "empty device info");
{
std::lock_guard lockGuard(castLock_);
descriptor_.sessionId_ = sessionToken.sessionId;
}
bool isPcmScreen = (sessionToken.sessionId == "pcmCastSession" &&
((static_cast<uint32_t>(outputDeviceInfo.deviceInfos_[0].supportedProtocols_) &
ProtocolType::TYPE_CAST_PLUS_STREAM) != 0));
if (isPcmScreen) {
AVRouter::GetInstance().OnSystemCommonEvent(QUERY_PINCODE, "");
}
if (castHandle_ > 0 && !isPcmScreen) {
if (castHandleDeviceId_ == outputDeviceInfo.deviceInfos_[0].deviceId_) {
SLOGI("repeat startcast %{public}lld", static_cast<long long>(castHandle_));
SendStateChangeRequest(sessionToken);
{
std::lock_guard lockGuard(castLock_);
descriptor_.uid_ = sessionToken.uid;
CHECK_AND_RETURN_RET_LOG(descriptor_.outputDeviceInfo_.deviceInfos_.size() > 0, ERR_INVALID_PARAM,
"empty device info");
descriptor_.outputDeviceInfo_.deviceInfos_[0].hiPlayDeviceInfo_.castUid_ = sessionToken.uid;
}
return ERR_REPEAT_CAST;
} else {
SLOGI("cast check with pre cast alive %{public}lld, unregister callback",
static_cast<long long>(castHandle_));
{
std::lock_guard lockGuard(castLock_);
multiDeviceState_ = MultiDeviceState::CASTING_SWITCH_DEVICE;
newOutputDeviceInfo_ = outputDeviceInfo;
newSessionToken_ = sessionToken;
newServiceNameStatePair_ = serviceNameStatePair;
}
StopCast(DeviceRemoveAction::ACTION_TO_SWITCH_HIPLAY);
return AVSESSION_SUCCESS;
}
}
OutputDeviceInfo connectOutputDeviceInfo = ConstructConnectOutputDeviceInfo(outputDeviceInfo);
int sourceAllConnectResult = CollaborationManagerHiPlay::GetInstance().CastAddToCollaboration(
connectOutputDeviceInfo.deviceInfos_[0]);
if (sourceAllConnectResult != AVSESSION_SUCCESS) {
AVSessionUtils::PublishCommonEvent(MEDIA_CAST_ERROR);
SLOGE("Collaboration to start cast failed");
return sourceAllConnectResult;
}
return isPcmScreen ? StartScreenCast(connectOutputDeviceInfo, serviceNameStatePair, sessionToken) :
SubStartCast(connectOutputDeviceInfo, serviceNameStatePair, sessionToken);
}
OutputDeviceInfo PcmCastSession::ConstructConnectOutputDeviceInfo(const OutputDeviceInfo& outputDeviceInfo)
{
OutputDeviceInfo connectOutputDeviceInfo = outputDeviceInfo;
if ((static_cast<uint32_t>(outputDeviceInfo.deviceInfos_[0].supportedProtocols_) &
ProtocolType::TYPE_CAST_PLUS_STREAM) != 0) {
connectOutputDeviceInfo.deviceInfos_[0].realDeviceId_ = outputDeviceInfo.deviceInfos_[0].deviceId_;
}
return connectOutputDeviceInfo;
}
int32_t PcmCastSession::StartScreenCast(const OutputDeviceInfo& outputDeviceInfo,
std::pair<std::string, std::string>& serviceNameStatePair, const SessionToken& sessionToken)
{
SLOGI("PcmCastSession StartCastScreen");
// add mutex
std::unique_lock<std::mutex> lock(screenLock_);
bool hasPinCode = startCastCondition_.wait_for(lock, std::chrono::seconds(1), [this] {
return !pinCode_.empty();
});
if (!hasPinCode) {
SLOGI("cannot get the pinCode");
return AVSESSION_ERROR;
}
castHandle_ = AVRouter::GetInstance().StartCast(outputDeviceInfo, serviceNameStatePair, "pcmCastSession");
CHECK_AND_RETURN_RET_LOG(castHandle_ != AVSESSION_ERROR, AVSESSION_ERROR, "StartCast failed");
AVRouter::GetInstance().RegisterCallback(castHandle_, shared_from_this(),
"pcmCastSession", outputDeviceInfo.deviceInfos_[0]);
{
std::lock_guard lockGuard(castLock_);
tempDeviceInfo_ = outputDeviceInfo.deviceInfos_[0];
}
int32_t castId = static_cast<int32_t>(castHandle_);
CastEngine::ConnectionConfig connectionConfig = {};
connectionConfig.triggerType = CastEngine::TriggerType::HIPLAY_SCAN_QRCODE;
connectionConfig.pinCode = pinCode_;
int32_t ret = AVRouter::GetInstance().AddDeviceWithConnectionConfig(castId, outputDeviceInfo, 0, connectionConfig);
if (ret == AVSESSION_SUCCESS) {
castHandleDeviceId_ = outputDeviceInfo.deviceInfos_[0].deviceId_;
SLOGI("PcmCastSession StartCast castHandleDeviceId_: %{public}s", castHandleDeviceId_.c_str());
CreateExtraInfo("TV", "hotel");
needHandleTimer_ = true;
} else {
DestroyTask();
}
SLOGI("PcmCastSession StartCast ret %{public}d", ret);
return ret;
}
int32_t PcmCastSession::SubStartCast(const OutputDeviceInfo& outputDeviceInfo,
std::pair<std::string, std::string>& serviceNameStatePair, const SessionToken& sessionToken)
{
AVSessionSysEvent::GetInstance().updateStartCastTime(PCM_CAST_SESSION,
PCM_CAST_SESSION, PCM_CAST_SESSION, PCM_CAST_SESSION);
castHandle_ = AVRouter::GetInstance().StartCast(outputDeviceInfo, serviceNameStatePair, "pcmCastSession");
CHECK_AND_RETURN_RET_LOG(castHandle_ != AVSESSION_ERROR, AVSESSION_ERROR, "StartCast failed");
AVRouter::GetInstance().RegisterCallback(castHandle_, shared_from_this(),
"pcmCastSession", outputDeviceInfo.deviceInfos_[0]);
bool isDeviceLevel = (sessionToken.sessionId == "pcmCastSession");
int32_t castMode = isDeviceLevel ? HiPlayCastMode::DEVICE_LEVEL : HiPlayCastMode::APP_LEVEL;
{
std::lock_guard lockGuard(castLock_);
tempDeviceInfo_ = outputDeviceInfo.deviceInfos_[0];
tempDeviceInfo_.hiPlayDeviceInfo_.castMode_ = castMode;
descriptor_.uid_ = isDeviceLevel ? 0 : sessionToken.uid;
SLOGI("PcmCastSession StartCast castMode: %{public}d", tempDeviceInfo_.hiPlayDeviceInfo_.castMode_);
}
SendStateChangeRequest(sessionToken);
WriteCastPairToFile(outputDeviceInfo.deviceInfos_[0].deviceId_, castMode);
int32_t castId = static_cast<int32_t>(castHandle_);
int32_t ret = AVRouter::GetInstance().AddDevice(castId, outputDeviceInfo, 0);
if (ret == AVSESSION_SUCCESS) {
castHandleDeviceId_ = outputDeviceInfo.deviceInfos_[0].deviceId_;
SLOGI("PcmCastSession StartCast-castHandle_ %{public}lld", static_cast<long long>(castHandle_));
CreateExtraInfo("SPEAKER", "default");
} else {
DestroyTask();
}
SLOGI("PcmCastSession StartCast ret %{public}d", ret);
return ret;
}
void PcmCastSession::StopCast(const DeviceRemoveAction deviceRemoveAction)
{
SLOGI("PcmCastSession StopCast");
ReleaseStreamPlayer();
needHandleTimer_ = false;
int64_t ret = AVRouter::GetInstance().StopCast(castHandle_, deviceRemoveAction);
SLOGI("StopCast with unchange castHandle is %{public}lld", static_cast<long long>(castHandle_));
CHECK_AND_RETURN_LOG(ret != AVSESSION_ERROR, "StopCast failed");
}
void PcmCastSession::WriteCastPairToFile(const std::string& deviceId, int32_t castMode)
{
CHECK_AND_RETURN_LOG(AVSessionUtils::IsValidFileName(deviceId), "deviceId is not a valid file name");
SLOGI("PcmCastSession start write file");
std::pair<std::string, int32_t> castPair = { deviceId, castMode };
SLOGI("PcmCastSession castPair: deviceId=%{public}s, castMode=%{public}d",
AVSessionUtils::GetAnonymousDeviceId(castPair.first).c_str(), castPair.second);
int32_t userId = AVSessionService::GetUsersManager().GetCurrentUserId();
std::string fileDir = AVSessionUtils::GetFixedPathNameForDevice(userId);
std::string fileName = deviceId + "_cast_pair" + AVSessionUtils::GetPairFileSuffix();
AVSessionUtils::WritePairToFile(castPair, fileDir, fileName);
SLOGI("PcmCastSession ExecuteCommonCommand finished.");
}
int32_t PcmCastSession::SendStateChangeRequest(const SessionToken& sessionToken)
{
cJSON* jsonObj = cJSON_CreateObject();
if (!jsonObj) {
SLOGE("Failed to create cJSON object");
return AVSESSION_ERROR;
}
int32_t castMode = HiPlayCastMode::DEVICE_LEVEL;
{
std::lock_guard lockGuard(castLock_);
castMode = tempDeviceInfo_.hiPlayDeviceInfo_.castMode_;
}
cJSON_AddItemToObject(jsonObj, "mode", cJSON_CreateNumber(castMode));
cJSON_AddItemToObject(jsonObj, "sessionId", cJSON_CreateString(sessionToken.sessionId.c_str()));
cJSON_AddItemToObject(jsonObj, "uid", cJSON_CreateNumber(sessionToken.uid));
SLOGI("SendStateChangeRequest, sessionId=%{public}s, uid=%{public}d, castMode=%{public}d",
AVSessionUtils::GetAnonySessionId(sessionToken.sessionId).c_str(), sessionToken.uid, castMode);
char* jsonStr = cJSON_Print(jsonObj);
if (jsonStr != nullptr) {
std::string params(jsonStr);
cJSON_free(jsonStr);
AVRouter::GetInstance().SendCommandArgsToCast(castHandle_, CAST_MODE_CHANGE_COMMAND, params);
} else {
SLOGE("get jsonStr nullptr");
cJSON_Delete(jsonObj);
return AVSESSION_ERROR;
}
cJSON_Delete(jsonObj);
return AVSESSION_SUCCESS;
}
void PcmCastSession::ExecuteCommonCommand(const std::string& commonCommand, const AAFwk::WantParams& commandArgs)
{
const auto& it = COMMON_COMMAND_MAPS.find(commonCommand);
CHECK_AND_RETURN_LOG(it != COMMON_COMMAND_MAPS.end(), "commonCommand is not support");
switch (it->second) {
case CAST_MODE_CHANGE_COMMAND:
CastStateCommandParams(commandArgs);
break;
case BYPASS_COMMAND_NUM:
BypassCommandParams(commandArgs);
break;
case QUERY_COMMAND_NUM:
QueryCommandParams(commandArgs);
break;
case CONTROL_COMMAND_NUM:
ControlCommandParams(commandArgs);
break;
case UPDATE_DEVICE_NAME_COMMAND:
UpdateDeviceNameCommandParams(commandArgs);
break;
default:
break;
}
}
void PcmCastSession::CastStateCommandParams(const AAFwk::WantParams& commandArgs)
{
SLOGI("PcmCastSession ExecuteCommonCommand process");
std::string params = commandArgs.ToString();
AVRouter::GetInstance().SendCommandArgsToCast(castHandle_, CAST_MODE_CHANGE_COMMAND, params);
}
void PcmCastSession::DestroyTask()
{
SLOGI("PcmCastSession DestroyTask process");
CollaborationManagerHiPlay::GetInstance().PublishServiceState(collaborationNeedDeviceId_.c_str(),
ServiceCollaborationManagerBussinessStatus::SCM_IDLE);
if (!collaborationNeedNetworkId_.empty()) {
CollaborationManagerHiPlay::GetInstance().PublishServiceState(collaborationNeedNetworkId_.c_str(),
ServiceCollaborationManagerBussinessStatus::SCM_IDLE);
}
AVRouter::GetInstance().UnRegisterCallback(castHandle_, shared_from_this(), "pcmCastSession");
AVRouter::GetInstance().StopCastSession(castHandle_);
castHandle_ = -1;
castState_ = CastState::DISCONNECTED;
castHandleDeviceId_ = "-100";
{
std::lock_guard lockGuard(castLock_);
descriptor_.uid_ = 0;
}
}
int32_t PcmCastSession::GetCastMode() const
{
return tempDeviceInfo_.hiPlayDeviceInfo_.castMode_;
}
pid_t PcmCastSession::GetUid() const
{
return descriptor_.uid_;
}
std::string PcmCastSession::GetModuleId()
{
std::lock_guard lockGuard(castLock_);
return tempDeviceInfo_.hiPlayDeviceInfo_.moduleId_;
}
std::string PcmCastSession::GetSubModuleId()
{
std::lock_guard lockGuard(castLock_);
return tempDeviceInfo_.hiPlayDeviceInfo_.submoduleId_;
}
int64_t PcmCastSession::GetCastHandle() const
{
return castHandle_;
}
bool PcmCastSession::CheckIsCasting() const
{
return castState_ != CastState::DISCONNECTED;
}
AVSessionDescriptor PcmCastSession::GetDescriptor()
{
std::lock_guard lockGuard(castLock_);
return descriptor_;
}
void PcmCastSession::BypassCommandParams(const AAFwk::WantParams& commandArgs)
{
std::string commandType = commandArgs.GetStringParam(COMMAND_TYPE);
const auto& it = BYPASS_COMMAND_MAPS.find(commandType);
CHECK_AND_RETURN_LOG(it != BYPASS_COMMAND_MAPS.end(), "bypassCommand is not support");
AAFwk::WantParams commandBody = commandArgs.GetWantParams(COMMAND_BODY);
std::string params = commandBody.ToString();
switch (it->second) {
case BYPASS_TO_CAST_NUM:
AVRouter::GetInstance().SendCommandArgsToCast(castHandle_, BYPASS_COMMAND_NUM, params);
break;
default:
break;
}
}
void PcmCastSession::QueryCommandParams(const AAFwk::WantParams& commandArgs)
{
std::string commandType = commandArgs.GetStringParam(COMMAND_TYPE);
const auto& it = QUERY_COMMAND_MAPS.find(commandType);
CHECK_AND_RETURN_LOG(it != QUERY_COMMAND_MAPS.end(), "queryCommand is not support");
AAFwk::WantParams commandBody = commandArgs.GetWantParams(COMMAND_BODY);
std::string params = commandBody.ToString();
switch (it->second) {
case QUERY_TO_CAST_NUM:
AVRouter::GetInstance().SendCommandArgsToCast(castHandle_, QUERY_COMMAND_NUM, params);
break;
case QUERY_TO_AVSESSION_NUM:
QueryData(commandBody);
break;
default:
break;
}
}
void PcmCastSession::ControlCommandParams(const AAFwk::WantParams& commandArgs)
{
std::string commandType = commandArgs.GetStringParam(COMMAND_TYPE);
const auto& it = CONTROL_COMMAND_MAPS.find(commandType);
CHECK_AND_RETURN_LOG(it != CONTROL_COMMAND_MAPS.end(), "controlCommand is not support");
AAFwk::WantParams commandBody = commandArgs.GetWantParams(COMMAND_BODY);
std::string params = commandBody.ToString();
switch (it->second) {
case SAVE_TO_PCM_NUM:
SaveDataInPcm(commandBody);
break;
case CREATE_STREAM_PLAYER_NUM:
SLOGI("Start to create stream player");
CreateStreamPlayer(commandBody);
break;
case RELEASE_STREAM_PLAYER_NUM:
SLOGI("Start to release stream player");
ReleaseStreamPlayer();
break;
case CHANGE_SCREEN_MODE_NUM:
ReleaseStreamPlayer();
AVRouter::GetInstance().SendCommandArgsToCast(castHandle_, CONTROL_COMMAND_NUM, params);
break;
default:
break;
}
}
void PcmCastSession::UpdateDeviceNameCommandParams(const AAFwk::WantParams& commandArgs)
{
SLOGI("PcmCastSession UpdateDeviceNameCommandParams process");
std::string params = commandArgs.ToString();
OnDeviceNameSystemCommonEvent(params);
}
void PcmCastSession::QueryData(const AAFwk::WantParams& commandBody)
{
std::string key = commandBody.GetStringParam(KEY);
const auto& it = DATA_KEY_MAPS.find(key);
CHECK_AND_RETURN_LOG(it != DATA_KEY_MAPS.end(), "data key is not support");
switch (it->second) {
case CAST_SESSION_ID_NUM:
QueryCastSessionId();
break;
default:
break;
}
}
void PcmCastSession::QueryCastSessionId()
{
std::string castSessionId = AVRouter::GetInstance().QueryCastSessionId(castHandle_);
cJSON* jsonObj = cJSON_CreateObject();
if (!jsonObj) {
SLOGE("Failed to create cJSON object");
return;
}
cJSON_AddItemToObject(jsonObj, "VALUE", cJSON_CreateString(castSessionId.c_str()));
char* jsonStr = cJSON_Print(jsonObj);
if (jsonStr != nullptr) {
std::string jsonParams(jsonStr);
cJSON_free(jsonStr);
AVRouter::GetInstance().OnSystemCommonEvent(CAST_SESSION_ID, jsonParams);
}
cJSON_Delete(jsonObj);
}
void PcmCastSession::SaveDataInPcm(const AAFwk::WantParams& commandBody)
{
std::string key = commandBody.GetStringParam(KEY);
const auto& it = DATA_KEY_MAPS.find(key);
CHECK_AND_RETURN_LOG(it != DATA_KEY_MAPS.end(), "data key is not support");
switch (it->second) {
case PIN_CODE_NUM:
SavePinCode(commandBody);
break;
default:
break;
}
}
void PcmCastSession::SavePinCode(const AAFwk::WantParams& commandBody)
{
std::string value = commandBody.GetStringParam(VALUE);
std::lock_guard<std::mutex> lock(screenLock_);
pinCode_ = value;
startCastCondition_.notify_all();
}
void PcmCastSession::CreateStreamPlayer(const AAFwk::WantParams& commandBody)
{
streamCastingSessionId_ = commandBody.GetStringParam(SESSION_ID);
if (castState_ != CastState::STREAM) {
needStreamCasting_ = true;
return;
}
FindSessionAndStreamCasting();
}
void PcmCastSession::ReleaseStreamPlayer()
{
OutputDeviceInfo outputDeviceInfo;
{
std::lock_guard lockGuard(castLock_);
outputDeviceInfo.deviceInfos_.emplace_back(tempDeviceInfo_);
}
sptr<AVSessionItem> session =
AVSessionService::GetUsersManager().GetContainerFromAll().GetSessionById(streamCastingSessionId_);
CHECK_AND_RETURN_LOG(session != nullptr, "session is not existed");
SLOGI("start to dealoutputdevicechange");
session->SetAndDealOutputDeviceChange(ConnectionState::STATE_DISCONNECTED, outputDeviceInfo);
session->SetCastHandle(-1);
OutputDeviceInfo localDeviceInfo;
DeviceInfo deviceInfo;
deviceInfo.castCategory_ = AVCastCategory::CATEGORY_LOCAL;
deviceInfo.deviceId_ = "0";
deviceInfo.deviceName_ = "LocalDevice";
localDeviceInfo.deviceInfos_.emplace_back(deviceInfo);
session->SetIsHiPlayStreamCasting(false);
session->SetAndDealOutputDeviceChange(ConnectionState::STATE_CONNECTED, localDeviceInfo);
session->ReleaseAVCastControllerInner();
AVRouter::GetInstance().OnSystemCommonEvent(CAST_SESSION_RELEASED, "");
{
std::lock_guard lockGuard(castLock_);
streamCastingSessionId_ = "";
descriptor_.sessionId_ = "pcmCastSession";
}
}
void PcmCastSession::FindSessionAndStreamCasting()
{
OutputDeviceInfo outputDeviceInfo;
{
std::lock_guard lockGuard(castLock_);
outputDeviceInfo.deviceInfos_.emplace_back(tempDeviceInfo_);
}
sptr<AVSessionItem> session =
AVSessionService::GetUsersManager().GetContainerFromAll().GetSessionById(streamCastingSessionId_);
CHECK_AND_RETURN_LOG(session != nullptr, "session is not existed");
SLOGI("start to dealoutputdevicechange");
session->SetIsHiPlayStreamCasting(true);
session->SetCastHandle(castHandle_);
session->SetAndDealOutputDeviceChange(ConnectionState::STATE_CONNECTED, outputDeviceInfo);
}
void PcmCastSession::CreateExtraInfo(std::string deviceType, std::string scenario)
{
cJSON* jsonObj = cJSON_CreateObject();
if (!jsonObj) {
SLOGE("Failed to create cJSON object");
return;
}
cJSON_AddItemToObject(jsonObj, "deviceType", cJSON_CreateString(deviceType.c_str()));
cJSON_AddItemToObject(jsonObj, "scenario", cJSON_CreateString(scenario.c_str()));
if (deviceType == "TV" && scenario == "hotel") {
cJSON_AddItemToObject(jsonObj, "needFastCastControl", cJSON_CreateString("true"));
}
char* jsonStr = cJSON_Print(jsonObj);
if (jsonStr != nullptr) {
std::string jsonParams(jsonStr);
cJSON_free(jsonStr);
extraInfo_ = jsonParams;
}
cJSON_Delete(jsonObj);
}
void PcmCastSession::SendModeChangeToCast(int32_t screenMode)
{
cJSON* jsonObj = cJSON_CreateObject();
if (!jsonObj) {
SLOGE("Failed to create cJSON object");
return;
}
cJSON_AddItemToObject(jsonObj, "mode", cJSON_CreateNumber(screenMode));
char* jsonStr = cJSON_Print(jsonObj);
if (jsonStr != nullptr) {
std::string jsonParams(jsonStr);
cJSON_free(jsonStr);
AVRouter::GetInstance().SendCommandArgsToCast(castHandle_, CONTROL_COMMAND_NUM, jsonParams);
}
cJSON_Delete(jsonObj);
}
} // namespace OHOS::AVSession