mirror of
https://github.com/openharmony/multimedia_av_session.git
synced 2026-08-24 18:26:13 -04:00
9034926149
Signed-off-by: weixin_44014140 <chenyuming12@h-partners.com>
786 lines
32 KiB
C++
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
|