/* * 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. */ #pragma once #include "addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_general.h" #include "interfaces/IAnnouncer.h" #include "pvr/PVRComponentRegistration.h" #include "pvr/epg/EpgContainer.h" #include "pvr/guilib/PVRGUIActionListener.h" #include "pvr/settings/PVRSettings.h" #include "threads/CriticalSection.h" #include "threads/Event.h" #include "threads/Thread.h" #include "utils/EventStream.h" #include #include #include class CFileItem; class CStopWatch; namespace PVR { class CPVRChannel; class CPVRChannelGroup; class CPVRChannelGroupsContainer; class CPVRProviders; class CPVRClient; class CPVRClients; class CPVRDatabase; class CPVRGUIInfo; class CPVRGUIProgressHandler; class CPVRManagerJobQueue; class CPVRPlaybackState; class CPVRRecording; class CPVRRecordings; class CPVRTimers; enum class PVREvent { // PVR Manager states ManagerError = 0, ManagerStopped, ManagerStarting, ManagerStopping, ManagerInterrupted, ManagerStarted, // Channel events ChannelPlaybackStopped, // Channel group events ChannelGroup, ChannelGroupInvalidated, ChannelGroupsInvalidated, // Recording events RecordingsInvalidated, // Timer events AnnounceReminder, Timers, TimersInvalidated, // Client events ClientsInvalidated, // EPG events Epg, EpgActiveItem, EpgContainer, EpgItemUpdate, EpgUpdatePending, EpgDeleted, // Saved searches events SavedSearchesInvalidated, // Item events CurrentItem, // System events SystemSleep, SystemWake, }; class CPVRManager : private CThread, public ANNOUNCEMENT::IAnnouncer { public: /*! * @brief Create a new CPVRManager instance, which handles all PVR related operations in XBMC. */ CPVRManager(); /*! * @brief Stop the PVRManager and destroy all objects it created. */ ~CPVRManager() override; void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const std::string& sender, const std::string& message, const CVariant& data) override; /*! * @brief Get a PVR component. * @return The component. */ template T& Get() { return *m_components->GetComponent(); } /*! * @brief Get the providers container. * @return The providers container. */ std::shared_ptr Providers() const; /*! * @brief Get the channel groups container. * @return The groups container. */ std::shared_ptr ChannelGroups() const; /*! * @brief Get the recordings container. * @return The recordings container. */ std::shared_ptr Recordings() const; /*! * @brief Get the timers container. * @return The timers container. */ std::shared_ptr Timers() const; /*! * @brief Get the timers container. * @return The timers container. */ std::shared_ptr Clients() const; /*! * @brief Get the instance of a client that matches the given item. * @param item The item containing a PVR recording, a PVR channel, a PVR timer or a PVR EPG event. * @return the requested client on success, nullptr otherwise. */ std::shared_ptr GetClient(const CFileItem& item) const; /*! * @brief Get the instance of a client that matches the given id. * @param iClientId The id of a PVR client. * @return the requested client on success, nullptr otherwise. */ std::shared_ptr GetClient(int iClientId) const; /*! * @brief Get access to the pvr playback state. * @return The playback state. */ std::shared_ptr PlaybackState() const; /*! * @brief Get access to the epg container. * @return The epg container. */ CPVREpgContainer& EpgContainer(); /*! * @brief Init PVRManager. */ void Init(); /*! * @brief Start the PVRManager, which loads all PVR data and starts some threads to update the PVR data. */ void Start(); /*! * @brief Stop PVRManager. */ void Stop(bool bRestart = false); /*! * @brief Stop PVRManager, unload data. */ void Unload(); /*! * @brief Deinit PVRManager, unload data, unload addons. */ void Deinit(); /*! * @brief Propagate event on system sleep */ void OnSleep(); /*! * @brief Propagate event on system wake */ void OnWake(); /*! * @brief Get the TV database. * @return The TV database. */ std::shared_ptr GetTVDatabase() const; /*! * @brief Check whether the PVRManager has fully started. * @return True if started, false otherwise. */ bool IsStarted() const { return GetState() == ManagerState::STATE_STARTED; } /*! * @brief Check whether EPG tags for channels have been created. * @return True if EPG tags have been created, false otherwise. */ bool EpgsCreated() const; /*! * @brief Inform PVR manager that playback of an item just started. * @param item The item that started to play. */ void OnPlaybackStarted(const CFileItem& item); /*! * @brief Inform PVR manager that playback of an item was stopped due to user interaction. * @param item The item that stopped to play. */ void OnPlaybackStopped(const CFileItem& item); /*! * @brief Inform PVR manager that playback of an item has stopped without user interaction. * @param item The item that ended to play. */ void OnPlaybackEnded(const CFileItem& item); /*! * @brief Let the background thread create epg tags for all channels. */ void TriggerEpgsCreate(); /*! * @brief Let the background thread update the recordings list. * @param clientId The id of the PVR client to update. */ void TriggerRecordingsUpdate(int clientId); void TriggerRecordingsUpdate(); /*! * @brief Let the background thread update the size for any in progress recordings. */ void TriggerRecordingsSizeInProgressUpdate(); /*! * @brief Let the background thread update the timer list. * @param clientId The id of the PVR client to update. */ void TriggerTimersUpdate(int clientId); void TriggerTimersUpdate(); /*! * @brief Let the background thread update the channel list. * @param clientId The id of the PVR client to update. */ void TriggerChannelsUpdate(int clientId); void TriggerChannelsUpdate(); /*! * @brief Let the background thread update the provider list. * @param clientId The id of the PVR client to update. */ void TriggerProvidersUpdate(int clientId); void TriggerProvidersUpdate(); /*! * @brief Let the background thread update the channel groups list. * @param clientId The id of the PVR client to update. */ void TriggerChannelGroupsUpdate(int clientId); void TriggerChannelGroupsUpdate(); /*! * @brief Let the background thread search for all missing channel icons. */ void TriggerSearchMissingChannelIcons(); /*! * @brief Let the background thread erase stale texture db entries and image files. */ void TriggerCleanupCachedImages(); /*! * @brief Let the background thread search for missing channel icons for channels contained in the given group. * @param group The channel group. */ void TriggerSearchMissingChannelIcons(const std::shared_ptr& group); /*! * @brief Check whether names are still correct after the language settings changed. */ void LocalizationChanged(); /*! * @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. */ bool IsParentalLocked(const std::shared_ptr& channel) const; /*! * @brief Check if parental lock is overridden at the given moment. * @param epgTag The epg tag to check. * @return True if parental lock is overridden, false otherwise. */ bool IsParentalLocked(const std::shared_ptr& epgTag) const; /*! * @brief Restart the parental timer. */ void RestartParentalTimer(); /*! * @brief Create EPG tags for all channels in internal channel groups * @return True if EPG tags where created successfully, false otherwise */ bool CreateChannelEpgs(); /*! * @brief Signal a connection change of a client */ void ConnectionStateChange(CPVRClient* client, const std::string& connectString, PVR_CONNECTION_STATE state, const std::string& message); /*! * @brief Query the events available for CEventStream */ CEventStream& Events() { return m_events; } /*! * @brief Publish an event * @param state the event */ void PublishEvent(PVREvent state); protected: /*! * @brief PVR update and control thread. */ void Process() override; private: /*! * @brief Executes "pvrpowermanagement.setwakeupcmd" */ bool SetWakeupCommand(); enum class ManagerState { STATE_ERROR = 0, STATE_STOPPED, STATE_STARTING, STATE_SSTOPPING, STATE_INTERRUPTED, STATE_STARTED }; /*! * @return True while the PVRManager is initialising. */ bool IsInitialising() const { return GetState() == ManagerState::STATE_STARTING; } /*! * @brief Check whether the PVRManager has been stopped. * @return True if stopped, false otherwise. */ bool IsStopped() const { return GetState() == ManagerState::STATE_STOPPED; } /*! * @brief Get the current state of the PVR manager. * @return the state. */ ManagerState GetState() const; /*! * @brief Set the current state of the PVR manager. * @param state the new state. */ void SetState(ManagerState state); /*! * @brief Wait until at least one client is up. Update all data from database and the given PVR clients. * @param stateToCheck Required state of the PVR manager while this method gets called. */ void UpdateComponents(ManagerState stateToCheck); /*! * @brief Update all data from database and the given PVR clients. * @param stateToCheck Required state of the PVR manager while this method gets called. * @param progressHandler The progress handler to use for showing the different stages. * @return True if at least one client is known and successfully loaded, false otherwise. */ bool UpdateComponents(ManagerState stateToCheck, const std::unique_ptr& progressHandler); /*! * @brief Unload all PVR data (recordings, timers, channelgroups). */ void UnloadComponents(); /*! * @brief Check whether the given client id belongs to a known client. * @return True if the client is known, false otherwise. */ bool IsKnownClient(int clientID) const; /*! * @brief Reset all properties. */ void ResetProperties(); /*! * @brief Destroy PVRManager's objects. */ void Clear(); /*! * @brief Continue playback on the last played channel. */ void TriggerPlayChannelOnStartup(); bool IsCurrentlyParentalLocked(const std::shared_ptr& channel, bool bGenerallyLocked) const; CEventSource m_events; /** @name containers */ //@{ std::shared_ptr m_providers; /*!< pointer to the providers container */ std::shared_ptr m_channelGroups; /*!< pointer to the channel groups container */ std::shared_ptr m_recordings; /*!< pointer to the recordings container */ std::shared_ptr m_timers; /*!< pointer to the timers container */ std::shared_ptr m_addons; /*!< pointer to the pvr addon container */ std::unique_ptr m_guiInfo; /*!< pointer to the guiinfo data */ std::shared_ptr m_components; /*!< pointer to the PVR components */ CPVREpgContainer m_epgContainer; /*!< the epg container */ //@} std::vector> m_knownClients; /*!< vector with all known clients */ std::unique_ptr m_pendingUpdates; /*!< vector of pending pvr updates */ std::shared_ptr m_database; /*!< the database for all PVR related data */ mutable CCriticalSection m_critSection; /*!< critical section for all changes to this class, except for changes to triggers */ bool m_bFirstStart = true; /*!< true when the PVR manager was started first, false otherwise */ bool m_bEpgsCreated = false; /*!< true if epg data for channels has been created */ mutable CCriticalSection m_managerStateMutex; ManagerState m_managerState = ManagerState::STATE_STOPPED; std::unique_ptr m_parentalTimer; CCriticalSection m_startStopMutex; // mutex for protecting pvr manager's start/restart/stop sequence */ const std::shared_ptr m_playbackState; CPVRGUIActionListener m_actionListener; CPVRSettings m_settings; }; } // namespace PVR