aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Sommerfeld <kai.sommerfeld@gmx.com>2019-10-02 16:56:38 +0200
committerGitHub <noreply@github.com>2019-10-02 16:56:38 +0200
commit35b2594f369a8b79f22471943a4c47d526023dbc (patch)
tree3819ee8f73dc83305da4ed0fa46c0648bebde1d5
parent4563684b314ca63a70cd22e2a763f2ece88af44d (diff)
parent321f2e305dcfbf66999ceb909da55049b396e9bc (diff)
Merge pull request #16699 from ksooo/pvr-refactor-playbackstate
[PVR] PVRManager: Factor out playback state functionality into its own class
-rw-r--r--xbmc/interfaces/json-rpc/PVROperations.cpp5
-rw-r--r--xbmc/interfaces/json-rpc/PlayerOperations.cpp26
-rw-r--r--xbmc/pvr/CMakeLists.txt2
-rw-r--r--xbmc/pvr/PVRActionListener.cpp7
-rw-r--r--xbmc/pvr/PVRGUIActions.cpp49
-rw-r--r--xbmc/pvr/PVRGUIChannelNavigator.cpp7
-rw-r--r--xbmc/pvr/PVRGUIInfo.cpp70
-rw-r--r--xbmc/pvr/PVRGUITimesInfo.cpp11
-rw-r--r--xbmc/pvr/PVRManager.cpp307
-rw-r--r--xbmc/pvr/PVRManager.h158
-rw-r--r--xbmc/pvr/PVRPlaybackState.cpp330
-rw-r--r--xbmc/pvr/PVRPlaybackState.h212
-rw-r--r--xbmc/pvr/addons/PVRClients.cpp3
-rw-r--r--xbmc/pvr/channels/PVRChannelGroupInternal.cpp3
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp3
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp9
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp3
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRRadioRDSInfo.cpp5
-rw-r--r--xbmc/pvr/epg/EpgInfoTag.cpp3
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRBase.cpp7
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRGuide.cpp6
21 files changed, 688 insertions, 538 deletions
diff --git a/xbmc/interfaces/json-rpc/PVROperations.cpp b/xbmc/interfaces/json-rpc/PVROperations.cpp
index d960920bb9..28b3079d75 100644
--- a/xbmc/interfaces/json-rpc/PVROperations.cpp
+++ b/xbmc/interfaces/json-rpc/PVROperations.cpp
@@ -11,6 +11,7 @@
#include "ServiceBroker.h"
#include "pvr/PVRGUIActions.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/channels/PVRChannelGroups.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
@@ -199,7 +200,7 @@ JSONRPC_STATUS CPVROperations::Record(const std::string &method, ITransportLayer
CVariant channel = parameterObject["channel"];
if (channel.isString() && channel.asString() == "current")
{
- pChannel = CServiceBroker::GetPVRManager().GetPlayingChannel();
+ pChannel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
if (!pChannel)
return InternalError;
}
@@ -252,7 +253,7 @@ JSONRPC_STATUS CPVROperations::GetPropertyValue(const std::string &property, CVa
else if (property == "recording")
{
if (started)
- result = CServiceBroker::GetPVRManager().IsRecording();
+ result = CServiceBroker::GetPVRManager().PlaybackState()->IsRecording();
else
result = false;
}
diff --git a/xbmc/interfaces/json-rpc/PlayerOperations.cpp b/xbmc/interfaces/json-rpc/PlayerOperations.cpp
index e38749c6be..2dcb0d7b1e 100644
--- a/xbmc/interfaces/json-rpc/PlayerOperations.cpp
+++ b/xbmc/interfaces/json-rpc/PlayerOperations.cpp
@@ -28,6 +28,7 @@
#include "pictures/GUIWindowSlideShow.h"
#include "pvr/PVRGUIActions.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
#include "pvr/epg/EpgInfoTag.h"
@@ -149,12 +150,12 @@ JSONRPC_STATUS CPlayerOperations::GetItem(const std::string &method, ITransportL
case Video:
case Audio:
{
- fileItem = CFileItemPtr(new CFileItem(g_application.CurrentFileItem()));
+ fileItem = std::make_shared<CFileItem>(g_application.CurrentFileItem());
if (IsPVRChannel())
{
- std::shared_ptr<CPVRChannel> currentChannel(CServiceBroker::GetPVRManager().GetPlayingChannel());
+ const std::shared_ptr<CPVRChannel> currentChannel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
if (currentChannel)
- fileItem = CFileItemPtr(new CFileItem(currentChannel));
+ fileItem = std::make_shared<CFileItem>(currentChannel);
}
else if (player == Video)
{
@@ -1198,9 +1199,12 @@ int CPlayerOperations::GetActivePlayers()
{
int activePlayers = 0;
- if (g_application.GetAppPlayer().IsPlayingVideo() || CServiceBroker::GetPVRManager().IsPlayingTV() || CServiceBroker::GetPVRManager().IsPlayingRecording())
+ if (g_application.GetAppPlayer().IsPlayingVideo() ||
+ CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingTV() ||
+ CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingRecording())
activePlayers |= Video;
- if (g_application.GetAppPlayer().IsPlayingAudio() || CServiceBroker::GetPVRManager().IsPlayingRadio())
+ if (g_application.GetAppPlayer().IsPlayingAudio() ||
+ CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingRadio())
activePlayers |= Audio;
if (CServiceBroker::GetGUI()->GetWindowManager().IsWindowActive(WINDOW_SLIDESHOW))
activePlayers |= Picture;
@@ -1895,17 +1899,19 @@ double CPlayerOperations::ParseTimeInSeconds(const CVariant &time)
bool CPlayerOperations::IsPVRChannel()
{
- return CServiceBroker::GetPVRManager().IsPlayingTV() || CServiceBroker::GetPVRManager().IsPlayingRadio();
+ const std::shared_ptr<CPVRPlaybackState> state = CServiceBroker::GetPVRManager().PlaybackState();
+ return state->IsPlayingTV() || state->IsPlayingRadio();
}
std::shared_ptr<CPVREpgInfoTag> CPlayerOperations::GetCurrentEpg()
{
- if (!CServiceBroker::GetPVRManager().IsPlayingTV() && !CServiceBroker::GetPVRManager().IsPlayingRadio())
- return std::shared_ptr<CPVREpgInfoTag>();
+ const std::shared_ptr<CPVRPlaybackState> state = CServiceBroker::GetPVRManager().PlaybackState();
+ if (!state->IsPlayingTV() && !state->IsPlayingRadio())
+ return {};
- std::shared_ptr<CPVRChannel> currentChannel(CServiceBroker::GetPVRManager().GetPlayingChannel());
+ const std::shared_ptr<CPVRChannel> currentChannel = state->GetPlayingChannel();
if (!currentChannel)
- return std::shared_ptr<CPVREpgInfoTag>();
+ return {};
return currentChannel->GetEPGNow();
}
diff --git a/xbmc/pvr/CMakeLists.txt b/xbmc/pvr/CMakeLists.txt
index a04e193015..072a99735b 100644
--- a/xbmc/pvr/CMakeLists.txt
+++ b/xbmc/pvr/CMakeLists.txt
@@ -15,6 +15,7 @@ set(SOURCES PVRActionListener.cpp
PVRGUITimerInfo.cpp
PVRGUITimesInfo.cpp
PVRStreamProperties.cpp
+ PVRPlaybackState.cpp
PVRThumbLoader.cpp)
set(HEADERS PVRActionListener.h
@@ -34,6 +35,7 @@ set(HEADERS PVRActionListener.h
PVRGUITimerInfo.h
PVRGUITimesInfo.h
PVRStreamProperties.h
+ PVRPlaybackState.h
PVRThumbLoader.h)
core_add_library(pvr)
diff --git a/xbmc/pvr/PVRActionListener.cpp b/xbmc/pvr/PVRActionListener.cpp
index 0896d1f60b..3417310db3 100644
--- a/xbmc/pvr/PVRActionListener.cpp
+++ b/xbmc/pvr/PVRActionListener.cpp
@@ -19,6 +19,7 @@
#include "messaging/ApplicationMessenger.h"
#include "pvr/PVRGUIActions.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/addons/PVRClients.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/channels/PVRChannelGroup.h"
@@ -90,8 +91,8 @@ ChannelSwitchMode CPVRActionListener::GetChannelSwitchMode(int iAction)
bool CPVRActionListener::OnAction(const CAction& action)
{
bool bIsJumpSMS = false;
- bool bIsPlayingPVR(CServiceBroker::GetPVRManager().IsPlaying() &&
- g_application.CurrentFileItem().HasPVRChannelInfoTag());
+ bool bIsPlayingPVR = CServiceBroker::GetPVRManager().PlaybackState()->IsPlaying() &&
+ g_application.CurrentFileItem().HasPVRChannelInfoTag();
switch (action.GetID())
{
@@ -244,7 +245,7 @@ bool CPVRActionListener::OnAction(const CAction& action)
int iChannelNumber = static_cast<int>(action.GetAmount(0));
int iSubChannelNumber = static_cast<int>(action.GetAmount(1));
- const std::shared_ptr<CPVRChannel> currentChannel = CServiceBroker::GetPVRManager().GetPlayingChannel();
+ const std::shared_ptr<CPVRChannel> currentChannel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
const std::shared_ptr<CPVRChannelGroup> selectedGroup = CServiceBroker::GetPVRManager().ChannelGroups()->Get(currentChannel->IsRadio())->GetSelectedGroup();
const std::shared_ptr<CPVRChannel> channel = selectedGroup->GetByChannelNumber(CPVRChannelNumber(iChannelNumber, iSubChannelNumber));
diff --git a/xbmc/pvr/PVRGUIActions.cpp b/xbmc/pvr/PVRGUIActions.cpp
index de745ad4d8..0b7a3a27e4 100644
--- a/xbmc/pvr/PVRGUIActions.cpp
+++ b/xbmc/pvr/PVRGUIActions.cpp
@@ -35,6 +35,7 @@
#include "pvr/PVREventLogJob.h"
#include "pvr/PVRItem.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/PVRStreamProperties.h"
#include "pvr/addons/PVRClients.h"
#include "pvr/channels/PVRChannel.h"
@@ -592,7 +593,7 @@ namespace PVR
bool CPVRGUIActions::ToggleRecordingOnPlayingChannel()
{
- const std::shared_ptr<CPVRChannel> channel = CServiceBroker::GetPVRManager().GetPlayingChannel();
+ const std::shared_ptr<CPVRChannel> channel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
if (channel && channel->CanRecord())
return SetRecordingOnChannel(channel, !CServiceBroker::GetPVRManager().Timers()->IsRecordingOnChannel(*channel));
@@ -1252,7 +1253,7 @@ namespace PVR
if (!recording)
return false;
- if (CServiceBroker::GetPVRManager().IsPlayingRecording(recording))
+ if (CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingRecording(recording))
{
CGUIMessage msg(GUI_MSG_FULLSCREEN, 0, CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow());
CServiceBroker::GetGUI()->GetWindowManager().SendMessage(msg);
@@ -1274,7 +1275,7 @@ namespace PVR
if (!epgTag)
return false;
- if (CServiceBroker::GetPVRManager().IsPlayingEpgTag(epgTag))
+ if (CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingEpgTag(epgTag))
{
CGUIMessage msg(GUI_MSG_FULLSCREEN, 0, CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow());
CServiceBroker::GetGUI()->GetWindowManager().SendMessage(msg);
@@ -1294,12 +1295,12 @@ namespace PVR
const std::shared_ptr<CPVRChannel> channel(CPVRItem(item).GetChannel());
if (channel)
{
- bool bSwitchToFullscreen = CServiceBroker::GetPVRManager().IsPlayingChannel(channel);
+ bool bSwitchToFullscreen = CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingChannel(channel);
if (!bSwitchToFullscreen)
{
recording = CServiceBroker::GetPVRManager().Recordings()->GetRecordingForEpgTag(channel->GetEPGNow());
- bSwitchToFullscreen = recording && CServiceBroker::GetPVRManager().IsPlayingRecording(recording);
+ bSwitchToFullscreen = recording && CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingRecording(recording);
}
if (bSwitchToFullscreen)
@@ -1363,7 +1364,7 @@ namespace PVR
{
case PlaybackTypeRadio:
{
- if (CServiceBroker::GetPVRManager().IsPlayingRadio())
+ if (CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingRadio())
return true;
const std::shared_ptr<CPVRChannelGroup> allGroup = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAllRadio();
@@ -1375,7 +1376,7 @@ namespace PVR
}
case PlaybackTypeTV:
{
- if (CServiceBroker::GetPVRManager().IsPlayingTV())
+ if (CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingTV())
return true;
const std::shared_ptr<CPVRChannelGroup> allGroup = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAllTV();
@@ -1385,7 +1386,7 @@ namespace PVR
break;
}
default:
- if (CServiceBroker::GetPVRManager().IsPlaying())
+ if (CServiceBroker::GetPVRManager().PlaybackState()->IsPlaying())
return true;
channel = CServiceBroker::GetPVRManager().ChannelGroups()->GetLastPlayedChannel();
@@ -1400,7 +1401,7 @@ namespace PVR
else
{
// if we don't, find the active channel group of the demanded type and play it's first channel
- const std::shared_ptr<CPVRChannelGroup> channelGroup(CServiceBroker::GetPVRManager().GetPlayingGroup(bIsRadio));
+ const std::shared_ptr<CPVRChannelGroup> channelGroup = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingGroup(bIsRadio);
if (channelGroup)
{
// try to start playback of first channel in this group
@@ -1449,7 +1450,7 @@ namespace PVR
}
CLog::Log(LOGNOTICE, "PVR is starting playback of channel '%s'", channel->ChannelName().c_str());
- CServiceBroker::GetPVRManager().SetPlayingGroup(group);
+ CServiceBroker::GetPVRManager().PlaybackState()->SetPlayingGroup(group);
return SwitchToChannel(std::make_shared<CFileItem>(channel), true);
}
@@ -1650,7 +1651,7 @@ namespace PVR
pDlgProgress->Open();
pDlgProgress->Progress();
- if (CServiceBroker::GetPVRManager().IsPlaying())
+ if (CServiceBroker::GetPVRManager().PlaybackState()->IsPlaying())
{
CLog::Log(LOGNOTICE, "PVR is stopping playback for %s database reset", bResetEPGOnly ? "EPG" : "PVR and EPG");
CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_STOP);
@@ -1981,7 +1982,7 @@ namespace PVR
return;
}
- if (CServiceBroker::GetPVRManager().IsPlayingChannel(timer->Channel()))
+ if (CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingChannel(timer->Channel()))
{
// no need for an announcement. channel in question is already playing.
return;
@@ -2122,7 +2123,7 @@ namespace PVR
if (m_settings.GetBoolValue(CSettings::SETTING_PVRMANAGER_PRESELECTPLAYINGCHANNEL))
{
// if preselect playing channel is activated, return the path of the playing channel, if any.
- const std::shared_ptr<CPVRChannel> playingChannel(CServiceBroker::GetPVRManager().GetPlayingChannel());
+ const std::shared_ptr<CPVRChannel> playingChannel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
if (playingChannel && playingChannel->IsRadio() == bRadio)
return playingChannel->Path();
}
@@ -2136,7 +2137,7 @@ namespace PVR
time_t playbackStartTime = CServiceBroker::GetDataCacheCore().GetStartTime();
if (playbackStartTime > 0)
{
- const std::shared_ptr<CPVRChannel> playingChannel = CServiceBroker::GetPVRManager().GetPlayingChannel();
+ const std::shared_ptr<CPVRChannel> playingChannel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
if (playingChannel)
{
time_t nextTime = 0;
@@ -2173,7 +2174,7 @@ namespace PVR
time_t playbackStartTime = CServiceBroker::GetDataCacheCore().GetStartTime();
if (playbackStartTime > 0)
{
- const std::shared_ptr<CPVRChannel> playingChannel = CServiceBroker::GetPVRManager().GetPlayingChannel();
+ const std::shared_ptr<CPVRChannel> playingChannel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
if (playingChannel)
{
time_t prevTime = 0;
@@ -2258,7 +2259,7 @@ namespace PVR
void CPVRChannelSwitchingInputHandler::GetChannelNumbers(std::vector<std::string>& channelNumbers)
{
CPVRManager& pvrMgr = CServiceBroker::GetPVRManager();
- const std::shared_ptr<CPVRChannel> playingChannel = pvrMgr.GetPlayingChannel();
+ const std::shared_ptr<CPVRChannel> playingChannel = pvrMgr.PlaybackState()->GetPlayingChannel();
if (playingChannel)
{
const std::shared_ptr<CPVRChannelGroup> group = pvrMgr.ChannelGroups()->GetGroupAll(playingChannel->IsRadio());
@@ -2276,16 +2277,16 @@ namespace PVR
void CPVRChannelSwitchingInputHandler::SwitchToChannel(const CPVRChannelNumber& channelNumber)
{
- if (channelNumber.IsValid() && CServiceBroker::GetPVRManager().IsPlaying())
+ if (channelNumber.IsValid() && CServiceBroker::GetPVRManager().PlaybackState()->IsPlaying())
{
- const std::shared_ptr<CPVRChannel> playingChannel(CServiceBroker::GetPVRManager().GetPlayingChannel());
+ const std::shared_ptr<CPVRChannel> playingChannel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
if (playingChannel)
{
if (channelNumber != playingChannel->ChannelNumber())
{
// channel number present in playing group?
bool bRadio = playingChannel->IsRadio();
- const std::shared_ptr<CPVRChannelGroup> group = CServiceBroker::GetPVRManager().GetPlayingGroup(bRadio);
+ const std::shared_ptr<CPVRChannelGroup> group = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingGroup(bRadio);
std::shared_ptr<CPVRChannel> channel = group->GetByChannelNumber(channelNumber);
if (!channel)
@@ -2299,7 +2300,7 @@ namespace PVR
if (channel)
{
// switch channel group
- CServiceBroker::GetPVRManager().SetPlayingGroup(currentGroup);
+ CServiceBroker::GetPVRManager().PlaybackState()->SetPlayingGroup(currentGroup);
break;
}
}
@@ -2320,15 +2321,15 @@ namespace PVR
void CPVRChannelSwitchingInputHandler::SwitchToPreviousChannel()
{
- if (CServiceBroker::GetPVRManager().IsPlaying())
+ if (CServiceBroker::GetPVRManager().PlaybackState()->IsPlaying())
{
- const std::shared_ptr<CPVRChannel> playingChannel(CServiceBroker::GetPVRManager().GetPlayingChannel());
+ const std::shared_ptr<CPVRChannel> playingChannel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
if (playingChannel)
{
- const std::shared_ptr<CPVRChannelGroup> group(CServiceBroker::GetPVRManager().ChannelGroups()->GetPreviousPlayedGroup());
+ const std::shared_ptr<CPVRChannelGroup> group = CServiceBroker::GetPVRManager().ChannelGroups()->GetPreviousPlayedGroup();
if (group)
{
- CServiceBroker::GetPVRManager().SetPlayingGroup(group);
+ CServiceBroker::GetPVRManager().PlaybackState()->SetPlayingGroup(group);
const std::shared_ptr<CPVRChannel> channel = group->GetLastPlayedChannel(playingChannel->ChannelID());
if (channel)
{
diff --git a/xbmc/pvr/PVRGUIChannelNavigator.cpp b/xbmc/pvr/PVRGUIChannelNavigator.cpp
index 05c7fa8910..689aae60c3 100644
--- a/xbmc/pvr/PVRGUIChannelNavigator.cpp
+++ b/xbmc/pvr/PVRGUIChannelNavigator.cpp
@@ -14,6 +14,7 @@
#include "guilib/GUIComponent.h"
#include "pvr/PVRGUIActions.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/channels/PVRChannelGroup.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
@@ -117,12 +118,12 @@ namespace PVR
std::shared_ptr<CPVRChannel> CPVRGUIChannelNavigator::GetNextOrPrevChannel(bool bNext)
{
- const bool bPlayingRadio = CServiceBroker::GetPVRManager().IsPlayingRadio();
- const bool bPlayingTV = CServiceBroker::GetPVRManager().IsPlayingTV();
+ const bool bPlayingRadio = CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingRadio();
+ const bool bPlayingTV = CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingTV();
if (bPlayingTV || bPlayingRadio)
{
- const std::shared_ptr<CPVRChannelGroup> group = CServiceBroker::GetPVRManager().GetPlayingGroup(bPlayingRadio);
+ const std::shared_ptr<CPVRChannelGroup> group = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingGroup(bPlayingRadio);
if (group)
{
CSingleLock lock(m_critSection);
diff --git a/xbmc/pvr/PVRGUIInfo.cpp b/xbmc/pvr/PVRGUIInfo.cpp
index 7ab3062b56..c1497e62b1 100644
--- a/xbmc/pvr/PVRGUIInfo.cpp
+++ b/xbmc/pvr/PVRGUIInfo.cpp
@@ -19,6 +19,7 @@
#include "pvr/PVRGUIActions.h"
#include "pvr/PVRItem.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/addons/PVRClients.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/channels/PVRChannelGroup.h"
@@ -194,11 +195,11 @@ void CPVRGUIInfo::UpdateQualityData(void)
if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_PVRPLAYBACK_SIGNALQUALITY))
{
- bool bIsPlayingRecording = CServiceBroker::GetPVRManager().IsPlayingRecording();
+ bool bIsPlayingRecording = CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingRecording();
if (!bIsPlayingRecording)
{
std::shared_ptr<CPVRClient> client;
- CServiceBroker::GetPVRManager().Clients()->GetCreatedClient(CServiceBroker::GetPVRManager().GetPlayingClientID(), client);
+ CServiceBroker::GetPVRManager().Clients()->GetCreatedClient(CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingClientID(), client);
if (client && client->SignalQuality(qualityInfo) == PVR_ERROR_NO_ERROR)
{
m_qualityInfo = qualityInfo;
@@ -212,11 +213,11 @@ void CPVRGUIInfo::UpdateDescrambleData(void)
PVR_DESCRAMBLE_INFO descrambleInfo;
ClearDescrambleInfo(descrambleInfo);
- bool bIsPlayingRecording = CServiceBroker::GetPVRManager().IsPlayingRecording();
+ bool bIsPlayingRecording = CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingRecording();
if (!bIsPlayingRecording)
{
std::shared_ptr<CPVRClient> client;
- CServiceBroker::GetPVRManager().Clients()->GetCreatedClient(CServiceBroker::GetPVRManager().GetPlayingClientID(), client);
+ CServiceBroker::GetPVRManager().Clients()->GetCreatedClient(CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingClientID(), client);
if (client && client->GetDescrambleInfo(descrambleInfo) == PVR_ERROR_NO_ERROR)
{
m_descrambleInfo = descrambleInfo;
@@ -226,38 +227,41 @@ void CPVRGUIInfo::UpdateDescrambleData(void)
void CPVRGUIInfo::UpdateMisc(void)
{
- bool bStarted = CServiceBroker::GetPVRManager().IsStarted();
+ CPVRManager& mgr = CServiceBroker::GetPVRManager();
+ bool bStarted = mgr.IsStarted();
+ const std::shared_ptr<CPVRPlaybackState> state = mgr.PlaybackState();
+
/* safe to fetch these unlocked, since they're updated from the same thread as this one */
- std::string strPlayingClientName = bStarted ? CServiceBroker::GetPVRManager().GetPlayingClientName() : "";
- bool bHasTVRecordings = bStarted && CServiceBroker::GetPVRManager().Recordings()->GetNumTVRecordings() > 0;
- bool bHasRadioRecordings = bStarted && CServiceBroker::GetPVRManager().Recordings()->GetNumRadioRecordings() > 0;
- bool bIsPlayingTV = bStarted && CServiceBroker::GetPVRManager().IsPlayingTV();
- bool bIsPlayingRadio = bStarted && CServiceBroker::GetPVRManager().IsPlayingRadio();
- bool bIsPlayingRecording = bStarted && CServiceBroker::GetPVRManager().IsPlayingRecording();
- bool bIsPlayingEpgTag = bStarted && CServiceBroker::GetPVRManager().IsPlayingEpgTag();
- bool bIsPlayingEncryptedStream = bStarted && CServiceBroker::GetPVRManager().IsPlayingEncryptedChannel();
- bool bHasTVChannels = bStarted && CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAllTV()->HasChannels();
- bool bHasRadioChannels = bStarted && CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAllRadio()->HasChannels();
- bool bCanRecordPlayingChannel = bStarted && CServiceBroker::GetPVRManager().CanRecordOnPlayingChannel();
- bool bIsRecordingPlayingChannel = bStarted && CServiceBroker::GetPVRManager().IsRecordingOnPlayingChannel();
- bool bIsPlayingActiveRecording = bStarted && CServiceBroker::GetPVRManager().IsPlayingActiveRecording();
- std::string strPlayingTVGroup = (bStarted && bIsPlayingTV) ? CServiceBroker::GetPVRManager().GetPlayingGroup(false)->GroupName() : "";
- std::string strPlayingRadioGroup = (bStarted && bIsPlayingRadio) ? CServiceBroker::GetPVRManager().GetPlayingGroup(true)->GroupName() : "";
+ const std::string strPlayingClientName = bStarted ? state->GetPlayingClientName() : "";
+ const bool bHasTVRecordings = bStarted && mgr.Recordings()->GetNumTVRecordings() > 0;
+ const bool bHasRadioRecordings = bStarted && mgr.Recordings()->GetNumRadioRecordings() > 0;
+ const bool bIsPlayingTV = bStarted && state->IsPlayingTV();
+ const bool bIsPlayingRadio = bStarted && state->IsPlayingRadio();
+ const bool bIsPlayingRecording = bStarted && state->IsPlayingRecording();
+ const bool bIsPlayingEpgTag = bStarted && state->IsPlayingEpgTag();
+ const bool bIsPlayingEncryptedStream = bStarted && state->IsPlayingEncryptedChannel();
+ const bool bHasTVChannels = bStarted && mgr.ChannelGroups()->GetGroupAllTV()->HasChannels();
+ const bool bHasRadioChannels = bStarted && mgr.ChannelGroups()->GetGroupAllRadio()->HasChannels();
+ const bool bCanRecordPlayingChannel = bStarted && state->CanRecordOnPlayingChannel();
+ const bool bIsRecordingPlayingChannel = bStarted && state->IsRecordingOnPlayingChannel();
+ const bool bIsPlayingActiveRecording = bStarted && state->IsPlayingActiveRecording();
+ const std::string strPlayingTVGroup = (bStarted && bIsPlayingTV) ? state->GetPlayingGroup(false)->GroupName() : "";
+ const std::string strPlayingRadioGroup = (bStarted && bIsPlayingRadio) ? state->GetPlayingGroup(true)->GroupName() : "";
CSingleLock lock(m_critSection);
- m_strPlayingClientName = strPlayingClientName;
- m_bHasTVRecordings = bHasTVRecordings;
- m_bHasRadioRecordings = bHasRadioRecordings;
- m_bIsPlayingTV = bIsPlayingTV;
- m_bIsPlayingRadio = bIsPlayingRadio;
- m_bIsPlayingRecording = bIsPlayingRecording;
- m_bIsPlayingEpgTag = bIsPlayingEpgTag;
+ m_strPlayingClientName = strPlayingClientName;
+ m_bHasTVRecordings = bHasTVRecordings;
+ m_bHasRadioRecordings = bHasRadioRecordings;
+ m_bIsPlayingTV = bIsPlayingTV;
+ m_bIsPlayingRadio = bIsPlayingRadio;
+ m_bIsPlayingRecording = bIsPlayingRecording;
+ m_bIsPlayingEpgTag = bIsPlayingEpgTag;
m_bIsPlayingEncryptedStream = bIsPlayingEncryptedStream;
- m_bHasTVChannels = bHasTVChannels;
- m_bHasRadioChannels = bHasRadioChannels;
- m_strPlayingTVGroup = strPlayingTVGroup;
- m_strPlayingRadioGroup = strPlayingRadioGroup;
- m_bCanRecordPlayingChannel = bCanRecordPlayingChannel;
+ m_bHasTVChannels = bHasTVChannels;
+ m_bHasRadioChannels = bHasRadioChannels;
+ m_strPlayingTVGroup = strPlayingTVGroup;
+ m_strPlayingRadioGroup = strPlayingRadioGroup;
+ m_bCanRecordPlayingChannel = bCanRecordPlayingChannel;
m_bIsRecordingPlayingChannel = bIsRecordingPlayingChannel;
m_bIsPlayingActiveRecording = bIsPlayingActiveRecording;
}
@@ -1542,7 +1546,7 @@ void CPVRGUIInfo::CharInfoEncryption(std::string& strValue) const
}
else
{
- const std::shared_ptr<CPVRChannel> channel(CServiceBroker::GetPVRManager().GetPlayingChannel());
+ const std::shared_ptr<CPVRChannel> channel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
if (channel)
{
strValue = channel->EncryptionName();
diff --git a/xbmc/pvr/PVRGUITimesInfo.cpp b/xbmc/pvr/PVRGUITimesInfo.cpp
index 2c4a9c4356..b6ecbd2db9 100644
--- a/xbmc/pvr/PVRGUITimesInfo.cpp
+++ b/xbmc/pvr/PVRGUITimesInfo.cpp
@@ -11,6 +11,7 @@
#include "ServiceBroker.h"
#include "cores/DataCacheCore.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
#include "pvr/epg/EpgInfoTag.h"
@@ -52,8 +53,8 @@ void CPVRGUITimesInfo::Reset()
void CPVRGUITimesInfo::UpdatePlayingTag()
{
- const std::shared_ptr<CPVRChannel> currentChannel = CServiceBroker::GetPVRManager().GetPlayingChannel();
- std::shared_ptr<CPVREpgInfoTag> currentTag = CServiceBroker::GetPVRManager().GetPlayingEpgTag();
+ const std::shared_ptr<CPVRChannel> currentChannel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
+ std::shared_ptr<CPVREpgInfoTag> currentTag = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingEpgTag();
if (currentChannel || currentTag)
{
@@ -87,7 +88,7 @@ void CPVRGUITimesInfo::UpdatePlayingTag()
}
else
{
- const std::shared_ptr<CPVRRecording> recording = CServiceBroker::GetPVRManager().GetPlayingRecording();
+ const std::shared_ptr<CPVRRecording> recording = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingRecording();
if (recording)
{
CSingleLock lock(m_critSection);
@@ -99,7 +100,7 @@ void CPVRGUITimesInfo::UpdatePlayingTag()
void CPVRGUITimesInfo::UpdateTimeshiftData()
{
- if (!CServiceBroker::GetPVRManager().IsPlayingTV() && !CServiceBroker::GetPVRManager().IsPlayingRadio())
+ if (!CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingTV() && !CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingRadio())
{
// If nothing is playing (anymore), there is no need to update data.
Reset();
@@ -111,7 +112,7 @@ void CPVRGUITimesInfo::UpdateTimeshiftData()
int64_t iPlayTime, iMinTime, iMaxTime;
CServiceBroker::GetDataCacheCore().GetPlayTimes(iStartTime, iPlayTime, iMinTime, iMaxTime);
bool bPlaying = CServiceBroker::GetDataCacheCore().GetSpeed() == 1.0;
- const std::shared_ptr<CPVRChannel> playingChannel = CServiceBroker::GetPVRManager().GetPlayingChannel();
+ const std::shared_ptr<CPVRChannel> playingChannel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
CSingleLock lock(m_critSection);
diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp
index ea696d8528..66656b3405 100644
--- a/xbmc/pvr/PVRManager.cpp
+++ b/xbmc/pvr/PVRManager.cpp
@@ -18,6 +18,7 @@
#include "pvr/PVRGUIChannelIconUpdater.h"
#include "pvr/PVRGUIInfo.h"
#include "pvr/PVRGUIProgressHandler.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/addons/PVRClients.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/channels/PVRChannelGroup.h"
@@ -180,8 +181,8 @@ CPVRManager::CPVRManager(void) :
m_pendingUpdates(new CPVRManagerJobQueue),
m_database(new CPVRDatabase),
m_parentalTimer(new CStopWatch),
+ m_playbackState(new CPVRPlaybackState),
m_settings({
- CSettings::SETTING_PVRPLAYBACK_DELAYMARKLASTWATCHED,
CSettings::SETTING_PVRPOWERMANAGEMENT_ENABLED,
CSettings::SETTING_PVRPOWERMANAGEMENT_SETWAKEUPCMD,
CSettings::SETTING_PVRPARENTAL_ENABLED,
@@ -291,6 +292,12 @@ std::shared_ptr<CPVRGUIActions> CPVRManager::GUIActions(void) const
return m_guiActions;
}
+std::shared_ptr<CPVRPlaybackState> CPVRManager::PlaybackState() const
+{
+ CSingleLock lock(m_critSection);
+ return m_playbackState;
+}
+
CPVREpgContainer& CPVRManager::EpgContainer()
{
// note: m_epgContainer is const (only set/reset in ctor/dtor). no need for a lock here.
@@ -309,6 +316,7 @@ void CPVRManager::Clear(void)
m_recordings.reset();
m_channelGroups.reset();
m_parentalTimer.reset();
+ m_playbackState.reset();
m_database.reset();
m_bEpgsCreated = false;
@@ -325,6 +333,7 @@ void CPVRManager::ResetProperties(void)
m_timers.reset(new CPVRTimers);
m_guiInfo.reset(new CPVRGUIInfo);
m_parentalTimer.reset(new CStopWatch);
+ m_playbackState.reset(new CPVRPlaybackState);
}
void CPVRManager::Init()
@@ -371,7 +380,7 @@ void CPVRManager::Stop(void)
return;
/* stop playback if needed */
- if (IsPlaying())
+ if (m_playbackState->IsPlaying())
{
CLog::LogFC(LOGDEBUG, LOGPVR, "Stopping PVR playback");
CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_STOP);
@@ -649,108 +658,6 @@ void CPVRManager::TriggerPlayChannelOnStartup(void)
}
}
-bool CPVRManager::IsPlaying(void) const
-{
- return IsStarted() && (m_playingChannel || m_playingRecording || m_playingEpgTag);
-}
-
-bool CPVRManager::IsPlayingChannel(const std::shared_ptr<CPVRChannel>& channel) const
-{
- bool bReturn(false);
-
- if (channel && IsStarted())
- {
- std::shared_ptr<CPVRChannel> current(GetPlayingChannel());
- if (current && *current == *channel)
- bReturn = true;
- }
-
- return bReturn;
-}
-
-bool CPVRManager::IsPlayingEncryptedChannel(void) const
-{
- return IsStarted() && m_playingChannel && m_playingChannel->IsEncrypted();
-}
-
-bool CPVRManager::IsPlayingRecording(const std::shared_ptr<CPVRRecording>& recording) const
-{
- bool bReturn(false);
-
- if (recording && IsStarted())
- {
- std::shared_ptr<CPVRRecording> current(GetPlayingRecording());
- if (current && *current == *recording)
- bReturn = true;
- }
-
- return bReturn;
-}
-
-bool CPVRManager::IsPlayingEpgTag(const std::shared_ptr<CPVREpgInfoTag>& epgTag) const
-{
- bool bReturn(false);
-
- if (epgTag && IsStarted())
- {
- std::shared_ptr<CPVREpgInfoTag> current(GetPlayingEpgTag());
- if (current && *current == *epgTag)
- bReturn = true;
- }
-
- return bReturn;
-}
-
-bool CPVRManager::IsPlayingChannel(int iClientID, int iUniqueChannelID) const
-{
- if (m_playingChannel)
- return m_playingClientId == iClientID && m_iplayingChannelUniqueID == iUniqueChannelID;
-
- return false;
-}
-
-std::shared_ptr<CPVRChannel> CPVRManager::GetPlayingChannel(void) const
-{
- return m_playingChannel;
-}
-
-std::shared_ptr<CPVRRecording> CPVRManager::GetPlayingRecording(void) const
-{
- return m_playingRecording;
-}
-
-std::shared_ptr<CPVREpgInfoTag> CPVRManager::GetPlayingEpgTag(void) const
-{
- return m_playingEpgTag;
-}
-
-std::string CPVRManager::GetPlayingClientName(void) const
-{
- return m_strPlayingClientName;
-}
-
-int CPVRManager::GetPlayingClientID(void) const
-{
- return m_playingClientId;
-}
-
-bool CPVRManager::IsRecordingOnPlayingChannel(void) const
-{
- const std::shared_ptr<CPVRChannel> currentChannel = GetPlayingChannel();
- return currentChannel && m_timers && m_timers->IsRecordingOnChannel(*currentChannel);
-}
-
-bool CPVRManager::IsPlayingActiveRecording() const
-{
- return IsStarted() && m_playingRecording ? m_playingRecording->IsInProgress() : false;
-}
-
-bool CPVRManager::CanRecordOnPlayingChannel(void) const
-{
- const std::shared_ptr<CPVRChannel> currentChannel = GetPlayingChannel();
- return currentChannel && currentChannel->CanRecord();
-}
-
void CPVRManager::RestartParentalTimer()
{
if (m_parentalTimer)
@@ -778,7 +685,7 @@ bool CPVRManager::IsCurrentlyParentalLocked(const std::shared_ptr<CPVRChannel>&
if (!channel || !bGenerallyLocked)
return bReturn;
- const std::shared_ptr<CPVRChannel> currentChannel = GetPlayingChannel();
+ const std::shared_ptr<CPVRChannel> currentChannel = m_playbackState->GetPlayingChannel();
if (// if channel in question is currently playing it must be currently unlocked.
(!currentChannel || channel != currentChannel) &&
@@ -794,114 +701,9 @@ bool CPVRManager::IsCurrentlyParentalLocked(const std::shared_ptr<CPVRChannel>&
return bReturn;
}
-void CPVRManager::SetPlayingGroup(const std::shared_ptr<CPVRChannelGroup>& group)
-{
- if (m_channelGroups && group)
- m_channelGroups->Get(group->IsRadio())->SetSelectedGroup(group);
-}
-
-void CPVRManager::SetPlayingGroup(const std::shared_ptr<CPVRChannel>& channel)
-{
- std::shared_ptr<CPVRChannelGroup> group = m_channelGroups->GetSelectedGroup(channel->IsRadio());
- if (!group || !group->IsGroupMember(channel))
- {
- // The channel we'll switch to is not part of the current selected group.
- // Set the first group as the selected group where the channel is a member.
- CPVRChannelGroups* channelGroups = m_channelGroups->Get(channel->IsRadio());
- std::vector<std::shared_ptr<CPVRChannelGroup>> groups = channelGroups->GetGroupsByChannel(channel, true);
- if (!groups.empty())
- channelGroups->SetSelectedGroup(groups.front());
- }
-}
-
-std::shared_ptr<CPVRChannelGroup> CPVRManager::GetPlayingGroup(bool bRadio /* = false */) const
-{
- if (m_channelGroups)
- return m_channelGroups->GetSelectedGroup(bRadio);
-
- return std::shared_ptr<CPVRChannelGroup>();
-}
-
-class CPVRManager::CLastWatchedUpdateTimer : public CTimer, private ITimerCallback
-{
-public:
- explicit CLastWatchedUpdateTimer(CPVRManager& pvrMgr,
- const std::shared_ptr<CPVRChannel>& channel,
- const CDateTime& time)
- : CTimer(this),
- m_pvrMgr(pvrMgr),
- m_channel(channel),
- m_time(time)
- {
- }
-
- // ITimerCallback implementation
- void OnTimeout() override
- {
- m_pvrMgr.UpdateLastWatched(m_channel, m_time);
- }
-
-private:
- CLastWatchedUpdateTimer() = delete;
-
- CPVRManager& m_pvrMgr;
- const std::shared_ptr<CPVRChannel> m_channel;
- const CDateTime m_time;
-};
-
void CPVRManager::OnPlaybackStarted(const CFileItemPtr item)
{
- m_playingChannel.reset();
- m_playingRecording.reset();
- m_playingEpgTag.reset();
- m_playingClientId = -1;
- m_iplayingChannelUniqueID = -1;
- m_strPlayingClientName.clear();
-
- if (item->HasPVRChannelInfoTag())
- {
- const std::shared_ptr<CPVRChannel> channel(item->GetPVRChannelInfoTag());
-
- m_playingChannel = channel;
- m_playingClientId = m_playingChannel->ClientID();
- m_iplayingChannelUniqueID = m_playingChannel->UniqueID();
-
- SetPlayingGroup(channel);
-
- int iLastWatchedDelay = m_settings.GetIntValue(CSettings::SETTING_PVRPLAYBACK_DELAYMARKLASTWATCHED) * 1000;
- if (iLastWatchedDelay > 0)
- {
- // Insert new / replace existing last watched update timer
- if (m_lastWatchedUpdateTimer)
- m_lastWatchedUpdateTimer->Stop(true);
-
- m_lastWatchedUpdateTimer.reset(new CLastWatchedUpdateTimer(*this, channel, CDateTime::GetUTCDateTime()));
- m_lastWatchedUpdateTimer->Start(iLastWatchedDelay);
- }
- else
- {
- // Store last watched timestamp immediately
- UpdateLastWatched(channel, CDateTime::GetUTCDateTime());
- }
- }
- else if (item->HasPVRRecordingInfoTag())
- {
- m_playingRecording = item->GetPVRRecordingInfoTag();
- m_playingClientId = m_playingRecording->m_iClientId;
- }
- else if (item->HasEPGInfoTag())
- {
- m_playingEpgTag = item->GetEPGInfoTag();
- m_playingClientId = m_playingEpgTag->ClientID();
- }
-
- if (m_playingClientId != -1)
- {
- const std::shared_ptr<CPVRClient> client = GetClient(m_playingClientId);
- if (client)
- m_strPlayingClientName = client->GetFriendlyName();
- }
-
+ m_playbackState->OnPlaybackStarted(item);
m_guiActions->OnPlaybackStarted(item);
m_epgContainer.OnPlaybackStarted();
}
@@ -909,50 +711,9 @@ void CPVRManager::OnPlaybackStarted(const CFileItemPtr item)
void CPVRManager::OnPlaybackStopped(const CFileItemPtr item)
{
// Playback ended due to user interaction
-
- if (item->HasPVRChannelInfoTag() && item->GetPVRChannelInfoTag() == m_playingChannel)
- {
- bool bUpdateLastWatched = true;
-
- if (m_lastWatchedUpdateTimer)
- {
- if (m_lastWatchedUpdateTimer->IsRunning())
- {
- // If last watched timer is still running, cancel it. Channel was not watched long enough to store the value.
- m_lastWatchedUpdateTimer->Stop(true);
- bUpdateLastWatched = false;
- }
- m_lastWatchedUpdateTimer.reset();
- }
-
- if (bUpdateLastWatched)
- {
- // If last watched timer is not running (any more), channel was watched long enough to store the value.
- UpdateLastWatched(m_playingChannel, CDateTime::GetUTCDateTime());
- }
-
+ if (m_playbackState->OnPlaybackStopped(item))
PublishEvent(PVREvent::ChannelPlaybackStopped);
- m_playingChannel.reset();
- m_playingClientId = -1;
- m_iplayingChannelUniqueID = -1;
- m_strPlayingClientName.clear();
- }
- else if (item->HasPVRRecordingInfoTag() && item->GetPVRRecordingInfoTag() == m_playingRecording)
- {
- m_playingRecording.reset();
- m_playingClientId = -1;
- m_iplayingChannelUniqueID = -1;
- m_strPlayingClientName.clear();
- }
- else if (item->HasEPGInfoTag() && item->GetEPGInfoTag() == m_playingEpgTag)
- {
- m_playingEpgTag.reset();
- m_playingClientId = -1;
- m_iplayingChannelUniqueID = -1;
- m_strPlayingClientName.clear();
- }
-
m_guiActions->OnPlaybackStopped(item);
m_epgContainer.OnPlaybackStopped();
}
@@ -963,11 +724,6 @@ void CPVRManager::OnPlaybackEnded(const CFileItemPtr item)
OnPlaybackStopped(item);
}
-bool CPVRManager::IsRecording(void) const
-{
- return IsStarted() && m_timers ? m_timers->IsRecording() : false;
-}
-
void CPVRManager::LocalizationChanged(void)
{
CSingleLock lock(m_critSection);
@@ -984,26 +740,6 @@ bool CPVRManager::EpgsCreated(void) const
return m_bEpgsCreated;
}
-bool CPVRManager::IsPlayingTV(void) const
-{
- return IsStarted() && m_playingChannel && !m_playingChannel->IsRadio();
-}
-
-bool CPVRManager::IsPlayingRadio(void) const
-{
- return IsStarted() && m_playingChannel && m_playingChannel->IsRadio();
-}
-
-bool CPVRManager::IsPlayingRecording(void) const
-{
- return IsStarted() && m_playingRecording;
-}
-
-bool CPVRManager::IsPlayingEpgTag(void) const
-{
- return IsStarted() && m_playingEpgTag;
-}
-
void CPVRManager::TriggerEpgsCreate()
{
m_pendingUpdates->Append("pvr-create-epgs", [this]() {
@@ -1085,18 +821,3 @@ bool CPVRManager::CreateChannelEpgs(void)
m_bEpgsCreated = bEpgsCreated;
return m_bEpgsCreated;
}
-
-void CPVRManager::UpdateLastWatched(const std::shared_ptr<CPVRChannel>& channel, const CDateTime& time)
-{
- time_t iTime;
- time.GetAsTime(iTime);
-
- channel->SetLastWatched(iTime);
-
- // update last watched timestamp for group
- std::shared_ptr<CPVRChannelGroup> group(GetPlayingGroup(channel->IsRadio()));
- group->SetLastWatched(iTime);
-
- /* update last played group */
- m_channelGroups->SetLastPlayedGroup(group);
-}
diff --git a/xbmc/pvr/PVRManager.h b/xbmc/pvr/PVRManager.h
index 56218708b6..31ca5b5e68 100644
--- a/xbmc/pvr/PVRManager.h
+++ b/xbmc/pvr/PVRManager.h
@@ -37,6 +37,7 @@ namespace PVR
class CPVRGUIInfo;
class CPVRGUIProgressHandler;
class CPVRManagerJobQueue;
+ class CPVRPlaybackState;
class CPVRRecording;
class CPVRRecordings;
class CPVRTimers;
@@ -139,6 +140,12 @@ namespace PVR
std::shared_ptr<CPVRGUIActions> GUIActions(void) const;
/*!
+ * @brief Get access to the pvr playback state.
+ * @return The playback state.
+ */
+ std::shared_ptr<CPVRPlaybackState> PlaybackState() const;
+
+ /*!
* @brief Get access to the epg container.
* @return The epg container.
*/
@@ -186,33 +193,6 @@ namespace PVR
std::shared_ptr<CPVRDatabase> GetTVDatabase(void) const;
/*!
- * @brief Check if a TV channel, radio channel or recording is playing.
- * @return True if it's playing, false otherwise.
- */
- bool IsPlaying(void) const;
-
- /*!
- * @brief Check if the given channel is playing.
- * @param channel The channel to check.
- * @return True if it's playing, false otherwise.
- */
- bool IsPlayingChannel(const std::shared_ptr<CPVRChannel>& channel) const;
-
- /*!
- * @brief Check if the given recording is playing.
- * @param recording The recording to check.
- * @return True if it's playing, false otherwise.
- */
- bool IsPlayingRecording(const std::shared_ptr<CPVRRecording>& recording) const;
-
- /*!
- * @brief Check if the given epg tag is playing.
- * @param epgTag The tag to check.
- * @return True if it's playing, false otherwise.
- */
- bool IsPlayingEpgTag(const std::shared_ptr<CPVREpgInfoTag>& epgTag) const;
-
- /*!
* @return True while the PVRManager is initialising.
*/
inline bool IsInitialising(void) const
@@ -248,62 +228,6 @@ namespace PVR
}
/*!
- * @brief Check whether playing channel matches given uids.
- * @param iClientID The client id.
- * @param iUniqueChannelID The channel uid.
- * @return True on match, false if there is no match or no channel is playing.
- */
- bool IsPlayingChannel(int iClientID, int iUniqueChannelID) const;
-
- /*!
- * @brief Return the channel that is currently playing.
- * @return The channel or NULL if none is playing.
- */
- std::shared_ptr<CPVRChannel> GetPlayingChannel(void) const;
-
- /*!
- * @brief Return the recording that is currently playing.
- * @return The recording or NULL if none is playing.
- */
- std::shared_ptr<CPVRRecording> GetPlayingRecording(void) const;
-
- /*!
- * @brief Return the epg tag that is currently playing.
- * @return The tag or NULL if none is playing.
- */
- std::shared_ptr<CPVREpgInfoTag> GetPlayingEpgTag(void) const;
-
- /*!
- * @brief Get the name of the playing client, if there is one.
- * @return The name of the client or an empty string if nothing is playing.
- */
- std::string GetPlayingClientName(void) const;
-
- /*!
- * @brief Get the ID of the playing client, if there is one.
- * @return The ID or -1 if no client is playing.
- */
- int GetPlayingClientID(void) const;
-
- /*!
- * @brief Check whether there is an active recording on the currenlyt playing channel.
- * @return True if there is a playing channel and there is an active recording on that channel, false otherwise.
- */
- bool IsRecordingOnPlayingChannel(void) const;
-
- /*!
- * @brief Check if an active recording is playing.
- * @return True if an in-progress (active) recording is playing, false otherwise.
- */
- bool IsPlayingActiveRecording() const;
-
- /*!
- * @brief Check whether the currently playing channel can be recorded.
- * @return True if there is a playing channel that can be recorded, false otherwise.
- */
- bool CanRecordOnPlayingChannel(void) const;
-
- /*!
* @brief Check whether EPG tags for channels have been created.
* @return True if EPG tags have been created, false otherwise.
*/
@@ -334,19 +258,6 @@ namespace PVR
bool IsRecording(void) const;
/*!
- * @brief Set the current playing group, used to load the right channel.
- * @param group The new group.
- */
- void SetPlayingGroup(const std::shared_ptr<CPVRChannelGroup>& group);
-
- /*!
- * @brief Get the current playing group, used to load the right channel.
- * @param bRadio True to get the current radio group, false to get the current TV group.
- * @return The current group or the group containing all channels if it's not set.
- */
- std::shared_ptr<CPVRChannelGroup> GetPlayingGroup(bool bRadio = false) const;
-
- /*!
* @brief Let the background thread create epg tags for all channels.
*/
void TriggerEpgsCreate(void);
@@ -388,36 +299,6 @@ namespace PVR
void LocalizationChanged(void);
/*!
- * @brief Check if a TV channel is playing.
- * @return True if it's playing, false otherwise.
- */
- bool IsPlayingTV(void) const;
-
- /*!
- * @brief Check if a radio channel is playing.
- * @return True if it's playing, false otherwise.
- */
- bool IsPlayingRadio(void) const;
-
- /*!
- * @brief Check if a an encrypted TV or radio channel is playing.
- * @return True if it's playing, false otherwise.
- */
- bool IsPlayingEncryptedChannel(void) const;
-
- /*!
- * @brief Check if a recording is playing.
- * @return True if it's playing, false otherwise.
- */
- bool IsPlayingRecording(void) const;
-
- /*!
- * @brief Check if an epg tag is playing.
- * @return True if it's playing, false otherwise.
- */
- bool IsPlayingEpgTag(void) const;
-
- /*!
* @brief Check if parental lock is overridden at the given moment.
* @param channel The channel to check.
* @return True if parental lock is overridden, false otherwise.
@@ -469,19 +350,6 @@ namespace PVR
private:
/*!
- * @brief Updates the last watched timestamps of the channel and group which are currently playing.
- * @param channel The channel which is updated
- * @param time The last watched time to set
- */
- void UpdateLastWatched(const std::shared_ptr<CPVRChannel>& channel, const CDateTime& time);
-
- /*!
- * @brief Set the playing group to the first group the channel is in if the given channel is not part of the current playing group
- * @param channel The channel
- */
- void SetPlayingGroup(const std::shared_ptr<CPVRChannel>& channel);
-
- /*!
* @brief Executes "pvrpowermanagement.setwakeupcmd"
*/
bool SetWakeupCommand(void);
@@ -562,17 +430,9 @@ namespace PVR
CEventSource<PVREvent> m_events;
+ std::shared_ptr<CPVRPlaybackState> m_playbackState;
+
CPVRActionListener m_actionListener;
CPVRSettings m_settings;
-
- std::shared_ptr<CPVRChannel> m_playingChannel;
- std::shared_ptr<CPVRRecording> m_playingRecording;
- std::shared_ptr<CPVREpgInfoTag> m_playingEpgTag;
- std::string m_strPlayingClientName;
- int m_playingClientId = -1;
- int m_iplayingChannelUniqueID = -1;
-
- class CLastWatchedUpdateTimer;
- std::unique_ptr<CLastWatchedUpdateTimer> m_lastWatchedUpdateTimer;
};
}
diff --git a/xbmc/pvr/PVRPlaybackState.cpp b/xbmc/pvr/PVRPlaybackState.cpp
new file mode 100644
index 0000000000..b531fb0037
--- /dev/null
+++ b/xbmc/pvr/PVRPlaybackState.cpp
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2012-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "PVRPlaybackState.h"
+
+#include "FileItem.h"
+#include "ServiceBroker.h"
+#include "XBDateTime.h"
+#include "addons/PVRClient.h"
+#include "pvr/PVRManager.h"
+#include "pvr/channels/PVRChannel.h"
+#include "pvr/channels/PVRChannelGroup.h"
+#include "pvr/channels/PVRChannelGroups.h"
+#include "pvr/channels/PVRChannelGroupsContainer.h"
+#include "pvr/epg/EpgInfoTag.h"
+#include "pvr/recordings/PVRRecording.h"
+#include "pvr/timers/PVRTimers.h"
+#include "settings/Settings.h"
+#include "settings/SettingsComponent.h"
+#include "threads/Timer.h"
+
+using namespace PVR;
+
+class CPVRPlaybackState::CLastWatchedUpdateTimer : public CTimer, private ITimerCallback
+{
+public:
+ CLastWatchedUpdateTimer(CPVRPlaybackState& state,
+ const std::shared_ptr<CPVRChannel>& channel,
+ const CDateTime& time)
+ : CTimer(this)
+ , m_state(state)
+ , m_channel(channel)
+ , m_time(time)
+ {
+ }
+
+ // ITimerCallback implementation
+ void OnTimeout() override
+ {
+ m_state.UpdateLastWatched(m_channel, m_time);
+ }
+
+private:
+ CLastWatchedUpdateTimer() = delete;
+
+ CPVRPlaybackState& m_state;
+ const std::shared_ptr<CPVRChannel> m_channel;
+ const CDateTime m_time;
+};
+
+
+CPVRPlaybackState::CPVRPlaybackState() = default;
+
+CPVRPlaybackState::~CPVRPlaybackState() = default;
+
+void CPVRPlaybackState::OnPlaybackStarted(const std::shared_ptr<CFileItem> item)
+{
+ m_playingChannel.reset();
+ m_playingRecording.reset();
+ m_playingEpgTag.reset();
+ m_playingClientId = -1;
+ m_iplayingChannelUniqueID = -1;
+ m_strPlayingClientName.clear();
+
+ if (item->HasPVRChannelInfoTag())
+ {
+ const std::shared_ptr<CPVRChannel> channel = item->GetPVRChannelInfoTag();
+
+ m_playingChannel = channel;
+ m_playingClientId = m_playingChannel->ClientID();
+ m_iplayingChannelUniqueID = m_playingChannel->UniqueID();
+
+ SetPlayingGroup(channel);
+
+ int iLastWatchedDelay = CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(CSettings::SETTING_PVRPLAYBACK_DELAYMARKLASTWATCHED) * 1000;
+ if (iLastWatchedDelay > 0)
+ {
+ // Insert new / replace existing last watched update timer
+ if (m_lastWatchedUpdateTimer)
+ m_lastWatchedUpdateTimer->Stop(true);
+
+ m_lastWatchedUpdateTimer.reset(new CLastWatchedUpdateTimer(*this, channel, CDateTime::GetUTCDateTime()));
+ m_lastWatchedUpdateTimer->Start(iLastWatchedDelay);
+ }
+ else
+ {
+ // Store last watched timestamp immediately
+ UpdateLastWatched(channel, CDateTime::GetUTCDateTime());
+ }
+ }
+ else if (item->HasPVRRecordingInfoTag())
+ {
+ m_playingRecording = item->GetPVRRecordingInfoTag();
+ m_playingClientId = m_playingRecording->m_iClientId;
+ }
+ else if (item->HasEPGInfoTag())
+ {
+ m_playingEpgTag = item->GetEPGInfoTag();
+ m_playingClientId = m_playingEpgTag->ClientID();
+ }
+
+ if (m_playingClientId != -1)
+ {
+ const std::shared_ptr<CPVRClient> client = CServiceBroker::GetPVRManager().GetClient(m_playingClientId);
+ if (client)
+ m_strPlayingClientName = client->GetFriendlyName();
+ }
+}
+
+bool CPVRPlaybackState::OnPlaybackStopped(const std::shared_ptr<CFileItem> item)
+{
+ // Playback ended due to user interaction
+
+ bool bChanged = false;
+
+ if (item->HasPVRChannelInfoTag() && item->GetPVRChannelInfoTag() == m_playingChannel)
+ {
+ bool bUpdateLastWatched = true;
+
+ if (m_lastWatchedUpdateTimer)
+ {
+ if (m_lastWatchedUpdateTimer->IsRunning())
+ {
+ // If last watched timer is still running, cancel it. Channel was not watched long enough to store the value.
+ m_lastWatchedUpdateTimer->Stop(true);
+ bUpdateLastWatched = false;
+ }
+ m_lastWatchedUpdateTimer.reset();
+ }
+
+ if (bUpdateLastWatched)
+ {
+ // If last watched timer is not running (any more), channel was watched long enough to store the value.
+ UpdateLastWatched(m_playingChannel, CDateTime::GetUTCDateTime());
+ }
+
+ bChanged = true;
+ m_playingChannel.reset();
+ m_playingClientId = -1;
+ m_iplayingChannelUniqueID = -1;
+ m_strPlayingClientName.clear();
+ }
+ else if (item->HasPVRRecordingInfoTag() && item->GetPVRRecordingInfoTag() == m_playingRecording)
+ {
+ bChanged = true;
+ m_playingRecording.reset();
+ m_playingClientId = -1;
+ m_iplayingChannelUniqueID = -1;
+ m_strPlayingClientName.clear();
+ }
+ else if (item->HasEPGInfoTag() && item->GetEPGInfoTag() == m_playingEpgTag)
+ {
+ bChanged = true;
+ m_playingEpgTag.reset();
+ m_playingClientId = -1;
+ m_iplayingChannelUniqueID = -1;
+ m_strPlayingClientName.clear();
+ }
+
+ return bChanged;
+}
+
+void CPVRPlaybackState::OnPlaybackEnded(const std::shared_ptr<CFileItem> item)
+{
+ // Playback ended, but not due to user interaction
+ OnPlaybackStopped(item);
+}
+
+bool CPVRPlaybackState::IsPlaying() const
+{
+ return m_playingChannel != nullptr || m_playingRecording != nullptr || m_playingEpgTag != nullptr;
+}
+
+bool CPVRPlaybackState::IsPlayingTV() const
+{
+ return m_playingChannel && !m_playingChannel->IsRadio();
+}
+
+bool CPVRPlaybackState::IsPlayingRadio() const
+{
+ return m_playingChannel && m_playingChannel->IsRadio();
+}
+
+bool CPVRPlaybackState::IsPlayingEncryptedChannel() const
+{
+ return m_playingChannel && m_playingChannel->IsEncrypted();
+}
+
+bool CPVRPlaybackState::IsPlayingRecording() const
+{
+ return m_playingRecording != nullptr;
+}
+
+bool CPVRPlaybackState::IsPlayingEpgTag() const
+{
+ return m_playingEpgTag != nullptr;
+}
+
+bool CPVRPlaybackState::IsPlayingChannel(int iClientID, int iUniqueChannelID) const
+{
+ return m_playingChannel && m_playingClientId == iClientID && m_iplayingChannelUniqueID == iUniqueChannelID;
+}
+
+bool CPVRPlaybackState::IsPlayingChannel(const std::shared_ptr<CPVRChannel>& channel) const
+{
+ if (channel)
+ {
+ const std::shared_ptr<CPVRChannel> current = GetPlayingChannel();
+ if (current && *current == *channel)
+ return true;
+ }
+
+ return false;
+}
+
+bool CPVRPlaybackState::IsPlayingRecording(const std::shared_ptr<CPVRRecording>& recording) const
+{
+ if (recording)
+ {
+ const std::shared_ptr<CPVRRecording> current = GetPlayingRecording();
+ if (current && *current == *recording)
+ return true;
+ }
+
+ return false;
+}
+
+bool CPVRPlaybackState::IsPlayingEpgTag(const std::shared_ptr<CPVREpgInfoTag>& epgTag) const
+{
+ if (epgTag)
+ {
+ const std::shared_ptr<CPVREpgInfoTag> current = GetPlayingEpgTag();
+ if (current && *current == *epgTag)
+ return true;
+ }
+
+ return false;
+}
+
+std::shared_ptr<CPVRChannel> CPVRPlaybackState::GetPlayingChannel() const
+{
+ return m_playingChannel;
+}
+
+std::shared_ptr<CPVRRecording> CPVRPlaybackState::GetPlayingRecording() const
+{
+ return m_playingRecording;
+}
+
+std::shared_ptr<CPVREpgInfoTag> CPVRPlaybackState::GetPlayingEpgTag() const
+{
+ return m_playingEpgTag;
+}
+
+std::string CPVRPlaybackState::GetPlayingClientName() const
+{
+ return m_strPlayingClientName;
+}
+
+int CPVRPlaybackState::GetPlayingClientID() const
+{
+ return m_playingClientId;
+}
+
+bool CPVRPlaybackState::IsRecording() const
+{
+ return CServiceBroker::GetPVRManager().Timers()->IsRecording();
+}
+
+bool CPVRPlaybackState::IsRecordingOnPlayingChannel() const
+{
+ const std::shared_ptr<CPVRChannel> currentChannel = GetPlayingChannel();
+ return currentChannel && CServiceBroker::GetPVRManager().Timers()->IsRecordingOnChannel(*currentChannel);
+}
+
+bool CPVRPlaybackState::IsPlayingActiveRecording() const
+{
+ const std::shared_ptr<CPVRRecording> currentRecording = GetPlayingRecording();
+ return currentRecording && currentRecording->IsInProgress();
+}
+
+bool CPVRPlaybackState::CanRecordOnPlayingChannel() const
+{
+ const std::shared_ptr<CPVRChannel> currentChannel = GetPlayingChannel();
+ return currentChannel && currentChannel->CanRecord();
+}
+
+void CPVRPlaybackState::SetPlayingGroup(const std::shared_ptr<CPVRChannelGroup>& group)
+{
+ if (group)
+ CServiceBroker::GetPVRManager().ChannelGroups()->Get(group->IsRadio())->SetSelectedGroup(group);
+}
+
+void CPVRPlaybackState::SetPlayingGroup(const std::shared_ptr<CPVRChannel>& channel)
+{
+ const std::shared_ptr<CPVRChannelGroup> group = CServiceBroker::GetPVRManager().ChannelGroups()->GetSelectedGroup(channel->IsRadio());
+ if (!group || !group->IsGroupMember(channel))
+ {
+ // The channel we'll switch to is not part of the current selected group.
+ // Set the first group as the selected group where the channel is a member.
+ CPVRChannelGroups* channelGroups = CServiceBroker::GetPVRManager().ChannelGroups()->Get(channel->IsRadio());
+ const std::vector<std::shared_ptr<CPVRChannelGroup>> groups = channelGroups->GetGroupsByChannel(channel, true);
+ if (!groups.empty())
+ channelGroups->SetSelectedGroup(groups.front());
+ }
+}
+
+std::shared_ptr<CPVRChannelGroup> CPVRPlaybackState::GetPlayingGroup(bool bRadio) const
+{
+ return CServiceBroker::GetPVRManager().ChannelGroups()->GetSelectedGroup(bRadio);
+}
+
+void CPVRPlaybackState::UpdateLastWatched(const std::shared_ptr<CPVRChannel>& channel, const CDateTime& time)
+{
+ time_t iTime;
+ time.GetAsTime(iTime);
+
+ channel->SetLastWatched(iTime);
+
+ // update last watched timestamp for group
+ const std::shared_ptr<CPVRChannelGroup> group = GetPlayingGroup(channel->IsRadio());
+ group->SetLastWatched(iTime);
+
+ CServiceBroker::GetPVRManager().ChannelGroups()->SetLastPlayedGroup(group);
+}
diff --git a/xbmc/pvr/PVRPlaybackState.h b/xbmc/pvr/PVRPlaybackState.h
new file mode 100644
index 0000000000..f33c171271
--- /dev/null
+++ b/xbmc/pvr/PVRPlaybackState.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2012-2019 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+class CDateTime;
+class CFileItem;
+
+namespace PVR
+{
+class CPVRChannel;
+class CPVRChannelGroup;
+class CPVREpgInfoTag;
+class CPVRRecording;
+
+class CPVRPlaybackState
+{
+public:
+ /*!
+ * @brief ctor.
+ */
+ CPVRPlaybackState();
+
+ /*!
+ * @brief dtor.
+ */
+ virtual ~CPVRPlaybackState();
+
+ /*!
+ * @brief Inform that playback of an item just started.
+ * @param item The item that started to play.
+ */
+ void OnPlaybackStarted(const std::shared_ptr<CFileItem> item);
+
+ /*!
+ * @brief Inform that playback of an item was stopped due to user interaction.
+ * @param item The item that stopped to play.
+ * @return True, if the state has changed, false otherwise
+ */
+ bool OnPlaybackStopped(const std::shared_ptr<CFileItem> item);
+
+ /*!
+ * @brief Inform that playback of an item has stopped without user interaction.
+ * @param item The item that ended to play.
+ */
+ void OnPlaybackEnded(const std::shared_ptr<CFileItem> item);
+
+ /*!
+ * @brief Check if a TV channel, radio channel or recording is playing.
+ * @return True if it's playing, false otherwise.
+ */
+ bool IsPlaying() const;
+
+ /*!
+ * @brief Check if a TV channel is playing.
+ * @return True if it's playing, false otherwise.
+ */
+ bool IsPlayingTV() const;
+
+ /*!
+ * @brief Check if a radio channel is playing.
+ * @return True if it's playing, false otherwise.
+ */
+ bool IsPlayingRadio() const;
+
+ /*!
+ * @brief Check if a an encrypted TV or radio channel is playing.
+ * @return True if it's playing, false otherwise.
+ */
+ bool IsPlayingEncryptedChannel() const;
+
+ /*!
+ * @brief Check if a recording is playing.
+ * @return True if it's playing, false otherwise.
+ */
+ bool IsPlayingRecording() const;
+
+ /*!
+ * @brief Check if an epg tag is playing.
+ * @return True if it's playing, false otherwise.
+ */
+ bool IsPlayingEpgTag() const;
+
+ /*!
+ * @brief Check whether playing channel matches given uids.
+ * @param iClientID The client id.
+ * @param iUniqueChannelID The channel uid.
+ * @return True on match, false if there is no match or no channel is playing.
+ */
+ bool IsPlayingChannel(int iClientID, int iUniqueChannelID) const;
+
+ /*!
+ * @brief Check if the given channel is playing.
+ * @param channel The channel to check.
+ * @return True if it's playing, false otherwise.
+ */
+ bool IsPlayingChannel(const std::shared_ptr<CPVRChannel>& channel) const;
+
+ /*!
+ * @brief Check if the given recording is playing.
+ * @param recording The recording to check.
+ * @return True if it's playing, false otherwise.
+ */
+ bool IsPlayingRecording(const std::shared_ptr<CPVRRecording>& recording) const;
+
+ /*!
+ * @brief Check if the given epg tag is playing.
+ * @param epgTag The tag to check.
+ * @return True if it's playing, false otherwise.
+ */
+ bool IsPlayingEpgTag(const std::shared_ptr<CPVREpgInfoTag>& epgTag) const;
+
+ /*!
+ * @brief Return the channel that is currently playing.
+ * @return The channel or nullptr if none is playing.
+ */
+ std::shared_ptr<CPVRChannel> GetPlayingChannel() const;
+
+ /*!
+ * @brief Return the recording that is currently playing.
+ * @return The recording or nullptr if none is playing.
+ */
+ std::shared_ptr<CPVRRecording> GetPlayingRecording() const;
+
+ /*!
+ * @brief Return the epg tag that is currently playing.
+ * @return The tag or nullptr if none is playing.
+ */
+ std::shared_ptr<CPVREpgInfoTag> GetPlayingEpgTag() const;
+
+ /*!
+ * @brief Get the name of the playing client, if there is one.
+ * @return The name of the client or an empty string if nothing is playing.
+ */
+ std::string GetPlayingClientName() const;
+
+ /*!
+ * @brief Get the ID of the playing client, if there is one.
+ * @return The ID or -1 if no client is playing.
+ */
+ int GetPlayingClientID() const;
+
+ /*!
+ * @brief Check whether there are active recordings.
+ * @return True if there are active recordings, false otherwise.
+ */
+ bool IsRecording() const;
+
+ /*!
+ * @brief Check whether there is an active recording on the currenlyt playing channel.
+ * @return True if there is a playing channel and there is an active recording on that channel, false otherwise.
+ */
+ bool IsRecordingOnPlayingChannel() const;
+
+ /*!
+ * @brief Check if an active recording is playing.
+ * @return True if an in-progress (active) recording is playing, false otherwise.
+ */
+ bool IsPlayingActiveRecording() const;
+
+ /*!
+ * @brief Check whether the currently playing channel can be recorded.
+ * @return True if there is a playing channel that can be recorded, false otherwise.
+ */
+ bool CanRecordOnPlayingChannel() const;
+
+ /*!
+ * @brief Set the current playing group, used to load the right channel.
+ * @param group The new group.
+ */
+ void SetPlayingGroup(const std::shared_ptr<CPVRChannelGroup>& group);
+
+ /*!
+ * @brief Get the current playing group, used to load the right channel.
+ * @param bRadio True to get the current radio group, false to get the current TV group.
+ * @return The current group or the group containing all channels if it's not set.
+ */
+ std::shared_ptr<CPVRChannelGroup> GetPlayingGroup(bool bRadio) const;
+
+private:
+ /*!
+ * @brief Set the playing group to the first group the channel is in if the given channel is not part of the current playing group
+ * @param channel The channel
+ */
+ void SetPlayingGroup(const std::shared_ptr<CPVRChannel>& channel);
+
+ /*!
+ * @brief Updates the last watched timestamps of the channel and group which are currently playing.
+ * @param channel The channel which is updated
+ * @param time The last watched time to set
+ */
+ void UpdateLastWatched(const std::shared_ptr<CPVRChannel>& channel, const CDateTime& time);
+
+ std::shared_ptr<CPVRChannel> m_playingChannel;
+ std::shared_ptr<CPVRRecording> m_playingRecording;
+ std::shared_ptr<CPVREpgInfoTag> m_playingEpgTag;
+ std::string m_strPlayingClientName;
+ int m_playingClientId = -1;
+ int m_iplayingChannelUniqueID = -1;
+
+ class CLastWatchedUpdateTimer;
+ std::unique_ptr<CLastWatchedUpdateTimer> m_lastWatchedUpdateTimer;
+};
+} // namespace PVR
diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp
index b05294fb32..89f2616842 100644
--- a/xbmc/pvr/addons/PVRClients.cpp
+++ b/xbmc/pvr/addons/PVRClients.cpp
@@ -14,6 +14,7 @@
#include "messaging/ApplicationMessenger.h"
#include "pvr/PVREventLogJob.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/channels/PVRChannelGroupInternal.h"
#include "utils/JobManager.h"
#include "utils/log.h"
@@ -202,7 +203,7 @@ bool CPVRClients::RequestRestart(AddonPtr addon, bool bDataChanged)
bool CPVRClients::StopClient(const AddonPtr& addon, bool bRestart)
{
// stop playback if needed
- if (CServiceBroker::GetPVRManager().IsPlaying())
+ if (CServiceBroker::GetPVRManager().PlaybackState()->IsPlaying())
CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_STOP);
CSingleLock lock(m_critSection);
diff --git a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp
index db632819af..d72e0e8700 100644
--- a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp
@@ -13,6 +13,7 @@
#include "messaging/helpers/DialogOKHelper.h"
#include "pvr/PVRDatabase.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/addons/PVRClients.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/epg/EpgContainer.h"
@@ -162,7 +163,7 @@ bool CPVRChannelGroupInternal::RemoveFromGroup(const std::shared_ptr<CPVRChannel
return false;
/* check if this channel is currently playing if we are hiding it */
- std::shared_ptr<CPVRChannel> currentChannel(CServiceBroker::GetPVRManager().GetPlayingChannel());
+ const std::shared_ptr<CPVRChannel> currentChannel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
if (currentChannel && currentChannel == channel)
{
HELPERS::ShowOKDialogText(CVariant{19098}, CVariant{19102});
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp
index f6824c2dd2..10b2623ad6 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp
@@ -11,6 +11,7 @@
#include "FileItem.h"
#include "ServiceBroker.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/epg/EpgInfoTag.h"
@@ -34,7 +35,7 @@ void CGUIDialogPVRChannelGuide::OnInitWindow()
{
// no user-specific channel is set; use current playing channel
if (!m_channel)
- m_channel = CServiceBroker::GetPVRManager().GetPlayingChannel();
+ m_channel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
if (!m_channel)
{
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp
index 406aeaaab7..7ddc2ba6c5 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp
@@ -18,6 +18,7 @@
#include "messaging/ApplicationMessenger.h"
#include "pvr/PVRGUIActions.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/channels/PVRChannelGroup.h"
#include "pvr/channels/PVRChannelGroups.h"
@@ -72,7 +73,7 @@ bool CGUIDialogPVRChannelsOSD::OnMessage(CGUIMessage& message)
void CGUIDialogPVRChannelsOSD::OnInitWindow()
{
- if (!CServiceBroker::GetPVRManager().IsPlayingTV() && !CServiceBroker::GetPVRManager().IsPlayingRadio())
+ if (!CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingTV() && !CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingRadio())
{
Close();
return;
@@ -126,7 +127,7 @@ bool CGUIDialogPVRChannelsOSD::OnAction(const CAction& action)
const std::shared_ptr<CPVRChannelGroup> nextGroup = action.GetID() == ACTION_NEXT_CHANNELGROUP
? groups->GetNextGroup(*m_group)
: groups->GetPreviousGroup(*m_group);
- CServiceBroker::GetPVRManager().SetPlayingGroup(nextGroup);
+ CServiceBroker::GetPVRManager().PlaybackState()->SetPlayingGroup(nextGroup);
m_group = nextGroup;
Init();
Update();
@@ -167,10 +168,10 @@ void CGUIDialogPVRChannelsOSD::Update()
pvrMgr.Events().Subscribe(this, &CGUIDialogPVRChannelsOSD::Notify);
pvrMgr.EpgContainer().Events().Subscribe(this, &CGUIDialogPVRChannelsOSD::Notify);
- const std::shared_ptr<CPVRChannel> channel = pvrMgr.GetPlayingChannel();
+ const std::shared_ptr<CPVRChannel> channel = pvrMgr.PlaybackState()->GetPlayingChannel();
if (channel)
{
- const std::shared_ptr<CPVRChannelGroup> group = pvrMgr.GetPlayingGroup(channel->IsRadio());
+ const std::shared_ptr<CPVRChannelGroup> group = pvrMgr.PlaybackState()->GetPlayingGroup(channel->IsRadio());
if (group)
{
const std::vector<std::shared_ptr<PVRChannelGroupMember>> groupMembers = group->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE);
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp b/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
index f8ae44b353..abef8c60e4 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
@@ -22,6 +22,7 @@
#include "messaging/helpers//DialogOKHelper.h"
#include "pvr/PVRGUIDirectory.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/channels/PVRChannelGroups.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
@@ -449,7 +450,7 @@ void CGUIDialogPVRGroupManager::Update()
if (m_selectedGroup)
{
/* set this group in the pvrmanager, so it becomes the selected group in other dialogs too */
- CServiceBroker::GetPVRManager().SetPlayingGroup(m_selectedGroup);
+ CServiceBroker::GetPVRManager().PlaybackState()->SetPlayingGroup(m_selectedGroup);
SET_CONTROL_LABEL(CONTROL_CURRENT_GROUP_LABEL, m_selectedGroup->GroupName());
SET_CONTROL_SELECTED(GetID(), BUTTON_HIDE_GROUP, m_selectedGroup->IsHidden());
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRRadioRDSInfo.cpp b/xbmc/pvr/dialogs/GUIDialogPVRRadioRDSInfo.cpp
index 707fb12d6a..844804681e 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRRadioRDSInfo.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRRadioRDSInfo.cpp
@@ -15,6 +15,7 @@
#include "guilib/GUITextBox.h"
#include "guilib/LocalizeStrings.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/channels/PVRRadioRDSInfoTag.h"
@@ -63,7 +64,7 @@ bool CGUIDialogPVRRadioRDSInfo::OnMessage(CGUIMessage& message)
}
else if (iControl == SPIN_CONTROL_INFO)
{
- const std::shared_ptr<CPVRChannel> channel = CServiceBroker::GetPVRManager().GetPlayingChannel();
+ const std::shared_ptr<CPVRChannel> channel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
if (!channel)
return false;
@@ -157,7 +158,7 @@ void CGUIDialogPVRRadioRDSInfo::InitInfoControls()
void CGUIDialogPVRRadioRDSInfo::UpdateInfoControls()
{
- const std::shared_ptr<CPVRChannel> channel = CServiceBroker::GetPVRManager().GetPlayingChannel();
+ const std::shared_ptr<CPVRChannel> channel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
if (!channel)
return;
diff --git a/xbmc/pvr/epg/EpgInfoTag.cpp b/xbmc/pvr/epg/EpgInfoTag.cpp
index e69a427b9c..83d0babd88 100644
--- a/xbmc/pvr/epg/EpgInfoTag.cpp
+++ b/xbmc/pvr/epg/EpgInfoTag.cpp
@@ -13,6 +13,7 @@
#include "addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_types.h"
#include "cores/DataCacheCore.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/epg/Epg.h"
#include "pvr/epg/EpgChannelData.h"
#include "pvr/epg/EpgDatabase.h"
@@ -237,7 +238,7 @@ void CPVREpgInfoTag::ToSortable(SortItem& sortable, Field field) const
CDateTime CPVREpgInfoTag::GetCurrentPlayingTime() const
{
- if (CServiceBroker::GetPVRManager().IsPlayingChannel(ClientID(), UniqueChannelID()))
+ if (CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingChannel(ClientID(), UniqueChannelID()))
{
// start time valid?
time_t startTime = CServiceBroker::GetDataCacheCore().GetStartTime();
diff --git a/xbmc/pvr/windows/GUIWindowPVRBase.cpp b/xbmc/pvr/windows/GUIWindowPVRBase.cpp
index 85688cfe2f..b7a8495a21 100644
--- a/xbmc/pvr/windows/GUIWindowPVRBase.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRBase.cpp
@@ -25,6 +25,7 @@
#include "pvr/PVRGUIActions.h"
#include "pvr/PVRGUIDirectory.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/channels/PVRChannelGroup.h"
#include "pvr/channels/PVRChannelGroups.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
@@ -427,13 +428,13 @@ bool CGUIWindowPVRBase::InitChannelGroup()
std::shared_ptr<CPVRChannelGroup> group;
if (m_channelGroupPath.empty())
{
- group = CServiceBroker::GetPVRManager().GetPlayingGroup(m_bRadio);
+ group = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingGroup(m_bRadio);
}
else
{
group = CServiceBroker::GetPVRManager().ChannelGroups()->Get(m_bRadio)->GetGroupByPath(m_channelGroupPath);
if (group)
- CServiceBroker::GetPVRManager().SetPlayingGroup(group);
+ CServiceBroker::GetPVRManager().PlaybackState()->SetPlayingGroup(group);
else
CLog::LogF(LOGERROR, "Found no %s channel group with path '%s'!", m_bRadio ? "radio" : "TV", m_vecItems->GetPath().c_str());
}
@@ -481,7 +482,7 @@ void CGUIWindowPVRBase::SetChannelGroup(std::shared_ptr<CPVRChannelGroup> &&grou
if (updateChannelGroup)
{
- CServiceBroker::GetPVRManager().SetPlayingGroup(updateChannelGroup);
+ CServiceBroker::GetPVRManager().PlaybackState()->SetPlayingGroup(updateChannelGroup);
Update(GetDirectoryPath());
}
}
diff --git a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
index 8b585e5e48..0e20fddf49 100644
--- a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
@@ -24,6 +24,7 @@
#include "messaging/helpers/DialogHelper.h"
#include "pvr/PVRGUIActions.h"
#include "pvr/PVRManager.h"
+#include "pvr/PVRPlaybackState.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/channels/PVRChannelGroup.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
@@ -663,7 +664,8 @@ bool CGUIWindowPVRGuideBase::OnContextButtonNavigate(CONTEXT_BUTTON button)
buttons.Add(&CGUIWindowPVRGuideBase::GotoEnd, 19064); // Last programme
buttons.Add(&CGUIWindowPVRGuideBase::OpenDateSelectionDialog, 19288); // Date selector
buttons.Add(&CGUIWindowPVRGuideBase::GotoFirstChannel, 19322); // First channel
- if (CServiceBroker::GetPVRManager().IsPlayingTV() || CServiceBroker::GetPVRManager().IsPlayingRadio())
+ if (CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingTV() ||
+ CServiceBroker::GetPVRManager().PlaybackState()->IsPlayingRadio())
buttons.Add(&CGUIWindowPVRGuideBase::GotoPlayingChannel, 19323); // Playing channel
buttons.Add(&CGUIWindowPVRGuideBase::GotoLastChannel, 19324); // Last channel
buttons.Add(&CGUIWindowPVRBase::ActivatePreviousChannelGroup, 19319); // Previous group
@@ -840,7 +842,7 @@ bool CGUIWindowPVRGuideBase::GotoLastChannel()
bool CGUIWindowPVRGuideBase::GotoPlayingChannel()
{
- const std::shared_ptr<CPVRChannel> channel = CServiceBroker::GetPVRManager().GetPlayingChannel();
+ const std::shared_ptr<CPVRChannel> channel = CServiceBroker::GetPVRManager().PlaybackState()->GetPlayingChannel();
if (channel)
{
GetGridControl()->SetChannel(channel);