Merge pull request #4539 from Matricom/amcodec
[vuplus_xbmc] / xbmc / pvr / PVRManager.h
1 #pragma once
2 /*
3  *      Copyright (C) 2012-2013 Team XBMC
4  *      http://xbmc.org
5  *
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)
9  *  any later version.
10  *
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.
15  *
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/>.
19  *
20  */
21
22 #include <map>
23
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"
31
32 class CGUIDialogProgressBarHandle;
33 class CStopWatch;
34 class CAction;
35 class CFileItemList;
36
37 namespace EPG
38 {
39   class CEpgContainer;
40 }
41
42 namespace PVR
43 {
44   class CPVRClients;
45   class CPVRChannel;
46   typedef boost::shared_ptr<PVR::CPVRChannel> CPVRChannelPtr;
47   class CPVRChannelGroupsContainer;
48   class CPVRChannelGroup;
49   class CPVRRecording;
50   class CPVRRecordings;
51   class CPVRTimers;
52   class CPVRGUIInfo;
53   class CPVRDatabase;
54   class CGUIWindowPVRCommon;
55
56   enum ManagerState
57   {
58     ManagerStateError = 0,
59     ManagerStateStopped,
60     ManagerStateStarting,
61     ManagerStateStopping,
62     ManagerStateInterrupted,
63     ManagerStateStarted
64   };
65
66   enum PlaybackType
67   {
68     PlaybackTypeAny = 0,
69     PlaybackTypeTv,
70     PlaybackTypeRadio
71   };
72
73   enum ChannelStartLast
74   {
75     START_LAST_CHANNEL_OFF  = 0,
76     START_LAST_CHANNEL_MIN,
77     START_LAST_CHANNEL_ON
78   };
79
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()
85
86   typedef boost::shared_ptr<PVR::CPVRChannelGroup> CPVRChannelGroupPtr;
87
88   class CPVRManager : public ISettingCallback, private CThread, public Observable, public ANNOUNCEMENT::IAnnouncer
89   {
90     friend class CPVRClients;
91
92   private:
93     /*!
94      * @brief Create a new CPVRManager instance, which handles all PVR related operations in XBMC.
95      */
96     CPVRManager(void);
97
98   public:
99     /*!
100      * @brief Stop the PVRManager and destroy all objects it created.
101      */
102     virtual ~CPVRManager(void);
103
104     virtual void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data);
105
106     /*!
107      * @brief Get the instance of the PVRManager.
108      * @return The PVRManager instance.
109      */
110     static CPVRManager &Get(void);
111
112     virtual void OnSettingChanged(const CSetting *setting);
113     virtual void OnSettingAction(const CSetting *setting);
114
115     /*!
116      * @brief Get the channel groups container.
117      * @return The groups container.
118      */
119     CPVRChannelGroupsContainer *ChannelGroups(void) const { return m_channelGroups; }
120
121     /*!
122      * @brief Get the recordings container.
123      * @return The recordings container.
124      */
125     CPVRRecordings *Recordings(void) const { return m_recordings; }
126
127     /*!
128      * @brief Get the timers container.
129      * @return The timers container.
130      */
131     CPVRTimers *Timers(void) const { return m_timers; }
132
133     /*!
134      * @brief Get the timers container.
135      * @return The timers container.
136      */
137     CPVRClients *Clients(void) const { return m_addons; }
138
139     /*!
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
143      */
144     void Start(bool bAsync = false, bool bOpenPVRWindow = false);
145
146     /*!
147      * @brief Stop the PVRManager and destroy all objects it created.
148      */
149     void Stop(void);
150
151     /*!
152      * @brief Delete PVRManager's objects.
153      */
154     void Cleanup(void);
155
156     /*!
157      * @return True when a PVR window is active, false otherwise.
158      */
159     bool IsPVRWindowActive(void) const;
160
161     /*!
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.
165      */
166     bool InstallAddonAllowed(const std::string& strAddonId) const;
167
168     /*!
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
172      */
173     void MarkAsOutdated(const std::string& strAddonId, const std::string& strReferer);
174
175     /*!
176      * @return True when updated, false when the pvr manager failed to load after the attempt
177      */
178     bool UpgradeOutdatedAddons(void);
179
180     /*!
181      * @brief Get the TV database.
182      * @return The TV database.
183      */
184     CPVRDatabase *GetTVDatabase(void) const { return m_database; }
185
186     /*!
187      * @brief Updates the recordings and the "now" and "next" timers.
188      */
189     void UpdateRecordingsCache(void);
190
191     /*!
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.
195      */
196     bool TranslateCharInfo(DWORD dwInfo, CStdString &strValue) const;
197
198     /*!
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.
202      */
203     int TranslateIntInfo(DWORD dwInfo) const;
204
205     /*!
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.
209      */
210     bool TranslateBoolInfo(DWORD dwInfo) const;
211
212     /*!
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 :-)
216      */
217     void ShowPlayerInfo(int iTimeout);
218
219     /*!
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.
222      */
223     void ResetDatabase(bool bResetEPGOnly = false);
224
225     /*!
226      * @brief Check if a TV channel, radio channel or recording is playing.
227      * @return True if it's playing, false otherwise.
228      */
229     bool IsPlaying(void) const;
230
231     /*!
232      * @return True while the PVRManager is initialising.
233      */
234     inline bool IsInitialising(void) const
235     {
236       return GetState() == ManagerStateStarting;
237     }
238     
239     /*!
240      * @brief Check whether the PVRManager has fully started.
241      * @return True if started, false otherwise.
242      */
243     inline bool IsStarted(void) const
244     {
245       return GetState() == ManagerStateStarted;
246     }
247     
248     /*!
249      * @brief Check whether the PVRManager is stopping
250      * @return True while the PVRManager is stopping.
251      */
252     inline bool IsStopping(void) const
253     {
254       return GetState() == ManagerStateStopping;
255     }
256     
257     /*!
258      * @brief Check whether the PVRManager has been stopped.
259      * @return True if stopped, false otherwise.
260      */
261     inline bool IsStopped(void) const
262     {
263       return GetState() == ManagerStateStopped;
264     }
265
266     /*!
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.
270      */
271     bool GetCurrentChannel(CPVRChannelPtr &channel) const;
272
273     /*!
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.
277      */
278     int GetCurrentEpg(CFileItemList &results) const;
279
280     /*!
281      * @brief Check whether EPG tags for channels have been created.
282      * @return True if EPG tags have been created, false otherwise.
283      */
284     bool EpgsCreated(void) const;
285
286     /*!
287      * @brief Reset the playing EPG tag.
288      */
289     void ResetPlayingTag(void);
290
291     /*!
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.
296      */
297     bool PerformChannelSwitch(const CPVRChannel &channel, bool bPreview);
298
299     /*!
300      * @brief Close an open PVR stream.
301      */
302     void CloseStream(void);
303
304     /*!
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.
308      */
309     bool OpenLiveStream(const CFileItem &channel);
310
311     /*!
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.
315      */
316     bool OpenRecordedStream(const CPVRRecording &tag);
317
318     /*!
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.
322      */
323     bool ToggleRecordingOnChannel(unsigned int iChannelId);
324
325     /*!
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.
329      */
330     bool StartRecordingOnPlayingChannel(bool bOnOff);
331
332     /*!
333      * @brief Get the channel number of the previously selected channel.
334      * @return The requested channel number or -1 if it wasn't found.
335      */
336     int GetPreviousChannel(void);
337
338     /*!
339      * @brief Check whether there are active timers.
340      * @return True if there are active timers, false otherwise.
341      */
342     bool HasTimers(void) const;
343
344     /*!
345      * @brief Check whether there are active recordings.
346      * @return True if there are active recordings, false otherwise.
347      */
348     bool IsRecording(void) const;
349
350     /*!
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.
353      */
354     bool IsIdle(void) const;
355
356     /*!
357      * @brief Set the current playing group, used to load the right channel.
358      * @param group The new group.
359      */
360     void SetPlayingGroup(CPVRChannelGroupPtr group);
361
362     /*!
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.
366      */
367     CPVRChannelGroupPtr GetPlayingGroup(bool bRadio = false);
368
369     /*!
370      * @brief Let the background thread create epg tags for all channels.
371      */
372     void TriggerEpgsCreate(void);
373
374     /*!
375      * @brief Let the background thread update the recordings list.
376      */
377     void TriggerRecordingsUpdate(void);
378
379     /*!
380      * @brief Let the background thread update the timer list.
381      */
382     void TriggerTimersUpdate(void);
383
384     /*!
385      * @brief Let the background thread update the channel list.
386      */
387     void TriggerChannelsUpdate(void);
388
389     /*!
390      * @brief Let the background thread update the channel groups list.
391      */
392     void TriggerChannelGroupsUpdate(void);
393
394     /*!
395      * @brief Let the background thread save the current video settings.
396      */
397     void TriggerSaveChannelSettings(void);
398
399     /*!
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.
403      */
404     bool UpdateItem(CFileItem& item);
405
406     /*!
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.
410      */
411     bool ChannelSwitch(unsigned int iChannelNumber);
412
413     /*!
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.
419      */
420     bool ChannelUp(unsigned int *iNewChannelNumber, bool bPreview = false) { return ChannelUpDown(iNewChannelNumber, bPreview, true); }
421
422     /*!
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.
428      */
429     bool ChannelDown(unsigned int *iNewChannelNumber, bool bPreview = false) { return ChannelUpDown(iNewChannelNumber, bPreview, false); }
430
431     /*!
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.
434      */
435     int GetTotalTime(void) const;
436
437     /*!
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.
440      */
441     int GetStartTime(void) const;
442
443     /*!
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.
448      */
449     bool StartPlayback(const CPVRChannel *channel, bool bPreview = false);
450
451     /*!
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.
455      */
456     bool StartPlayback(PlaybackType type = PlaybackTypeAny);
457
458     /*!
459      * @brief Update the current playing file in the guiinfomanager and application.
460      */
461     void UpdateCurrentFile(void);
462
463     /*!
464      * @brief Check whether names are still correct after the language settings changed.
465      */
466     void LocalizationChanged(void);
467
468     /*!
469      * @brief Check if a TV channel is playing.
470      * @return True if it's playing, false otherwise.
471      */
472     bool IsPlayingTV(void) const;
473
474     /*!
475      * @brief Check if a radio channel is playing.
476      * @return True if it's playing, false otherwise.
477      */
478     bool IsPlayingRadio(void) const;
479
480     /*!
481      * @brief Check if a recording is playing.
482      * @return True if it's playing, false otherwise.
483      */
484     bool IsPlayingRecording(void) const;
485
486     /*!
487      * @return True when a channel scan is currently running, false otherwise.
488      */
489     bool IsRunningChannelScan(void) const;
490
491     /*!
492      * @brief Open a selection dialog and start a channel scan on the selected client.
493      */
494     void StartChannelScan(void);
495
496     /*!
497      * @brief Try to find missing channel icons automatically
498      */
499     void SearchMissingChannelIcons(void);
500
501     /*!
502      * @brief Persist the current channel settings in the database.
503      */
504     void SaveCurrentChannelSettings(void);
505
506     /*!
507      * @brief Load the settings for the current channel from the database.
508      */
509     void LoadCurrentChannelSettings(void);
510
511     /*!
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.
515      */
516     bool CheckParentalLock(const CPVRChannel &channel);
517
518     /*!
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.
522      */
523     bool IsParentalLocked(const CPVRChannel &channel);
524
525     /*!
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.
529      */
530     bool CheckParentalPIN(const char *strTitle = NULL);
531
532     /*!
533      * @brief Executes "pvrpowermanagement.setwakeupcmd"
534      */
535     bool SetWakeupCommand(void);
536
537     /*!
538      * @brief Wait until the pvr manager is loaded
539      * @return True when loaded, false otherwise
540      */
541     bool WaitUntilInitialised(void);
542
543     /*!
544      * @brief Handle PVR specific cActions
545      * @param action The action to process
546      * @return True if action could be handled, false otherwise.
547      */
548     bool OnAction(const CAction &action);
549
550     static void SettingOptionsPvrStartLastChannelFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current);
551
552     /*!
553      * @brief Create EPG tags for all channels in internal channel groups
554      * @return True if EPG tags where created successfully, false otherwise
555      */
556     bool CreateChannelEpgs(void);
557
558   protected:
559     /*!
560      * @brief PVR update and control thread.
561      */
562     virtual void Process(void);
563
564   private:
565     /*!
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.
569      */
570     bool Load(void);
571
572     /*!
573      * @brief Update all recordings.
574      */
575     void UpdateRecordings(void);
576
577     /*!
578      * @brief Update all timers.
579      */
580     void UpdateTimers(void);
581
582     /*!
583      * @brief Update all channels.
584      */
585     void UpdateChannels(void);
586
587     /*!
588      * @brief Update all channel groups and channels in them.
589      */
590     void UpdateChannelGroups(void);
591
592     /*!
593      * @brief Reset all properties.
594      */
595     void ResetProperties(void);
596
597     /*!
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.
603      */
604     bool ChannelUpDown(unsigned int *iNewChannelNumber, bool bPreview, bool bUp);
605
606     /*!
607      * @brief Stop the EPG and PVR threads but do not remove their data.
608      */
609     void StopUpdateThreads(void);
610
611     /*!
612      * @brief Restart the EPG and PVR threads after they've been stopped by StopUpdateThreads()
613      */
614     bool StartUpdateThreads(void);
615
616     /*!
617      * @brief Continue playback on the last channel if it was stored in the database.
618      * @return True if playback was continued, false otherwise.
619      */
620     bool ContinueLastChannel(void);
621
622     /*!
623      * @brief Show or update the progress dialog.
624      * @param strText The current status.
625      * @param iProgress The current progress in %.
626      */
627     void ShowProgressDialog(const CStdString &strText, int iProgress);
628
629     /*!
630      * @brief Hide the progress dialog if it's visible.
631      */
632     void HideProgressDialog(void);
633
634     void ExecutePendingJobs(void);
635
636     bool IsJobPending(const char *strJobName) const;
637
638     /*!
639      * @brief Adds the job to the list of pending jobs unless an identical 
640      * job is already queued
641      * @param job the job
642      */
643     void QueueJob(CJob *job);
644
645     ManagerState GetState(void) const;
646
647     void SetState(ManagerState state);
648     /** @name containers */
649     //@{
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 */
655     //@}
656
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 */
660
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 */
668
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;
674   };
675
676   class CPVREpgsCreateJob : public CJob
677   {
678   public:
679     CPVREpgsCreateJob(void) {}
680     virtual ~CPVREpgsCreateJob() {}
681     virtual const char *GetType() const { return "pvr-create-epgs"; }
682
683     virtual bool DoWork();
684   };
685
686   class CPVRRecordingsUpdateJob : public CJob
687   {
688   public:
689     CPVRRecordingsUpdateJob(void) {}
690     virtual ~CPVRRecordingsUpdateJob() {}
691     virtual const char *GetType() const { return "pvr-update-recordings"; }
692
693     virtual bool DoWork();
694   };
695
696   class CPVRTimersUpdateJob : public CJob
697   {
698   public:
699     CPVRTimersUpdateJob(void) {}
700     virtual ~CPVRTimersUpdateJob() {}
701     virtual const char *GetType() const { return "pvr-update-timers"; }
702
703     virtual bool DoWork();
704   };
705
706   class CPVRChannelsUpdateJob : public CJob
707   {
708   public:
709     CPVRChannelsUpdateJob(void) {}
710     virtual ~CPVRChannelsUpdateJob() {}
711     virtual const char *GetType() const { return "pvr-update-channels"; }
712
713     virtual bool DoWork();
714   };
715
716   class CPVRChannelGroupsUpdateJob : public CJob
717   {
718   public:
719     CPVRChannelGroupsUpdateJob(void) {}
720     virtual ~CPVRChannelGroupsUpdateJob() {}
721     virtual const char *GetType() const { return "pvr-update-channelgroups"; }
722
723     virtual bool DoWork();
724   };
725
726   class CPVRChannelSettingsSaveJob : public CJob
727   {
728   public:
729     CPVRChannelSettingsSaveJob(void) {}
730     virtual ~CPVRChannelSettingsSaveJob() {}
731     virtual const char *GetType() const { return "pvr-save-channelsettings"; }
732
733     bool DoWork();
734   };
735
736   class CPVRChannelSwitchJob : public CJob
737   {
738   public:
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"; }
742
743     virtual bool DoWork();
744   private:
745     CFileItem* m_previous;
746     CFileItem* m_next;
747   };
748 }