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

3870 lines
156 KiB
C++

/*
* Copyright (c) 2022-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 "av_router.h"
#include "avsession_service.h"
#include "avcontroller_item.h"
#include "avsession_log.h"
#include "avsession_errors.h"
#include "avsession_descriptor.h"
#include "avsession_trace.h"
#include "avsession_sysevent.h"
#include "avsession_storage_event.h"
#include "avsession_utils.h"
#include "remote_session_sink.h"
#include "remote_session_source.h"
#include "remote_session_source_proxy.h"
#include "remote_session_sink_proxy.h"
#include "permission_checker.h"
#include "session_xcollie.h"
#include "avsession_item.h"
#include "avsession_radar.h"
#include "avsession_event_handler.h"
#include "bundle_status_adapter.h"
#include "array_wrapper.h"
#include "bool_wrapper.h"
#include "string_wrapper.h"
#include "int_wrapper.h"
#include "want_agent_helper.h"
#include "avsession_hianalytics_report.h"
#include "avmedia_center_control_type.h"
#include "avsession_whitelist_config_manager.h"
#include "stream_dfx_manager.h"
#include "audio_errors.h"
#include <filesystem>
#include <cinttypes>
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
#include "avcast_controller_proxy.h"
#include "avcast_controller_item.h"
#include "collaboration_manager_urlcasting.h"
#endif
#if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM) and !defined(IOS_PLATFORM)
#include <malloc.h>
#include <string>
#endif
using namespace OHOS::AudioStandard;
namespace OHOS::AVSession {
const std::map<int32_t, std::string> sessionTypeMap_ = {
{AVSession::SESSION_TYPE_VIDEO, "video"},
{AVSession::SESSION_TYPE_VOICE_CALL, "voice_call"},
{AVSession::SESSION_TYPE_VIDEO_CALL, "video_call"},
{AVSession::SESSION_TYPE_PHOTO, "photo"},
};
const std::map<int32_t, int32_t> g_cmdToOffsetMap = {
{AVControlCommand::SESSION_CMD_SET_TARGET_LOOP_MODE, 9},
{AVControlCommand::SESSION_CMD_PLAY, 8},
{AVControlCommand::SESSION_CMD_PAUSE, 7},
{AVControlCommand::SESSION_CMD_PLAY_NEXT, 6},
{AVControlCommand::SESSION_CMD_PLAY_PREVIOUS, 5},
{AVControlCommand::SESSION_CMD_FAST_FORWARD, 4},
{AVControlCommand::SESSION_CMD_REWIND, 3},
{AVControlCommand::SESSION_CMD_SEEK, 2},
{AVControlCommand::SESSION_CMD_SET_LOOP_MODE, 1},
{AVControlCommand::SESSION_CMD_TOGGLE_FAVORITE, 0}
};
enum SendCodeEnum : uint32_t {
OPEN = 1,
CLOSE = 2,
LOCK = 3,
UNLOCK = 4,
};
constexpr int32_t PROGRESS_ADJUST_VALUE = 5;
#ifdef ENABLE_AVSESSION_SYSEVENT_CONTROL
static const int32_t CONTROL_COLD_START = 2;
#endif
AVSessionItem::AVSessionItem(const AVSessionDescriptor& descriptor, int32_t userId, AVSessionItemExtension *extension)
: descriptor_(descriptor), userId_(userId), extension_(extension)
{
SLOGI("constructor session id=%{public}s, userId=%{public}d",
AVSessionUtils::GetAnonySessionId(descriptor_.sessionId_).c_str(), userId_);
{
std::lock_guard aliveLockGuard(isAliveLock_);
isAlivePtr_ = std::make_shared<bool>(true);
}
STORAGE_EVENT_RECORD_SESSION(descriptor_.sessionId_, GetBundleName(), userId_);
}
void AVSessionItem::InitListener()
{
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
SLOGI("session init listener");
cssListener_ = std::make_shared<CssListener>(sptr<AVSessionItem>(this));
InitCastEventHandlers();
#endif
}
AVSessionItem::~AVSessionItem()
{
SLOGI("destroy with aliveLock session id=%{public}s, userId=%{public}d",
AVSessionUtils::GetAnonySessionId(descriptor_.sessionId_).c_str(), userId_);
if (IsActive()) {
Deactivate();
}
{
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
std::lock_guard callbackForCastCapLockGuard(callbackForCastCapLock_);
if (castControllerProxy_ != nullptr) {
castControllerProxy_->SetSessionCallbackForCastCap(nullptr);
}
#endif
}
{
std::lock_guard aliveLockGuard(isAliveLock_);
if (isAlivePtr_ != nullptr) {
*isAlivePtr_ = false;
}
}
}
// LCOV_EXCL_START
std::string AVSessionItem::GetSessionId()
{
return descriptor_.sessionId_;
}
std::string AVSessionItem::GetSessionType()
{
auto iter = sessionTypeMap_.find(descriptor_.sessionType_);
if (iter != sessionTypeMap_.end()) {
return iter->second;
} else {
return "audio";
}
}
std::string AVSessionItem::GetSessionTag()
{
return descriptor_.sessionTag_;
}
// LCOV_EXCL_STOP
void AVSessionItem::UpdateSessionElement(const AppExecFwk::ElementName& elementName)
{
descriptor_.elementName_ = elementName;
}
int32_t AVSessionItem::Destroy()
{
SLOGI("AVSessionItem check service destroy event with service, check serviceCallback exist");
{
std::lock_guard lockGuard(destroyLock_);
if (isDestroyed_.load()) {
SLOGE("AVSessionItem Destroy process but check already destroyed");
return AVSESSION_SUCCESS;
}
}
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "Destroy", "BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_, "SESSION_TYPE", GetSessionType(),
"ERROR_CODE", AVSESSION_SUCCESS, "ERROR_MSG", "SUCCESS");
if (serviceCallback_) {
SLOGI("AVSessionItem send service destroy event to service");
serviceCallback_(*this);
}
return AVSESSION_SUCCESS;
}
void AVSessionItem::DelRecommend()
{
CHECK_AND_RETURN_LOG(descriptor_.sessionTag_ != "RemoteCast", "remote cast session, return");
if (isRecommend_) {
AVSessionHiAnalyticsReport::PublishRecommendInfo(GetBundleName(), "", "", "", -1);
isRecommend_ = false;
}
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
CHECK_AND_RETURN_LOG(castHandle_ > 0, "delete recommend without casthandler");
PublishAVCastHa(disconnectStateFromCast_, GetDescriptor().outputDeviceInfo_.deviceInfos_[0]);
#endif
}
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
void AVSessionItem::DestroyCast(bool continuePlay)
{
if (descriptor_.sessionTag_ != "RemoteCast" && castHandle_ > 0) {
if (serviceCallbackForPhotoCast_ && descriptor_.sessionType_ == AVSession::SESSION_TYPE_PHOTO) {
serviceCallbackForPhotoCast_(descriptor_.sessionId_, false);
}
CollaborationManagerURLCasting::GetInstance().PublishServiceState(collaborationNeedDeviceId_.c_str(),
ServiceCollaborationManagerBussinessStatus::SCM_IDLE);
if (!collaborationNeedNetworkId_.empty()) {
CollaborationManagerURLCasting::GetInstance().PublishServiceState(collaborationNeedNetworkId_.c_str(),
ServiceCollaborationManagerBussinessStatus::SCM_IDLE);
}
AVRouter::GetInstance().UnRegisterCallback(castHandle_, cssListener_, GetSessionId());
ReleaseCast(continuePlay);
StopCastSession();
}
}
#endif
int32_t AVSessionItem::DestroyTask(bool continuePlay)
{
{
std::lock_guard lockGuard(destroyLock_);
CHECK_AND_RETURN_RET_LOG(!isDestroyed_.load(), AVSESSION_SUCCESS, "session is already destroyed.");
isDestroyed_.store(true);
}
std::string sessionId = descriptor_.sessionId_;
std::string fileNameLocal = AVSessionUtils::GetCachePathName(userId_) + sessionId + AVSessionUtils::GetFileSuffix();
AVSessionUtils::DeleteFile(fileNameLocal);
STORAGE_EVENT_RECORD_FILE_DELETE(fileNameLocal, userId_);
std::string fileNameCast =
AVSessionUtils::GetCachePathNameForCast(userId_) + sessionId + AVSessionUtils::GetFileSuffix();
AVSessionUtils::DeleteFile(fileNameCast);
STORAGE_EVENT_RECORD_FILE_DELETE(fileNameCast, userId_);
DelRecommend();
std::list<sptr<AVControllerItem>> controllerList;
{
std::lock_guard controllerLockGuard(controllersLock_);
for (auto it = controllers_.begin(); it != controllers_.end();) {
if (it->second) {
controllerList.push_back(it->second);
}
it = controllers_.erase(it);
}
}
for (auto& controller : controllerList) {
controller->HandleSessionDestroy();
}
{
std::lock_guard lockGuard(callbackLock_);
if (callback_) {
callback_.clear();
}
}
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
SLOGI("Session destroy with castHandle: %{public}lld", (long long)castHandle_);
DestroyCast(continuePlay);
ReleaseAVCastControllerInner();
StopCastDisplayListener();
#endif
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::SetAVCallMetaData(const AVCallMetaData& avCallMetaData)
{
std::lock_guard lockGuard(avsessionItemLock_);
CHECK_AND_RETURN_RET_LOG(avCallMetaData_.CopyFrom(avCallMetaData), AVSESSION_ERROR, "AVCallMetaData set error");
{
std::unique_lock<std::shared_mutex> lock(writeAndReadImgLock_);
std::shared_ptr<AVSessionPixelMap> innerPixelMap = avCallMetaData_.GetMediaImage();
if (innerPixelMap != nullptr) {
std::string sessionId = GetSessionId();
std::string fileDir = AVSessionUtils::GetCachePathName(userId_);
std::string fileName = sessionId + AVSessionUtils::GetFileSuffix();
AVSessionUtils::WriteImageToFile(innerPixelMap, fileDir, fileName);
STORAGE_EVENT_RECORD_FILE_WRITE(fileDir + fileName, GetBundleName(), userId_);
innerPixelMap->Clear();
avCallMetaData_.SetMediaImage(innerPixelMap);
}
}
{
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
controller->HandleAVCallMetaDataChange(avCallMetaData);
}
}
}
return AVSESSION_SUCCESS;
}
// LCOV_EXCL_START
int32_t AVSessionItem::SetAVCallState(const AVCallState& avCallState)
{
{
std::lock_guard lockGuard(avsessionItemLock_);
CHECK_AND_RETURN_RET_LOG(avCallState_.CopyFrom(avCallState), AVSESSION_ERROR, "AVCallState set error");
}
{
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
controller->HandleAVCallStateChange(avCallState);
}
}
}
return AVSESSION_SUCCESS;
}
// LCOV_EXCL_STOP
int32_t AVSessionItem::GetAVMetaData(AVMetaData& meta)
{
std::lock_guard lockGuard(avsessionItemLock_);
SessionXCollie sessionXCollie("avsession::GetAVMetaData");
std::shared_ptr<AVSessionPixelMap> innerPixelMap = metaData_.GetMediaImage();
ReadMetaDataImg(innerPixelMap);
std::shared_ptr<AVSessionPixelMap> avQueuePixelMap = metaData_.GetAVQueueImage();
ReadMetaDataAVQueueImg(avQueuePixelMap);
meta = metaData_;
return AVSESSION_SUCCESS;
}
// LCOV_EXCL_START
int32_t AVSessionItem::ProcessFrontSession(const std::string& source)
{
SLOGI("directlyHandle %{public}s ", source.c_str());
HandleFrontSession();
return AVSESSION_SUCCESS;
}
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
void AVSessionItem::UpdateRecommendInfo(bool needRecommend)
{
if (descriptor_.sessionTag_ == "RemoteCast") {
return;
}
AVMetaData meta;
AAFwk::WantParams extra;
{
std::lock_guard lockGuard(avsessionItemLock_);
meta = metaData_;
extra = extras_;
}
SLOGI("assetChange:%{public}d AddFront:%{public}d supportCast:%{public}d filter:%{public}d duration:%{public}d",
isRecommendMediaChange_, isFirstAddToFront_, IsAppSupportCast(), meta.GetFilter(),
static_cast<int>(meta.GetDuration()));
if (needRecommend) {
if (isRecommendMediaChange_ && !isFirstAddToFront_ && IsAppSupportCast() && meta.GetDuration() != 0) {
isRecommendMediaChange_ = false;
isRecommend_ = true;
AVSessionHiAnalyticsReport::PublishRecommendInfo(GetBundleName(), GetSessionId(),
GetSessionType(), meta.GetAssetId(), meta.GetDuration());
}
} else {
if (isRecommend_) {
isRecommendMediaChange_ = true;
AVSessionHiAnalyticsReport::PublishRecommendInfo(GetBundleName(), GetSessionId(), GetSessionType(),
metaData_.GetAssetId(), -1);
}
}
}
#endif
void AVSessionItem::HandleFrontSession()
{
bool isMetaEmpty;
bool isCastMetaEmpty;
bool isSupportedCmdEmpty;
bool isSupportedCastCmdsEmpty;
{
std::lock_guard lockGuard(avsessionItemLock_);
isMetaEmpty = (metaData_.GetTitle().empty() && metaData_.GetMediaImage() == nullptr);
AVQueueItem item;
GetCurrentCastItem(item);
isCastMetaEmpty = (item.GetDescription() == nullptr ||
(item.GetDescription()->GetTitle().empty() && item.GetDescription()->GetIconUri().empty()));
isSupportedCmdEmpty = supportedCmd_.empty();
isSupportedCastCmdsEmpty = supportedCastCmds_.empty();
SLOGI("bundle=%{public}s MetaEmpty=%{public}d CastMetaEmpty=%{public}d Cmd=%{public}d "
"castCmd=%{public}d first%{public}d",
GetBundleName().c_str(), isMetaEmpty, isCastMetaEmpty, static_cast<int32_t>(supportedCmd_.size()),
static_cast<int32_t>(supportedCastCmds_.size()), isFirstAddToFront_);
}
bool needRemoveNtfInMirror = false;
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
// stream to mirror state remove notification
needRemoveNtfInMirror = !AVRouter::GetInstance().IsInMirrorToStreamState() &&
(AVRouter::GetInstance().GetMirrorCastHandle() != -1) &&
(isMetaEmpty || isSupportedCmdEmpty);
#endif
if ((isMetaEmpty && isCastMetaEmpty) ||
(isSupportedCmdEmpty && isSupportedCastCmdsEmpty) || needRemoveNtfInMirror) {
if (!isFirstAddToFront_ && serviceCallbackForUpdateSession_) {
serviceCallbackForUpdateSession_(GetSessionId(), false);
isFirstAddToFront_ = true;
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
UpdateRecommendInfo(false);
#endif
}
} else {
if (isFirstAddToFront_ && serviceCallbackForUpdateSession_) {
serviceCallbackForUpdateSession_(GetSessionId(), true);
isFirstAddToFront_ = false;
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
UpdateRecommendInfo(true);
#endif
}
}
}
bool AVSessionItem::HasAvQueueInfo()
{
std::lock_guard lockGuard(avsessionItemLock_);
if (metaData_.GetAVQueueName().empty() || metaData_.GetAVQueueId().empty()) {
SLOGD("avqueuename or avqueueid is empty");
return false;
}
if (metaData_.GetAVQueueImage() == nullptr && metaData_.GetAVQueueImageUri().empty()) {
SLOGD("avqueue img is empty");
return false;
}
if (playbackState_.GetState() != AVPlaybackState::PLAYBACK_STATE_PLAY) {
SLOGD("current avqueueinfo is not playing");
return false;
}
return true;
}
void AVSessionItem::ReportSetAVMetaDataInfo(const AVMetaData& meta)
{
std::string mediaImage = "false";
std::string avQueueImage = "false";
if (meta.GetMediaImage() != nullptr || !(meta.GetMediaImageUri().empty())) {
mediaImage = "true";
}
if (meta.GetAVQueueImage() != nullptr || !(meta.GetAVQueueImageUri().empty())) {
avQueueImage = "true";
}
std::string apiParamString = "assetId: " + meta.GetAssetId() + ", "
+ "artist: " + meta.GetArtist() + ", "
+ "title: " + meta.GetTitle() + ", "
+ "subtitle: " + meta.GetSubTitle() + ", "
+ "avQueueId: " + meta.GetAVQueueId() + ", "
+ "duration: " + std::to_string(meta.GetDuration()) + ", "
+ "avQueueName: " + meta.GetAVQueueName() + ", "
+ "mediaImage: " + mediaImage + ", "
+ "avqueueImage: " + avQueueImage + ", "
+ "filter: " + std::to_string(meta.GetFilter());
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR", "API_NAME", "SetAVMetaData",
"BUNDLE_NAME", GetBundleName(), "SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_, "SESSION_TYPE", GetSessionType(), "API_PARAM", apiParamString,
"ERROR_CODE", AVSESSION_SUCCESS, "ERROR_MSG", "SUCCESS");
}
bool AVSessionItem::CheckTitleChange(const AVMetaData& meta)
{
bool isTitleChange = metaData_.GetTitle() != meta.GetTitle();
bool isAncoTitleLyric = GetUid() == audioBrokerUid && meta.GetArtist().find("-") != std::string::npos;
bool isTitleLyric = (GetBundleName() == defaultBundleName && !meta.GetDescription().empty()) || isAncoTitleLyric;
SLOGI("isTitleLyric:%{public}d isAncoTitleLyric:%{public}d isTitleChange:%{public}d",
isTitleLyric, isAncoTitleLyric, isTitleChange);
return isTitleChange && !isTitleLyric;
}
void AVSessionItem::CheckUseAVMetaData(const AVMetaData& meta)
{
bool hasPixelMap = (meta.GetMediaImage() != nullptr);
SLOGI("MediaCapsule addLocalCapsule hasImage_:%{public}d isMediaChange_:%{public}d", hasPixelMap, isMediaChange_);
if (isMediaChange_) {
if (descriptor_.sessionType_ == AVSession::SESSION_TYPE_PHOTO) {
SLOGI("photo MediaChange");
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
if (serviceCallbackForPhotoCast_ && IsCasting()) {
serviceCallbackForPhotoCast_(GetSessionId(), true);
isMediaChange_ = false;
}
#endif
} else if (serviceCallbackForNtf_ && hasPixelMap) {
serviceCallbackForNtf_(GetSessionId(), isMediaChange_);
isMediaChange_ = false;
}
}
ProcessFrontSession("SetAVMetaData");
if (HasAvQueueInfo() && serviceCallbackForAddAVQueueInfo_) {
serviceCallbackForAddAVQueueInfo_(*this);
}
{
std::lock_guard lockGuard(avsessionItemLock_);
std::shared_ptr<AVSessionPixelMap> avQueueImg = meta.GetAVQueueImage();
if (avQueueImg != nullptr && avQueueImg->GetInnerImgBuffer().size() > 0 &&
!metaData_.GetAVQueueName().empty() && !metaData_.GetAVQueueId().empty()) {
std::string fileDir = AVSessionUtils::GetFixedPathName(userId_);
std::string fileName = GetBundleName() + "_" + meta.GetAVQueueId() + AVSessionUtils::GetFileSuffix();
CHECK_AND_RETURN_LOG(AVSessionUtils::IsValidFileName(fileName), "fileName is not valid");
SLOGI("save avQueueImg to file for %{public}s", meta.GetAVQueueId().c_str());
AVSessionUtils::WriteImageToFile(avQueueImg, fileDir, fileName);
STORAGE_EVENT_RECORD_FILE_WRITE(fileDir + fileName, GetBundleName(), userId_);
avQueueImg->Clear();
}
}
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
bool isSupportCast = IsAppSupportCast() && GetMetaDataWithoutImg().GetDuration() != 0;
SLOGI("UpdateRecommendInfo isSupportCast %{public}d", isSupportCast);
UpdateRecommendInfo(isSupportCast);
#endif
}
int32_t AVSessionItem::UpdateAVQueueInfo(const AVQueueInfo& info)
{
std::shared_ptr<AVSessionPixelMap> innerPixelMap = info.GetAVQueueImage();
if (innerPixelMap != nullptr) {
std::string fileDir = AVSessionUtils::GetFixedPathName(userId_);
std::string fileName = GetBundleName() + "_" + info.GetAVQueueId() + AVSessionUtils::GetFileSuffix();
CHECK_AND_RETURN_RET_LOG(AVSessionUtils::IsValidFileName(fileName), AVSESSION_ERROR,
"fileName not valid");
std::string filePath = fileDir + fileName;
std::filesystem::path resolvedPath = std::filesystem::absolute(filePath);
CHECK_AND_RETURN_RET_LOG(resolvedPath.string().find(fileDir) != std::string::npos, AVSESSION_ERROR,
"check fileName not valid");
SLOGI("write image to file for %{public}s", info.GetAVQueueId().c_str());
AVSessionUtils::WriteImageToFile(innerPixelMap, fileDir, fileName);
STORAGE_EVENT_RECORD_FILE_WRITE(filePath, GetBundleName(), userId_);
innerPixelMap->Clear();
}
return AVSESSION_SUCCESS;
}
void AVSessionItem::UpdateMetaData(const AVMetaData& meta)
{
std::lock_guard lockGuard(avsessionItemLock_);
SessionXCollie sessionXCollie("avsession::SetAVMetaData");
ReportSetAVMetaDataInfo(meta);
if ((metaData_.GetAssetId() != meta.GetAssetId()) || CheckTitleChange(meta)) {
isMediaChange_ = true;
isRecommendMediaChange_ = true;
SetLyricTitle(meta.GetTitle());
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
if (AVRouter::GetInstance().IsStreamToMirrorFromSink()) {
isMediaChangeForMirrorToStream_.store(true);
if (serviceCallbackForStream_) {
SLOGI("AVSessionItem send mirrortostream event to service after metadata change");
serviceCallbackForStream_(GetSessionId());
}
}
#endif
}
std::string oldImageUri = metaData_.GetMediaImageUri();
CHECK_AND_RETURN_LOG(metaData_.CopyFrom(meta), "AVMetaData set error");
std::unique_lock<std::shared_mutex> lock(writeAndReadImgLock_);
std::shared_ptr<AVSessionPixelMap> innerPixelMap = metaData_.GetMediaImage();
if (innerPixelMap != nullptr) {
std::string fileDir = AVSessionUtils::GetCachePathName(userId_);
std::shared_ptr<AVSessionPixelMap> oldPixelMap = std::make_shared<AVSessionPixelMap>();
std::string fileName = GetSessionId() + AVSessionUtils::GetFileSuffix();
AVSessionUtils::ReadImageFromFile(oldPixelMap, fileDir, fileName);
if (oldPixelMap == nullptr || oldImageUri != metaData_.GetMediaImageUri() ||
oldPixelMap->GetInnerImgBuffer() != innerPixelMap->GetInnerImgBuffer()) {
isMediaChange_ = true;
}
AVSessionUtils::WriteImageToFile(innerPixelMap, fileDir, fileName);
STORAGE_EVENT_RECORD_FILE_WRITE(fileDir + fileName, GetBundleName(), userId_);
innerPixelMap->Clear();
std::shared_ptr<AVSessionPixelMap> newPixelMap = std::make_shared<AVSessionPixelMap>();
metaData_.SetMediaImage(newPixelMap);
}
}
void AVSessionItem::ReadMediaAndAVQueueImg(AVMetaData::MetaMaskType recordFilter, AVMetaData& oldData,
AVMetaData newData)
{
if (recordFilter.test(AVMetaData::META_KEY_AVQUEUE_IMAGE) && newData.GetAVQueueImage() != nullptr &&
newData.GetAVQueueImage()->GetInnerImgBuffer().size() > 0 && !newData.GetAVQueueName().empty() &&
!newData.GetAVQueueId().empty()) {
std::shared_ptr<AVSessionPixelMap> avQueueImage = oldData.GetAVQueueImage();
ReadMetaDataAVQueueImg(avQueueImage);
if (avQueueImage != nullptr && avQueueImage->GetInnerImgBuffer().size() > 0) {
oldData.SetAVQueueImage(avQueueImage);
}
}
if (recordFilter.test(AVMetaData::META_KEY_MEDIA_IMAGE) && newData.GetMediaImage() != nullptr &&
newData.GetMediaImage()->GetInnerImgBuffer().size() > 0) {
std::shared_ptr<AVSessionPixelMap> mediaImage = oldData.GetMediaImage();
ReadMetaDataImg(mediaImage);
if (mediaImage != nullptr && mediaImage->GetInnerImgBuffer().size() > 0) {
oldData.SetMediaImage(mediaImage);
}
}
}
std::map<pid_t, sptr<AVControllerItem>> AVSessionItem::GetControllerMap()
{
std::lock_guard controllerLockGuard(controllersLock_);
return controllers_;
}
int32_t AVSessionItem::SetAVMetaData(const AVMetaData& meta)
{
AVMetaData::MetaMaskType recordFilter;
AVMetaData::MetaMaskType changedDataMask;
{
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
AVMetaData::MetaMaskType controllerFilter;
controller->GetMetaFilter(controllerFilter);
if (!controllerFilter.all()) {
recordFilter |= controllerFilter;
}
}
}
}
if (recordFilter.any()) {
std::lock_guard lockGuard(avsessionItemLock_);
ReadMediaAndAVQueueImg(recordFilter, metaData_, meta);
changedDataMask = metaData_.GetChangedDataMask(recordFilter, meta);
}
UpdateMetaData(meta);
CheckUseAVMetaData(meta);
SLOGI("send metadata change event to controllers with title %{public}s from pid:%{public}d, isAlive:%{public}d",
AVSessionUtils::GetAnonyTitle(meta.GetTitle()).c_str(),
static_cast<int>(GetPid()), (isAlivePtr_ == nullptr) ? -1 : *isAlivePtr_);
AVSessionEventHandler::GetInstance().AVSessionPostTask([this, meta, isAlivePtr = isAlivePtr_, changedDataMask]() {
std::lock_guard aliveLockGuard(isAliveLock_);
CHECK_AND_RETURN_LOG(isAlivePtr != nullptr && *isAlivePtr, "handle metadatachange with session gone, return");
SLOGI("HandleMetaDataChange in postTask with title %{public}s",
AVSessionUtils::GetAnonyTitle(meta.GetTitle()).c_str());
auto controllers = GetControllerMap();
for (const auto& [pid, controller] : controllers) {
if (controller != nullptr) {
controller->HandleMetaDataChange(meta, changedDataMask);
}
}
}, "HandleMetaDataChange", 0);
std::lock_guard remoteSourceLockGuard(remoteSourceLock_);
if (remoteSource_ != nullptr) {
SLOGI("set remote AVMetaData");
auto ret = remoteSource_->SetAVMetaData(meta);
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "SetAVMetaData failed");
}
#ifdef ENABLE_AVSESSION_SYSEVENT_CONTROL
ReportMetadataChange(meta);
#endif
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::GetAVQueueItems(std::vector<AVQueueItem>& items)
{
std::lock_guard lock_guard(avsessionItemLock_);
items = queueItems_;
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::SetAVQueueItems(const std::vector<AVQueueItem>& items)
{
{
std::lock_guard lock_guard(avsessionItemLock_);
queueItems_ = items;
}
{
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
controller->HandleQueueItemsChange(items);
}
}
}
std::lock_guard remoteSourceLockGuard(remoteSourceLock_);
if (remoteSource_ != nullptr) {
auto ret = remoteSource_->SetAVQueueItems(items);
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "SetAVQueueItems failed");
}
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::GetAVQueueTitle(std::string& title)
{
std::lock_guard lockGuard(avsessionItemLock_);
title = queueTitle_;
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::SetAVQueueTitle(const std::string& title)
{
{
std::lock_guard lockGuard(avsessionItemLock_);
queueTitle_ = title;
}
{
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
controller->HandleQueueTitleChange(title);
}
}
}
std::lock_guard remoteSourceLockGuard(remoteSourceLock_);
if (remoteSource_ != nullptr) {
auto ret = remoteSource_->SetAVQueueTitle(title);
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "SetAVQueueTitle failed");
}
return AVSESSION_SUCCESS;
}
void AVSessionItem::SendCustomDataInner(const AAFwk::WantParams& data)
{
std::lock_guard controllerLockGuard(controllersLock_);
if (controllers_.size() > 0) {
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
controller->HandleCustomData(data);
}
}
}
}
int32_t AVSessionItem::SendCustomData(const AAFwk::WantParams& data)
{
CHECK_AND_RETURN_RET_LOG(data.HasParam("customData"), AVSESSION_ERROR, "Params don't have customData");
auto value = data.GetParam("customData");
AAFwk::IString* stringValue = AAFwk::IString::Query(value);
CHECK_AND_RETURN_RET_LOG(stringValue != nullptr, AVSESSION_ERROR, "customData is an invalid string");
SendCustomDataInner(data);
return AVSESSION_SUCCESS;
}
void AVSessionItem::CheckIfSendCapsule(const AVPlaybackState& state)
{
if (GetUid() != audioBrokerUid) {
return;
}
if (state.GetState() == AVPlaybackState::PLAYBACK_STATE_PLAY && (!isPlayingState_.load() || isMediaChange_)) {
isPlayingState_.store(true);
{
std::lock_guard mediaSessionLockGuard(mediaSessionCallbackLock_);
if (serviceCallbackForMediaSession_) {
SLOGI("anco capsule add for %{public}s", GetBundleName().c_str());
serviceCallbackForMediaSession_(GetSessionId(), true, false);
}
}
} else if (state.GetState() == AVPlaybackState::PLAYBACK_STATE_PAUSE ||
state.GetState() == AVPlaybackState::PLAYBACK_STATE_STOP) {
isPlayingState_.store(false);
AVSessionEventHandler::GetInstance().AVSessionRemoveTask("CancelAncoMediaCapsule");
auto weakSelf = wptr<AVSessionItem>(this);
AVSessionEventHandler::GetInstance().AVSessionPostTask(
[weakSelf]() {
auto shardPtr = weakSelf.promote();
CHECK_AND_RETURN_LOG(shardPtr != nullptr, "CheckIfSendCapsule session is null");
{
std::lock_guard lockGuard(shardPtr->destroyLock_);
CHECK_AND_RETURN_LOG(!shardPtr->isDestroyed_.load(), "CheckIfSendCapsule session is destroy");
}
std::lock_guard mediaSessionLockGuard(shardPtr->mediaSessionCallbackLock_);
if (shardPtr->serviceCallbackForMediaSession_ && !shardPtr->isPlayingState_.load()) {
SLOGI("anco capsule del for %{public}s", shardPtr->GetBundleName().c_str());
shardPtr->serviceCallbackForMediaSession_(shardPtr->GetSessionId(), false, false);
}
}, "CancelAncoMediaCapsule", cancelTimeoutMs);
} else {
SLOGD("CheckIfSendCapsule not valid state, dont proc capsule");
}
}
void AVSessionItem::GetCurrentAppIndexForSession()
{
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
CHECK_AND_RETURN_LOG(samgr != nullptr, "GetSystemAbilityManager return nullptr");
sptr<IRemoteObject> object = samgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
CHECK_AND_RETURN_LOG(object != nullptr, "GetSystemAbility return nullptr");
sptr<OHOS::AppExecFwk::IBundleMgr> bms = iface_cast<OHOS::AppExecFwk::IBundleMgr>(object);
CHECK_AND_RETURN_LOG(bms != nullptr, "GetBundleMgr return nullptr");
std::string bundleName;
int32_t appIndex = 0;
auto ret = bms->GetNameAndIndexForUid(GetUid(), bundleName, appIndex);
CHECK_AND_RETURN_LOG(ret == AVSESSION_SUCCESS, "GetNameAndIndexForUid failed");
{
std::lock_guard lockGuard(avsessionItemLock_);
appIndex_ = appIndex;
}
}
AbilityRuntime::WantAgent::WantAgent AVSessionItem::CreateWantAgentWithIndex(
const AbilityRuntime::WantAgent::WantAgent& ability, int32_t index)
{
std::shared_ptr<AAFwk::Want> want = std::make_shared<AAFwk::Want>();
std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> launchWantAgent =
std::make_shared<AbilityRuntime::WantAgent::WantAgent>(ability);
int res = AVSESSION_ERROR;
if (want != nullptr && launchWantAgent != nullptr) {
res = AbilityRuntime::WantAgent::WantAgentHelper::GetWant(launchWantAgent, want);
}
if (res == AVSESSION_SUCCESS && want != nullptr) {
AAFwk::WantParams params = want->GetParams();
params.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, AAFwk::Integer::Box(index));
want->SetParams(params);
}
std::vector<AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags = {
AbilityRuntime::WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG
};
std::vector<std::shared_ptr<AAFwk::Want>> wants{ want };
AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
0,
AbilityRuntime::WantAgent::WantAgentConstant::OperationType::START_ABILITIES,
flags,
wants,
nullptr
);
auto launchAbility = AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo, GetUserId(), GetUid());
CHECK_AND_RETURN_RET_LOG(launchAbility != nullptr, ability, "CreateWantAgentWithIndex failed");
return *launchAbility;
}
AVPlaybackState::PlaybackStateMaskType AVSessionItem::GetControlItemsPlaybackFilter()
{
AVPlaybackState::PlaybackStateMaskType recordFilter;
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
AVPlaybackState::PlaybackStateMaskType controllerFilter;
controller->GetPlaybackFilter(controllerFilter);
if (!controllerFilter.all()) {
recordFilter |= controllerFilter;
}
}
}
return recordFilter;
}
int32_t AVSessionItem::SetAVPlaybackState(const AVPlaybackState& state)
{
AVPlaybackState::PlaybackStateMaskType recordFilter = GetControlItemsPlaybackFilter();
AVPlaybackState::PlaybackStateMaskType changedStateMask;
{
std::lock_guard lockGuard(avsessionItemLock_);
if (recordFilter.any()) {
changedStateMask = playbackState_.GetChangedStateMask(recordFilter, state);
}
CHECK_AND_RETURN_RET_LOG(playbackState_.CopyFrom(state), AVSESSION_ERROR, "AVPlaybackState set error");
}
if (HasAvQueueInfo() && serviceCallbackForAddAVQueueInfo_) {
serviceCallbackForAddAVQueueInfo_(*this);
}
CheckIfSendCapsule(state);
{
std::lock_guard controllerLockGuard(controllersLock_);
SLOGD("send HandlePlaybackStateChange in postTask with state %{public}d and controller size %{public}d",
state.GetState(), static_cast<int>(controllers_.size()));
if (controllers_.size() > 0) {
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
controller->HandlePlaybackStateChange(state, changedStateMask);
}
}
}
}
std::string isFavor = state.GetFavorite()? "true" : "false";
std::string apiParamString = "state: " + std::to_string(state.GetState()) + ", "
+ "elapsedTime: " + std::to_string(state.GetPosition().elapsedTime_) + ", "
+ "updateTime: " + std::to_string(state.GetPosition().updateTime_) + ", "
+ "loopMode: " + std::to_string(state.GetLoopMode()) + ", "
+ "isFavorite: " + isFavor;
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "SetAVPlaybackState", "BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_,
"SESSION_TYPE", GetSessionType(), "API_PARAM", apiParamString,
"ERROR_CODE", AVSESSION_SUCCESS, "ERROR_MSG", "SUCCESS");
std::lock_guard remoteSourceLockGuard(remoteSourceLock_);
if (remoteSource_ != nullptr) {
remoteSource_->SetAVPlaybackState(state);
}
#ifdef ENABLE_AVSESSION_SYSEVENT_CONTROL
ReportPlaybackState(state);
#endif
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::GetAVPlaybackState(AVPlaybackState& state)
{
std::lock_guard lockGuard(avsessionItemLock_);
state = playbackState_;
return AVSESSION_SUCCESS;
}
// LCOV_EXCL_STOP
void AVSessionItem::SetDesktopLyricFeatureSupported(bool isSupported)
{
SLOGI("Set up support for desktop lyrics: isSupported=%{public}d", isSupported);
isSupportedDesktopLyric_ = isSupported;
}
int32_t AVSessionItem::EnableDesktopLyric(bool isEnabled)
{
CHECK_AND_CALL_FUNC_RETURN_RET_LOG(isSupportedDesktopLyric_.load(), ERR_DESKTOPLYRIC_NOT_SUPPORT,
AudioStandard::StreamDfxManager::GetInstance().SendAudioErrorEvent(static_cast<int32_t>(getuid()),
AudioStandard::AVSESSION_CONTROL_DESKTOPLYRIC_NOT_SUPPORT_LOCAL_SET,
"The desktop lyrics feature is not supported", false), "The desktop lyrics feature is not supported.");
SLOGI("enable desktop lyrics: isEnable=%{public}d", isEnabled);
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "EnableDesktopLyric", "BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_, "SESSION_TYPE", GetSessionType(),
"API_PARAM", "isEnabled: " + std::to_string(isEnabled),
"APP_VERSION_NAME", BundleStatusAdapter::GetInstance().GetAppVersion(GetBundleName()),
"COST_TIME", 0,
"OS_VERSION", AVSessionSysEvent::GetInstance().GetOsVersion(),
"SDK_VERSION", AVSessionSysEvent::GetInstance().GetSdkVersion(),
"ERROR_CODE", AVSESSION_SUCCESS, "ERROR_MSG", "SUCCESS");
isEnabledDesktopLyric_ = isEnabled;
if (isEnabledDesktopLyric_ == false) {
isDesktopLyricVisible_ = false;
desktopLyricState_.isLocked_ = false;
}
{
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto& [pid, controller] : controllers_) {
CHECK_AND_CONTINUE(controller != nullptr);
controller->HandleDesktopLyricEnabled(isEnabled);
}
}
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::IsDesktopLyricEnabled(bool &isEnabled)
{
CHECK_AND_CALL_FUNC_RETURN_RET_LOG(isSupportedDesktopLyric_.load(), ERR_DESKTOPLYRIC_NOT_SUPPORT,
AudioStandard::StreamDfxManager::GetInstance().SendAudioErrorEvent(static_cast<int32_t>(getuid()),
AudioStandard::AVSESSION_CONTROL_DESKTOPLYRIC_NOT_SUPPORT_LOCAL_GET,
"The desktop lyrics feature is not supported", false), "The desktop lyrics feature is not supported.");
SLOGI("Entry");
isEnabled = isEnabledDesktopLyric_;
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::SetDesktopLyricVisible(bool isVisible)
{
return SetDesktopLyricVisibleInner(isVisible, GetBundleName());
}
int32_t AVSessionItem::IsDesktopLyricVisible(bool &isVisible)
{
CHECK_AND_CALL_FUNC_RETURN_RET_LOG(isSupportedDesktopLyric_.load(), ERR_DESKTOPLYRIC_NOT_SUPPORT,
AudioStandard::StreamDfxManager::GetInstance().SendAudioErrorEvent(static_cast<int32_t>(getuid()),
AudioStandard::AVSESSION_CONTROL_DESKTOPLYRIC_NOT_SUPPORT_LOCAL_GET,
"The desktop lyrics feature is not supported", false), "The desktop lyrics feature is not supported.");
CHECK_AND_CALL_FUNC_RETURN_RET_LOG(isEnabledDesktopLyric_.load(), ERR_DESKTOPLYRIC_NOT_ENABLE,
AudioStandard::StreamDfxManager::GetInstance().SendAudioErrorEvent(static_cast<int32_t>(getuid()),
AudioStandard::AVSESSION_CONTROL_DESKTOPLYRIC_NOT_ENABLE_LOCAL_GET,
"The desktop lyrics feature is not enabled", false),
"The desktop lyrics feature of this application is not enabled.");
SLOGI("Entry");
std::lock_guard<std::mutex> lock(desktopLyricVisibleMutex_);
isVisible = isDesktopLyricVisible_;
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::SetDesktopLyricState(DesktopLyricState state)
{
return SetDesktopLyricStateInner(state, GetBundleName());
}
int32_t AVSessionItem::GetDesktopLyricState(DesktopLyricState &state)
{
CHECK_AND_CALL_FUNC_RETURN_RET_LOG(isSupportedDesktopLyric_.load(), ERR_DESKTOPLYRIC_NOT_SUPPORT,
AudioStandard::StreamDfxManager::GetInstance().SendAudioErrorEvent(static_cast<int32_t>(getuid()),
AudioStandard::AVSESSION_CONTROL_DESKTOPLYRIC_NOT_SUPPORT_LOCAL_GET,
"The desktop lyrics feature is not supported", false),
"The desktop lyrics feature is not supported.");
CHECK_AND_CALL_FUNC_RETURN_RET_LOG(isEnabledDesktopLyric_.load(), ERR_DESKTOPLYRIC_NOT_ENABLE,
AudioStandard::StreamDfxManager::GetInstance().SendAudioErrorEvent(static_cast<int32_t>(getuid()),
AudioStandard::AVSESSION_CONTROL_DESKTOPLYRIC_NOT_ENABLE_LOCAL_GET,
"The desktop lyrics feature is not enabled", false),
"The desktop lyrics feature of this application is not enabled.");
SLOGI("entry");
std::lock_guard<std::mutex> lock(desktopLyricStateMutex_);
state = desktopLyricState_;
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::SetDesktopLyricVisibleInner(bool isVisible, const std::string &handler)
{
CHECK_AND_CALL_FUNC_RETURN_RET_LOG(isSupportedDesktopLyric_.load(), ERR_DESKTOPLYRIC_NOT_SUPPORT,
AudioStandard::StreamDfxManager::GetInstance().SendAudioErrorEvent(static_cast<int32_t>(getuid()),
AudioStandard::AVSESSION_CONTROL_DESKTOPLYRIC_NOT_SUPPORT_LOCAL_SET,
"The desktop lyrics feature is not supported", false),
"The desktop lyrics feature is not supported.");
CHECK_AND_CALL_FUNC_RETURN_RET_LOG(isEnabledDesktopLyric_.load(), ERR_DESKTOPLYRIC_NOT_ENABLE,
AudioStandard::StreamDfxManager::GetInstance().SendAudioErrorEvent(static_cast<int32_t>(getuid()),
AudioStandard::AVSESSION_CONTROL_DESKTOPLYRIC_NOT_ENABLE_LOCAL_SET,
"The desktop lyrics feature is not enabled", false),
"The desktop lyrics feature of this application is not enabled.");
CHECK_AND_RETURN_RET_LOG(extension_ != nullptr, AVSESSION_ERROR, "not support extension ability.");
SLOGI("set desktop lyrics visible: isVisible=%{public}d", isVisible);
std::lock_guard<std::mutex> lock(desktopLyricVisibleMutex_);
if (isVisible) {
if (extension_->StartDesktopLyricAbility(GetSessionId(), handler) != AVSESSION_SUCCESS) {
SLOGE("launch media control failed");
return AVSESSION_ERROR;
}
}
isDesktopLyricVisible_ = isVisible;
HandleDesktopLyricVisibilityChanged(isVisible);
extension_->UploadDesktopLyricOperationInfo(GetSessionId(), handler,
isVisible ? SendCodeEnum::OPEN : SendCodeEnum::CLOSE);
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::SetDesktopLyricStateInner(const DesktopLyricState &state, const std::string &handler)
{
CHECK_AND_CALL_FUNC_RETURN_RET_LOG(isSupportedDesktopLyric_.load(), ERR_DESKTOPLYRIC_NOT_SUPPORT,
AudioStandard::StreamDfxManager::GetInstance().SendAudioErrorEvent(static_cast<int32_t>(getuid()),
AudioStandard::AVSESSION_CONTROL_DESKTOPLYRIC_NOT_SUPPORT_LOCAL_SET,
"The desktop lyrics feature is not supported", false),
"The desktop lyrics feature is not supported.");
CHECK_AND_CALL_FUNC_RETURN_RET_LOG(isEnabledDesktopLyric_.load(), ERR_DESKTOPLYRIC_NOT_ENABLE,
AudioStandard::StreamDfxManager::GetInstance().SendAudioErrorEvent(static_cast<int32_t>(getuid()),
AudioStandard::AVSESSION_CONTROL_DESKTOPLYRIC_NOT_ENABLE_LOCAL_SET,
"The desktop lyrics feature is not enabled", false),
"The desktop lyrics feature of this application is not enabled.");
CHECK_AND_RETURN_RET_LOG(extension_ != nullptr, AVSESSION_ERROR, "not support extension ability.");
SLOGI("set desktop lyrics state: isLocked=%{public}d", state.isLocked_);
std::lock_guard<std::mutex> lock(desktopLyricStateMutex_);
desktopLyricState_ = state;
HandleDesktopLyricStateChanged(state);
extension_->UploadDesktopLyricOperationInfo(GetSessionId(), handler,
state.isLocked_ ? SendCodeEnum::LOCK : SendCodeEnum::UNLOCK);
return AVSESSION_SUCCESS;
}
void AVSessionItem::HandleDesktopLyricVisibilityChanged(bool isVisible)
{
{
std::lock_guard callbackLockGuard(callbackLock_);
if (callback_ != nullptr) {
callback_->OnDesktopLyricVisibilityChanged(isVisible);
}
}
{
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto& [pid, controller] : controllers_) {
CHECK_AND_CONTINUE(controller != nullptr);
controller->HandleDesktopLyricVisibilityChanged(isVisible);
}
}
}
void AVSessionItem::HandleDesktopLyricStateChanged(const DesktopLyricState &state)
{
{
std::lock_guard callbackLockGuard(callbackLock_);
if (callback_ != nullptr) {
callback_->OnDesktopLyricStateChanged(state);
}
}
{
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto &[pid, controller] : controllers_) {
CHECK_AND_CONTINUE(controller != nullptr);
controller->HandleDesktopLyricStateChanged(state);
}
}
}
int32_t AVSessionItem::SetBackgroundPlayMode(int32_t mode)
{
SLOGI("SetBackgroundPlayMode %{public}d", mode);
playMode_.store(mode);
if (serviceCallbackForBgPlayModeChange_) {
serviceCallbackForBgPlayModeChange_(GetSessionId(), mode);
}
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::GetBackgroundPlayMode()
{
return playMode_.load();
}
int32_t AVSessionItem::SetLaunchAbility(const AbilityRuntime::WantAgent::WantAgent& ability)
{
{
std::lock_guard lockGuard(avsessionItemLock_);
isSetLaunchAbility_.store(true);
}
GetCurrentAppIndexForSession();
{
std::lock_guard lockGuard(launchAbilityLock_);
launchAbility_ = ability;
}
std::shared_ptr<AAFwk::Want> want = std::make_shared<AAFwk::Want>();
std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> launchWantAgent =
std::make_shared<AbilityRuntime::WantAgent::WantAgent>(ability);
int res = AVSESSION_ERROR;
if (want != nullptr && launchWantAgent != nullptr) {
res = AbilityRuntime::WantAgent::WantAgentHelper::GetWant(launchWantAgent, want);
AAFwk::WantParams params = want->GetParams();
if (!params.HasParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY)) {
std::lock_guard lockGuard(launchAbilityLock_);
launchAbility_ = CreateWantAgentWithIndex(ability, appIndex_);
} else {
auto appIndex = params.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, -1);
if (appIndex != appIndex_) {
std::lock_guard lockGuard(launchAbilityLock_);
launchAbility_ = CreateWantAgentWithIndex(ability, appIndex_);
}
}
}
std::string errMsg = "Get want failed.";
std::string bundleName = "";
std::string abilityName = "";
std::string moduleName = "";
if (res == AVSESSION_SUCCESS) {
bundleName = want->GetElement().GetBundleName().c_str();
abilityName = want->GetElement().GetAbilityName().c_str();
moduleName = want->GetElement().GetModuleName().c_str();
errMsg = "SUCCESS";
}
std::string apiParamString = "bundleName: " + bundleName + ", " +
"moduleName: " + moduleName + ", " + "abilityName: " + abilityName;
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "SetLaunchAbility", "BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_,
"SESSION_TYPE", GetSessionType(), "API_PARAM", apiParamString,
"ERROR_CODE", res, "ERROR_MSG", errMsg);
return AVSESSION_SUCCESS;
}
// LCOV_EXCL_START
int32_t AVSessionItem::GetExtras(AAFwk::WantParams& extras)
{
std::lock_guard lockGuard(avsessionItemLock_);
extras = extras_;
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::SetExtras(const AAFwk::WantParams& extras)
{
{
std::lock_guard lockGuard(avsessionItemLock_);
extras_ = extras;
}
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
if (extras.HasParam("requireAbilityList")) {
AAFwk::IArray* list = AAFwk::IArray::Query(extras.GetParam("requireAbilityList"));
if (list != nullptr && AAFwk::Array::IsStringArray(list)) {
SetExtrasInner(list);
}
}
if (isRecommendMediaChange_ && !isFirstAddToFront_ && IsAppSupportCast() &&
GetMetaDataWithoutImg().GetDuration() != 0) {
isRecommendMediaChange_ = false;
isRecommend_ = true;
AVSessionHiAnalyticsReport::PublishRecommendInfo(GetBundleName(), GetSessionId(),
GetSessionType(), GetMetaDataWithoutImg().GetAssetId(), GetMetaDataWithoutImg().GetDuration());
}
SetSpid(extras);
#endif
if (extras.HasParam("hw_live_view_hidden_when_keyguard")) {
AAFwk::IArray* list = AAFwk::IArray::Query(extras.GetParam("hw_live_view_hidden_when_keyguard"));
if (list != nullptr && AAFwk::Array::IsBooleanArray(list)) {
NotificationExtras(list);
}
}
if (extras.HasParam("support-keyevent")) {
AAFwk::IArray* list = AAFwk::IArray::Query(extras.GetParam("support-keyevent"));
if (list != nullptr && AAFwk::Array::IsBooleanArray(list)) {
KeyEventExtras(list);
}
}
CheckSupportColdStartExtra(extras);
{
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
controller->HandleExtrasChange(extras);
}
}
}
std::lock_guard remoteSourceLockGuard(remoteSourceLock_);
if (remoteSource_ != nullptr) {
auto ret = remoteSource_->SetExtrasRemote(extras);
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "SetRemoteExtras failed");
}
return AVSESSION_SUCCESS;
}
void AVSessionItem::CheckSupportColdStartExtra(const AAFwk::WantParams& extras)
{
CHECK_AND_RETURN_LOG(GetUid() == audioBrokerUid, "not audio broker");
CHECK_AND_RETURN_LOG(extras.HasParam("isSupportColdStart") && extras.HasParam("ColdStartBundleName") &&
extras.HasParam("ColdStartAbilityName"), "extras don't have cold start param");
auto supportValue = AAFwk::IBoolean::Query(extras.GetParam("isSupportColdStart"));
auto bundleValue = AAFwk::IString::Query(extras.GetParam("ColdStartBundleName"));
auto abilityValue = AAFwk::IString::Query(extras.GetParam("ColdStartAbilityName"));
CHECK_AND_RETURN_LOG(supportValue != nullptr && bundleValue != nullptr && abilityValue != nullptr,
"extras don't have cold start value");
bool isSupport = AAFwk::Boolean::Unbox(supportValue);
std::string bundleName = AAFwk::String::Unbox(bundleValue);
std::string abilityName = AAFwk::String::Unbox(abilityValue);
std::lock_guard coldStartLockGuard(coldStartCallbackLock_);
if (isSupport && serviceCallbackForAncoStart_ != nullptr) {
SLOGI("anco %{public}s support cold start", bundleName.c_str());
serviceCallbackForAncoStart_(GetSessionId(), bundleName, abilityName);
}
}
sptr<IRemoteObject> AVSessionItem::GetControllerInner()
{
{
std::lock_guard controllerLockGuard(controllersLock_);
auto iter = controllers_.find(GetPid());
if (iter != controllers_.end()) {
return iter->second;
}
}
sptr<AVSessionItem> session(this);
sptr<AVControllerItem> result = new(std::nothrow) AVControllerItem(GetPid(), session, userId_);
CHECK_AND_RETURN_RET_LOG(result != nullptr, nullptr, "malloc controller failed");
result->isFromSession_ = true;
SLOGI("New controller from sessionItem:%{public}d when get controller.", static_cast<int>(GetPid()));
{
std::lock_guard controllerLockGuard(controllersLock_);
auto iter = controllers_.find(GetPid());
if (iter != controllers_.end()) {
return iter->second;
}
controllers_.insert({GetPid(), result});
}
return result;
}
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
void AVSessionItem::InitAVCastControllerProxy()
{
if (castControllerProxy_ == nullptr) {
SLOGI("CastControllerProxy is null, start get new proxy");
if (descriptor_.sessionTag_ == "RemoteCast") {
CHECK_AND_RETURN_LOG(AVRouter::GetInstance().IsRemoteCasting(), "get remote controller till connected");
}
{
std::lock_guard lockGuard(castLock_);
castControllerProxy_ = AVRouter::GetInstance().GetRemoteController(castHandle_);
}
}
}
void AVSessionItem::ReportAVCastControllerInfo()
{
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "getAVCastController", "BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_, "SESSION_TYPE", GetSessionType(),
"ERROR_CODE", AVSESSION_SUCCESS, "ERROR_MSG", "SUCCESS");
}
void AVSessionItem::ReportOnPlayerError(int32_t errorCode, const std::string& errorMsg)
{
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR", "API_NAME", "OnPlayerError",
"BUNDLE_NAME", GetBundleName(), "SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_, "SESSION_TYPE", GetSessionType(),
"API_PARAM", "default", "ERROR_CODE", errorCode, "ERROR_MSG", errorMsg,
"APP_VERSION_NAME", BundleStatusAdapter::GetInstance().GetAppVersion(GetBundleName()),
"COST_TIME", 0, "OS_VERSION", AVSessionSysEvent::GetInstance().GetOsVersion(),
"SDK_VERSION", AVSessionSysEvent::GetInstance().GetSdkVersion());
}
void AVSessionItem::dealValidCallback(int32_t cmd, std::vector<int32_t>& supportedCastCmds)
{
{
std::lock_guard lockGuard(avsessionItemLock_);
SLOGI("process cast valid cmd: %{public}d", cmd);
if (cmd == AVCastControlCommand::CAST_CONTROL_CMD_INVALID) {
supportedCastCmds_.clear();
supportedCastCmds = supportedCastCmds_;
HandleCastValidCommandChange(supportedCastCmds_);
return;
}
if (cmd == AVCastControlCommand::CAST_CONTROL_CMD_MAX) {
supportedCastCmds = supportedCastCmds_;
return;
}
if (descriptor_.sessionTag_ == "RemoteCast") {
SLOGI("sink session should not modify valid cmds");
supportedCastCmds = {};
return;
}
}
if (cmd > removeCmdStep_) {
DeleteSupportCastCommand(cmd - removeCmdStep_);
} else {
AddSupportCastCommand(cmd);
}
supportedCastCmds = supportedCastCmds_;
return;
}
sptr<IRemoteObject> AVSessionItem::GetAVCastControllerInner()
{
InitAVCastControllerProxy();
std::shared_ptr<IAVCastControllerProxy> castControllerProxy = nullptr;
{
std::lock_guard lockGuard(castLock_);
castControllerProxy = castControllerProxy_;
}
CHECK_AND_RETURN_RET_LOG(castControllerProxy != nullptr, nullptr, "castControllerProxy_ null at getCastController");
sptr<AVCastControllerItem> castController = new (std::nothrow) AVCastControllerItem();
CHECK_AND_RETURN_RET_LOG(castController != nullptr, nullptr, "malloc avCastController failed");
std::shared_ptr<AVCastControllerItem> sharedPtr = std::shared_ptr<AVCastControllerItem>(castController.GetRefPtr(),
[holder = castController](const auto*) {});
CHECK_AND_RETURN_RET_LOG(sharedPtr != nullptr, nullptr, "malloc AVCastControllerItem failed");
ReportAVCastControllerInfo();
auto weakThis = wptr<AVSessionItem>(this);
auto validCallback = [weakThis](int32_t cmd, std::vector<int32_t>& supportedCastCmds) {
auto sharedThis = weakThis.promote();
CHECK_AND_RETURN_LOG(sharedThis != nullptr, "AVSessionItem is already destroyed");
sharedThis->dealValidCallback(cmd, supportedCastCmds);
};
auto preparecallback = [weakThis]() {
auto sharedThis = weakThis.promote();
CHECK_AND_RETURN_LOG(sharedThis != nullptr, "AVSessionItem is already destroyed");
if (AVRouter::GetInstance().GetMirrorCastHandle() != -1 && sharedThis->isFirstCallback_) {
sharedThis->isFirstCallback_ = false;
CHECK_AND_RETURN_LOG(!sharedThis->GetDescriptor().outputDeviceInfo_.deviceInfos_.empty(), "empty devInfos");
AVRouter::GetInstance().DisconnectOtherSession(sharedThis->GetSessionId(),
sharedThis->GetDescriptor().outputDeviceInfo_.deviceInfos_[0]);
}
};
auto playerErrorCallback = [weakThis](int32_t errorCode, const std::string& errorMsg) {
auto sharedThis = weakThis.promote();
CHECK_AND_RETURN_LOG(sharedThis != nullptr, "AVSessionItem is already destroyed");
sharedThis->ReportOnPlayerError(errorCode, errorMsg);
};
sharedPtr->Init(castControllerProxy, validCallback, preparecallback, playerErrorCallback);
{
std::lock_guard lockGuard(castControllersLock_);
castControllers_.emplace_back(sharedPtr);
}
sptr<IRemoteObject> remoteObject = castController;
sharedPtr->SetSessionTag(descriptor_.sessionTag_);
sharedPtr->SetSessionId(descriptor_.sessionId_);
sharedPtr->SetUserId(userId_);
SetCastControllerCallbackForCastCap(castControllerProxy);
InitializeCastCommands();
if (SearchSpidInCapability(castHandleDeviceId_)) { castControllerProxy->SetSpid(GetSpid()); }
return remoteObject;
}
void AVSessionItem::SetCastControllerCallbackForCastCap(std::shared_ptr<IAVCastControllerProxy> castControllerProxy)
{
if (descriptor_.sessionTag_ == "RemoteCast" || castControllerProxy == nullptr) {
return;
}
std::lock_guard callbackForCastCapLockGuard(callbackForCastCapLock_);
auto weakThis = wptr<AVSessionItem>(this);
castControllerProxy->SetSessionCallbackForCastCap([weakThis](bool isPlaying, bool isMediaChange) {
std::thread([weakThis, isPlaying, isMediaChange]() {
auto sharedThis = weakThis.promote();
CHECK_AND_RETURN_LOG(sharedThis != nullptr, "AVSessionItem is already destroyed");
CHECK_AND_RETURN_LOG(sharedThis->serviceCallbackForCastNtf_ != nullptr,
"serviceCallbackForCastNtf_ is empty");
SLOGI("MediaCapsule CastCapsule for service isPlaying %{public}d, isMediaChange %{public}d",
isPlaying, isMediaChange);
sharedThis->serviceCallbackForCastNtf_(sharedThis->descriptor_.sessionId_, isPlaying, isMediaChange);
}).detach();
});
}
void AVSessionItem::ReleaseAVCastControllerInner()
{
SLOGI("Release AVCastControllerInner");
std::lock_guard lockGuard(castControllersLock_);
for (auto controller : castControllers_) {
if (controller != nullptr) {
controller->Destroy();
}
}
{
std::lock_guard castLockGuard(castLock_);
castControllerProxy_ = nullptr;
}
isFirstCallback_ = true;
}
#endif
void AVSessionItem::RegisterAVSessionCallback(std::shared_ptr<AVSessionCallback> callbackOfMigrate)
{
std::lock_guard callbackLockGuard(callbackLock_);
callbackForMigrate_ = callbackOfMigrate;
}
int32_t AVSessionItem::RegisterCallbackInner(const sptr<IAVSessionCallback>& callback)
{
std::lock_guard callbackLockGuard(callbackLock_);
callback_ = callback;
return AVSESSION_SUCCESS;
}
// LCOV_EXCL_STOP
int32_t AVSessionItem::Activate()
{
descriptor_.isActive_ = true;
std::lock_guard controllerLockGuard(controllersLock_);
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "Activate", "BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_, "SESSION_TYPE", GetSessionType(),
"ERROR_CODE", AVSESSION_SUCCESS, "ERROR_MSG", "SUCCESS");
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
controller->HandleActiveStateChange(true);
}
}
if (descriptor_.sessionType_ == AVSession::SESSION_TYPE_VOICE_CALL ||
descriptor_.sessionType_ == AVSession::SESSION_TYPE_VIDEO_CALL) {
SLOGI("set audio scene for voip start");
AudioSystemManager *audioManager = AudioSystemManager::GetInstance();
AudioScene audioScene = AudioScene::AUDIO_SCENE_CALL_START;
if (audioManager != nullptr) {
audioManager->SetAudioScene(audioScene);
}
}
return AVSESSION_SUCCESS;
}
// LCOV_EXCL_START
int32_t AVSessionItem::Deactivate()
{
descriptor_.isActive_ = false;
std::lock_guard controllerLockGuard(controllersLock_);
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "Deactivate", "BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_, "SESSION_TYPE", GetSessionType(),
"ERROR_CODE", AVSESSION_SUCCESS, "ERROR_MSG", "SUCCESS");
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
controller->HandleActiveStateChange(false);
}
}
if (descriptor_.sessionType_ == AVSession::SESSION_TYPE_VOICE_CALL ||
descriptor_.sessionType_ == AVSession::SESSION_TYPE_VIDEO_CALL) {
SLOGI("set audio scene for voip end");
AudioSystemManager *audioManager = AudioSystemManager::GetInstance();
AudioScene audioScene = AudioScene::AUDIO_SCENE_CALL_END;
if (audioManager != nullptr) {
audioManager->SetAudioScene(audioScene);
}
}
return AVSESSION_SUCCESS;
}
// LCOV_EXCL_STOP
bool AVSessionItem::IsActive()
{
return descriptor_.isActive_ || GetSessionId() == "DEFAULT";
}
// LCOV_EXCL_START
int32_t AVSessionItem::AddSupportCommand(int32_t cmd)
{
CHECK_AND_RETURN_RET_LOG(cmd > AVControlCommand::SESSION_CMD_INVALID, AVSESSION_ERROR, "invalid cmd");
CHECK_AND_RETURN_RET_LOG(cmd < AVControlCommand::SESSION_CMD_MAX, AVSESSION_ERROR, "invalid cmd");
SLOGI("AddSupportCommand=%{public}d", cmd);
if (cmd == AVControlCommand::SESSION_CMD_MEDIA_KEY_SUPPORT) {
SLOGI("enable media key event listen");
isMediaKeySupport.store(true);
return AVSESSION_SUCCESS;
}
std::vector<int32_t> tempSupportedCmds;
{
std::lock_guard lockGuard(avsessionItemLock_);
auto iter = std::find(supportedCmd_.begin(), supportedCmd_.end(), cmd);
CHECK_AND_RETURN_RET_LOG(iter == supportedCmd_.end(), AVSESSION_SUCCESS, "cmd already been added");
supportedCmd_.push_back(cmd);
tempSupportedCmds = supportedCmd_;
}
std::string apiParamString = "cmd :" + std::to_string(cmd);
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "OnEvent", "BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_,
"SESSION_TYPE", GetSessionType(), "API_PARAM", apiParamString,
"ERROR_CODE", AVSESSION_SUCCESS, "ERROR_MSG", "SUCCESS");
ProcessFrontSession("AddSupportCommand");
{
std::lock_guard controllerLockGuard(controllersLock_);
SLOGI("send add command event to controller, size:%{public}d", static_cast<int>(controllers_.size()));
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
controller->HandleValidCommandChange(tempSupportedCmds);
}
}
}
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
AddSessionCommandToCast(cmd);
#endif
#ifdef ENABLE_AVSESSION_SYSEVENT_CONTROL
ReportCommandChange();
#endif
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::DeleteSupportCommand(int32_t cmd)
{
CHECK_AND_RETURN_RET_LOG(cmd > AVControlCommand::SESSION_CMD_INVALID, AVSESSION_ERROR, "invalid cmd");
CHECK_AND_RETURN_RET_LOG(cmd < AVControlCommand::SESSION_CMD_MAX, AVSESSION_ERROR, "invalid cmd");
SLOGI("DeleteSupportCommand=%{public}d", cmd);
if (cmd == AVControlCommand::SESSION_CMD_MEDIA_KEY_SUPPORT) {
SLOGI("disable media key event listen");
isMediaKeySupport.store(false);
return AVSESSION_SUCCESS;
}
std::vector<int32_t> tempSupportedCmds;
{
std::lock_guard lockGuard(avsessionItemLock_);
auto iter = std::remove(supportedCmd_.begin(), supportedCmd_.end(), cmd);
supportedCmd_.erase(iter, supportedCmd_.end());
tempSupportedCmds = supportedCmd_;
}
std::string apiParamString = "cmd :" + std::to_string(cmd);
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "OffEvent",
"BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_,
"SESSION_TYPE", GetSessionType(),
"API_PARAM", apiParamString,
"ERROR_CODE", AVSESSION_SUCCESS,
"ERROR_MSG", "SUCCESS");
ProcessFrontSession("DeleteSupportCommand");
{
SLOGI("send delete command event to controller, size:%{public}d", static_cast<int>(controllers_.size()));
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
controller->HandleValidCommandChange(tempSupportedCmds);
}
}
}
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
RemoveSessionCommandFromCast(cmd);
#endif
#ifdef ENABLE_AVSESSION_SYSEVENT_CONTROL
ReportCommandChange();
#endif
return AVSESSION_SUCCESS;
}
// LCOV_EXCL_STOP
int32_t AVSessionItem::SetMediaCenterControlType(const std::vector<int32_t>& controlTypes)
{
{
std::lock_guard lockGuard(avsessionItemLock_);
mediaCenterControlTypes_ = controlTypes;
}
SLOGI("SetMediaCenterControlType size=%{public}zu", controlTypes.size());
std::string apiParamString = "controlTypes: " + std::to_string(controlTypes.size());
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "SetMediaCenterControlType", "BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_,
"SESSION_TYPE", GetSessionType(), "API_PARAM", apiParamString,
"ERROR_CODE", AVSESSION_SUCCESS, "ERROR_MSG", "SUCCESS");
{
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto& [pid, controller] : controllers_) {
controller != nullptr ? controller->HandleMediaCenterControlTypeChange(controlTypes) : (void)0;
}
}
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::GetMediaCenterControlType(std::vector<int32_t>& controlTypes)
{
std::lock_guard lockGuard(avsessionItemLock_);
controlTypes = mediaCenterControlTypes_;
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::SetSupportedPlaySpeeds(const std::vector<double>& speeds)
{
{
std::lock_guard lockGuard(avsessionItemLock_);
supportedPlaySpeeds_ = speeds;
}
SLOGI("SetSupportedPlaySpeeds size=%{public}zu", speeds.size());
std::string apiParamString = "speeds: " + std::to_string(speeds.size());
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "SetSupportedPlaySpeeds", "BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_,
"SESSION_TYPE", GetSessionType(), "API_PARAM", apiParamString,
"ERROR_CODE", AVSESSION_SUCCESS, "ERROR_MSG", "SUCCESS");
{
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto& [pid, controller] : controllers_) {
controller != nullptr ? controller->HandleSupportedPlaySpeedsChange(speeds) : (void)0;
}
}
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::GetSupportedPlaySpeeds(std::vector<double>& speeds)
{
std::lock_guard lockGuard(avsessionItemLock_);
speeds = supportedPlaySpeeds_;
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::SetSupportedLoopModes(const std::vector<int32_t>& loopModes)
{
{
std::lock_guard lockGuard(avsessionItemLock_);
supportedLoopModes_ = loopModes;
}
SLOGI("SetSupportedLoopModes size=%{public}zu", loopModes.size());
std::string apiParamString = "loopModes: " + std::to_string(loopModes.size());
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "SetSupportedLoopModes", "BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_,
"SESSION_TYPE", GetSessionType(), "API_PARAM", apiParamString,
"ERROR_CODE", AVSESSION_SUCCESS, "ERROR_MSG", "SUCCESS");
{
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto& [pid, controller] : controllers_) {
controller != nullptr ? controller->HandleSupportedLoopModesChange(loopModes) : (void)0;
}
}
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::GetSupportedLoopModes(std::vector<int32_t>& loopModes)
{
std::lock_guard lockGuard(avsessionItemLock_);
loopModes = supportedLoopModes_;
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::SetSessionEvent(const std::string& event, const AAFwk::WantParams& args)
{
#ifdef INPUT_REDISTRIBUTE_ENABLE
if (event == "InputRedistributeEvent") {
if (AAFwk::IInteger* codeValue = AAFwk::IInteger::Query(args.GetParam("keyCode"))) {
int32_t keyCode = AAFwk::Integer::Unbox(codeValue);
return ProcessInputRedistributeEvent(keyCode);
}
return AVSESSION_ERROR;
}
#endif
{
std::lock_guard controllerLockGuard(controllersLock_);
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
controller->HandleSetSessionEvent(event, args);
}
}
}
std::lock_guard remoteSourceLockGuard(remoteSourceLock_);
if (remoteSource_ != nullptr) {
auto ret = remoteSource_->SetSessionEventRemote(event, args);
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "SetSessionEvent failed");
}
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::ProcessInputRedistributeEvent(const int32_t keyCode)
{
HISYSEVENT_BEHAVIOR("SESSION_INPUT_REDISTRIBUTE",
"KEY_CODE", keyCode,
"BUNDLE_NAME", GetBundleName());
SLOGI("ProcessInputRedistributeEvent keyCode %{public}d", keyCode);
if (!IsKeyEventSupported(GetBundleName())) {
return AVSESSION_ERROR;
}
std::lock_guard callbackLockGuard(callbackLock_);
if (keyCode == MMI::KeyEvent::KEYCODE_SPACE) {
SLOGI("ProcessInputRedistributeEvent playbackState %{public}d", playbackState_.GetState());
if (playbackState_.GetState() == AVPlaybackState::PLAYBACK_STATE_PLAY) {
if (callbackForMigrate_) {
callbackForMigrate_->OnPause();
}
CHECK_AND_RETURN_RET_LOG(callback_ != nullptr, AVSESSION_ERROR, "callback_ is nullptr");
callback_->OnPause();
} else {
AVControlCommand command;
command.SetCommand(AVControlCommand::SESSION_CMD_PLAY);
if (callbackForMigrate_) {
callbackForMigrate_->OnPlay(command);
}
CHECK_AND_RETURN_RET_LOG(callback_ != nullptr, AVSESSION_ERROR, "callback_ is nullptr");
callback_->OnPlay(command);
}
} else if (keyCode == MMI::KeyEvent::KEYCODE_DPAD_UP) {
return UpdateVolume(true);
} else if (keyCode == MMI::KeyEvent::KEYCODE_DPAD_DOWN) {
return UpdateVolume(false);
} else if (keyCode == MMI::KeyEvent::KEYCODE_DPAD_LEFT) {
CHECK_AND_RETURN_RET_LOG(callback_ != nullptr, AVSESSION_ERROR, "callback_ is nullptr");
AVControlCommand command;
command.SetCommand(AVControlCommand::SESSION_CMD_REWIND);
command.SetRewindTime(PROGRESS_ADJUST_VALUE);
callback_->OnRewind(PROGRESS_ADJUST_VALUE, command);
} else if (keyCode == MMI::KeyEvent::KEYCODE_DPAD_RIGHT) {
CHECK_AND_RETURN_RET_LOG(callback_ != nullptr, AVSESSION_ERROR, "callback_ is nullptr");
AVControlCommand command;
command.SetCommand(AVControlCommand::SESSION_CMD_FAST_FORWARD);
command.SetForwardTime(PROGRESS_ADJUST_VALUE);
callback_->OnFastForward(PROGRESS_ADJUST_VALUE, command);
} else {
return AVSESSION_ERROR;
}
HISYSEVENT_BEHAVIOR("SESSION_INPUT_REDISTRIBUTE_SUCC",
"KEY_CODE", keyCode,
"BUNDLE_NAME", GetBundleName());
return AVSESSION_SUCCESS;
}
bool AVSessionItem::IsKeyEventSupported(const std::string &bundleName)
{
if (bundleName.empty()) {
SLOGE("bundleName is empty");
return false;
}
auto manager = DelayedSingleton<AVSessionWhitelistConfigManager>::GetInstance();
if (manager == nullptr) {
SLOGE("failed, manager is nullptr");
return false;
}
bool supportKeyEvent = manager->IsKeyEventSupported(bundleName);
return supportKeyEvent;
}
int32_t AVSessionItem::UpdateVolume(bool up)
{
AudioStandard::AudioVolumeType streamType = AudioStandard::AudioVolumeType::STREAM_MUSIC;
AudioSystemManager *audioManager = AudioSystemManager::GetInstance();
int32_t volumeMax = audioManager->GetMaxVolume(streamType);
int32_t volumeMin = audioManager->GetMinVolume(streamType);
int32_t volume = audioManager->GetVolume(streamType, GetCallingUid());
volume = up ? ++volume : --volume;
volume = std::min(volumeMax, std::max(volume, volumeMin));
SLOGI("updateVolume volume:%{public}d max:%{public}d min:%{public}d", volume, volumeMax, volumeMin);
auto ret = audioManager->SetVolume(streamType, volume, GetCallingUid());
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "SetVolume failed");
int32_t keyCode = up ? MMI::KeyEvent::KEYCODE_DPAD_UP : MMI::KeyEvent::KEYCODE_DPAD_DOWN;
HISYSEVENT_BEHAVIOR("SESSION_INPUT_REDISTRIBUTE_SUCC",
"KEY_CODE", keyCode,
"BUNDLE_NAME", GetBundleName());
return AVSESSION_SUCCESS;
}
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
int32_t AVSessionItem::RegisterListenerStreamToCast(const std::pair<std::string, std::string>& serviceNameStatePair,
DeviceInfo deviceInfo)
{
std::lock_guard lockGuard(castLock_);
if (castHandle_ > 0) {
return AVSESSION_ERROR;
}
castServiceNameStatePair_ = serviceNameStatePair;
OutputDeviceInfo outputDeviceInfo;
outputDeviceInfo.deviceInfos_.emplace_back(deviceInfo);
if (AVRouter::GetInstance().GetMirrorCastHandle() == -1) {
SetCastHandle(AVRouter::GetInstance().StartCast(outputDeviceInfo, castServiceNameStatePair_, GetSessionId()));
CHECK_AND_RETURN_RET_LOG(castHandle_ != AVSESSION_ERROR, AVSESSION_ERROR, "StartCast failed");
AVRouter::GetInstance().RegisterCallback(castHandle_, cssListener_, GetSessionId(), deviceInfo);
AVRouter::GetInstance().GetRemoteDrmCapabilities(castHandle_, deviceInfo.realDeviceId_,
deviceInfo.supportedDrmCapabilities_);
AVRouter::GetInstance().SetServiceAllConnectState(castHandle_, deviceInfo);
mirrorToStreamOnceFlag_ = true;
InitAVCastControllerProxy();
} else {
SetCastHandle(AVRouter::GetInstance().GetMirrorCastHandle());
InitAVCastControllerProxy();
if (AVRouter::GetInstance().IsInMirrorToStreamState()) {
SetCastHandle(-1);
castControllerProxy_ = nullptr;
mirrorToStreamOnceFlag_ = false;
return AVSESSION_ERROR;
}
AVRouter::GetInstance().RegisterCallback(castHandle_, cssListener_, GetSessionId(), deviceInfo);
mirrorToStreamOnceFlag_ = true;
}
castHandleDeviceId_ = deviceInfo.deviceId_;
AVRouter::GetInstance().SetCastingDeviceName(deviceInfo.deviceName_);
SLOGI("RegisterListenerStreamToCast check handle set to %{public}lld", (long long)castHandle_);
UpdateCastDeviceMap(deviceInfo);
DoContinuousTaskRegister();
return AVSESSION_SUCCESS;
}
// LCOV_EXCL_START
void AVSessionItem::InitializeCastCommands()
{
std::lock_guard lockGuard(avsessionItemLock_);
// always support setVolume command
auto iter = std::find(supportedCastCmds_.begin(), supportedCastCmds_.end(),
AVCastControlCommand::CAST_CONTROL_CMD_SET_VOLUME);
if (iter == supportedCastCmds_.end()) {
supportedCastCmds_.push_back(AVCastControlCommand::CAST_CONTROL_CMD_SET_VOLUME);
}
iter = std::find(supportedCastCmds_.begin(), supportedCastCmds_.end(),
AVCastControlCommand::CAST_CONTROL_CMD_SET_SPEED);
if (iter == supportedCastCmds_.end()) {
supportedCastCmds_.push_back(AVCastControlCommand::CAST_CONTROL_CMD_SET_SPEED);
}
iter = std::find(supportedCastCmds_.begin(), supportedCastCmds_.end(),
AVCastControlCommand::CAST_CONTROL_CMD_SEEK);
if (iter == supportedCastCmds_.end()) {
supportedCastCmds_.push_back(AVCastControlCommand::CAST_CONTROL_CMD_SEEK);
supportedCastCmds_.push_back(AVCastControlCommand::CAST_CONTROL_CMD_FAST_FORWARD);
supportedCastCmds_.push_back(AVCastControlCommand::CAST_CONTROL_CMD_REWIND);
}
iter = std::find(supportedCmd_.begin(), supportedCmd_.end(), AVControlCommand::SESSION_CMD_SET_LOOP_MODE);
if (iter != supportedCmd_.end()) {
AddSessionCommandToCast(AVControlCommand::SESSION_CMD_SET_LOOP_MODE);
}
}
int32_t AVSessionItem::SessionCommandToCastCommand(int32_t cmd)
{
if (cmd == AVControlCommand::SESSION_CMD_SET_LOOP_MODE) {
return AVCastControlCommand::CAST_CONTROL_CMD_SET_LOOP_MODE;
}
return AVCastControlCommand::CAST_CONTROL_CMD_INVALID;
}
void AVSessionItem::AddSessionCommandToCast(int32_t cmd)
{
if (cmd != AVControlCommand::SESSION_CMD_SET_LOOP_MODE) {
return;
}
if (castControllerProxy_ != nullptr) {
int32_t castCmd = SessionCommandToCastCommand(cmd);
std::lock_guard lockGuard(avsessionItemLock_);
auto iter = std::find(supportedCastCmds_.begin(), supportedCastCmds_.end(), castCmd);
if (iter != supportedCastCmds_.end()) {
SLOGI("castCmd have already been added, cmd:%{public}d", castCmd);
return;
}
supportedCastCmds_.push_back(castCmd);
HandleCastValidCommandChange(supportedCastCmds_);
}
}
void AVSessionItem::RemoveSessionCommandFromCast(int32_t cmd)
{
if (cmd != AVControlCommand::SESSION_CMD_SET_LOOP_MODE) {
return;
}
if (castControllerProxy_ != nullptr) {
int32_t castCmd = SessionCommandToCastCommand(cmd);
std::lock_guard lockGuard(avsessionItemLock_);
SLOGI("remove castcmd:%{public}d", castCmd);
auto iter = std::remove(supportedCastCmds_.begin(), supportedCastCmds_.end(), castCmd);
supportedCastCmds_.erase(iter, supportedCastCmds_.end());
HandleCastValidCommandChange(supportedCastCmds_);
}
}
int32_t AVSessionItem::AddSupportCastCommand(int32_t cmd)
{
if (cmd <= AVCastControlCommand::CAST_CONTROL_CMD_INVALID ||
cmd >= AVCastControlCommand::CAST_CONTROL_CMD_MAX) {
SLOGI("add invalid cmd: %{public}d", cmd);
return AVSESSION_ERROR;
}
{
std::lock_guard lockGuard(avsessionItemLock_);
if (cmd == AVCastControlCommand::CAST_CONTROL_CMD_PLAY_STATE_CHANGE) {
auto iter = std::find(
supportedCastCmds_.begin(), supportedCastCmds_.end(), AVCastControlCommand::CAST_CONTROL_CMD_PLAY);
CHECK_AND_RETURN_RET_LOG(iter == supportedCastCmds_.end(), AVSESSION_SUCCESS, "cmd already been added");
supportedCastCmds_.push_back(AVCastControlCommand::CAST_CONTROL_CMD_PLAY);
supportedCastCmds_.push_back(AVCastControlCommand::CAST_CONTROL_CMD_PAUSE);
supportedCastCmds_.push_back(AVCastControlCommand::CAST_CONTROL_CMD_STOP);
} else if (cmd == AVCastControlCommand::CAST_CONTROL_CMD_SEEK) {
auto iter = std::find(supportedCastCmds_.begin(), supportedCastCmds_.end(), cmd);
CHECK_AND_RETURN_RET_LOG(iter == supportedCastCmds_.end(), AVSESSION_SUCCESS, "cmd already been added");
supportedCastCmds_.push_back(cmd);
supportedCastCmds_.push_back(AVCastControlCommand::CAST_CONTROL_CMD_FAST_FORWARD);
supportedCastCmds_.push_back(AVCastControlCommand::CAST_CONTROL_CMD_REWIND);
} else {
auto iter = std::find(supportedCastCmds_.begin(), supportedCastCmds_.end(), cmd);
CHECK_AND_RETURN_RET_LOG(iter == supportedCastCmds_.end(), AVSESSION_SUCCESS, "cmd already been added");
supportedCastCmds_.push_back(cmd);
}
}
ProcessFrontSession("AddSupportCastCommand");
HandleCastValidCommandChange(supportedCastCmds_);
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::DeleteSupportCastCommand(int32_t cmd)
{
if (cmd <= AVCastControlCommand::CAST_CONTROL_CMD_INVALID ||
cmd >= AVCastControlCommand::CAST_CONTROL_CMD_MAX) {
SLOGI("delete invalid cmd: %{public}d", cmd);
return AVSESSION_ERROR;
}
{
std::lock_guard lockGuard(avsessionItemLock_);
if (cmd == AVCastControlCommand::CAST_CONTROL_CMD_PLAY_STATE_CHANGE) {
auto iter = std::remove(
supportedCastCmds_.begin(), supportedCastCmds_.end(), AVCastControlCommand::CAST_CONTROL_CMD_PLAY);
supportedCastCmds_.erase(iter, supportedCastCmds_.end());
iter = std::remove(
supportedCastCmds_.begin(), supportedCastCmds_.end(), AVCastControlCommand::CAST_CONTROL_CMD_PAUSE);
supportedCastCmds_.erase(iter, supportedCastCmds_.end());
iter = std::remove(
supportedCastCmds_.begin(), supportedCastCmds_.end(), AVCastControlCommand::CAST_CONTROL_CMD_STOP);
supportedCastCmds_.erase(iter, supportedCastCmds_.end());
} else if (cmd == AVCastControlCommand::CAST_CONTROL_CMD_SEEK) {
auto iter = std::remove(supportedCastCmds_.begin(), supportedCastCmds_.end(), cmd);
supportedCastCmds_.erase(iter, supportedCastCmds_.end());
iter = std::remove(supportedCastCmds_.begin(), supportedCastCmds_.end(),
AVCastControlCommand::CAST_CONTROL_CMD_FAST_FORWARD);
supportedCastCmds_.erase(iter, supportedCastCmds_.end());
iter = std::remove(
supportedCastCmds_.begin(), supportedCastCmds_.end(), AVCastControlCommand::CAST_CONTROL_CMD_REWIND);
supportedCastCmds_.erase(iter, supportedCastCmds_.end());
} else {
auto iter = std::remove(supportedCastCmds_.begin(), supportedCastCmds_.end(), cmd);
supportedCastCmds_.erase(iter, supportedCastCmds_.end());
}
}
ProcessFrontSession("DeleteSupportCastCommand");
HandleCastValidCommandChange(supportedCastCmds_);
return AVSESSION_SUCCESS;
}
void AVSessionItem::HandleCastValidCommandChange(const std::vector<int32_t>& cmds)
{
std::lock_guard lockGuard(castControllersLock_);
SLOGI("send command change event to controller, controller size: %{public}d",
static_cast<int>(castControllers_.size()));
for (auto controller : castControllers_) {
if (controller != nullptr) {
controller->HandleCastValidCommandChange(cmds);
}
}
}
int32_t AVSessionItem::ReleaseCast(bool continuePlay)
{
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "StopCasting",
"BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_,
"SESSION_TYPE", GetSessionType(),
"ERROR_CODE", AVSESSION_SUCCESS,
"ERROR_MSG", "SUCCESS");
DeviceRemoveAction deviceRemoveAction = continuePlay ?
DeviceRemoveAction::ACTION_CONTINUE_PLAY : DeviceRemoveAction::ACTION_DISCONNECT;
return StopCast(deviceRemoveAction);
}
int32_t AVSessionItem::CastAddToCollaboration(const OutputDeviceInfo& outputDeviceInfo)
{
CHECK_AND_RETURN_RET_LOG(castDeviceInfoMap_.count(outputDeviceInfo.deviceInfos_[0].deviceId_),
AVSESSION_ERROR, "deviceId map deviceinfo is not exit");
DeviceInfo deviceInfo = castDeviceInfoMap_[outputDeviceInfo.deviceInfos_[0].deviceId_];
return CollaborationManagerURLCasting::GetInstance().CastAddToCollaboration(deviceInfo);
}
int32_t AVSessionItem::StartCast(const OutputDeviceInfo& outputDeviceInfo)
{
std::lock_guard lockGuard(castLock_);
if (AVRouter::GetInstance().GetMirrorCastHandle() != -1 && castHandle_ <= 0 &&
descriptor_.sessionType_ == AVSession::SESSION_TYPE_VIDEO &&
AVRouter::GetInstance().GetMirrorDeviceId() == outputDeviceInfo.deviceInfos_[0].deviceId_) {
SetCastHandle(AVRouter::GetInstance().GetMirrorCastHandle());
InitAVCastControllerProxy();
AVRouter::GetInstance().RegisterCallback(castHandle_, cssListener_,
GetSessionId(), outputDeviceInfo.deviceInfos_[0]);
castHandleDeviceId_ = outputDeviceInfo.deviceInfos_[0].deviceId_;
mirrorToStreamOnceFlag_ = true;
DoContinuousTaskRegister();
SLOGI("RegisterListenerStreamToCast check handle set to %{public}lld", (long long)castHandle_);
return AVSESSION_SUCCESS;
}
// unregister pre castSession callback to avoid previous session timeout disconnect influence current session
if (castHandle_ > 0) {
if (castHandleDeviceId_ == outputDeviceInfo.deviceInfos_[0].deviceId_) {
SLOGI("repeat startcast %{public}lld", (long long)castHandle_);
return ERR_REPEAT_CAST;
} else {
SLOGI("cast check with pre cast alive %{public}lld, unregister callback", (long long)castHandle_);
AVSessionUtils::PublishCommonEvent(CASTING_SWITCH_DEVICE);
multiDeviceState_ = MultiDeviceState::CASTING_SWITCH_DEVICE;
newOutputDeviceInfo_ = outputDeviceInfo;
ProtocolType protocol = static_cast<ProtocolType>(outputDeviceInfo.deviceInfos_[0].supportedProtocols_);
StopCast(deviceRemoveActionMap_[protocol]);
return AVSESSION_SUCCESS;
}
} else {
if (AVRouter::GetInstance().GetCastSide() == CAST_SIDE::CAST_SINK) {
multiDeviceState_ = MultiDeviceState::CASTED_AND_CASTING;
newOutputDeviceInfo_ = outputDeviceInfo;
StopCast();
return AVSESSION_SUCCESS;
}
if (AVRouter::GetInstance().GetCastSide() == CAST_SIDE::CAST_SOURCE &&
AVRouter::GetInstance().IsRemoteCasting() &&
(!AVRouter::GetInstance().IsHiPlayCasting()) &&
AVRouter::GetInstance().GetMirrorCastHandle() == -1) {
return SubStartCast(outputDeviceInfo);
}
int32_t sourceAllConnectResult = CastAddToCollaboration(outputDeviceInfo);
if (sourceAllConnectResult != AVSESSION_SUCCESS) {
AVSessionUtils::PublishCommonEvent(MEDIA_CAST_ERROR);
SLOGE("collaboration to start cast fail");
return sourceAllConnectResult;
}
}
return SubStartCast(outputDeviceInfo);
}
int32_t AVSessionItem::SubStartCast(const OutputDeviceInfo& outputDeviceInfo)
{
AVSessionSysEvent::GetInstance().updateStartCastTime(GetSessionId(), GetBundleName(),
BundleStatusAdapter::GetInstance().GetAppVersion(GetBundleName()), GetSessionType());
int64_t castHandle = AVRouter::GetInstance().StartCast(outputDeviceInfo, castServiceNameStatePair_, GetSessionId());
CHECK_AND_RETURN_RET_LOG(castHandle != AVSESSION_ERROR, AVSESSION_ERROR, "StartCast failed");
SetCastHandle(castHandle);
int32_t ret = AddDevice(castHandle, outputDeviceInfo, GetSpid());
if (ret == AVSESSION_SUCCESS) {
castHandleDeviceId_ = outputDeviceInfo.deviceInfos_[0].deviceId_;
DoContinuousTaskRegister();
SLOGI("start cast check handle set to %{public}lld", (long long)castHandle_);
} else {
DestroyCast(false);
}
return ret;
}
int32_t AVSessionItem::AddDevice(const int64_t castHandle, const OutputDeviceInfo& outputDeviceInfo, uint32_t spid)
{
SLOGI("Add device process");
std::lock_guard lockGuard(castLock_);
AVRouter::GetInstance().RegisterCallback(castHandle, cssListener_,
GetSessionId(), outputDeviceInfo.deviceInfos_[0]);
int32_t castId = static_cast<int32_t>(castHandle);
int32_t ret = AVRouter::GetInstance().AddDevice(castId, outputDeviceInfo, spid);
SLOGI("Add device process with ret %{public}d", ret);
return ret;
}
void AVSessionItem::DealDisconnect(DeviceInfo deviceInfo, bool isNeedRemove)
{
std::lock_guard lockGuard(castLock_);
SLOGI("Is remotecast, received disconnect event for castHandle_: %{public}" PRId64, castHandle_);
if (isNeedRemove) {
AVRouter::GetInstance().UnRegisterCallback(castHandle_, cssListener_, GetSessionId());
AVRouter::GetInstance().StopCastSession(castHandle_);
AVRouter::GetInstance().SetMirrorCastHandle(-1);
DoContinuousTaskUnregister();
} else {
// clear pre session cast info in streamplayer to avoid flash when cast compete
if (castControllerProxy_ != nullptr) {
castControllerProxy_->RefreshCurrentAVQueueItem(AVQueueItem {});
}
}
SetCastHandle(-1);
castHandleDeviceId_ = "-100";
{
std::lock_guard lockGuard(castLock_);
castControllerProxy_ = nullptr;
}
isFirstCallback_ = true;
castServiceNameStatePair_ = {};
if (multiDeviceState_ != MultiDeviceState::CASTING_SWITCH_DEVICE) {
{
std::lock_guard lockGuard(avsessionItemLock_);
supportedCastCmds_.clear();
}
ProcessFrontSession("Disconnect");
}
SaveLocalDeviceInfo();
if (serviceCallbackForCastNtf_) {
serviceCallbackForCastNtf_(GetSessionId(), false, false);
}
ReportStopCastFinish("AVSessionItem::OnCastStateChange", deviceInfo);
AVSessionSysEvent::GetInstance().ReportSessionCastControl(streamCast_, GetSessionId(), deviceInfo);
}
void AVSessionItem::DealCollaborationPublishState(int32_t castState, DeviceInfo deviceInfo)
{
SLOGI("enter DealCollaborationPublishState");
CHECK_AND_RETURN_LOG(castServiceNameStatePair_.second != deviceStateConnection,
"cast not add to collaboration when mirror to stream cast");
CHECK_AND_RETURN_LOG(multiDeviceState_ != MultiDeviceState::CASTED_AND_CASTING,
"session casted already publish service state");
if (castState == authingStateFromCast_) {
CollaborationManagerURLCasting::GetInstance().PublishServiceState(collaborationNeedDeviceId_.c_str(),
ServiceCollaborationManagerBussinessStatus::SCM_CONNECTING);
}
if (castState == connectStateFromCast_) { // 6 is connected status (stream)
CollaborationManagerURLCasting::GetInstance().PublishServiceState(collaborationNeedNetworkId_.c_str(),
ServiceCollaborationManagerBussinessStatus::SCM_CONNECTED);
}
if (castState == disconnectStateFromCast_) { // 5 is disconnected status
if (collaborationNeedNetworkId_.empty()) {
SLOGI("networkId is empty, try use deviceId:%{public}s",
AVSessionUtils::GetAnonyNetworkId(deviceInfo.realDeviceId_).c_str());
collaborationNeedNetworkId_ = deviceInfo.realDeviceId_;
}
CollaborationManagerURLCasting::GetInstance().PublishServiceState(collaborationNeedDeviceId_.c_str(),
ServiceCollaborationManagerBussinessStatus::SCM_IDLE);
CollaborationManagerURLCasting::GetInstance().PublishServiceState(collaborationNeedNetworkId_.c_str(),
ServiceCollaborationManagerBussinessStatus::SCM_IDLE);
}
}
void AVSessionItem::DealLocalState(const int32_t castState, const OutputDeviceInfo& outputDeviceInfo)
{
CHECK_AND_RETURN(castState == static_cast<int32_t>(ConnectionState::STATE_DISCONNECTED));
OutputDeviceInfo localDeviceInfo;
DeviceInfo deviceInfo;
deviceInfo.castCategory_ = AVCastCategory::CATEGORY_LOCAL;
deviceInfo.deviceId_ = "0";
deviceInfo.deviceName_ = "LocalDevice";
localDeviceInfo.deviceInfos_.emplace_back(deviceInfo);
switch (multiDeviceState_) {
case MultiDeviceState::DEFAULT:
SetOutputDevice(localDeviceInfo);
break;
case MultiDeviceState::CASTING_SWITCH_DEVICE:
case MultiDeviceState::CASTED_AND_CASTING:
{
std::lock_guard lockGuard(castLock_);
multiDeviceState_ = MultiDeviceState::DEFAULT;
CHECK_AND_RETURN(newOutputDeviceInfo_.deviceInfos_.size() > 0);
std::this_thread::sleep_for(std::chrono::milliseconds(SWITCH_WAIT_TIME));
if (CastAddToCollaboration(newOutputDeviceInfo_) != AVSESSION_SUCCESS ||
SubStartCast(newOutputDeviceInfo_) != AVSESSION_SUCCESS) {
OnCastStateChange(disconnectStateFromCast_,
newOutputDeviceInfo_.deviceInfos_[0], false, noReasonCode_);
AVSessionUtils::PublishCommonEvent(MEDIA_CAST_ERROR);
}
}
break;
case MultiDeviceState::CASTING_AND_CASTED:
{
std::lock_guard lockGuard(castLock_);
multiDeviceState_ = MultiDeviceState::DEFAULT;
CHECK_AND_RETURN(newOutputDeviceInfo_.deviceInfos_.size() > 0);
AVRouter::GetInstance().SetCastingDeviceName(outputDeviceInfo.deviceInfos_[0].deviceName_);
SetOutputDevice(localDeviceInfo);
AVRouter::GetInstance().NotifyCastSessionCreated();
}
break;
}
}
void AVSessionItem::ListenCollaborationOnStop()
{
SLOGI("enter ListenCollaborationOnStop");
auto weakSelf = wptr<AVSessionItem>(this);
CollaborationManagerURLCasting::GetInstance().SendCollaborationOnStop([weakSelf](void) {
auto sharedPtr = weakSelf.promote();
CHECK_AND_RETURN_LOG(sharedPtr != nullptr, "AVSessionItem is null in ListenCollaborationOnStop");
{
std::lock_guard lockGuard(sharedPtr->destroyLock_);
CHECK_AND_RETURN_LOG(!sharedPtr->isDestroyed_.load(), "AVSessionItem is destroyed, skip StopCast");
}
if (sharedPtr->descriptor_.sessionTag_ == "RemoteCast") {
SLOGI("notify controller avplayer cancle cast when pc recive onstop callback");
AVRouter::GetInstance().StopCastSession(sharedPtr->castHandle_);
} else {
sharedPtr->StopCast();
}
});
}
void AVSessionItem::PublishAVCastHa(int32_t castState, DeviceInfo deviceInfo)
{
CHECK_AND_RETURN_LOG(descriptor_.sessionTag_ != "RemoteCast", "remote cast session, return");
if (castState == connectStateFromCast_) {
AVSessionHiAnalyticsReport::PublishCastEvent(GetBundleName(), connectStateFromCast_,
castDeviceInfoMap_[deviceInfo.deviceId_]);
} else if (castState == disconnectStateFromCast_) {
AVSessionHiAnalyticsReport::PublishCastEvent(GetBundleName(), disconnectStateFromCast_,
castDeviceInfoMap_[deviceInfo.deviceId_]);
AVSessionHiAnalyticsReport::PublishCastRecord(GetBundleName(), castDeviceInfoMap_[deviceInfo.deviceId_]);
}
}
void AVSessionItem::BuildCollaborationPublishStateParam(int32_t castState, DeviceInfo deviceInfo)
{
std::lock_guard lockGuard(castLock_);
if (castState == connectStateFromCast_) { // 6 is connected status (stream)
AVRouter::GetInstance().GetRemoteNetWorkId(
castHandle_, deviceInfo.realDeviceId_, collaborationNeedNetworkId_);
if (collaborationNeedNetworkId_.empty()) {
SLOGI("networkId is empty, try use deviceId:%{public}s",
AVSessionUtils::GetAnonyNetworkId(deviceInfo.realDeviceId_).c_str());
collaborationNeedNetworkId_ = deviceInfo.realDeviceId_;
}
collaborationNeedDeviceId_ = deviceInfo.realDeviceId_;
}
}
void AVSessionItem::OnCastStateChange(int32_t castState, DeviceInfo deviceInfo, bool isNeedRemove, int32_t reasonCode)
{
SLOGI("OnCastStateChange in with BundleName:%{public}s|state:%{public}d|id:%{public}s", GetBundleName().c_str(),
static_cast<int32_t>(castState), AVSessionUtils::GetAnonyNetworkId(deviceInfo.deviceId_).c_str());
CHECK_AND_RETURN_LOG(validCastStates_.count(castState) > 0, "castState is invalid");
if (deviceInfo.deviceId_ == "-1") { //cast_engine_service abnormal terminated, update deviceId in item
deviceInfo = descriptor_.outputDeviceInfo_.deviceInfos_[0];
}
BuildCollaborationPublishStateParam(castState, deviceInfo);
if (isNeedRemove) { //same device cast exchange no publish when hostpot scene
DealCollaborationPublishState(castState, deviceInfo);
}
if (SearchSpidInCapability(deviceInfo.deviceId_)) {
deviceInfo.supportedPullClients_.clear();
deviceInfo.supportedPullClients_.push_back(GetSpid());
SLOGI("OnCastStateChange add pull client: %{public}u", GetSpid());
}
ListenCollaborationOnStop();
OutputDeviceInfo outputDeviceInfo;
{
std::lock_guard lockGuard(castDeviceInfoMapMutex_);
bool hasDevice = castDeviceInfoMap_.count(deviceInfo.deviceId_) > 0;
if (hasDevice && (static_cast<uint32_t>(castDeviceInfoMap_[deviceInfo.deviceId_].supportedProtocols_) &
ProtocolType::TYPE_CAST_PLUS_AUDIO)) {
castDeviceInfoMap_[deviceInfo.deviceId_].audioCapabilities_ = deviceInfo.audioCapabilities_;
}
outputDeviceInfo.deviceInfos_.emplace_back(hasDevice ? castDeviceInfoMap_[deviceInfo.deviceId_] : deviceInfo);
}
PublishAVCastHa(castState, deviceInfo);
if (castState == connectStateFromCast_) { // 6 is connected status (stream)
castState = 1; // 1 is connected status (local)
descriptor_.outputDeviceInfo_ = outputDeviceInfo;
ReportConnectFinish("AVSessionItem::OnCastStateChange", deviceInfo);
if (callStartCallback_ && isNeedRemove && descriptor_.sessionTag_ == "RemoteCast") {
SLOGI("AVSessionItem send callStart event to service for connected");
callStartCallback_(*this);
}
if (serviceCallbackForPhotoCast_ && descriptor_.sessionType_ == AVSession::SESSION_TYPE_PHOTO) {
serviceCallbackForPhotoCast_(GetSessionId(), true);
}
} else if (castState == disconnectStateFromCast_) { // 5 is disconnected status
castState = 6; // 6 is disconnected status of AVSession
if (serviceCallbackForPhotoCast_ && descriptor_.sessionType_ == AVSession::SESSION_TYPE_PHOTO &&
multiDeviceState_ != MultiDeviceState::CASTING_SWITCH_DEVICE) {
serviceCallbackForPhotoCast_(GetSessionId(), false);
}
DealDisconnect(outputDeviceInfo.deviceInfos_[0], isNeedRemove);
}
DealOutputDeviceChange(castState, outputDeviceInfo);
ResetCastControlInfo(castState, reasonCode, outputDeviceInfo);
}
void AVSessionItem::ResetCastControlInfo(int32_t castState, int32_t reasonCode,
const OutputDeviceInfo& outputDeviceInfo)
{
if (castState == authingStateFromCast_ && reasonCode == reasonShowTrustSelectUI_) {
SLOGI("OnCastStateChange: authing state with show pin, reset isNeedRecord_");
AVSessionSysEvent::GetInstance().clearCastControlInfo(GetSessionId());
}
if (castState == mirrorToStream_) {
AVSessionSysEvent::GetInstance().updateStartCastTime(GetSessionId(), GetBundleName(),
BundleStatusAdapter::GetInstance().GetAppVersion(GetBundleName()), GetSessionType());
AVSessionSysEvent::GetInstance().ReportSessionCastControl(mirrorToStreamCast_,
GetSessionId(), outputDeviceInfo.deviceInfos_[0]);
}
if (castState == ConnectionState::STATE_DISCONNECTED && descriptor_.sessionTag_ == "RemoteCast") {
SLOGI("Sink cast session is disconnected, avsession item need be destroyed.");
Destroy();
} else {
DealLocalState(castState, outputDeviceInfo);
}
}
void AVSessionItem::DealOutputDeviceChange(const int32_t castState, const OutputDeviceInfo& outputDeviceInfo)
{
CHECK_AND_RETURN_LOG(multiDeviceState_ != MultiDeviceState::CASTED_AND_CASTING,
"current session no need deal output device change");
if (castState == ConnectionState::STATE_CONNECTED && mirrorToStreamOnceFlag_ &&
AVRouter::GetInstance().IsInMirrorToStreamState()) {
mirrorToStreamOnceFlag_ = false;
SLOGI("mirror to stream prevent connection callback from cast caused by app distribute resource");
return;
}
HandleOutputDeviceChange(castState, outputDeviceInfo);
std::lock_guard controllersLockGuard(controllersLock_);
for (const auto& controller : controllers_) {
if (controller.second != nullptr) {
controller.second->HandleOutputDeviceChange(castState, outputDeviceInfo);
}
}
}
void AVSessionItem::OnCastEventRecv(int32_t errorCode, std::string& errorMsg)
{
SLOGI("OnCastEventRecv in with code and msg %{public}d %{public}s", errorCode, errorMsg.c_str());
auto it = castEventHandlers_.find(errorCode);
if (it != castEventHandlers_.end()) {
it->second();
} else {
SLOGW("Unhandled cast event: %{public}d", errorCode);
}
}
int32_t AVSessionItem::StopCast(const DeviceRemoveAction deviceRemoveAction)
{
if (isHiPlayStreamCasting_.load()) {
return AVRouter::GetInstance().PcmCastSessionReleasePlayer();
}
std::lock_guard lockGuard(castLock_);
if (descriptor_.sessionTag_ == "RemoteCast") {
CollaborationManagerURLCasting::GetInstance().PublishServiceState(collaborationNeedDeviceId_.c_str(),
ServiceCollaborationManagerBussinessStatus::SCM_IDLE);
CollaborationManagerURLCasting::GetInstance().PublishServiceState(collaborationNeedNetworkId_.c_str(),
ServiceCollaborationManagerBussinessStatus::SCM_IDLE);
AVRouter::GetInstance().UnRegisterCallback(castHandle_, cssListener_, GetSessionId());
int32_t ret = AVRouter::GetInstance().StopCastSession(castHandle_);
SetCastHandle(-1);
castHandleDeviceId_ = "-100";
SLOGI("Unregister and Stop cast process for sink with ret %{public}d", ret);
return ret;
}
if (AVRouter::GetInstance().GetCastSide() == CAST_SIDE::CAST_SINK) {
CHECK_AND_RETURN_RET_LOG(serviceCallbackStopSinkCast_ != nullptr, AVSESSION_ERROR, "callback nullptr");
AVRouter::GetInstance().RegisterStashCallback(INT64_MAX, cssListener_, GetSessionId());
serviceCallbackStopSinkCast_();
return AVSESSION_SUCCESS;
}
CHECK_AND_RETURN_RET_LOG(castHandle_ != 0 && castHandle_ != -1, AVSESSION_SUCCESS, "Not cast session, return");
std::string callingBundleName = BundleStatusAdapter::GetInstance().GetBundleNameFromUid(GetCallingUid());
bool isMediaOrSceneBoard = (callingBundleName == MEDIA_CONTROL_BUNDLENAME) ||
(callingBundleName == SCENE_BOARD_BUNDLENAME);
SLOGI("Stop cast process %{public}lld with rm device %{public}d", (long long)castHandle_, isMediaOrSceneBoard);
if ((castHandle_ == AVRouter::GetInstance().GetMirrorCastHandle()) && !isMediaOrSceneBoard) {
CHECK_AND_RETURN_RET(castControllerProxy_ != nullptr, AVSESSION_SUCCESS);
AVCastControlCommand cmd;
cmd.SetCommand(AVCastControlCommand::CAST_CONTROL_CMD_STOP);
castControllerProxy_->SendControlCommand(cmd);
} else {
AVSessionRadarInfo info("AVSessionItem::StopCast");
AVSessionRadar::GetInstance().StopCastBegin(descriptor_.outputDeviceInfo_, info);
int64_t ret = AVRouter::GetInstance().StopCast(castHandle_, deviceRemoveAction);
AVSessionRadar::GetInstance().StopCastEnd(descriptor_.outputDeviceInfo_, info);
SLOGI("StopCast with unchange castHandle is %{public}lld", (long long)castHandle_);
CHECK_AND_RETURN_RET_LOG(ret != AVSESSION_ERROR, AVSESSION_ERROR, "StopCast failed");
}
return AVSESSION_SUCCESS;
}
void AVSessionItem::SetCastHandle(const int64_t castHandle)
{
castHandle_ = castHandle;
if (serviceCallbackForUpdateSession_) {
serviceCallbackForUpdateSession_(sessionCastState_, IsCasting());
}
}
void AVSessionItem::RegisterDeviceStateCallback()
{
CHECK_AND_RETURN_LOG(cssListener_ != nullptr, "cssListener_ is nullptr");
OutputDeviceInfo localDevice;
DeviceInfo localInfo;
localInfo.castCategory_ = AVCastCategory::CATEGORY_LOCAL;
localInfo.deviceId_ = "0";
localInfo.deviceName_ = "LocalDevice";
localDevice.deviceInfos_.emplace_back(localInfo);
descriptor_.outputDeviceInfo_ = localDevice;
AVRouter::GetInstance().RegisterCallback(castHandle_, cssListener_, GetSessionId(), localInfo);
SLOGI("register callback for device state change done");
}
void AVSessionItem::UnRegisterDeviceStateCallback()
{
CHECK_AND_RETURN_LOG(cssListener_ != nullptr, "cssListener_ is nullptr");
AVRouter::GetInstance().UnRegisterCallback(castHandle_, cssListener_, GetSessionId());
}
void AVSessionItem::StopCastSession()
{
std::lock_guard lockGuard(castLock_);
SLOGI("Stop cast session process with castHandle: %{public}" PRId64, castHandle_);
int64_t ret = AVRouter::GetInstance().StopCastSession(castHandle_);
DoContinuousTaskUnregister();
if (ret != AVSESSION_ERROR) {
SetCastHandle(-1);
castHandleDeviceId_ = "-100";
} else {
SLOGE("Stop cast session process error");
}
}
int32_t AVSessionItem::StartCastDisplayListener()
{
SLOGI("StartCastDisplayListener in");
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "onCastDisplayChange",
"BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_,
"SESSION_TYPE", GetSessionType(),
"ERROR_CODE", AVSESSION_SUCCESS,
"ERROR_MSG", "SUCCESS");
sptr<IAVSessionCallback> callback;
{
std::lock_guard callbackLockGuard(callbackLock_);
CHECK_AND_RETURN_RET_LOG(callback_ != nullptr, AVSESSION_ERROR, "callback_ is nullptr");
callback = callback_;
}
GetDisplayListener(callback);
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::StopCastDisplayListener()
{
SLOGI("StopCastDisplayListener in");
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "offCastDisplayChange",
"BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_,
"SESSION_TYPE", GetSessionType(),
"ERROR_CODE", AVSESSION_SUCCESS,
"ERROR_MSG", "SUCCESS");
std::lock_guard displayListenerLockGuard(displayListenerLock_);
CHECK_AND_RETURN_RET_LOG(displayListener_ != nullptr, AVSESSION_ERROR, "displayListener_ is nullptr");
Rosen::DMError ret = Rosen::ScreenManagerLite::GetInstance().UnregisterScreenListener(displayListener_);
if (ret != Rosen::DMError::DM_OK) {
SLOGE("UnregisterScreenListener failed, ret: %{public}d.", ret);
}
displayListener_ = nullptr;
return AVSESSION_SUCCESS;
}
void AVSessionItem::GetDisplayListener(sptr<IAVSessionCallback> callback)
{
SLOGI("GetDisplayListener in");
std::lock_guard displayListenerLockGuard(displayListenerLock_);
if (displayListener_ == nullptr) {
SLOGI("displayListener_ is null, try to create new listener");
bool isPcMode = false;
if (serviceCallbackForPcMode_ != nullptr) {
isPcMode = serviceCallbackForPcMode_();
SLOGI("GetDisplayListener isPcMode %{public}d", isPcMode);
}
displayListener_ = new HwCastDisplayListener(callback, !isPcMode);
CHECK_AND_RETURN_LOG(displayListener_ != nullptr, "Create displayListener failed");
SLOGI("Start to register display listener");
Rosen::DMError ret = Rosen::ScreenManagerLite::GetInstance().RegisterScreenListener(displayListener_);
if (ret != Rosen::DMError::DM_OK) {
SLOGE("UnregisterScreenListener failed, ret: %{public}d.", ret);
}
}
return;
}
int32_t AVSessionItem::GetAllCastDisplays(std::vector<CastDisplayInfo>& castDisplays)
{
SLOGI("GetAllCastDisplays in");
sptr<HwCastDisplayListener> displayListener;
{
std::lock_guard displayListenerLockGuard(displayListenerLock_);
displayListener = displayListener_;
}
std::vector<Rosen::DisplayId> allDisplayIds = Rosen::DisplayManagerLite::GetInstance().GetAllDisplayIds();
std::vector<CastDisplayInfo> displays;
for (auto &displayId : allDisplayIds) {
sptr<Rosen::DisplayLite> display = Rosen::DisplayManagerLite::GetInstance().GetDisplayById(displayId);
CHECK_AND_RETURN_RET_LOG(display != nullptr, AVSESSION_ERROR, "display is nullptr");
auto displayInfo = display->GetDisplayInfo();
if (displayInfo->GetName() == "HwCast_AppModeDisplay") {
displays.clear();
SLOGI("GetAllCastDisplays AppCast");
if (displayListener != nullptr) {
displayListener->SetAppCastDisplayId(displayInfo->GetDisplayId());
}
break;
}
auto flag = Rosen::DisplayManagerLite::GetInstance().GetVirtualScreenFlag(displayInfo->GetDisplayId());
if (flag == Rosen::VirtualScreenFlag::CAST) {
SLOGI("ReportCastDisplay start in");
CastDisplayInfo castDisplayInfo;
castDisplayInfo.displayState = CastDisplayState::STATE_ON;
castDisplayInfo.displayId = displayInfo->GetDisplayId();
castDisplayInfo.name = displayInfo->GetName();
castDisplayInfo.width = static_cast<int32_t>(displayInfo->GetWidth());
castDisplayInfo.height = static_cast<int32_t>(displayInfo->GetHeight());
displays.push_back(castDisplayInfo);
if (displayListener != nullptr) {
displayListener->SetDisplayInfo(displayInfo);
}
}
}
castDisplays = displays;
if (displayListener != nullptr && !displayListener->IsSupportExtendedScreen()) {
SLOGI("GetAllCastDisplays not support extended screen, return empty");
castDisplays.clear();
}
SLOGI("GetAllCastDisplays out");
return AVSESSION_SUCCESS;
}
void AVSessionItem::SetSpid(const AAFwk::WantParams& extras)
{
std::unique_lock <std::mutex> lock(spidMutex_);
if (extras.HasParam("request-tv-client")) {
auto value = extras.GetParam("request-tv-client");
AAFwk::IInteger* intValue = AAFwk::IInteger::Query(value);
if (intValue != nullptr && AAFwk::Integer::Unbox(intValue) > 0) {
spid_ = static_cast<uint32_t>(AAFwk::Integer::Unbox(intValue));
SLOGI("AVSessionItem SetSpid %{public}u", spid_);
} else {
SLOGE("AVSessionItem SetSpid failed");
}
}
}
uint32_t AVSessionItem::GetSpid()
{
std::unique_lock <std::mutex> lock(spidMutex_);
return spid_;
}
bool AVSessionItem::SearchSpidInCapability(const std::string& deviceId)
{
std::unique_lock <std::mutex> lock(spidMutex_);
auto iter = castDeviceInfoMap_.find(deviceId);
if (iter == castDeviceInfoMap_.end()) {
SLOGE("deviceId map deviceinfo is not exit");
return false;
}
for (uint32_t cap : iter->second.supportedPullClients_) {
if (cap == spid_) {
return true;
}
}
return false;
}
void AVSessionItem::SubSetExtrasInner()
{
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "SetExtras", "BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_, "SESSION_TYPE", GetSessionType(),
"API_PARAM", "requireAbilityList: url-cast",
"APP_VERSION_NAME", BundleStatusAdapter::GetInstance().GetAppVersion(GetBundleName()),
"COST_TIME", 0,
"OS_VERSION", AVSessionSysEvent::GetInstance().GetOsVersion(),
"SDK_VERSION", AVSessionSysEvent::GetInstance().GetSdkVersion(),
"ERROR_CODE", AVSESSION_SUCCESS, "ERROR_MSG", "SUCCESS");
if (descriptor_.sessionType_ == AVSession::SESSION_TYPE_VIDEO && serviceCallbackForStream_) {
SLOGI("AVSessionItem send mirrortostream event to service");
serviceCallbackForStream_(GetSessionId());
}
}
void AVSessionItem::SetExtrasInner(AAFwk::IArray* list)
{
auto func = [this](AAFwk::IInterface* object) {
if (object != nullptr) {
AAFwk::IString* stringValue = AAFwk::IString::Query(object);
if (stringValue != nullptr && AAFwk::String::Unbox(stringValue) == "url-cast") {
SubSetExtrasInner();
}
}
};
AAFwk::Array::ForEach(list, func);
}
bool AVSessionItem::IsAppSupportCast()
{
CHECK_AND_RETURN_RET_LOG(GetExtras().HasParam("requireAbilityList"), false, "extras not have requireAbilityList");
auto value = GetExtras().GetParam("requireAbilityList");
AAFwk::IArray* list = AAFwk::IArray::Query(value);
CHECK_AND_RETURN_RET_LOG(list != nullptr && AAFwk::Array::IsStringArray(list), false, "extras have no value");
bool result = false;
auto func = [&result](AAFwk::IInterface* object) {
CHECK_AND_RETURN(result != true);
CHECK_AND_RETURN_LOG(object != nullptr, "object is nullptr");
AAFwk::IString* stringValue = AAFwk::IString::Query(object);
CHECK_AND_RETURN_LOG(stringValue != nullptr, "stringValue is nullptr");
result = (AAFwk::String::Unbox(stringValue) == "url-cast");
};
AAFwk::Array::ForEach(list, func);
SLOGI("url-cast:%{public}d|filter:%{public}d", result, GetMetaDataWithoutImg().GetFilter());
return result && (GetMetaDataWithoutImg().GetFilter() != 0);
}
bool AVSessionItem::IsMediaChangeForMirrorToStream() const
{
return isMediaChangeForMirrorToStream_.load();
}
void AVSessionItem::SetMediaChangeForMirrorToStream(bool isMediaChange)
{
isMediaChangeForMirrorToStream_.store(isMediaChange);
}
void AVSessionItem::SetServiceCallbackForStream(const std::function<void(std::string)>& callback)
{
SLOGI("SetServiceCallbackForStream in");
serviceCallbackForStream_ = callback;
}
void AVSessionItem::SetServiceCallbackForCastNtfCapsule(const std::function<void(std::string, bool, bool)>& callback)
{
SLOGI("SetServiceCallbackForCastNtfCapsule in");
serviceCallbackForCastNtf_ = callback;
}
void AVSessionItem::SetServiceCallbackForStopSinkCast(const std::function<void()>& callback)
{
SLOGI("SetServiceCallbackForStopSinkCast in");
serviceCallbackStopSinkCast_ = callback;
}
void AVSessionItem::SetMultiDeviceState(MultiDeviceState multiDeviceState)
{
multiDeviceState_.store(multiDeviceState);
}
MultiDeviceState AVSessionItem::GetMultiDeviceState()
{
return multiDeviceState_.load();
}
void AVSessionItem::SetServiceCallbackForPhotoCast(const std::function<void(std::string, bool)>& callback)
{
SLOGI("SetServiceCallbackForPhotoCast in");
serviceCallbackForPhotoCast_ = callback;
}
void AVSessionItem::SetIsHiPlayStreamCasting(bool isHiPlayStreamCasting)
{
SLOGI("SetIsHiPlayStreamCasting in");
isHiPlayStreamCasting_.store(isHiPlayStreamCasting);
}
void AVSessionItem::SetSupportExtendedScreen(bool isSupport, bool isHotSwitch)
{
SLOGI("SetSupportExtendedScreen %{public}d", isSupport);
sptr<HwCastDisplayListener> displayListener;
{
std::lock_guard displayListenerLockGuard(displayListenerLock_);
displayListener = displayListener_;
}
CHECK_AND_RETURN_LOG(displayListener != nullptr, "displayListener_ is null");
if (isSupport) {
std::vector<CastDisplayInfo> castDisplays;
GetAllCastDisplays(castDisplays);
}
displayListener->SetSupportExtendedScreen(isSupport, isHotSwitch);
}
void AVSessionItem::SetServiceCallbackForPcMode(const std::function<bool()>& callback)
{
SLOGI("SetServiceCallbackForPcMode in");
serviceCallbackForPcMode_ = callback;
}
#endif
void AVSessionItem::SetServiceCallbackForUpdateExtras(const std::function<void(std::string)>& callback)
{
SLOGI("SetServiceCallbackForUpdateExtras in");
updateExtrasCallback_ = callback;
}
AVSessionDescriptor AVSessionItem::GetDescriptor()
{
return descriptor_;
}
AVCallState AVSessionItem::GetAVCallState()
{
std::lock_guard lockGuard(avsessionItemLock_);
return avCallState_;
}
AVCallMetaData AVSessionItem::GetAVCallMetaData()
{
std::lock_guard lockGuard(avsessionItemLock_);
std::shared_ptr<AVSessionPixelMap> innerPixelMap = avCallMetaData_.GetMediaImage();
ReadMetaDataImg(innerPixelMap);
return avCallMetaData_;
}
AVPlaybackState AVSessionItem::GetPlaybackState()
{
std::lock_guard lockGuard(avsessionItemLock_);
return playbackState_;
}
AVMetaData AVSessionItem::GetMetaDataWithoutImg()
{
std::lock_guard lockGuard(avsessionItemLock_);
return metaData_;
}
AVMetaData AVSessionItem::GetMetaData()
{
std::lock_guard lockGuard(avsessionItemLock_);
std::shared_ptr<AVSessionPixelMap> innerPixelMap = metaData_.GetMediaImage();
ReadMetaDataImg(innerPixelMap);
std::shared_ptr<AVSessionPixelMap> avQueuePixelMap = metaData_.GetAVQueueImage();
ReadMetaDataAVQueueImg(avQueuePixelMap);
return metaData_;
}
void AVSessionItem::ReadMetaDataImg(std::shared_ptr<AVSessionPixelMap>& innerPixelMap, bool isCast)
{
std::shared_lock<std::shared_mutex> lock(writeAndReadImgLock_);
std::string sessionId = GetSessionId();
std::string fileDir = isCast ?
AVSessionUtils::GetCachePathNameForCast(userId_) : AVSessionUtils::GetCachePathName(userId_);
std::string fileName = sessionId + AVSessionUtils::GetFileSuffix();
AVSessionUtils::ReadImageFromFile(innerPixelMap, fileDir, fileName);
}
void AVSessionItem::ReadMetaDataAVQueueImg(std::shared_ptr<AVSessionPixelMap>& avQueuePixelMap)
{
std::string avQueueFileDir = AVSessionUtils::GetFixedPathName(userId_);
std::string avQueueFileName = GetBundleName() + "_" + metaData_.GetAVQueueId() + AVSessionUtils::GetFileSuffix();
if (appIndex_ != 0) {
avQueueFileName = GetBundleName() + "_" + std::to_string(appIndex_) + "_" + metaData_.GetAVQueueId() +
AVSessionUtils::GetFileSuffix();
}
CHECK_AND_RETURN_LOG(AVSessionUtils::IsValidFileName(avQueueFileName), "avQueueFileName is not valid");
AVSessionUtils::ReadImageFromFile(avQueuePixelMap, avQueueFileDir, avQueueFileName);
}
std::vector<AVQueueItem> AVSessionItem::GetQueueItems()
{
std::lock_guard lock_guard(avsessionItemLock_);
return queueItems_;
}
std::string AVSessionItem::GetQueueTitle()
{
std::lock_guard lockGuard(avsessionItemLock_);
return queueTitle_;
}
std::vector<int32_t> AVSessionItem::GetSupportCommand()
{
std::lock_guard lockGuard(avsessionItemLock_);
if (descriptor_.elementName_.GetBundleName() == "castBundleName"
&& descriptor_.elementName_.GetAbilityName() == "castAbilityName") {
std::vector<int32_t> supportedCmdForCastSession {
AVControlCommand::SESSION_CMD_PLAY,
AVControlCommand::SESSION_CMD_PAUSE,
AVControlCommand::SESSION_CMD_STOP,
AVControlCommand::SESSION_CMD_PLAY_NEXT,
AVControlCommand::SESSION_CMD_PLAY_PREVIOUS,
AVControlCommand::SESSION_CMD_SEEK
};
return supportedCmdForCastSession;
}
return supportedCmd_;
}
void AVSessionItem::SetSupportCommand(std::vector<int32_t> cmds)
{
{
std::lock_guard lockGuard(avsessionItemLock_);
supportedCmd_ = cmds;
}
std::string apiParamString = "cmd num:" + std::to_string(cmds.size());
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "SetSupportCommand",
"BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_,
"SESSION_TYPE", GetSessionType(),
"API_PARAM", apiParamString,
"ERROR_CODE", AVSESSION_SUCCESS,
"ERROR_MSG", "SUCCESS");
ProcessFrontSession("SetSupportCommand");
{
std::lock_guard controllerLockGuard(controllersLock_);
SLOGI("send add command event to controller, size:%{public}d", static_cast<int>(controllers_.size()));
for (const auto& [pid, controller] : controllers_) {
if (controller != nullptr) {
controller->HandleValidCommandChange(supportedCmd_);
}
}
}
}
int32_t AVSessionItem::GetAppIndex()
{
std::lock_guard lockGuard(avsessionItemLock_);
return appIndex_;
}
AbilityRuntime::WantAgent::WantAgent AVSessionItem::GetLaunchAbility()
{
if (!isSetLaunchAbility_.load()) {
{
std::lock_guard lockGuard(avsessionItemLock_);
isSetLaunchAbility_.store(true);
}
GetCurrentAppIndexForSession();
std::vector<std::shared_ptr<AAFwk::Want>> wants;
std::shared_ptr<AAFwk::Want> want = std::make_shared<AAFwk::Want>();
want->SetElementName(GetBundleName(), GetAbilityName());
AAFwk::WantParams params;
params.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, AAFwk::Integer::Box(appIndex_));
want->SetParams(params);
wants.push_back(want);
std::vector<AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags;
flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG);
auto launchWantAgent = std::make_shared<AbilityRuntime::WantAgent::WantAgent>();
AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
0, AbilityRuntime::WantAgent::WantAgentConstant::OperationType::START_ABILITIES, flags, wants, nullptr);
auto launchAbility = AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo,
GetUserId(), GetUid());
std::lock_guard lockGuard(launchAbilityLock_);
CHECK_AND_RETURN_RET_LOG(launchAbility != nullptr, launchAbility_, "GetWantAgent failed");
launchAbility_ = *launchAbility;
}
std::lock_guard lockGuard(launchAbilityLock_);
return launchAbility_;
}
AAFwk::WantParams AVSessionItem::GetExtras()
{
std::lock_guard lockGuard(avsessionItemLock_);
return extras_;
}
void AVSessionItem::NotificationExtras(AAFwk::IArray* list)
{
auto func = [this](AAFwk::IInterface* object) {
if (object != nullptr) {
AAFwk::IBoolean* booleanValue = AAFwk::IBoolean::Query(object);
if (booleanValue != nullptr && AAFwk::Boolean ::Unbox(booleanValue)) {
isNotShowNotification_ = true;
} else {
isNotShowNotification_ = false;
}
SLOGI("NotificationExtras=%{public}d", isNotShowNotification_);
}
};
AAFwk::Array::ForEach(list, func);
if (updateExtrasCallback_) {
updateExtrasCallback_(GetSessionId());
}
}
void AVSessionItem::KeyEventExtras(AAFwk::IArray* list)
{
auto func = [this](AAFwk::IInterface* object) {
if (object != nullptr) {
AAFwk::IBoolean* booleanValue = AAFwk::IBoolean::Query(object);
if (booleanValue != nullptr && AAFwk::Boolean::Unbox(booleanValue) &&
serviceCallbackForKeyEvent_) {
SLOGI("AVSessionItem send addkeyeventsession event to service");
serviceCallbackForKeyEvent_(GetSessionId());
}
}
};
AAFwk::Array::ForEach(list, func);
}
bool AVSessionItem::IsNotShowNotification()
{
return isNotShowNotification_;
}
void AVSessionItem::PublishMediaKeyEvent(int32_t keyCode)
{
if (keyCode == MMI::KeyEvent::KEYCODE_MEDIA_PLAY) {
AVSessionUtils::PublishCtrlCmdEvent("OnPlay", GetUid(), GetPid());
} else if (keyCode == MMI::KeyEvent::KEYCODE_MEDIA_NEXT) {
AVSessionUtils::PublishCtrlCmdEvent("OnPlayNext", GetUid(), GetPid());
} else if (keyCode == MMI::KeyEvent::KEYCODE_MEDIA_PREVIOUS) {
AVSessionUtils::PublishCtrlCmdEvent("OnPlayPrevious", GetUid(), GetPid());
}
}
void AVSessionItem::HandleMediaKeyEvent(const MMI::KeyEvent& keyEvent, const CommandInfo& cmdInfo)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnMediaKeyEvent");
CHECK_AND_RETURN_LOG(descriptor_.isActive_, "session is deactive");
SLOGI("HandleMediaKeyEvent check isMediaKeySupport %{public}d for %{public}d to pid %{public}d",
static_cast<int>(isMediaKeySupport.load()),
static_cast<int>(keyEvent.GetKeyCode()),
static_cast<int>(GetPid()));
if (!isMediaKeySupport.load() && keyEventCaller_.count(keyEvent.GetKeyCode()) > 0) {
AVControlCommand cmd;
int32_t rewindSkip;
int32_t skipIntervals;
int32_t fastForwardSkip;
cmd.SetCommand(AVControlCommand::SESSION_CMD_PLAY);
{
std::lock_guard lockGuard(avsessionItemLock_);
rewindSkip = metaData_.GetRewindSkipIntervals();
skipIntervals = metaData_.GetSkipIntervals();
fastForwardSkip = metaData_.GetFastForwardSkipIntervals();
}
cmd.SetRewindTime(rewindSkip != 0 ? rewindSkip : skipIntervals);
cmd.SetForwardTime(fastForwardSkip != 0 ? fastForwardSkip : skipIntervals);
cmd.SetCommandInfo(cmdInfo);
keyEventCaller_[keyEvent.GetKeyCode()](cmd);
} else {
{
std::lock_guard callbackLockGuard(callbackLock_);
if (callback_ != nullptr) {
callback_->OnMediaKeyEvent(keyEvent);
}
}
PublishMediaKeyEvent(keyEvent.GetKeyCode());
}
#ifdef ENABLE_AVSESSION_SYSEVENT_CONTROL
ReportSessionControl(descriptor_.elementName_.GetBundleName(), AVControlCommand::SESSION_CMD_PLAY);
#endif
}
void AVSessionItem::ExecuteControllerCommand(const AVControlCommand& cmd)
{
HISYSEVENT_ADD_OPERATION_COUNT(Operation::OPT_ALL_CTRL_COMMAND);
int32_t code = cmd.GetCommand();
if (code < 0 || code >= SESSION_CMD_MAX) {
SLOGE("controlCommand invalid");
return;
}
auto cmdBack = cmd;
CommandInfo cmdInfo;
cmdBack.GetCommandInfo(cmdInfo);
auto callingUid = GetCallingUid();
if (callingUid == CAST_STATIC_UID) {
auto deviceInfos = descriptor_.outputDeviceInfo_.deviceInfos_;
if (deviceInfos.size() > 0) {
auto castDeviceId = deviceInfos[0].deviceId_;
cmdInfo.SetCallerDeviceId(castDeviceId);
}
} else {
std::string callerBundleName = BundleStatusAdapter::GetInstance().GetBundleNameFromUid(callingUid);
cmdInfo.SetCallerBundleName(callerBundleName);
}
cmdInfo.SetCallerType(callingUid == CAST_STATIC_UID ?
PlayTypeToString.at(PlayType::CAST) : PlayTypeToString.at(PlayType::APP));
// Existing commandInfo data cannot be overwritten
std::string callerModuleName {};
cmdInfo.GetCallerModuleName(callerModuleName);
if (!callerModuleName.empty() || callingUid == CAST_STATIC_UID) {
cmdBack.SetCommandInfo(cmdInfo);
SLOGI("ExecuteControllerCommand has moduleName do set CommandInfo");
}
SLOGI("ExecuteControllerCommand code %{public}d from pid %{public}d to pid %{public}d",
code, static_cast<int>(GetCallingPid()), static_cast<int>(GetPid()));
{
std::lock_guard remoteSinkLockGuard(remoteSinkLock_);
if (remoteSink_ != nullptr) {
SLOGI("set remote ControlCommand");
CHECK_AND_RETURN_LOG(remoteSink_->SetControlCommand(cmdBack) == AVSESSION_SUCCESS,
"SetControlCommand failed");
}
}
CHECK_AND_RETURN_LOG(callback_ != nullptr || callbackForMigrate_ != nullptr,
"callback_ or callbackForMigrate_ is nullptr");
CHECK_AND_RETURN_LOG(descriptor_.isActive_, "session is deactivate");
HISYSEVENT_ADD_OPERATION_COUNT(static_cast<Operation>(cmdBack.GetCommand()));
HISYSEVENT_ADD_OPERATION_COUNT(Operation::OPT_SUCCESS_CTRL_COMMAND);
HISYSEVENT_ADD_CONTROLLER_COMMAND_INFO(descriptor_.elementName_.GetBundleName(), GetPid(),
cmdBack.GetCommand(), descriptor_.sessionType_);
#ifdef ENABLE_AVSESSION_SYSEVENT_CONTROL
ReportSessionControl(descriptor_.elementName_.GetBundleName(), cmdBack.GetCommand());
#endif
return cmdHandlers[code](cmdBack);
HISYSEVENT_FAULT("CONTROL_COMMAND_FAILED", "ERROR_TYPE", "INVALID_COMMAND", "CMD", code,
"ERROR_INFO", "avsessionitem executecontrollercommand, invaild command");
}
// LCOV_EXCL_STOP
void AVSessionItem::ExecueCommonCommand(const std::string& commonCommand, const AAFwk::WantParams& commandArgs)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::ExecueCommonCommand");
{
std::lock_guard callbackLockGuard(callbackLock_);
if (callbackForMigrate_) {
callbackForMigrate_->OnCommonCommand(commonCommand, commandArgs);
}
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnCommonCommand(commonCommand, commandArgs);
}
std::lock_guard remoteSinkLockGuard(remoteSinkLock_);
if (remoteSink_ != nullptr) {
CHECK_AND_RETURN_LOG(remoteSink_->SetCommonCommand(commonCommand, commandArgs) == AVSESSION_SUCCESS,
"SetCommonCommand failed");
}
}
void AVSessionItem::ExecuteCustomData(const AAFwk::WantParams& data)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::ExecuteCustomData");
{
std::lock_guard callbackLockGuard(callbackLock_);
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnCustomData(data);
}
}
// LCOV_EXCL_START
void AVSessionItem::HandleSkipToQueueItem(const int32_t& itemId)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnSkipToQueueItem");
std::lock_guard callbackLockGuard(callbackLock_);
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnSkipToQueueItem(itemId);
}
void AVSessionItem::HandleOnAVCallAnswer(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnAVCallAnswer");
std::lock_guard callbackLockGuard(callbackLock_);
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnAVCallAnswer();
}
void AVSessionItem::HandleOnAVCallHangUp(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnAVCallHangUp");
std::lock_guard callbackLockGuard(callbackLock_);
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnAVCallHangUp();
}
void AVSessionItem::HandleOnAVCallToggleCallMute(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnAVCallToggleCallMute");
std::lock_guard callbackLockGuard(callbackLock_);
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnAVCallToggleCallMute();
}
void AVSessionItem::HandleOnPlay(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnPlay");
{
std::lock_guard callbackLockGuard(callbackLock_);
if (callbackForMigrate_) {
callbackForMigrate_->OnPlay(cmd);
}
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnPlay(cmd);
}
AVSessionUtils::PublishCtrlCmdEvent("OnPlay", GetUid(), GetPid());
std::string playParam = "";
auto ret = cmd.GetPlayParam(playParam);
SLOGI("handleOnplay with param %{public}s", playParam.c_str());
CHECK_AND_RETURN_LOG(ret == AVSESSION_SUCCESS && playParam == GetSessionId(), "no need update top");
CHECK_AND_RETURN_LOG(serviceCallbackForUpdateTop_, "updateTop callback not found");
std::lock_guard updateTopLockGuard(updateTopLock_);
serviceCallbackForUpdateTop_(playParam);
}
void AVSessionItem::HandleOnPause(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnPause");
std::lock_guard callbackLockGuard(callbackLock_);
if (callbackForMigrate_) {
callbackForMigrate_->OnPause();
}
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnPause();
}
void AVSessionItem::HandleOnPlayOrPause(const AVControlCommand& cmd)
{
std::lock_guard lockGuard(avsessionItemLock_);
SLOGI("check current playstate : %{public}d", playbackState_.GetState());
if (playbackState_.GetState() == AVPlaybackState::PLAYBACK_STATE_PLAY) {
HandleOnPause(cmd);
} else {
HandleOnPlay(cmd);
}
}
void AVSessionItem::HandleOnStop(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnStop");
std::lock_guard callbackLockGuard(callbackLock_);
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnStop();
}
void AVSessionItem::HandleOnPlayNext(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnPlayNext");
{
std::lock_guard callbackLockGuard(callbackLock_);
if (callbackForMigrate_) {
callbackForMigrate_->OnPlayNext(cmd);
}
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnPlayNext(cmd);
}
AVSessionUtils::PublishCtrlCmdEvent("OnPlayNext", GetUid(), GetPid());
}
void AVSessionItem::HandleOnPlayPrevious(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnPlayPrevious");
{
std::lock_guard callbackLockGuard(callbackLock_);
if (callbackForMigrate_) {
callbackForMigrate_->OnPlayPrevious((cmd));
}
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnPlayPrevious((cmd));
}
AVSessionUtils::PublishCtrlCmdEvent("OnPlayPrevious", GetUid(), GetPid());
}
void AVSessionItem::HandleOnFastForward(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnFastForward");
std::lock_guard callbackLockGuard(callbackLock_);
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
int64_t time = 0;
CHECK_AND_RETURN_LOG(cmd.GetForwardTime(time) == AVSESSION_SUCCESS, "GetForwardTime failed");
callback_->OnFastForward(time, cmd);
}
void AVSessionItem::HandleOnRewind(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnRewind");
std::lock_guard callbackLockGuard(callbackLock_);
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
int64_t time = 0;
CHECK_AND_RETURN_LOG(cmd.GetRewindTime(time) == AVSESSION_SUCCESS, "GetRewindTime failed");
callback_->OnRewind(time, cmd);
}
void AVSessionItem::HandleOnSeek(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnSeek");
std::lock_guard callbackLockGuard(callbackLock_);
int64_t time = 0;
CHECK_AND_RETURN_LOG(cmd.GetSeekTime(time) == AVSESSION_SUCCESS, "GetSeekTime failed");
if (callbackForMigrate_) {
callbackForMigrate_->OnSeek(time);
}
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnSeek(time);
}
void AVSessionItem::HandleOnSetSpeed(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnSetSpeed");
std::lock_guard callbackLockGuard(callbackLock_);
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
double speed = 0.0;
CHECK_AND_RETURN_LOG(cmd.GetSpeed(speed) == AVSESSION_SUCCESS, "GetSpeed failed");
std::string apiParamString = "speed: " + std::to_string(speed);
HISYSEVENT_BEHAVIOR("SESSION_API_BEHAVIOR",
"API_NAME", "SetSpeed", "BUNDLE_NAME", GetBundleName(),
"SESSION_ID", AVSessionUtils::GetAnonySessionId(GetSessionId()),
"SESSION_TAG", descriptor_.sessionTag_,
"SESSION_TYPE", GetSessionType(), "API_PARAM", apiParamString,
"ERROR_CODE", AVSESSION_SUCCESS, "ERROR_MSG", "SUCCESS");
callback_->OnSetSpeed(speed);
}
void AVSessionItem::HandleOnSetLoopMode(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnSetLoopMode");
std::lock_guard callbackLockGuard(callbackLock_);
int32_t loopMode = AVSESSION_ERROR;
CHECK_AND_RETURN_LOG(cmd.GetLoopMode(loopMode) == AVSESSION_SUCCESS, "GetLoopMode failed");
if (callbackForMigrate_) {
callbackForMigrate_->OnSetLoopMode(loopMode);
}
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnSetLoopMode(loopMode);
}
void AVSessionItem::HandleOnSetTargetLoopMode(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnSetTargetLoopMode");
std::lock_guard callbackLockGuard(callbackLock_);
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
int32_t targetLoopMode = AVSESSION_ERROR;
CHECK_AND_RETURN_LOG(cmd.GetTargetLoopMode(targetLoopMode) == AVSESSION_SUCCESS, "GetTargetLoopMode failed");
callback_->OnSetTargetLoopMode(targetLoopMode);
}
void AVSessionItem::HandleOnToggleFavorite(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnToggleFavorite");
std::lock_guard callbackLockGuard(callbackLock_);
std::string assetId;
CHECK_AND_RETURN_LOG(cmd.GetAssetId(assetId) == AVSESSION_SUCCESS, "GetMediaId failed");
if (callbackForMigrate_) {
callbackForMigrate_->OnToggleFavorite(assetId);
}
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnToggleFavorite(assetId);
}
void AVSessionItem::HandleOnPlayFromAssetId(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnPlayFromAssetId");
std::lock_guard callbackLockGuard(callbackLock_);
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
int64_t assetId = 0;
CHECK_AND_RETURN_LOG(cmd.GetPlayFromAssetId(assetId) == AVSESSION_SUCCESS, "Get playFromAssetId failed");
callback_->OnPlayFromAssetId(assetId);
}
void AVSessionItem::HandleOnPlayWithAssetId(const AVControlCommand& cmd)
{
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnPlayWithAssetId");
std::lock_guard callbackLockGuard(callbackLock_);
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
std::string assetId;
CHECK_AND_RETURN_LOG(cmd.GetPlayWithAssetId(assetId) == AVSESSION_SUCCESS, "Get playWithAssetId failed");
CHECK_AND_RETURN_LOG(!assetId.empty(), "assetId is empty");
callback_->OnPlayWithAssetId(assetId);
}
// LCOV_EXCL_STOP
int32_t AVSessionItem::AddController(pid_t pid, sptr<AVControllerItem>& controller)
{
std::lock_guard controllersLockGuard(controllersLock_);
SLOGI("handle controller newup:%{public}d for:%{public}d", static_cast<int>(pid), static_cast<int>(GetPid()));
controllers_.insert({pid, controller});
CHECK_AND_RETURN_RET_LOG(controller != nullptr, AVSESSION_SUCCESS, "controller newup nullptr");
controller->isFromSession_ = (pid == GetPid()) ? true : false;
return AVSESSION_SUCCESS;
}
void AVSessionItem::SetPid(pid_t pid)
{
descriptor_.pid_ = pid;
}
void AVSessionItem::SetUid(pid_t uid)
{
descriptor_.uid_ = uid;
}
pid_t AVSessionItem::GetPid() const
{
return descriptor_.pid_;
}
pid_t AVSessionItem::GetUid() const
{
return descriptor_.uid_;
}
int32_t AVSessionItem::GetUserId() const
{
return userId_;
}
std::string AVSessionItem::GetAbilityName() const
{
return descriptor_.elementName_.GetAbilityName();
}
// LCOV_EXCL_START
std::string AVSessionItem::GetBundleName() const
{
return descriptor_.elementName_.GetBundleName();
}
// LCOV_EXCL_STOP
void AVSessionItem::SetTop(bool top)
{
descriptor_.isTopSession_ = top;
}
std::shared_ptr<RemoteSessionSource> AVSessionItem::GetRemoteSource()
{
return remoteSource_;
}
void AVSessionItem::SetPlayingTime(int64_t playingTime)
{
playingTime_ = playingTime;
}
int64_t AVSessionItem::GetPlayingTime() const
{
return playingTime_;
}
void AVSessionItem::SetCastScreenUserId(int32_t userId)
{
#ifdef CAR_FEATURE_ENABLE
castScreenUserId_ = userId;
#endif
}
int32_t AVSessionItem::GetCastScreenUserId() const
{
#ifdef CAR_FEATURE_ENABLE
return castScreenUserId_;
#else
return AVSESSION_ERROR;
#endif
}
void AVSessionItem::SetLyricTitle(const std::string& title)
{
lyricTitle_ = title;
}
std::string AVSessionItem::GetLyricTitle() const
{
return lyricTitle_;
}
void AVSessionItem::HandleControllerRelease(pid_t pid)
{
std::lock_guard controllersLockGuard(controllersLock_);
SLOGI("handle controller release for pid: %{public}d", static_cast<int>(pid));
controllers_.erase(pid);
}
void AVSessionItem::SetServiceCallbackForRelease(const std::function<void(AVSessionItem&)>& callback)
{
SLOGI("SetServiceCallbackForRelease in");
serviceCallback_ = callback;
}
void AVSessionItem::SetServiceCallbackForAVQueueInfo(const std::function<void(AVSessionItem&)>& callback)
{
SLOGI("SetServiceCallbackForAVQueueInfo in");
serviceCallbackForAddAVQueueInfo_ = callback;
}
void AVSessionItem::SetServiceCallbackForCallStart(const std::function<void(AVSessionItem&)>& callback)
{
SLOGI("SetServiceCallbackForCallStart in");
callStartCallback_ = callback;
}
void AVSessionItem::SetServiceCallbackForUpdateSession(const std::function<void(std::string, bool)>& callback)
{
SLOGI("SetServiceCallbackForUpdateSession in");
serviceCallbackForUpdateSession_ = callback;
}
void AVSessionItem::SetServiceCallbackForMediaSession(const std::function<void(std::string, bool, bool)>& callback)
{
SLOGI("SetServiceCallbackForUpdateSession in");
std::lock_guard mediaSessionLockGuard(mediaSessionCallbackLock_);
serviceCallbackForMediaSession_ = callback;
}
void AVSessionItem::SetServiceCallbackForKeyEvent(const std::function<void(std::string)>& callback)
{
SLOGI("SetServiceCallbackForKeyEvent in");
serviceCallbackForKeyEvent_ = callback;
}
void AVSessionItem::SetServiceCallbackForNtfCapsule(const std::function<void(std::string, bool)>& callback)
{
SLOGI("SetServiceCallbackForNtfCapsule in");
serviceCallbackForNtf_ = callback;
}
void AVSessionItem::SetServiceCallbackForUpdateTop(const std::function<void(std::string)>& callback)
{
SLOGI("SetServiceCallbackForUpdateTop in");
std::lock_guard updateTopLockGuard(updateTopLock_);
serviceCallbackForUpdateTop_ = callback;
}
void AVSessionItem::SetServiceCallbackForAncoStart(
const std::function<void(std::string, std::string, std::string)>& callback)
{
SLOGI("SetServiceCallbackForAncoStart in");
std::lock_guard coldStartLockGuard(coldStartCallbackLock_);
serviceCallbackForAncoStart_ = callback;
}
void AVSessionItem::SetServiceCallbackForBgPlayModeChange(
const std::function<void(std::string, int32_t)>& callback)
{
SLOGI("SetServiceCallbackForBgPlayModeChange in");
serviceCallbackForBgPlayModeChange_ = callback;
}
void AVSessionItem::HandleOutputDeviceChange(const int32_t connectionState, const OutputDeviceInfo& outputDeviceInfo)
{
SLOGI("output device change, connection state is %{public}d", connectionState);
AVSESSION_TRACE_SYNC_START("AVSessionItem::OnOutputDeviceChange");
std::lock_guard callbackLockGuard(callbackLock_);
CHECK_AND_RETURN_LOG(callback_ != nullptr, "callback_ is nullptr");
callback_->OnOutputDeviceChange(connectionState, outputDeviceInfo);
}
void AVSessionItem::SetOutputDevice(const OutputDeviceInfo& info)
{
descriptor_.outputDeviceInfo_ = info;
int32_t connectionStateConnected = 1;
HandleOutputDeviceChange(connectionStateConnected, descriptor_.outputDeviceInfo_);
std::lock_guard controllersLockGuard(controllersLock_);
CHECK_AND_RETURN_LOG(controllers_.size() > 0, "handle with no controller, return");
for (const auto& controller : controllers_) {
if (controller.second != nullptr) {
(controller.second)->HandleOutputDeviceChange(connectionStateConnected, descriptor_.outputDeviceInfo_);
}
}
SLOGI("OutputDeviceInfo device size is %{public}d", static_cast<int32_t>(info.deviceInfos_.size()));
}
void AVSessionItem::SetAndDealOutputDeviceChange(const int32_t castState, const OutputDeviceInfo& outputDeviceInfo)
{
if (castState == ConnectionState::STATE_CONNECTED) {
descriptor_.outputDeviceInfo_ = outputDeviceInfo;
}
HandleOutputDeviceChange(castState, outputDeviceInfo);
std::vector<sptr<AVControllerItem>> controllerList;
{
std::lock_guard controllersLockGuard(controllersLock_);
CHECK_AND_RETURN_LOG(controllers_.size() > 0, "handle with no controller, return");
for (const auto& controller : controllers_) {
if (controller.second != nullptr) {
controllerList.push_back(controller.second);
}
}
}
for (const auto& controller : controllerList) {
controller->HandleOutputDeviceChange(castState, outputDeviceInfo);
}
SLOGI("OutputDeviceInfo device size is %{public}d", static_cast<int32_t>(outputDeviceInfo.deviceInfos_.size()));
}
// LCOV_EXCL_START
void AVSessionItem::GetOutputDevice(OutputDeviceInfo& info)
{
info = GetDescriptor().outputDeviceInfo_;
}
int32_t AVSessionItem::CastAudioToRemote(const std::string& sourceDevice, const std::string& sinkDevice,
const std::string& sinkCapability)
{
SLOGI("start cast audio to remote");
std::lock_guard remoteSourceLockGuard(remoteSourceLock_);
remoteSource_ = std::make_shared<RemoteSessionSourceProxy>();
CHECK_AND_RETURN_RET_LOG(remoteSource_ != nullptr, AVSESSION_ERROR, "remoteSource_ is nullptr");
int32_t ret = remoteSource_->CastSessionToRemote(this, sourceDevice, sinkDevice, sinkCapability);
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "CastSessionToRemote failed");
ret = remoteSource_->SetAVMetaData(GetMetaData());
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "SetAVMetaData failed");
ret = remoteSource_->SetAVPlaybackState(GetPlaybackState());
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "SetAVPlaybackState failed");
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::SourceCancelCastAudio(const std::string& sinkDevice)
{
SLOGI("start cancel cast audio");
std::lock_guard remoteSourceLockGuard(remoteSourceLock_);
CHECK_AND_RETURN_RET_LOG(remoteSource_ != nullptr, AVSESSION_ERROR, "remoteSource_ is nullptr");
int32_t ret = remoteSource_->CancelCastAudio(sinkDevice);
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "CastAudioToLocal failed");
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::CastAudioFromRemote(const std::string& sourceSessionId, const std::string& sourceDevice,
const std::string& sinkDevice, const std::string& sourceCapability)
{
SLOGI("start cast audio from remote");
std::lock_guard remoteSinkLockGuard(remoteSinkLock_);
remoteSink_ = std::make_shared<RemoteSessionSinkProxy>();
CHECK_AND_RETURN_RET_LOG(remoteSink_ != nullptr, AVSESSION_ERROR, "remoteSink_ is nullptr");
int32_t ret = remoteSink_->CastSessionFromRemote(this, sourceSessionId, sourceDevice, sinkDevice,
sourceCapability);
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "CastSessionFromRemote failed");
OutputDeviceInfo outputDeviceInfo;
GetOutputDevice(outputDeviceInfo);
int32_t castCategoryStreaming = ProtocolType::TYPE_CAST_PLUS_STREAM;
for (size_t i = 0; i < outputDeviceInfo.deviceInfos_.size(); i++) {
outputDeviceInfo.deviceInfos_[i].castCategory_ = castCategoryStreaming;
}
SetOutputDevice(outputDeviceInfo);
CHECK_AND_RETURN_RET_LOG(Activate() == AVSESSION_SUCCESS, AVSESSION_ERROR, "Activate failed");
std::vector<std::vector<int32_t>> value(SESSION_DATA_CATEGORY_MAX);
ret = JsonUtils::GetVectorCapability(sourceCapability, value);
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "GetVectorCapability error");
for (auto cmd : value[SESSION_DATA_CONTROL_COMMAND]) {
ret = AddSupportCommand(cmd);
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "AddSupportCommand failed");
}
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::SinkCancelCastAudio()
{
std::lock_guard remoteSinkLockGuard(remoteSinkLock_);
CHECK_AND_RETURN_RET_LOG(remoteSink_ != nullptr, AVSESSION_ERROR, "remoteSink_ is nullptr");
int32_t ret = remoteSink_->CancelCastSession();
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "CancelCastSession failed");
GetDescriptor().outputDeviceInfo_.deviceInfos_.clear();
DeviceInfo deviceInfo;
GetDescriptor().outputDeviceInfo_.deviceInfos_.emplace_back(deviceInfo);
SLOGI("SinkCancelCastAudio");
return AVSESSION_SUCCESS;
}
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
void AVSessionItem::UpdateCastDeviceMap(DeviceInfo deviceInfo)
{
SLOGI("UpdateCastDeviceMap with id: %{public}s",
AVSessionUtils::GetAnonyNetworkId(deviceInfo.deviceId_).c_str());
{
std::lock_guard lockGuard(castDeviceInfoMapMutex_);
castDeviceInfoMap_[deviceInfo.deviceId_] = deviceInfo;
}
if (descriptor_.outputDeviceInfo_.deviceInfos_.size() > 0 &&
descriptor_.outputDeviceInfo_.deviceInfos_[0].deviceId_ == deviceInfo.deviceId_) {
OutputDeviceInfo outputDeviceInfo;
outputDeviceInfo.deviceInfos_.emplace_back(deviceInfo);
descriptor_.outputDeviceInfo_ = outputDeviceInfo;
}
}
#endif
void AVSessionItem::ReportConnectFinish(const std::string func, const DeviceInfo &deviceInfo)
{
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
AVSessionRadarInfo info(func);
DeviceInfo cacheDeviceInfo;
bool hasDevice = false;
{
std::lock_guard lockGuard(castDeviceInfoMapMutex_);
hasDevice = castDeviceInfoMap_.count(deviceInfo.deviceId_) > 0;
if (hasDevice) {
cacheDeviceInfo = castDeviceInfoMap_[deviceInfo.deviceId_];
}
}
if (hasDevice) {
AVSessionRadar::GetInstance().ConnectFinish(cacheDeviceInfo, info);
} else {
AVSessionRadar::GetInstance().ConnectFinish(deviceInfo, info);
}
AVSessionSysEvent::GetInstance().updateDeviceConnectTime(GetSessionId());
#endif
}
void AVSessionItem::ReportStopCastFinish(const std::string func, const DeviceInfo &deviceInfo)
{
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
AVSessionRadarInfo info(func);
DeviceInfo cacheDeviceInfo;
bool hasDevice = false;
{
std::lock_guard lockGuard(castDeviceInfoMapMutex_);
hasDevice = castDeviceInfoMap_.count(deviceInfo.deviceId_) > 0;
if (hasDevice) {
cacheDeviceInfo = castDeviceInfoMap_[deviceInfo.deviceId_];
}
}
if (hasDevice) {
AVSessionRadar::GetInstance().StopCastFinish(cacheDeviceInfo, info);
} else {
AVSessionRadar::GetInstance().StopCastFinish(deviceInfo, info);
}
#endif
}
void AVSessionItem::SaveLocalDeviceInfo()
{
OutputDeviceInfo localDevice;
DeviceInfo localInfo;
localInfo.castCategory_ = AVCastCategory::CATEGORY_LOCAL;
localInfo.deviceId_ = "0";
localInfo.deviceName_ = "LocalDevice";
localDevice.deviceInfos_.emplace_back(localInfo);
descriptor_.outputDeviceInfo_ = localDevice;
}
int32_t AVSessionItem::DoContinuousTaskRegister()
{
#ifdef EFFICIENCY_MANAGER_ENABLE
if (descriptor_.sessionTag_ == "RemoteCast") {
SLOGI("sink session no need to register continuousTask");
return AVSESSION_SUCCESS;
}
int32_t uid = GetUid();
int32_t pid = GetPid();
std::string bundleName = BundleStatusAdapter::GetInstance().GetBundleNameFromUid(uid);
CHECK_AND_RETURN_RET_LOG(bundleName != "", AVSESSION_ERROR, "GetBundleNameFromUid failed");
void *handle_ = dlopen("libsuspend_manager_client.z.so", RTLD_NOW);
if (handle_ == nullptr) {
SLOGE("failed to open library libsuspend_manager_client reaseon %{public}s", dlerror());
return AVSESSION_ERROR;
}
typedef ErrCode (*handler) (int32_t eventType, int32_t uid, int32_t pid,
const std::string bundleName, int32_t taskState, int32_t serviceId);
handler reportContinuousTaskEventEx = reinterpret_cast<handler>(dlsym(handle_, "ReportContinuousTaskEventEx"));
if (reportContinuousTaskEventEx == nullptr) {
SLOGE("dlsym ReportContinuousTaskEventEx failed");
dlclose(handle_);
return AVSESSION_ERROR;
}
ErrCode errCode = reportContinuousTaskEventEx(0, uid, pid, bundleName, 1, AVSESSION_SERVICE_ID);
SLOGI("reportContinuousTaskEventEx done, result: %{public}d", errCode);
#ifndef TEST_COVERAGE
dlclose(handle_);
#endif
#endif
return AVSESSION_SUCCESS;
}
int32_t AVSessionItem::DoContinuousTaskUnregister()
{
#ifdef EFFICIENCY_MANAGER_ENABLE
if (descriptor_.sessionTag_ == "RemoteCast") {
SLOGI("sink session should not unregister ContinuousTask");
return AVSESSION_SUCCESS;
}
int32_t uid = GetUid();
int32_t pid = GetPid();
std::string bundleName = BundleStatusAdapter::GetInstance().GetBundleNameFromUid(uid);
CHECK_AND_RETURN_RET_LOG(bundleName != "", AVSESSION_ERROR, "GetBundleNameFromUid failed");
void *handle_ = dlopen("libsuspend_manager_client.z.so", RTLD_NOW);
if (handle_ == nullptr) {
SLOGE("failed to open library libsuspend_manager_client when stop cast, reaseon %{public}s", dlerror());
return AVSESSION_ERROR;
}
typedef ErrCode (*handler) (int32_t eventType, int32_t uid, int32_t pid,
const std::string bundleName, int32_t taskState, int32_t serviceId);
handler reportContinuousTaskEventEx = reinterpret_cast<handler>(dlsym(handle_, "ReportContinuousTaskEventEx"));
if (reportContinuousTaskEventEx == nullptr) {
SLOGE("dlsym ReportContinuousTaskEventEx failed");
dlclose(handle_);
return AVSESSION_ERROR;
}
ErrCode errCode = reportContinuousTaskEventEx(0, uid, pid, bundleName, 2, AVSESSION_SERVICE_ID);
SLOGI("reportContinuousTaskEventEx done when stop cast, result: %{public}d", errCode);
#ifndef TEST_COVERAGE
dlclose(handle_);
#endif
#endif
return AVSESSION_SUCCESS;
}
bool AVSessionItem::IsCasting()
{
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
if (descriptor_.sessionTag_ != "RemoteCast" && castHandle_ > 0 &&
(castHandle_ != AVRouter::GetInstance().GetMirrorCastHandle() ||
AVRouter::GetInstance().IsInMirrorToStreamState())) {
return true;
}
#endif
return false;
}
bool AVSessionItem::IsCastConnected()
{
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
return IsCasting() && AVRouter::GetInstance().IsRemoteCasting();
#endif
return false;
}
void AVSessionItem::GetCurrentCastItem(AVQueueItem& currentItem)
{
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
std::shared_ptr<IAVCastControllerProxy> proxy = nullptr;
{
std::lock_guard lockGuard(castLock_);
proxy = castControllerProxy_;
}
CHECK_AND_RETURN_LOG(proxy != nullptr, "streamPlayer null");
currentItem = proxy->GetCurrentItem();
#endif
return;
}
AVPlaybackState AVSessionItem::GetCastAVPlaybackState()
{
AVPlaybackState playbackState;
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
std::shared_ptr<IAVCastControllerProxy> proxy = nullptr;
{
std::lock_guard lockGuard(castLock_);
proxy = castControllerProxy_;
}
CHECK_AND_RETURN_RET_LOG(proxy != nullptr, playbackState, "streamPlayer null");
auto ret = proxy->GetCastAVPlaybackState(playbackState);
CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, playbackState, "getstate error");
#endif
return playbackState;
}
void AVSessionItem::SendControlCommandToCast(AVCastControlCommand cmd)
{
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
std::shared_ptr<IAVCastControllerProxy> proxy = nullptr;
{
std::lock_guard lockGuard(castLock_);
proxy = castControllerProxy_;
}
CHECK_AND_RETURN_LOG(proxy != nullptr, "streamPlayer null");
proxy->SendControlCommand(cmd);
#endif
}
#ifdef ENABLE_AVSESSION_SYSEVENT_CONTROL
void AVSessionItem::ReportPlaybackState(const AVPlaybackState& state)
{
if (state.GetState() == AVPlaybackState::PLAYBACK_STATE_PLAY ||
state.GetState() == AVPlaybackState::PLAYBACK_STATE_PAUSE) {
AVSessionSysEvent::GetInstance().UpdatePlaybackState(GetBundleName(),
static_cast<uint8_t>(state.GetState()));
}
}
void AVSessionItem::ReportMetadataChange(const AVMetaData& metadata)
{
if ((metadata.GetTitle().compare(lastMetaData_.GetTitle()) != 0) ||
(metadata.GetMediaImageUri().compare(lastMetaData_.GetMediaImageUri()) != 0)) {
lastMetaData_ = metadata;
bool hasTitle = !metadata.GetTitle().empty();
bool hasImage = metadata.GetMediaImage() != nullptr || !metadata.GetMediaImageUri().empty();
MetadataQuality metadataQuality;
if (!hasTitle && !hasImage) {
metadataQuality = MetadataQuality::METADATA_QUALITY_NONE;
} else if (hasTitle && hasImage) {
metadataQuality = MetadataQuality::METADATA_QUALITY_BOTH;
} else if (hasImage) {
metadataQuality = MetadataQuality::METADATA_QUALITY_IMG;
} else {
metadataQuality = MetadataQuality::METADATA_QUALITY_TITLE;
}
AVSessionSysEvent::GetInstance().UpdateMetaQuality(GetBundleName(), metadataQuality);
}
}
void AVSessionItem::ReportCommandChange()
{
int32_t commandQuality = 0;
for (auto cmd : GetSupportCommand()) {
auto it = g_cmdToOffsetMap.find(cmd);
if (it != g_cmdToOffsetMap.end()) {
commandQuality += (1 << it->second);
}
}
AVSessionSysEvent::GetInstance().UpdateCommandQuality(GetBundleName(), commandQuality);
}
void AVSessionItem::ReportSessionControl(const std::string& bundleName, int32_t cmd)
{
if (cmd == AVControlCommand::SESSION_CMD_PLAY ||
cmd == AVControlCommand::SESSION_CMD_PAUSE ||
cmd == CONTROL_COLD_START) {
auto uid = GetCallingUid();
auto callerBundleName = BundleStatusAdapter::GetInstance().GetBundleNameFromUid(uid);
AVSessionSysEvent::GetInstance().UpdateControl(bundleName, cmd,
callerBundleName.empty() ? std::to_string(uid) : callerBundleName);
}
}
#endif
#ifdef CASTPLUS_CAST_ENGINE_ENABLE
void AVSessionItem::InitCastEventHandlers()
{
castEventHandlers_ = {
{STREAM_TO_MIRROR_FROM_SINK, [this]() {
SLOGI("Stream to mirror from sink event received, stopping cast");
StopCast();
}},
};
}
#endif
// LCOV_EXCL_STOP
} // namespace OHOS::AVSession