diff --git a/interfaces/inner_api/native/session/include/av_cast_provider.h b/interfaces/inner_api/native/session/include/av_cast_provider.h new file mode 100644 index 0000000000000000000000000000000000000000..97309a13dd6e1631f83870e8981fc92cc21dce1c --- /dev/null +++ b/interfaces/inner_api/native/session/include/av_cast_provider.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AV_CAST_PROVIDER_H +#define AV_CAST_PROVIDER_H + +#include "cast_engine_common.h" +#include "i_avcast_state_listener.h" +#include "avsession_descriptor.h" +#include "i_avcast_controller_proxy.h" + +namespace OHOS::AVSession { +class AVCastProvider { +public: + AVCastProvider() = default; + virtual ~AVCastProvider() = default; + + virtual void Init() = 0; + virtual bool StartDiscovery(int castCapability) = 0; + virtual void StopDiscovery() = 0; + virtual void Release() = 0; + virtual bool RegisterCastStateListener(std::shared_ptr listener) = 0; + virtual bool UnRegisterCastStateListener(std::shared_ptr listener) = 0; + virtual bool AddCastDevice(int castId, DeviceInfo deviceInfo) = 0; + virtual bool RemoveCastDevice(int castId, DeviceInfo deviceInfo) = 0; + virtual int StartCastSession() = 0; + virtual void StopCastSession(int castId) = 0; + virtual std::shared_ptr GetRemoteController(int castId) = 0; + virtual bool RegisterCastSessionStateListener(int castId, + std::shared_ptr listener) = 0; + virtual bool UnRegisterCastSessionStateListener(int castId, + std::shared_ptr listener) = 0; +}; +} // namespace OHOS::AVSession + +#endif \ No newline at end of file diff --git a/interfaces/inner_api/native/session/include/i_avcast_controller_proxy.h b/interfaces/inner_api/native/session/include/i_avcast_controller_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..777632ac028fcfc31544c3316b35f5614d98c25e --- /dev/null +++ b/interfaces/inner_api/native/session/include/i_avcast_controller_proxy.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_I_AVCAST_CONTROLLER_PROXY_H +#define OHOS_I_AVCAST_CONTROLLER_PROXY_H + +#include +#include "avplayback_state.h" +#include "media_info_holder.h" +#include "media_info.h" +#include "avcast_control_command.h" +#include "avsession_info.h" + +/** + * @brief Router is a part related to cast media + * @since 10 + */ +namespace OHOS::AVSession { +class IAVCastControllerProxy { +public: + IAVCastControllerProxy () = default; + virtual ~IAVCastControllerProxy () = default; + + virtual void Release() = 0; + + virtual int32_t RegisterControllerListener( + const std::shared_ptr iAVCastControllerProxyListener) = 0; + + virtual int32_t UnRegisterControllerListener( + const std::shared_ptr iAVCastControllerProxyListener) = 0; + + virtual int32_t SetMediaList(const MediaInfoHolder& mediaInfoHolder) = 0; + + virtual void UpdateMediaInfo(const MediaInfo& mediaInfo) = 0; + + virtual void SendControlCommand(const AVCastControlCommand cmd) = 0; + + virtual int32_t GetDuration(int32_t& duration) = 0; + + virtual int32_t GetPosition(int32_t& position) = 0; + + virtual int32_t GetVolume(int32_t& volume) = 0; + + virtual int32_t GetLoopMode(int32_t& loopMode) = 0; + + virtual int32_t GetPlaySpeed(int32_t& playSpeed) = 0; + + virtual int32_t GetPlayState(AVCastPlayerState& playerState) = 0; + + virtual int32_t SetDisplaySurface(std::string& surfaceId) = 0; +}; +} // namespace OHOS::AVSession +#endif // OHOS_I_AVCAST_CONTROLLER_PROXY_H diff --git a/services/session/server/hw_cast_provider.cpp b/services/session/server/hw_cast_provider.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a3ea4dd8f238759aa4f32ed1eb32f0e8244b3c4e --- /dev/null +++ b/services/session/server/hw_cast_provider.cpp @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "hw_cast_provider.h" +#include "cast_session_manager.h" +#include "hw_cast_stream_player.h" +#include "avsession_log.h" +#include "avsession_errors.h" + +using namespace OHOS::CastEngine::CastEngineClient; +using namespace OHOS::CastEngine; + +namespace OHOS::AVSession { +HwCastProvider::~HwCastProvider() +{ + SLOGI("destruct the HwCastProvider"); + Release(); +} + +void HwCastProvider::Init() +{ + SLOGI("Init the HwCastProvider"); + CastSessionManager::GetInstance().RegisterListener(shared_from_this()); +} + + +bool HwCastProvider::StartDiscovery(int castCapability) +{ + SLOGI("start discovery and the castCapability is %{public}d", castCapability); + return CastSessionManager::GetInstance().StartDiscovery(castCapability); +} + + +void HwCastProvider::StopDiscovery() +{ + SLOGI("stop discovery"); + CastSessionManager::GetInstance().StopDiscovery(); +} + +void HwCastProvider::Release() +{ + hwCastProviderSessionMap_.clear(); + avCastControllerMap_.clear(); + castStateListenerList_.clear(); + castFlag_.clear(); + CastSessionManager::GetInstance().UnregisterListener(); + CastSessionManager::GetInstance().Release(); +} + +int HwCastProvider::StartCastSession() +{ + SLOGI("StartCastSession begin"); + CastSessionProperty property = {ProtocolType::CAST_PLUS_STREAM, EndType::CAST_SOURCE}; + std::shared_ptr castSession = nullptr; + CastSessionManager::GetInstance().CreateCastSession(property, castSession); + int castId; + { + std::lock_guard lock(mutex_); + std::vector::iterator iter = find(castFlag_.begin(), castFlag_.end(), false); + if (iter == castFlag_.end()) { + SLOGE("StartCastSession faileded"); + return AVSESSION_ERROR; + } + *iter = true; + castId = iter - castFlag_.begin(); + auto hwCastProviderSession = std::make_shared(castSession); + if (hwCastProviderSession) { + hwCastProviderSession->Init(); + } + hwCastProviderSessionMap_[castId] = hwCastProviderSession; + } + SLOGI("StartCastSession successed and return the castId is %{public}d", castId); + + return castId; +} +void HwCastProvider::StopCastSession(int castId) +{ + SLOGI("StopCastSession begin"); + std::lock_guard lock(mutex_); + if (hwCastProviderSessionMap_.find(castId) == hwCastProviderSessionMap_.end()) { + SLOGE("no need to release castSession for castId %{public}d is not exit in hwCastProviderSessionMap_", castId); + return; + } + auto hwCastProviderSession = hwCastProviderSessionMap_[castId]; + if (hwCastProviderSession) { + hwCastProviderSession->Release(); + } + hwCastProviderSessionMap_.erase(castId); + castFlag_[castId] = false; + + auto hwCastStreamPlayer = avCastControllerMap_[castId]; + if (hwCastStreamPlayer) { + hwCastStreamPlayer->Release(); + } + avCastControllerMap_.erase(castId); +} + +bool HwCastProvider::AddCastDevice(int castId, DeviceInfo deviceInfo) +{ + SLOGI("AddCastDevice with config castSession and corresonding castId is %{public}d", castId); + std::lock_guard lock(mutex_); + if (hwCastProviderSessionMap_.find(castId) == hwCastProviderSessionMap_.end()) { + SLOGE("the castId corresonding to castSession is not exist"); + return false; + } + auto hwCastProviderSession = hwCastProviderSessionMap_[castId]; + if (!hwCastProviderSession) { + SLOGE("the castId corresonding to castSession is nullptr"); + return false; + } + + return hwCastProviderSession->AddDevice(deviceInfo.deviceId_); +} + +bool HwCastProvider::RemoveCastDevice(int castId, DeviceInfo deviceInfo) +{ + SLOGI("RemoveCastDevice with config castSession and corresonding castId is %{public}d", castId); + std::lock_guard lock(mutex_); + if (hwCastProviderSessionMap_.find(castId) == hwCastProviderSessionMap_.end()) { + SLOGE("the castId corresonding to castSession is not exist"); + return false; + } + auto hwCastProviderSession = hwCastProviderSessionMap_[castId]; + if (!hwCastProviderSession) { + SLOGE("the castId corresonding to castSession is nullptr"); + return false; + } + + return hwCastProviderSession->RemoveDevice(deviceInfo.deviceId_); +} + +bool HwCastProvider::RegisterCastStateListener(std::shared_ptr listener) +{ + std::lock_guard lock(mutex_); + if (listener == nullptr) { + SLOGE("RegisterCastStateListener the listener is nullptr"); + return false; + } + if (find(castStateListenerList_.begin(), castStateListenerList_.end(), listener) != castStateListenerList_.end()) { + SLOGE("RegisterCastStateListener the listener is already be registered"); + return false; + } + SLOGI("RegisterCastStateListener successed, and save it in the castStateListenerList_"); + castStateListenerList_.emplace_back(listener); + + return true; +} + +bool HwCastProvider::UnRegisterCastStateListener(std::shared_ptr listener) +{ + std::lock_guard lock(mutex_); + if (listener == nullptr) { + SLOGE("UnRegisterCastStateListener the listener is nullptr"); + return false; + } + for (auto iter = castStateListenerList_.begin(); iter != castStateListenerList_.end();) { + if (*iter == listener) { + iter = castStateListenerList_.erase(iter); + SLOGI("UnRegisterCastStateListener successed, and erase it from castStateListenerList_"); + return true; + } else { + ++iter; + } + } + SLOGE("listener is not found in castStateListenerList_, so UnRegisterCastStateListener failed"); + + return false; +} + +std::shared_ptr HwCastProvider::GetRemoteController(int castId) +{ + std::lock_guard lock(mutex_); + if (avCastControllerMap_.find(castId) != avCastControllerMap_.end()) { + SLOGI("the castId corresonding to streamPlayer is already exist"); + return avCastControllerMap_[castId]; + } + if (hwCastProviderSessionMap_.find(castId) == hwCastProviderSessionMap_.end()) { + SLOGE("No castSession corresonding to castId exists"); + return nullptr; + } + auto hwCastProviderSession = hwCastProviderSessionMap_[castId]; + if (hwCastProviderSession == nullptr) { + SLOGE("castSession corresonding to castId is nullptr"); + return nullptr; + } + std::shared_ptr streamPlayer = hwCastProviderSession->CreateStreamPlayer(); + std::shared_ptr hwCastStreamPlayer = std::make_shared(streamPlayer); + if (!hwCastStreamPlayer) { + SLOGE("the created hwCastStreamPlayer is nullptr"); + return nullptr; + } + hwCastStreamPlayer->Init(); + avCastControllerMap_[castId] = hwCastStreamPlayer; + + return hwCastStreamPlayer; +} + +bool HwCastProvider::RegisterCastSessionStateListener(int castId, + std::shared_ptr listener) +{ + if (listener == nullptr) { + SLOGE("RegisterCastSessionStateListener failed for the listener is nullptr"); + return false; + } + std::lock_guard lock(mutex_); + if (hwCastProviderSessionMap_.find(castId) == hwCastProviderSessionMap_.end()) { + SLOGE("RegisterCastSessionStateListener failed for the castSession corresponding to castId is not exit"); + return false; + } + auto hwCastProviderSession = hwCastProviderSessionMap_[castId]; + if (hwCastProviderSession == nullptr) { + SLOGE("RegisterCastSessionStateListener failed for the hwCastProviderSession is nullptr"); + return false; + } + + return hwCastProviderSession->RegisterCastSessionStateListener(listener); +} + +bool HwCastProvider::UnRegisterCastSessionStateListener(int castId, + std::shared_ptr listener) +{ + if (listener == nullptr) { + SLOGE("UnRegisterCastSessionStateListener failed for the listener is nullptr"); + return false; + } + std::lock_guard lock(mutex_); + if (hwCastProviderSessionMap_.find(castId) == hwCastProviderSessionMap_.end()) { + SLOGE("UnRegisterCastSessionStateListener failed for the castSession corresponding to castId is not exit"); + return false; + } + auto hwCastProviderSession = hwCastProviderSessionMap_[castId]; + if (hwCastProviderSession == nullptr) { + SLOGE("UnRegisterCastSessionStateListener failed for the hwCastProviderSession is nullptr"); + return false; + } + + return hwCastProviderSession->UnRegisterCastSessionStateListener(listener); +} + + +void HwCastProvider::OnDeviceFound(const std::vector &deviceList) +{ + std::vector deviceInfoList; + for (CastRemoteDevice castRemoteDevice : deviceList) { + DeviceInfo deviceInfo; + deviceInfo.deviceId_ = castRemoteDevice.deviceId; + deviceInfo.deviceName_ = castRemoteDevice.deviceName; + deviceInfo.deviceType_ = static_cast(castRemoteDevice.deviceType); + deviceInfo.ipAddress_ = castRemoteDevice.ipAddress; + deviceInfoList.emplace_back(deviceInfo); + } + for (auto listener : castStateListenerList_) { + if (listener != nullptr) { + SLOGI("trigger the OnDeviceAvailable for registered listeners"); + listener->OnDeviceAvailable(deviceInfoList); + } + } +} + +void HwCastProvider::OnSessionCreated(const std::shared_ptr &castSession) +{ +} + +void HwCastProvider::OnServiceDied() +{ + for (auto listener : castStateListenerList_) { + if (listener != nullptr) { + SLOGI("trigger the OnServiceDied for registered listeners"); + listener->OnCastServerDied(); + } + } +} +} // namespace OHOS::AVSession diff --git a/services/session/server/hw_cast_provider.h b/services/session/server/hw_cast_provider.h new file mode 100644 index 0000000000000000000000000000000000000000..4feb75db6eb65744210ff1df194646df411eded0 --- /dev/null +++ b/services/session/server/hw_cast_provider.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HW_CAST_PROVIDER_H +#define HW_CAST_PROVIDER_H + +#include +#include "cast_session_manager.h" +#include "i_avcast_controller_proxy.h" +#include "i_cast_session.h" +#include "i_stream_player.h" +#include "i_cast_session_manager_listener.h" +#include "hw_cast_provider_session.h" +#include "avsession_info.h" +#include "av_cast_provider.h" + +namespace OHOS::AVSession { +class HwCastProvider : public AVCastProvider, public CastEngine::ICastSessionManagerListener, + public std::enable_shared_from_this { +public: + HwCastProvider() = default; + ~HwCastProvider() override; + + void Init() override; + bool StartDiscovery(int castCapability) override; + void StopDiscovery() override; + void Release() override; + int StartCastSession() override; + void StopCastSession(int castId) override; + bool AddCastDevice(int castId, DeviceInfo deviceInfo) override; + bool RemoveCastDevice(int castId, DeviceInfo deviceInfo) override; + std::shared_ptr GetRemoteController(int castId) override; + bool RegisterCastStateListener(std::shared_ptr listener) override; + bool UnRegisterCastStateListener(std::shared_ptr listener) override; + bool RegisterCastSessionStateListener(int castId, std::shared_ptr listener) override; + bool UnRegisterCastSessionStateListener(int castId, std::shared_ptr listener) override; + + void OnDeviceFound(const std::vector &deviceList) override; + void OnSessionCreated(const std::shared_ptr &castSession) override; + void OnServiceDied() override; + +private: + static const int MAX_CAST_SESSION_SIZE = 16; + std::vector castFlag_ = std::vector(MAX_CAST_SESSION_SIZE, false); + std::map> hwCastProviderSessionMap_; + std::map> avCastControllerMap_; + std::vector> castStateListenerList_; + std::mutex mutex_; +}; +} // namespace OHOS::AVSession + +#endif \ No newline at end of file diff --git a/services/session/server/hw_cast_provider_session.cpp b/services/session/server/hw_cast_provider_session.cpp new file mode 100644 index 0000000000000000000000000000000000000000..91dd49d21e90742eae9e8d186f390656c5d14515 --- /dev/null +++ b/services/session/server/hw_cast_provider_session.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "hw_cast_provider_session.h" +#include "avsession_log.h" + +using namespace OHOS::CastEngine; + +namespace OHOS::AVSession { +HwCastProviderSession::~HwCastProviderSession() +{ + SLOGI("destruct the HwCastProviderSession"); + Release(); +} + +void HwCastProviderSession::Init() +{ + SLOGI("Init the HwCastProviderSession"); + if (castSession_) { + castSession_->RegisterListener(shared_from_this()); + } +} + +void HwCastProviderSession::Release() +{ + SLOGI("release the HwCastProviderSession"); + if (!castSession_) { + SLOGE("castSession_ is not exist"); + return; + } + castSession_->UnregisterListener(); + castSession_->Release(); +} + +bool HwCastProviderSession::AddDevice(std::string deviceId) +{ + SLOGI("AddDevice in HwCastProviderSession"); + if (!castSession_) { + SLOGE("castSession_ is not exist"); + return false; + } + CastRemoteDevice castRemoteDevice = {}; + castRemoteDevice.deviceId = deviceId; + + return castSession_->AddDevice(castRemoteDevice); +} + +bool HwCastProviderSession::RemoveDevice(std::string deviceId) +{ + SLOGI("RemoveDevice in HwCastProviderSession"); + if (!castSession_) { + SLOGE("castSession_ is not exist"); + return false; + } + + return castSession_->RemoveDevice(deviceId); +} + +std::shared_ptr HwCastProviderSession::CreateStreamPlayer() +{ + SLOGI("CreateStreamPlayer in HwCastProviderSession"); + if (!castSession_) { + SLOGE("castSession_ is not exist"); + return nullptr; + } + + std::shared_ptr streamPlayerPtr = nullptr; + castSession_->CreateStreamPlayer(streamPlayerPtr); + return streamPlayerPtr; +} + +bool HwCastProviderSession::RegisterCastSessionStateListener(std::shared_ptr listener) +{ + if (listener == nullptr) { + SLOGE("RegisterCastSessionStateListener failed for the listener is nullptr"); + return false; + } + std::lock_guard lock(mutex_); + if (find(castSessionStateListenerList_.begin(), castSessionStateListenerList_.end(), listener) + != castSessionStateListenerList_.end()) { + SLOGE("listener is already in castSessionStateListenerList_"); + return false; + } + castSessionStateListenerList_.emplace_back(listener); + + return true; +} + +bool HwCastProviderSession::UnRegisterCastSessionStateListener(std::shared_ptr listener) +{ + if (listener == nullptr) { + SLOGE("UnRegisterCastSessionStateListener failed for the listener is nullptr"); + return false; + } + std::lock_guard lock(mutex_); + for (auto iter = castSessionStateListenerList_.begin(); iter != castSessionStateListenerList_.end();) { + if (*iter == listener) { + iter = castSessionStateListenerList_.erase(iter); + return true; + } else { + ++iter; + } + } + + return false; +} + +void HwCastProviderSession::OnDeviceState(const CastEngine::DeviceStateInfo &stateInfo) +{ + if (castSessionStateListenerList_.size() == 0) { + SLOGI("current has not registered listener"); + return; + } + for (auto listener : castSessionStateListenerList_) { + DeviceInfo deviceInfo; + deviceInfo.deviceId_ = stateInfo.deviceId; + if (listener != nullptr) { + SLOGI("trigger the OnCastStateChange for registered listeners"); + listener->OnCastStateChange(static_cast(stateInfo.deviceState), deviceInfo); + } + } +} + +void HwCastProviderSession::OnEvent(const CastEngine::EventId &eventId, const std::string &jsonParam) +{ +} +} diff --git a/services/session/server/hw_cast_provider_session.h b/services/session/server/hw_cast_provider_session.h new file mode 100644 index 0000000000000000000000000000000000000000..17113cb2bc40d49a24d1b96eb417bc73f5dd9963 --- /dev/null +++ b/services/session/server/hw_cast_provider_session.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HW_CAST_PROVIDER_SESSION_H +#define HW_CAST_PROVIDER_SESSION_H + +#include + +#include "i_cast_session.h" +#include "cast_engine_common.h" +#include "avsession_info.h" + +namespace OHOS::AVSession { +class HwCastProviderSession : public CastEngine::ICastSessionListener, + public std::enable_shared_from_this { +public: + explicit HwCastProviderSession(std::shared_ptr castSession) : castSession_(castSession) {} + ~HwCastProviderSession() override; + + void OnDeviceState(const CastEngine::DeviceStateInfo &stateInfo) override; + void OnEvent(const CastEngine::EventId &eventId, const std::string &jsonParam) override; + + void Init(); + void Release(); + bool AddDevice(std::string deviceId); + bool RemoveDevice(std::string deviceId); + std::shared_ptr CreateStreamPlayer(); + bool RegisterCastSessionStateListener(std::shared_ptr listener); + bool UnRegisterCastSessionStateListener(std::shared_ptr listener); + +private: + std::shared_ptr castSession_; + std::vector> castSessionStateListenerList_; + std::mutex mutex_; +}; +} // namespace OHOS::AVSession + +#endif diff --git a/services/session/server/hw_cast_stream_player.cpp b/services/session/server/hw_cast_stream_player.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c818d0d8276c0822e1107c9bf7289f893525356b --- /dev/null +++ b/services/session/server/hw_cast_stream_player.cpp @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "avsession_log.h" +#include "avcast_player_state.h" +#include "avqueue_item.h" +#include "avmedia_description.h" +#include "avsession_errors.h" +#include "hw_cast_stream_player.h" + +using namespace OHOS::CastEngine; + +namespace OHOS::AVSession { +HwCastStreamPlayer::~HwCastStreamPlayer() +{ + SLOGI("destruct the HwCastStreamPlayer"); + Release(); +} + +void HwCastStreamPlayer::Init() +{ + SLOGI("Init the HwCastStreamPlayer"); + if (streamPlayer_) { + SLOGI("register self in streamPlayer"); + streamPlayer_->RegisterListener(shared_from_this()); + } +} + +void HwCastStreamPlayer::Release() +{ + SLOGI("Release the HwCastStreamPlayer"); + streamPlayerListenerList_.clear(); + if (streamPlayer_) { + streamPlayer_->UnregisterListener(); + streamPlayer_->Release(); + } +} + +void HwCastStreamPlayer::SendControlCommand(const AVCastControlCommand castControlCommand) +{ + SLOGI("send command to streamPlayer"); + if (!streamPlayer_) { + SLOGE("streamPlayer is nullptr"); + return; + } + switch (castControlCommand.GetCommand()) { + case AVCastControlCommand::CAST_CONTROL_CMD_PLAY: + streamPlayer_ ->Play(); + break; + case AVCastControlCommand::CAST_CONTROL_CMD_PAUSE: + streamPlayer_ ->Pause(); + break; + case AVCastControlCommand::CAST_CONTROL_CMD_STOP: + streamPlayer_ ->Stop(); + break; + case AVCastControlCommand::CAST_CONTROL_CMD_PLAY_NEXT: + streamPlayer_ ->Next(); + break; + case AVCastControlCommand::CAST_CONTROL_CMD_PLAY_PREVIOUS: + streamPlayer_ ->Previous(); + break; + default: + SendControlCommandWithParams(castControlCommand); + break; + } +} + +void HwCastStreamPlayer::SendControlCommandWithParams(const AVCastControlCommand castControlCommand) +{ + int32_t currentPosition = 0; + switch (castControlCommand.GetCommand()) { + case AVCastControlCommand::CAST_CONTROL_CMD_FAST_FORWARD: + streamPlayer_->GetPosition(currentPosition); + int32_t forwardTime; + castControlCommand.GetForwardTime(forwardTime); + streamPlayer_ ->Seek(currentPosition + forwardTime); + break; + case AVCastControlCommand::CAST_CONTROL_CMD_REWIND: + streamPlayer_->GetPosition(currentPosition); + int32_t rewindTime; + castControlCommand.GetRewindTime(rewindTime); + streamPlayer_ ->Seek(rewindTime > currentPosition ? 0 : currentPosition - rewindTime); + break; + case AVCastControlCommand::CAST_CONTROL_CMD_SEEK: + int32_t seekTime; + castControlCommand.GetSeekTime(seekTime); + streamPlayer_ ->Seek(seekTime); + break; + case AVCastControlCommand::CAST_CONTROL_CMD_SET_VOLUME: + int32_t volume; + castControlCommand.GetVolume(volume); + streamPlayer_ ->SetVolume(volume); + break; + case AVCastControlCommand::CAST_CONTROL_CMD_SET_SPEED: + int32_t speed; + castControlCommand.GetSpeed(speed); + streamPlayer_ ->SetSpeed(static_cast(speed)); + break; + case AVCastControlCommand::CAST_CONTROL_CMD_SET_LOOP_MODE: + int32_t loopMode; + castControlCommand.GetLoopMode(loopMode); + streamPlayer_ ->SetLoopMode(static_cast(loopMode)); + break; + case AVCastControlCommand::CAST_CONTROL_CMD_TOGGLE_FAVORITE: + break; + default: + SLOGE("invalid command"); + break; + } +} + +int32_t HwCastStreamPlayer::SetMediaList(const MediaInfoHolder &mediaInfoHolder) +{ + CastEngine::MediaInfoHolder info; + info.currentIndex = mediaInfoHolder.GetCurrentIndex(); + std::vector mediaInfoList; + for (AVQueueItem item: mediaInfoHolder.GetPlayInfos()) { + std::shared_ptr mediaDescription = item.GetDescription(); + CastEngine::MediaInfo mediaInfo; + mediaInfo.mediaId = mediaDescription->GetMediaId(); + mediaInfo.mediaName = mediaDescription->GetTitle(); + mediaInfo.mediaUrl = mediaDescription->GetMediaUri(); + mediaInfo.mediaType = mediaDescription->GetMediaType(); + mediaInfo.mediaSize = mediaDescription->GetMediaSize(); + mediaInfo.startPosition = static_cast(mediaDescription->GetStartPosition()); + mediaInfo.duration = static_cast(mediaDescription->GetDuration()); + mediaInfo.albumTitle = mediaDescription->GetAlbumTitle(); + mediaInfo.mediaArtist = mediaDescription->GetArtist(); + mediaInfo.lrcUrl = mediaDescription->GetLyricUri(); + mediaInfo.appIconUrl = mediaDescription->GetIconUri(); + mediaInfo.appName = mediaDescription->GetAppName(); + mediaInfoList.emplace_back(mediaInfo); + } + info.mediaInfoList = mediaInfoList; + if (streamPlayer_ && streamPlayer_->Start(info)) { + SLOGI("SetMediaList successed"); + return AVSESSION_SUCCESS; + } + SLOGE("SetMediaList failed"); + return AVSESSION_ERROR; +} + +void HwCastStreamPlayer::UpdateMediaInfo(const MediaInfo &mediaInfo) +{ +} + +int32_t HwCastStreamPlayer::GetDuration(int32_t& duration) +{ + SLOGI("GetDuration begin"); + if (!streamPlayer_) { + SLOGE("streamPlayer is nullptr"); + return AVSESSION_ERROR; + } + streamPlayer_->GetDuration(duration); + SLOGI("GetDuration successed"); + return AVSESSION_SUCCESS; +} + +int32_t HwCastStreamPlayer::GetPosition(int32_t &position) +{ + SLOGI("GetPosition begin"); + if (!streamPlayer_) { + SLOGE("streamPlayer is nullptr"); + return AVSESSION_ERROR; + } + streamPlayer_->GetPosition(position); + SLOGI("GetPosition successed"); + return AVSESSION_SUCCESS; +} + +int32_t HwCastStreamPlayer::GetVolume(int32_t &volume) +{ + SLOGI("GetVolume begin"); + if (!streamPlayer_) { + SLOGE("streamPlayer is nullptr"); + return AVSESSION_ERROR; + } + streamPlayer_->GetVolume(volume); + SLOGI("GetVolume successed"); + return AVSESSION_SUCCESS; +} + +int32_t HwCastStreamPlayer::GetLoopMode(int32_t &loopMode) +{ + SLOGI("GetLoopMode begin"); + if (!streamPlayer_) { + SLOGE("streamPlayer is nullptr"); + return AVSESSION_ERROR; + } + CastEngine::LoopMode castLoopMode; + streamPlayer_->GetLoopMode(castLoopMode); + loopMode = static_cast(castLoopMode); + SLOGI("GetLoopMode successed"); + return AVSESSION_SUCCESS; +} + +int32_t HwCastStreamPlayer::GetPlaySpeed(int32_t &playSpeed) +{ + SLOGI("GetPlaySpeed begin"); + if (!streamPlayer_) { + SLOGE("streamPlayer is nullptr"); + return AVSESSION_ERROR; + } + CastEngine::PlaybackSpeed castPlaybackSpeed; + streamPlayer_->GetPlaySpeed(castPlaybackSpeed); + playSpeed = static_cast(castPlaybackSpeed); + SLOGI("GetPlaySpeed successed"); + return AVSESSION_SUCCESS; +} + +int32_t HwCastStreamPlayer::GetPlayState(AVCastPlayerState &playerState) +{ + SLOGI("GetPlayState begin"); + if (!streamPlayer_) { + SLOGE("streamPlayer is nullptr"); + return AVSESSION_ERROR; + } + CastEngine::PlayerStates castPlayerStates; + streamPlayer_->GetPlayerStatus(castPlayerStates); + playerState.castPlayerState_ = castPlusStateToString_[castPlayerStates]; + SLOGI("GetPlayState successed"); + return AVSESSION_SUCCESS; +} + +int32_t HwCastStreamPlayer::SetDisplaySurface(std::string &surfaceId) +{ + SLOGI("SetDisplaySurface begin"); + if (!streamPlayer_) { + SLOGE("streamPlayer is nullptr"); + return AVSESSION_ERROR; + } + streamPlayer_->SetSurface(surfaceId); + SLOGI("SetDisplaySurface successed"); + return AVSESSION_SUCCESS; +} + +int32_t HwCastStreamPlayer::RegisterControllerListener(std::shared_ptr listener) +{ + SLOGI("RegisterControllerListener begin"); + if (listener == nullptr) { + SLOGE("RegisterControllerListener failed for the listener is nullptr"); + return AVSESSION_ERROR; + } + std::lock_guard lock(mutex_); + if (find(streamPlayerListenerList_.begin(), streamPlayerListenerList_.end(), listener) + != streamPlayerListenerList_.end()) { + SLOGE("listener is already in streamPlayerListenerList_"); + return AVSESSION_ERROR; + } + SLOGI("RegisterControllerListener successed, and add it to streamPlayerListenerList_"); + streamPlayerListenerList_.emplace_back(listener); + + return AVSESSION_SUCCESS; +} + +int32_t HwCastStreamPlayer::UnRegisterControllerListener(std::shared_ptr listener) +{ + if (listener == nullptr) { + SLOGE("UnRegisterCastSessionStateListener failed for the listener is nullptr"); + return AVSESSION_ERROR; + } + std::lock_guard lock(mutex_); + for (auto iter = streamPlayerListenerList_.begin(); iter != streamPlayerListenerList_.end();) { + if (*iter == listener) { + iter = streamPlayerListenerList_.erase(iter); + SLOGI("UnRegisterControllerListener successed, and erase it from streamPlayerListenerList_"); + return AVSESSION_SUCCESS; + } else { + ++iter; + } + } + SLOGE("listener is not found in streamPlayerListenerList_, so UnRegisterControllerListener failed"); + + return AVSESSION_ERROR; +} + +void HwCastStreamPlayer::OnStateChanged(const CastEngine::PlayerStates playbackState, bool isPlayWhenReady) +{ + AVCastPlayerState avCastPlayerState; + if (castPlusStateToString_.count(playbackState) == 0) { + SLOGE("current playbackState status is not exist in castPlusStateToString_"); + avCastPlayerState.castPlayerState_ = "error"; + } else { + avCastPlayerState.castPlayerState_ = castPlusStateToString_[playbackState]; + } + for (auto listener : streamPlayerListenerList_) { + if (listener != nullptr) { + SLOGI("trigger the OnStateChanged for registered listeners"); + listener->OnStateChanged(avCastPlayerState); + } + } +} + +void HwCastStreamPlayer::OnPositionChanged(int position, int bufferPosition, int duration) +{ + for (auto listener : streamPlayerListenerList_) { + if (listener != nullptr) { + SLOGI("trigger the OnPositionChanged for registered listeners"); + listener->OnPositionChanged(position, bufferPosition, duration); + } + } +} + +void HwCastStreamPlayer::OnMediaItemChanged(const CastEngine::MediaInfo& mediaInfo) +{ + std::shared_ptr mediaDescription = std::make_shared(); + mediaDescription->SetMediaId(mediaInfo.mediaId); + mediaDescription->SetTitle(mediaInfo.mediaName); + mediaDescription->SetMediaUri(mediaInfo.mediaUrl); + mediaDescription->SetMediaType(mediaInfo.mediaType); + mediaDescription->SetMediaSize(mediaInfo.mediaSize); + mediaDescription->SetStartPosition(static_cast(mediaInfo.startPosition)); + mediaDescription->SetDuration(static_cast(mediaInfo.duration)); + mediaDescription->SetAlbumTitle(mediaInfo.albumTitle); + mediaDescription->SetArtist(mediaInfo.mediaArtist); + mediaDescription->SetLyricUri(mediaInfo.lrcUrl); + mediaDescription->SetIconUri(mediaInfo.appIconUrl); + mediaDescription->SetAppName(mediaInfo.appName); + AVQueueItem queueItem; + queueItem.SetDescription(mediaDescription); + for (auto listener : streamPlayerListenerList_) { + if (listener != nullptr) { + SLOGI("trigger the OnMediaItemChanged for registered listeners"); + listener->OnMediaItemChanged(queueItem); + } + } +} + +void HwCastStreamPlayer::OnVolumeChanged(int volume) +{ + for (auto listener : streamPlayerListenerList_) { + if (listener != nullptr) { + SLOGI("trigger the OnVolumeChanged for registered listeners"); + listener->OnVolumeChanged(volume); + } + } +} + +void HwCastStreamPlayer::OnLoopModeChanged(const CastEngine::LoopMode loopMode) +{ + for (auto listener : streamPlayerListenerList_) { + if (listener != nullptr) { + SLOGI("trigger the OnLoopModeChanged for registered listeners"); + listener->OnLoopModeChanged(static_cast(loopMode)); + } + } +} + +void HwCastStreamPlayer::OnPlaySpeedChanged(const CastEngine::PlaybackSpeed speed) +{ + for (auto listener : streamPlayerListenerList_) { + if (listener != nullptr) { + SLOGI("trigger the OnPlaySpeedChanged for registered listeners"); + listener->OnPlaySpeedChanged(static_cast(speed)); + } + } +} + +void HwCastStreamPlayer::OnPlayerError(int errorCode, const std::string &errorMsg) +{ + for (auto listener : streamPlayerListenerList_) { + if (listener != nullptr) { + SLOGI("trigger the OnPlayerError for registered listeners"); + listener->OnPlayerError(errorCode, errorMsg); + } + } +} + +void HwCastStreamPlayer::OnVideoSizeChanged(int width, int height) +{ + for (auto listener : streamPlayerListenerList_) { + if (listener != nullptr) { + SLOGI("trigger the OnVideoSizeChanged for registered listeners"); + listener->OnVideoSizeChanged(width, height); + } + } +} +} // namespace OHOS::AVSession diff --git a/services/session/server/hw_cast_stream_player.h b/services/session/server/hw_cast_stream_player.h new file mode 100644 index 0000000000000000000000000000000000000000..153e6b2851b1feee80cd665f9aeae64c237d6cc1 --- /dev/null +++ b/services/session/server/hw_cast_stream_player.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HW_CAST_STREAM_PLAYER_H +#define HW_CAST_STREAM_PLAYER_H + +#include + +#include "cast_engine_common.h" +#include "i_stream_player.h" +#include "i_avcast_controller_proxy.h" + +namespace OHOS::AVSession { +class HwCastStreamPlayer : public IAVCastControllerProxy, public CastEngine::IStreamPlayerListener, + public std::enable_shared_from_this { +public: + explicit HwCastStreamPlayer(std::shared_ptr streamPlayer) + : streamPlayer_(streamPlayer) {} + ~HwCastStreamPlayer() override; + void Init(); + void Release() override; + void SendControlCommand(const AVCastControlCommand castControlCommand) override; + int32_t SetMediaList(const MediaInfoHolder &mediaInfoHolder) override; + void UpdateMediaInfo(const MediaInfo &mediaInfo) override; + int32_t GetDuration(int32_t &duration) override; + int32_t GetPosition(int32_t &position) override; + int32_t GetVolume(int32_t &volume) override; + int32_t GetLoopMode(int32_t &loopMode) override; + int32_t GetPlaySpeed(int32_t &playSpeed) override; + int32_t GetPlayState(AVCastPlayerState &playerState) override; + int32_t SetDisplaySurface(std::string &surfaceId) override; + int32_t RegisterControllerListener(const std::shared_ptr) override; + int32_t UnRegisterControllerListener(const std::shared_ptr) override; + + void OnStateChanged(const CastEngine::PlayerStates playbackState, bool isPlayWhenReady) override; + void OnPositionChanged(int position, int bufferPosition, int duration) override; + void OnMediaItemChanged(const CastEngine::MediaInfo &mediaInfo) override; + void OnVolumeChanged(int volume) override; + void OnLoopModeChanged(const CastEngine::LoopMode loopMode) override; + void OnPlaySpeedChanged(const CastEngine::PlaybackSpeed speed) override; + void OnPlayerError(int errorCode, const std::string &errorMsg) override; + void OnVideoSizeChanged(int width, int height) override; + + void SendControlCommandWithParams(const AVCastControlCommand castControlCommand); + +private: + std::mutex mutex_; + std::shared_ptr streamPlayer_; + std::vector> streamPlayerListenerList_; + std::map castPlusStateToString_ = { + {CastEngine::PlayerStates::PLAYER_STATE_ERROR, "error"}, + {CastEngine::PlayerStates::PLAYER_IDLE, "idle"}, + {CastEngine::PlayerStates::PLAYER_STATE_ERROR, "error"}, + {CastEngine::PlayerStates::PLAYER_INITIALIZED, "initialized"}, + {CastEngine::PlayerStates::PLAYER_PREPARING, "preparing"}, + {CastEngine::PlayerStates::PLAYER_PREPARED, "prepared"}, + {CastEngine::PlayerStates::PLAYER_STARTED, "started"}, + {CastEngine::PlayerStates::PLAYER_PAUSED, "paused"}, + {CastEngine::PlayerStates::PLAYER_STOPPED, "stopped"}, + {CastEngine::PlayerStates::PLAYER_PLAYBACK_COMPLETE, "completed"}, + {CastEngine::PlayerStates::PLAYER_RELEASED, "released"} + }; +}; +} // namespace OHOS::AVSession + +#endif \ No newline at end of file