3 * Copyright (C) 2012-2013 Team XBMC
6 * This Program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This Program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with XBMC; see the file COPYING. If not, see
18 * <http://www.gnu.org/licenses/>.
24 #include "addons/include/xbmc_pvr_types.h"
25 #include "settings/lib/ISettingCallback.h"
26 #include "threads/Event.h"
27 #include "threads/Thread.h"
28 #include "utils/JobManager.h"
29 #include "utils/Observer.h"
30 #include "interfaces/IAnnouncer.h"
32 class CGUIDialogProgressBarHandle;
46 typedef boost::shared_ptr<PVR::CPVRChannel> CPVRChannelPtr;
47 class CPVRChannelGroupsContainer;
48 class CPVRChannelGroup;
54 class CGUIWindowPVRCommon;
58 ManagerStateError = 0,
62 ManagerStateInterrupted,
75 START_LAST_CHANNEL_OFF = 0,
76 START_LAST_CHANNEL_MIN,
80 #define g_PVRManager CPVRManager::Get()
81 #define g_PVRChannelGroups g_PVRManager.ChannelGroups()
82 #define g_PVRTimers g_PVRManager.Timers()
83 #define g_PVRRecordings g_PVRManager.Recordings()
84 #define g_PVRClients g_PVRManager.Clients()
86 typedef boost::shared_ptr<PVR::CPVRChannelGroup> CPVRChannelGroupPtr;
88 class CPVRManager : public ISettingCallback, private CThread, public Observable, public ANNOUNCEMENT::IAnnouncer
90 friend class CPVRClients;
94 * @brief Create a new CPVRManager instance, which handles all PVR related operations in XBMC.
100 * @brief Stop the PVRManager and destroy all objects it created.
102 virtual ~CPVRManager(void);
104 virtual void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data);
107 * @brief Get the instance of the PVRManager.
108 * @return The PVRManager instance.
110 static CPVRManager &Get(void);
112 virtual void OnSettingChanged(const CSetting *setting);
113 virtual void OnSettingAction(const CSetting *setting);
116 * @brief Get the channel groups container.
117 * @return The groups container.
119 CPVRChannelGroupsContainer *ChannelGroups(void) const { return m_channelGroups; }
122 * @brief Get the recordings container.
123 * @return The recordings container.
125 CPVRRecordings *Recordings(void) const { return m_recordings; }
128 * @brief Get the timers container.
129 * @return The timers container.
131 CPVRTimers *Timers(void) const { return m_timers; }
134 * @brief Get the timers container.
135 * @return The timers container.
137 CPVRClients *Clients(void) const { return m_addons; }
140 * @brief Start the PVRManager, which loads all PVR data and starts some threads to update the PVR data.
141 * @param bAsync True to (re)start the manager from another thread
142 * @param bOpenPVRWindow True to open the PVR window after starting, false otherwise
144 void Start(bool bAsync = false, bool bOpenPVRWindow = false);
147 * @brief Stop the PVRManager and destroy all objects it created.
152 * @brief Delete PVRManager's objects.
157 * @return True when a PVR window is active, false otherwise.
159 bool IsPVRWindowActive(void) const;
162 * @brief Check whether an add-on can be upgraded or installed without restarting the pvr manager, when the add-on is in use or the pvr window is active
163 * @param strAddonId The add-on to check.
164 * @return True when the add-on can be installed, false otherwise.
166 bool InstallAddonAllowed(const std::string& strAddonId) const;
169 * @brief Mark an add-on as outdated so it will be upgrade when it's possible again
170 * @param strAddonId The add-on to mark as outdated
171 * @param strReferer The referer to use when downloading
173 void MarkAsOutdated(const std::string& strAddonId, const std::string& strReferer);
176 * @return True when updated, false when the pvr manager failed to load after the attempt
178 bool UpgradeOutdatedAddons(void);
181 * @brief Get the TV database.
182 * @return The TV database.
184 CPVRDatabase *GetTVDatabase(void) const { return m_database; }
187 * @brief Updates the recordings and the "now" and "next" timers.
189 void UpdateRecordingsCache(void);
192 * @brief Get a GUIInfoManager character string.
193 * @param dwInfo The string to get.
194 * @return The requested string or an empty one if it wasn't found.
196 bool TranslateCharInfo(DWORD dwInfo, CStdString &strValue) const;
199 * @brief Get a GUIInfoManager integer.
200 * @param dwInfo The integer to get.
201 * @return The requested integer or 0 if it wasn't found.
203 int TranslateIntInfo(DWORD dwInfo) const;
206 * @brief Get a GUIInfoManager boolean.
207 * @param dwInfo The boolean to get.
208 * @return The requested boolean or false if it wasn't found.
210 bool TranslateBoolInfo(DWORD dwInfo) const;
213 * @brief Show the player info.
214 * @param iTimeout Hide the player info after iTimeout seconds.
215 * @todo not really the right place for this :-)
217 void ShowPlayerInfo(int iTimeout);
220 * @brief Reset the TV database to it's initial state and delete all the data inside.
221 * @param bResetEPGOnly True to only reset the EPG database, false to reset both PVR and EPG.
223 void ResetDatabase(bool bResetEPGOnly = false);
226 * @brief Check if a TV channel, radio channel or recording is playing.
227 * @return True if it's playing, false otherwise.
229 bool IsPlaying(void) const;
232 * @return True while the PVRManager is initialising.
234 inline bool IsInitialising(void) const
236 return GetState() == ManagerStateStarting;
240 * @brief Check whether the PVRManager has fully started.
241 * @return True if started, false otherwise.
243 inline bool IsStarted(void) const
245 return GetState() == ManagerStateStarted;
249 * @brief Check whether the PVRManager is stopping
250 * @return True while the PVRManager is stopping.
252 inline bool IsStopping(void) const
254 return GetState() == ManagerStateStopping;
258 * @brief Check whether the PVRManager has been stopped.
259 * @return True if stopped, false otherwise.
261 inline bool IsStopped(void) const
263 return GetState() == ManagerStateStopped;
267 * @brief Return the channel that is currently playing.
268 * @param channel The channel or NULL if none is playing.
269 * @return True if a channel is playing, false otherwise.
271 bool GetCurrentChannel(CPVRChannelPtr &channel) const;
274 * @brief Return the EPG for the channel that is currently playing.
275 * @param channel The EPG or NULL if no channel is playing.
276 * @return The amount of results that was added or -1 if none.
278 int GetCurrentEpg(CFileItemList &results) const;
281 * @brief Check whether EPG tags for channels have been created.
282 * @return True if EPG tags have been created, false otherwise.
284 bool EpgsCreated(void) const;
287 * @brief Reset the playing EPG tag.
289 void ResetPlayingTag(void);
292 * @brief Switch to the given channel.
293 * @param channel The channel to switch to.
294 * @param bPreview True to show a preview, false otherwise.
295 * @return Trrue if the switch was successful, false otherwise.
297 bool PerformChannelSwitch(const CPVRChannel &channel, bool bPreview);
300 * @brief Close an open PVR stream.
302 void CloseStream(void);
305 * @brief Open a stream from the given channel.
306 * @param channel The channel to open.
307 * @return True if the stream was opened, false otherwise.
309 bool OpenLiveStream(const CFileItem &channel);
312 * @brief Open a stream from the given recording.
313 * @param tag The recording to open.
314 * @return True if the stream was opened, false otherwise.
316 bool OpenRecordedStream(const CPVRRecording &tag);
319 * @brief Start recording on a given channel if it is not already recording, stop if it is.
320 * @param channel the channel to start/stop recording.
321 * @return True if the recording was started or stopped successfully, false otherwise.
323 bool ToggleRecordingOnChannel(unsigned int iChannelId);
326 * @brief Start or stop recording on the channel that is currently being played.
327 * @param bOnOff True to start recording, false to stop.
328 * @return True if the recording was started or stopped successfully, false otherwise.
330 bool StartRecordingOnPlayingChannel(bool bOnOff);
333 * @brief Get the channel number of the previously selected channel.
334 * @return The requested channel number or -1 if it wasn't found.
336 int GetPreviousChannel(void);
339 * @brief Check whether there are active timers.
340 * @return True if there are active timers, false otherwise.
342 bool HasTimers(void) const;
345 * @brief Check whether there are active recordings.
346 * @return True if there are active recordings, false otherwise.
348 bool IsRecording(void) const;
351 * @brief Check whether the pvr backend is idle.
352 * @return True if there are no active timers/recordings/wake-ups within the configured time span.
354 bool IsIdle(void) const;
357 * @brief Set the current playing group, used to load the right channel.
358 * @param group The new group.
360 void SetPlayingGroup(CPVRChannelGroupPtr group);
363 * @brief Get the current playing group, used to load the right channel.
364 * @param bRadio True to get the current radio group, false to get the current TV group.
365 * @return The current group or the group containing all channels if it's not set.
367 CPVRChannelGroupPtr GetPlayingGroup(bool bRadio = false);
370 * @brief Let the background thread create epg tags for all channels.
372 void TriggerEpgsCreate(void);
375 * @brief Let the background thread update the recordings list.
377 void TriggerRecordingsUpdate(void);
380 * @brief Let the background thread update the timer list.
382 void TriggerTimersUpdate(void);
385 * @brief Let the background thread update the channel list.
387 void TriggerChannelsUpdate(void);
390 * @brief Let the background thread update the channel groups list.
392 void TriggerChannelGroupsUpdate(void);
395 * @brief Let the background thread save the current video settings.
397 void TriggerSaveChannelSettings(void);
400 * @brief Update the channel that is currently active.
401 * @param item The new channel.
402 * @return True if it was updated correctly, false otherwise.
404 bool UpdateItem(CFileItem& item);
407 * @brief Switch to a channel given it's channel number.
408 * @param iChannelNumber The channel number to switch to.
409 * @return True if the channel was switched, false otherwise.
411 bool ChannelSwitch(unsigned int iChannelNumber);
414 * @brief Switch to the next channel in this group.
415 * @param iNewChannelNumber The new channel number after the switch.
416 * @param bPreview If true, don't do the actual switch but just update channel pointers.
417 * Used to display event info while doing "fast channel switching"
418 * @return True if the channel was switched, false otherwise.
420 bool ChannelUp(unsigned int *iNewChannelNumber, bool bPreview = false) { return ChannelUpDown(iNewChannelNumber, bPreview, true); }
423 * @brief Switch to the previous channel in this group.
424 * @param iNewChannelNumber The new channel number after the switch.
425 * @param bPreview If true, don't do the actual switch but just update channel pointers.
426 * Used to display event info while doing "fast channel switching"
427 * @return True if the channel was switched, false otherwise.
429 bool ChannelDown(unsigned int *iNewChannelNumber, bool bPreview = false) { return ChannelUpDown(iNewChannelNumber, bPreview, false); }
432 * @brief Get the total duration of the currently playing LiveTV item.
433 * @return The total duration in milliseconds or NULL if no channel is playing.
435 int GetTotalTime(void) const;
438 * @brief Get the current position in milliseconds since the start of a LiveTV item.
439 * @return The position in milliseconds or NULL if no channel is playing.
441 int GetStartTime(void) const;
444 * @brief Start playback on a channel.
445 * @param channel The channel to start to play.
446 * @param bPreview If true, open minimised.
447 * @return True if playback was started, false otherwise.
449 bool StartPlayback(const CPVRChannel *channel, bool bPreview = false);
452 * @brief Start playback of the last used channel, and if it fails use first channel in the current channelgroup.
453 * @param type The type of playback to be started (any, radio, tv). See PlaybackType enum
454 * @return True if playback was started, false otherwise.
456 bool StartPlayback(PlaybackType type = PlaybackTypeAny);
459 * @brief Update the current playing file in the guiinfomanager and application.
461 void UpdateCurrentFile(void);
464 * @brief Check whether names are still correct after the language settings changed.
466 void LocalizationChanged(void);
469 * @brief Check if a TV channel is playing.
470 * @return True if it's playing, false otherwise.
472 bool IsPlayingTV(void) const;
475 * @brief Check if a radio channel is playing.
476 * @return True if it's playing, false otherwise.
478 bool IsPlayingRadio(void) const;
481 * @brief Check if a recording is playing.
482 * @return True if it's playing, false otherwise.
484 bool IsPlayingRecording(void) const;
487 * @return True when a channel scan is currently running, false otherwise.
489 bool IsRunningChannelScan(void) const;
492 * @brief Open a selection dialog and start a channel scan on the selected client.
494 void StartChannelScan(void);
497 * @brief Try to find missing channel icons automatically
499 void SearchMissingChannelIcons(void);
502 * @brief Persist the current channel settings in the database.
504 void SaveCurrentChannelSettings(void);
507 * @brief Load the settings for the current channel from the database.
509 void LoadCurrentChannelSettings(void);
512 * @brief Check if channel is parental locked. Ask for PIN if neccessary.
513 * @param channel The channel to open.
514 * @return True if channel is unlocked (by default or PIN unlocked), false otherwise.
516 bool CheckParentalLock(const CPVRChannel &channel);
519 * @brief Check if parental lock is overriden at the given moment.
520 * @param channel The channel to open.
521 * @return True if parental lock is overriden, false otherwise.
523 bool IsParentalLocked(const CPVRChannel &channel);
526 * @brief Open Numeric dialog to check for parental PIN.
527 * @param strTitle Override the title of the dialog if set.
528 * @return True if entered PIN was correct, false otherwise.
530 bool CheckParentalPIN(const char *strTitle = NULL);
533 * @brief Executes "pvrpowermanagement.setwakeupcmd"
535 bool SetWakeupCommand(void);
538 * @brief Wait until the pvr manager is loaded
539 * @return True when loaded, false otherwise
541 bool WaitUntilInitialised(void);
544 * @brief Handle PVR specific cActions
545 * @param action The action to process
546 * @return True if action could be handled, false otherwise.
548 bool OnAction(const CAction &action);
550 static void SettingOptionsPvrStartLastChannelFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int ¤t);
553 * @brief Create EPG tags for all channels in internal channel groups
554 * @return True if EPG tags where created successfully, false otherwise
556 bool CreateChannelEpgs(void);
560 * @brief PVR update and control thread.
562 virtual void Process(void);
566 * @brief Load at least one client and load all other PVR data after loading the client.
567 * If some clients failed to load here, the pvrmanager will retry to load them every second.
568 * @return If at least one client and all pvr data was loaded, false otherwise.
573 * @brief Update all recordings.
575 void UpdateRecordings(void);
578 * @brief Update all timers.
580 void UpdateTimers(void);
583 * @brief Update all channels.
585 void UpdateChannels(void);
588 * @brief Update all channel groups and channels in them.
590 void UpdateChannelGroups(void);
593 * @brief Reset all properties.
595 void ResetProperties(void);
598 * @brief Called by ChannelUp() and ChannelDown() to perform a channel switch.
599 * @param iNewChannelNumber The new channel number after the switch.
600 * @param bPreview Preview window if true.
601 * @param bUp Go one channel up if true, one channel down if false.
602 * @return True if the switch was successful, false otherwise.
604 bool ChannelUpDown(unsigned int *iNewChannelNumber, bool bPreview, bool bUp);
607 * @brief Stop the EPG and PVR threads but do not remove their data.
609 void StopUpdateThreads(void);
612 * @brief Restart the EPG and PVR threads after they've been stopped by StopUpdateThreads()
614 bool StartUpdateThreads(void);
617 * @brief Continue playback on the last channel if it was stored in the database.
618 * @return True if playback was continued, false otherwise.
620 bool ContinueLastChannel(void);
623 * @brief Show or update the progress dialog.
624 * @param strText The current status.
625 * @param iProgress The current progress in %.
627 void ShowProgressDialog(const CStdString &strText, int iProgress);
630 * @brief Hide the progress dialog if it's visible.
632 void HideProgressDialog(void);
634 void ExecutePendingJobs(void);
636 bool IsJobPending(const char *strJobName) const;
639 * @brief Adds the job to the list of pending jobs unless an identical
640 * job is already queued
643 void QueueJob(CJob *job);
645 ManagerState GetState(void) const;
647 void SetState(ManagerState state);
648 /** @name containers */
650 CPVRChannelGroupsContainer * m_channelGroups; /*!< pointer to the channel groups container */
651 CPVRRecordings * m_recordings; /*!< pointer to the recordings container */
652 CPVRTimers * m_timers; /*!< pointer to the timers container */
653 CPVRClients * m_addons; /*!< pointer to the pvr addon container */
654 CPVRGUIInfo * m_guiInfo; /*!< pointer to the guiinfo data */
657 CCriticalSection m_critSectionTriggers; /*!< critical section for triggered updates */
658 CEvent m_triggerEvent; /*!< triggers an update */
659 std::vector<CJob *> m_pendingUpdates; /*!< vector of pending pvr updates */
661 CFileItem * m_currentFile; /*!< the PVR file that is currently playing */
662 CPVRDatabase * m_database; /*!< the database for all PVR related data */
663 CCriticalSection m_critSection; /*!< critical section for all changes to this class, except for changes to triggers */
664 bool m_bFirstStart; /*!< true when the PVR manager was started first, false otherwise */
665 bool m_bIsSwitchingChannels; /*!< true while switching channels */
666 bool m_bEpgsCreated; /*!< true if epg data for channels has been created */
667 CGUIDialogProgressBarHandle * m_progressHandle; /*!< progress dialog that is displayed while the pvrmanager is loading */
669 CCriticalSection m_managerStateMutex;
670 ManagerState m_managerState;
671 CStopWatch *m_parentalTimer;
672 bool m_bOpenPVRWindow;
673 std::map<std::string, std::string> m_outdatedAddons;
676 class CPVREpgsCreateJob : public CJob
679 CPVREpgsCreateJob(void) {}
680 virtual ~CPVREpgsCreateJob() {}
681 virtual const char *GetType() const { return "pvr-create-epgs"; }
683 virtual bool DoWork();
686 class CPVRRecordingsUpdateJob : public CJob
689 CPVRRecordingsUpdateJob(void) {}
690 virtual ~CPVRRecordingsUpdateJob() {}
691 virtual const char *GetType() const { return "pvr-update-recordings"; }
693 virtual bool DoWork();
696 class CPVRTimersUpdateJob : public CJob
699 CPVRTimersUpdateJob(void) {}
700 virtual ~CPVRTimersUpdateJob() {}
701 virtual const char *GetType() const { return "pvr-update-timers"; }
703 virtual bool DoWork();
706 class CPVRChannelsUpdateJob : public CJob
709 CPVRChannelsUpdateJob(void) {}
710 virtual ~CPVRChannelsUpdateJob() {}
711 virtual const char *GetType() const { return "pvr-update-channels"; }
713 virtual bool DoWork();
716 class CPVRChannelGroupsUpdateJob : public CJob
719 CPVRChannelGroupsUpdateJob(void) {}
720 virtual ~CPVRChannelGroupsUpdateJob() {}
721 virtual const char *GetType() const { return "pvr-update-channelgroups"; }
723 virtual bool DoWork();
726 class CPVRChannelSettingsSaveJob : public CJob
729 CPVRChannelSettingsSaveJob(void) {}
730 virtual ~CPVRChannelSettingsSaveJob() {}
731 virtual const char *GetType() const { return "pvr-save-channelsettings"; }
736 class CPVRChannelSwitchJob : public CJob
739 CPVRChannelSwitchJob(CFileItem* previous, CFileItem* next) : m_previous(previous), m_next(next) {}
740 virtual ~CPVRChannelSwitchJob() {}
741 virtual const char *GetType() const { return "pvr-channel-switch"; }
743 virtual bool DoWork();
745 CFileItem* m_previous;