2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
11 #include "addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_epg.h"
12 #include "pvr/settings/PVRSettings.h"
13 #include "threads/CriticalSection.h"
14 #include "threads/Event.h"
15 #include "threads/Thread.h"
16 #include "utils/EventStream.h"
30 class CEpgUpdateRequest
;
31 class CEpgTagStateChange
;
33 class CPVREpgChannelData
;
34 class CPVREpgDatabase
;
36 class CPVREpgSearchFilter
;
40 struct PVREpgSearchData
;
42 class CPVREpgContainer
: private CThread
44 friend class CPVREpgDatabase
;
47 CPVREpgContainer() = delete;
50 * @brief Create a new EPG table container.
52 explicit CPVREpgContainer(CEventSource
<PVREvent
>& eventSource
);
55 * @brief Destroy this instance.
57 ~CPVREpgContainer() override
;
60 * @brief Get a pointer to the database instance.
61 * @return A pointer to the database instance.
63 std::shared_ptr
<CPVREpgDatabase
> GetEpgDatabase() const;
66 * @brief Start the EPG update thread.
71 * @brief Stop the EPG update thread.
76 * @brief (re)load EPG data.
77 * @return True if loaded successfully, false otherwise.
82 * @brief unload all EPG data.
87 * @brief Check whether the EpgContainer has fully started.
88 * @return True if started, false otherwise.
90 bool IsStarted() const;
93 * @brief Queue the deletion of the given EPG tables from this container.
94 * @param epg The tables to delete.
95 * @return True on success, false otherwise.
97 bool QueueDeleteEpgs(const std::vector
<std::shared_ptr
<CPVREpg
>>& epgs
);
100 * @brief CEventStream callback for PVR events.
101 * @param event The event.
103 void Notify(const PVREvent
& event
);
106 * @brief Create the EPg for a given channel.
107 * @param iEpgId The EPG id.
108 * @param strScraperName The scraper name.
109 * @param channelData The channel data.
110 * @return the created EPG
112 std::shared_ptr
<CPVREpg
> CreateChannelEpg(int iEpgId
, const std::string
& strScraperName
, const std::shared_ptr
<CPVREpgChannelData
>& channelData
);
115 * @brief Get the start and end time across all EPGs.
116 * @return The times; first: start time, second: end time.
118 std::pair
<CDateTime
, CDateTime
> GetFirstAndLastEPGDate() const;
121 * @brief Get all EPGs.
124 std::vector
<std::shared_ptr
<CPVREpg
>> GetAllEpgs() const;
127 * @brief Get an EPG given its ID.
128 * @param iEpgId The database ID of the table.
129 * @return The EPG or nullptr if it wasn't found.
131 std::shared_ptr
<CPVREpg
> GetById(int iEpgId
) const;
134 * @brief Get an EPG given its client id and channel uid.
135 * @param iClientId the id of the pvr client providing the EPG
136 * @param iChannelUid the uid of the channel for the EPG
137 * @return The EPG or nullptr if it wasn't found.
139 std::shared_ptr
<CPVREpg
> GetByChannelUid(int iClientId
, int iChannelUid
) const;
142 * @brief Get the EPG event with the given event id
143 * @param epg The epg to lookup the event.
144 * @param iBroadcastId The event id to lookup.
145 * @return The requested event, or an empty tag when not found
147 std::shared_ptr
<CPVREpgInfoTag
> GetTagById(const std::shared_ptr
<const CPVREpg
>& epg
,
148 unsigned int iBroadcastId
) const;
151 * @brief Get the EPG event with the given database id
152 * @param iDatabaseId The id to lookup.
153 * @return The requested event, or an empty tag when not found
155 std::shared_ptr
<CPVREpgInfoTag
> GetTagByDatabaseId(int iDatabaseId
) const;
158 * @brief Get all EPG tags matching the given search criteria.
159 * @param searchData The search criteria.
160 * @return The matching tags.
162 std::vector
<std::shared_ptr
<CPVREpgInfoTag
>> GetTags(const PVREpgSearchData
& searchData
) const;
165 * @brief Notify EPG container that there are pending manual EPG updates
166 * @param bHasPendingUpdates The new value
168 void SetHasPendingUpdates(bool bHasPendingUpdates
= true);
171 * @brief A client triggered an epg update request for a channel
172 * @param iClientID The id of the client which triggered the update request
173 * @param iUniqueChannelID The uid of the channel for which the epg shall be updated
175 void UpdateRequest(int iClientID
, int iUniqueChannelID
);
178 * @brief A client announced an updated epg tag for a channel
179 * @param tag The epg tag containing the updated data
180 * @param eNewState The kind of change (CREATED, UPDATED, DELETED)
182 void UpdateFromClient(const std::shared_ptr
<CPVREpgInfoTag
>& tag
, EPG_EVENT_STATE eNewState
);
185 * @brief Get the number of past days to show in the guide and to import from backends.
186 * @return the number of past epg days.
188 int GetPastDaysToDisplay() const;
191 * @brief Get the number of future days to show in the guide and to import from backends.
192 * @return the number of future epg days.
194 int GetFutureDaysToDisplay() const;
197 * @brief Inform the epg container that playback of an item just started.
199 void OnPlaybackStarted();
202 * @brief Inform the epg container that playback of an item was stopped due to user interaction.
204 void OnPlaybackStopped();
207 * @brief Inform the epg container that the system is going to sleep
209 void OnSystemSleep();
212 * @brief Inform the epg container that the system gets awake from sleep
217 * @brief Erase stale texture db entries and image files.
218 * @return number of cleaned up images.
220 int CleanupCachedImages();
223 * @brief Get all saved searches from the database.
224 * @param bRadio Whether to fetch saved searches for radio or TV.
225 * @return The searches.
227 std::vector
<std::shared_ptr
<CPVREpgSearchFilter
>> GetSavedSearches(bool bRadio
);
230 * @brief Get the saved search matching the given id.
231 * @param bRadio Whether to fetch a TV or radio saved search.
233 * @return The saved search or nullptr if not found.
235 std::shared_ptr
<CPVREpgSearchFilter
> GetSavedSearchById(bool bRadio
, int iId
);
238 * @brief Persist a saved search in the database.
239 * @param search The saved search.
240 * @return True on success, false otherwise.
242 bool PersistSavedSearch(CPVREpgSearchFilter
& search
);
245 * @brief Update time last executed for the given search.
246 * @param epgSearch The search.
247 * @return True on success, false otherwise.
249 bool UpdateSavedSearchLastExecuted(const CPVREpgSearchFilter
& epgSearch
);
252 * @brief Delete a saved search from the database.
253 * @param search The saved search.
254 * @return True on success, false otherwise.
256 bool DeleteSavedSearch(const CPVREpgSearchFilter
& search
);
260 * @brief Notify EPG table observers when the currently active tag changed.
261 * @return True if the check was done, false if it was not the right time to check
263 bool CheckPlayingEvents();
266 * @brief The next EPG ID to be given to a table when the db isn't being used.
267 * @return The next ID.
272 * @brief Wait for an EPG update to finish.
274 void WaitForUpdateFinish();
277 * @brief Call Persist() on each table
278 * @param iMaxTimeslice time in milliseconds for max processing. Return after this time
279 * even if not all data was persisted, unless value is -1
280 * @return True when they all were persisted, false otherwise.
282 bool PersistAll(unsigned int iMaxTimeslice
) const;
285 * @brief Remove old EPG entries.
286 * @return True if the old entries were removed successfully, false otherwise.
288 bool RemoveOldEntries();
291 * @brief Load and update the EPG data.
292 * @param bOnlyPending Only check and update EPG tables with pending manual updates
293 * @return True if the update has not been interrupted, false otherwise.
295 bool UpdateEPG(bool bOnlyPending
= false);
298 * @brief Check whether a running update should be interrupted.
299 * @return True if a running update should be interrupted, false otherwise.
301 bool InterruptUpdate() const;
304 * @brief EPG update thread
306 void Process() override
;
309 * @brief Load all tables from the database
311 void LoadFromDatabase();
314 * @brief Insert data from database
315 * @param newEpg the EPG containing the updated data.
317 void InsertFromDB(const std::shared_ptr
<CPVREpg
>& newEpg
);
320 * @brief Queue the deletion of an EPG table from this container.
321 * @param epg The table to delete.
322 * @param database The database containing the epg data.
323 * @return True on success, false otherwise.
325 bool QueueDeleteEpg(const std::shared_ptr
<const CPVREpg
>& epg
,
326 const std::shared_ptr
<CPVREpgDatabase
>& database
);
328 std::shared_ptr
<CPVREpgDatabase
> m_database
; /*!< the EPG database */
330 bool m_bIsUpdating
= false; /*!< true while an update is running */
331 std::atomic
<bool> m_bIsInitialising
= {
332 true}; /*!< true while the epg manager hasn't loaded all tables */
333 bool m_bStarted
= false; /*!< true if EpgContainer has fully started */
334 bool m_bLoaded
= false; /*!< true after epg data is initially loaded from the database */
335 bool m_bPreventUpdates
= false; /*!< true to prevent EPG updates */
336 bool m_bPlaying
= false; /*!< true if Kodi is currently playing something */
337 int m_pendingUpdates
= 0; /*!< count of pending manual updates */
338 time_t m_iLastEpgCleanup
= 0; /*!< the time the EPG was cleaned up */
339 time_t m_iNextEpgUpdate
= 0; /*!< the time the EPG will be updated */
340 time_t m_iNextEpgActiveTagCheck
= 0; /*!< the time the EPG will be checked for active tag updates */
341 int m_iNextEpgId
= 0; /*!< the next epg ID that will be given to a new table when the db isn't being used */
343 std::map
<int, std::shared_ptr
<CPVREpg
>> m_epgIdToEpgMap
; /*!< the EPGs in this container. maps epg ids to epgs */
344 std::map
<std::pair
<int, int>, std::shared_ptr
<CPVREpg
>> m_channelUidToEpgMap
; /*!< the EPGs in this container. maps channel uids to epgs */
346 mutable CCriticalSection m_critSection
; /*!< a critical section for changes to this container */
347 CEvent m_updateEvent
; /*!< trigger when an update finishes */
349 std::list
<CEpgUpdateRequest
> m_updateRequests
; /*!< list of update requests triggered by addon */
350 CCriticalSection m_updateRequestsLock
; /*!< protect update requests */
352 std::list
<CEpgTagStateChange
> m_epgTagChanges
; /*!< list of updated epg tags announced by addon */
353 CCriticalSection m_epgTagChangesLock
; /*!< protect changed epg tags list */
355 bool m_bUpdateNotificationPending
= false; /*!< true while an epg updated notification to observers is pending. */
356 CPVRSettings m_settings
;
357 CEventSource
<PVREvent
>& m_events
;
359 std::atomic
<bool> m_bSuspended
= {false};