1 /*
2  *  Copyright (C) 2012-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_channels.h"
12 #include "pvr/channels/PVRChannelNumber.h"
13 #include "threads/CriticalSection.h"
14 #include "utils/ISerializable.h"
15 #include "utils/ISortable.h"
16 
17 #include <memory>
18 #include <string>
19 #include <utility>
20 #include <vector>
21 
22 class CDateTime;
23 
24 namespace PVR
25 {
26   enum class PVREvent;
27 
28   class CPVREpg;
29   class CPVREpgInfoTag;
30   class CPVRRadioRDSInfoTag;
31 
32   class CPVRChannel : public ISerializable, public ISortable
33   {
34     friend class CPVRDatabase;
35 
36   public:
37     explicit CPVRChannel(bool bRadio);
38     CPVRChannel(const PVR_CHANNEL& channel, unsigned int iClientId);
39 
40     virtual ~CPVRChannel();
41 
42     bool operator ==(const CPVRChannel& right) const;
43     bool operator !=(const CPVRChannel& right) const;
44 
45     void Serialize(CVariant& value) const override;
46 
47     /*! @name XBMC related channel methods
48      */
49     //@{
50 
51     /*!
52      * @brief Delete this channel from the database and delete the corresponding EPG table if it exists.
53      * @return True if it was deleted successfully, false otherwise.
54      */
55     bool QueueDelete();
56 
57     /*!
58      * @brief Update this channel tag with the data of the given channel tag.
59      * @param channel The new channel data.
60      * @return True if something changed, false otherwise.
61      */
62     bool UpdateFromClient(const std::shared_ptr<CPVRChannel>& channel);
63 
64     /*!
65      * @brief Persists the changes in the database.
66      * @return True if the changes were saved successfully, false otherwise.
67      */
68     bool Persist();
69 
70     /*!
71      * @return The identifier given to this channel by the TV database.
72      */
73     int ChannelID() const;
74 
75     /*!
76      * @return True when not persisted yet, false otherwise.
77      */
78     bool IsNew() const;
79 
80     /*!
81      * @brief Set the identifier for this channel.
82      * @param iDatabaseId The new channel ID
83      * @return True if the something changed, false otherwise.
84      */
85     bool SetChannelID(int iDatabaseId);
86 
87     /*!
88      * @brief Set the channel number for this channel.
89      * @param channelNumber The new channel number
90      */
91     void SetChannelNumber(const CPVRChannelNumber& channelNumber);
92 
93     /*!
94      * @brief Set the client channel number for this channel.
95      * @param clientChannelNumber The new client channel number
96      */
97     void SetClientChannelNumber(const CPVRChannelNumber& clientChannelNumber);
98 
99     /*!
100      * @brief Get the channel number for this channel.
101      * @return The channel number.
102      */
103     const CPVRChannelNumber& ChannelNumber() const;
104 
105     /*!
106      * @return True if this channel is a radio channel, false if not.
107      */
IsRadio()108     bool IsRadio() const { return m_bIsRadio; }
109 
110     /*!
111      * @return True if this channel is hidden. False if not.
112      */
113     bool IsHidden() const;
114 
115     /*!
116      * @brief Set to true to hide this channel. Set to false to unhide it.
117      *
118      * Set to true to hide this channel. Set to false to unhide it.
119      * The EPG of hidden channels won't be updated.
120      * @param bIsHidden The new setting.
121      * @return True if the something changed, false otherwise.
122      */
123     bool SetHidden(bool bIsHidden);
124 
125     /*!
126      * @return True if this channel is locked. False if not.
127      */
128     bool IsLocked() const;
129 
130     /*!
131      * @brief Set to true to lock this channel. Set to false to unlock it.
132      *
133      * Set to true to lock this channel. Set to false to unlock it.
134      * Locked channels need can only be viewed if parental PIN entered.
135      * @param bIsLocked The new setting.
136      * @return True if the something changed, false otherwise.
137      */
138     bool SetLocked(bool bIsLocked);
139 
140     /*!
141      * @brief Obtain the Radio RDS data for this channel, if available.
142      * @return The Radio RDS data or nullptr.
143      */
144     std::shared_ptr<CPVRRadioRDSInfoTag> GetRadioRDSInfoTag() const;
145 
146     /*!
147      * @brief Set the Radio RDS data for the channel.
148      * @param tag The RDS data.
149      */
150     void SetRadioRDSInfoTag(const std::shared_ptr<CPVRRadioRDSInfoTag>& tag);
151 
152     /*!
153      * @return True if this channel has archive support, false otherwise
154      */
155     bool HasArchive() const;
156 
157     /*!
158      * @return The path to the icon for this channel.
159      */
160     std::string IconPath() const;
161 
162     /*!
163      * @return True if this user changed icon via GUI. False if not.
164      */
165     bool IsUserSetIcon() const;
166 
167     /*!
168      * @return whether the user has changed the channel name through the GUI
169      */
170     bool IsUserSetName() const;
171 
172     /*!
173      * @brief Set the path to the icon for this channel.
174      * @param strIconPath The new path.
175      * @param bIsUserSetIcon true if user changed the icon via GUI, false otherwise.
176      * @return True if the something changed, false otherwise.
177      */
178     bool SetIconPath(const std::string& strIconPath, bool bIsUserSetIcon = false);
179 
180     /*!
181      * @return The name for this channel used by XBMC.
182      */
183     std::string ChannelName() const;
184 
185     /*!
186      * @brief Set the name for this channel used by XBMC.
187      * @param strChannelName The new channel name.
188      * @param bIsUserSetName whether the change was triggered by the user directly
189      * @return True if the something changed, false otherwise.
190      */
191     bool SetChannelName(const std::string& strChannelName, bool bIsUserSetName = false);
192 
193     /*!
194      * @return Time channel has been watched last.
195      */
196     time_t LastWatched() const;
197 
198     /*!
199      * @brief Last time channel has been watched
200      * @param iLastWatched The new value.
201      * @return True if the something changed, false otherwise.
202      */
203     bool SetLastWatched(time_t iLastWatched);
204 
205     /*!
206      * @brief True if this channel has no file or stream name
207      * @return True if this channel has no file or stream name
208      */
209     bool IsEmpty() const;
210 
211     bool IsChanged() const;
212 
213     /*!
214      * @brief reset changed flag after persist
215      */
216     void Persisted();
217     //@}
218 
219     /*! @name Client related channel methods
220      */
221     //@{
222 
223     /*!
224      * @brief A unique identifier for this channel.
225      *
226      * A unique identifier for this channel.
227      * It can be used to find the same channel on different providers
228      *
229      * @return The Unique ID.
230      */
231     int UniqueID() const;
232 
233     /*!
234      * @return The identifier of the client that serves this channel.
235      */
236     int ClientID() const;
237 
238     /*!
239      * @brief Set the identifier of the client that serves this channel.
240      * @param iClientId The new ID.
241      * @return True if the something changed, false otherwise.
242      */
243     bool SetClientID(int iClientId);
244 
245     /*!
246      * Get the channel number on the client.
247      * @return The channel number on the client.
248      */
249     const CPVRChannelNumber& ClientChannelNumber() const;
250 
251     /*!
252      * @return The name of this channel on the client.
253      */
254     std::string ClientChannelName() const;
255 
256     /*!
257      * @brief The stream input mime type
258      *
259      * The stream input type
260      * If it is empty, ffmpeg will try to scan the stream to find the right input format.
261      * See https://www.iana.org/assignments/media-types/media-types.xhtml for a
262      * list of the input formats.
263      *
264      * @return The stream input type
265      */
266     std::string MimeType() const;
267 
268     /*!
269      * @brief The path in the XBMC VFS to be used by PVRManager to open and read the stream.
270      * @return The path in the XBMC VFS to be used by PVRManager to open and read the stream.
271      */
272     std::string Path() const;
273 
274     // ISortable implementation
275     void ToSortable(SortItem& sortable, Field field) const override;
276 
277     /*!
278      * @brief Update the channel path
279      * @param channelGroup The (new) name of the group this channel belongs to
280      */
281     void UpdatePath(const std::string& channelGroup);
282 
283     /*!
284      * @return Storage id for this channel in CPVRChannelGroup
285      */
StorageId()286     std::pair<int, int> StorageId() const { return std::make_pair(m_iClientId, m_iUniqueId); }
287 
288     /*!
289      * @brief Return true if this channel is encrypted.
290      *
291      * Return true if this channel is encrypted. Does not inform whether XBMC can play the file.
292      * Decryption should be done by the client.
293      *
294      * @return Return true if this channel is encrypted.
295      */
296     bool IsEncrypted() const;
297 
298     /*!
299      * @brief Return the encryption system ID for this channel. 0 for FTA.
300      *
301      * Return the encryption system ID for this channel. 0 for FTA.
302      * The values are documented on: http://www.dvb.org/index.php?id=174.
303      *
304      * @return Return the encryption system ID for this channel.
305      */
306     int EncryptionSystem() const;
307 
308     /*!
309      * @return A friendly name for the used encryption system.
310      */
311     std::string EncryptionName() const;
312     //@}
313 
314     /*! @name EPG methods
315      */
316     //@{
317 
318     /*!
319      * @return The ID of the EPG table to use for this channel or -1 if it isn't set.
320      */
321     int EpgID() const;
322 
323     /*!
324      * @brief Create the EPG for this channel, if it does not yet exist
325      * @return true if a new epg was created, false otherwise.
326      */
327     bool CreateEPG();
328 
329     /*!
330      * @brief Get the EPG table for this channel.
331      * @return The EPG for this channel.
332      */
333     std::shared_ptr<CPVREpg> GetEPG() const;
334 
335     /*!
336      * @brief Get the EPG tags for this channel.
337      * @return The tags.
338      */
339     std::vector<std::shared_ptr<CPVREpgInfoTag>> GetEpgTags() const;
340 
341     /*!
342      * @brief Get all EPG tags for the given time frame, including "gap" tags.
343      * @param timelineStart Start of time line.
344      * @param timelineEnd End of time line.
345      * @param minEventEnd The minimum end time of the events to return.
346      * @param maxEventStart The maximum start time of the events to return.
347      * @return The matching tags.
348      */
349     std::vector<std::shared_ptr<CPVREpgInfoTag>> GetEPGTimeline(
350         const CDateTime& timelineStart,
351         const CDateTime& timelineEnd,
352         const CDateTime& minEventEnd,
353         const CDateTime& maxEventStart) const;
354 
355     /*!
356      * @brief Create a "gap" EPG tag.
357      * @param start Start of gap.
358      * @param end End of gap.
359      * @return The tag.
360      */
361     std::shared_ptr<CPVREpgInfoTag> CreateEPGGapTag(const CDateTime& start,
362                                                     const CDateTime& end) const;
363 
364     /*!
365      * @brief Clear the EPG for this channel.
366      * @return True if it was cleared, false if not.
367      */
368     bool ClearEPG() const;
369 
370     /*!
371      * @brief Get the EPG tag that is now active on this channel.
372      *
373      * Get the EPG tag that is now active on this channel.
374      * Will return an empty tag if there is none.
375      *
376      * @return The EPG tag that is now active.
377      */
378     std::shared_ptr<CPVREpgInfoTag> GetEPGNow() const;
379 
380     /*!
381      * @brief Get the EPG tag that was previously active on this channel.
382      *
383      * Get the EPG tag that was previously active on this channel.
384      * Will return an empty tag if there is none.
385      *
386      * @return The EPG tag that was previously activ.
387      */
388     std::shared_ptr<CPVREpgInfoTag> GetEPGPrevious() const;
389 
390     /*!
391      * @brief Get the EPG tag that will be next active on this channel.
392      *
393      * Get the EPG tag that will be next active on this channel.
394      * Will return an empty tag if there is none.
395      *
396      * @return The EPG tag that will be next active.
397      */
398     std::shared_ptr<CPVREpgInfoTag> GetEPGNext() const;
399 
400     /*!
401      * @return Don't use an EPG for this channel if set to false.
402      */
403     bool EPGEnabled() const;
404 
405     /*!
406      * @brief Set to true if an EPG should be used for this channel. Set to false otherwise.
407      * @param bEPGEnabled The new value.
408      * @return True if the something changed, false otherwise.
409      */
410     bool SetEPGEnabled(bool bEPGEnabled);
411 
412     /*!
413      * @brief Get the name of the scraper to be used for this channel.
414      *
415      * Get the name of the scraper to be used for this channel.
416      * The default is 'client', which means the EPG should be loaded from the backend.
417      *
418      * @return The name of the scraper to be used for this channel.
419      */
420     std::string EPGScraper() const;
421 
422     /*!
423      * @brief Set the name of the scraper to be used for this channel.
424      *
425      * Set the name of the scraper to be used for this channel.
426      * Set to "client" to load the EPG from the backend
427      *
428      * @param strScraper The new scraper name.
429      * @return True if the something changed, false otherwise.
430      */
431     bool SetEPGScraper(const std::string& strScraper);
432 
433     bool CanRecord() const;
434 
435     static std::string GetEncryptionName(int iCaid);
436 
437     /*!
438      * @brief Get the client order for this channel
439      * @return iOrder The order for this channel
440      */
ClientOrder()441     int ClientOrder() const { return m_iOrder; }
442 
443     /*!
444      * @brief Change the client order for this channel
445      * @param iOrder The new order for this channel
446      */
447     void SetClientOrder(int iOrder);
448 
449     /*!
450      * @brief CEventStream callback for PVR events.
451      * @param event The event.
452      */
453     void Notify(const PVREvent& event);
454 
455     /*!
456      * @brief Lock the instance. No other thread gets access to this channel until Unlock was called.
457      */
Lock()458     void Lock() { m_critSection.lock(); }
459 
460     /*!
461      * @brief Unlock the instance. Other threads may get access to this channel again.
462      */
Unlock()463     void Unlock() { m_critSection.unlock(); }
464 
465     //@}
466   private:
467     CPVRChannel();
468     CPVRChannel(const CPVRChannel& tag) = delete;
469     CPVRChannel& operator=(const CPVRChannel& channel) = delete;
470 
471     /*!
472      * @brief Update the encryption name after SetEncryptionSystem() has been called.
473      */
474     void UpdateEncryptionName();
475 
476     /*!
477      * @brief Reset the EPG instance pointer.
478      */
479     void ResetEPG();
480 
481     /*! @name XBMC related channel data
482      */
483     //@{
484     int m_iChannelId = -1; /*!< the identifier given to this channel by the TV database */
485     bool m_bIsRadio = false; /*!< true if this channel is a radio channel, false if not */
486     bool m_bIsHidden = false; /*!< true if this channel is hidden, false if not */
487     bool m_bIsUserSetName = false; /*!< true if user set the channel name via GUI, false if not */
488     bool m_bIsUserSetIcon = false; /*!< true if user set the icon via GUI, false if not */
489     bool m_bIsLocked = false; /*!< true if channel is locked, false if not */
490     std::string m_strIconPath; /*!< the path to the icon for this channel */
491     std::string m_strChannelName; /*!< the name for this channel used by XBMC */
492     time_t m_iLastWatched = 0; /*!< last time channel has been watched */
493     bool m_bChanged = false; /*!< true if anything in this entry was changed that needs to be persisted */
494     CPVRChannelNumber m_channelNumber; /*!< the active channel number this channel has in the currently selected channel group */
495     std::shared_ptr<CPVRRadioRDSInfoTag> m_rdsTag; /*! < the radio rds data, if available for the channel. */
496     bool m_bHasArchive = false; /*!< true if this channel supports archive */
497     //@}
498 
499     /*! @name EPG related channel data
500      */
501     //@{
502     int m_iEpgId = -1; /*!< the id of the EPG for this channel */
503     bool m_bEPGEnabled = false; /*!< don't use an EPG for this channel if set to false */
504     std::string m_strEPGScraper = "client"; /*!< the name of the scraper to be used for this channel */
505     std::shared_ptr<CPVREpg> m_epg;
506     //@}
507 
508     /*! @name Client related channel data
509      */
510     //@{
511     int m_iUniqueId = -1; /*!< the unique identifier for this channel */
512     int m_iClientId = -1; /*!< the identifier of the client that serves this channel */
513     CPVRChannelNumber m_clientChannelNumber; /*!< the channel number on the client for the currently selected channel group */
514     std::string m_strClientChannelName; /*!< the name of this channel on the client */
515     std::string
516         m_strMimeType; /*!< the stream input type based mime type, see @ref https://www.iana.org/assignments/media-types/media-types.xhtml#video */
517     std::string m_strFileNameAndPath; /*!< the filename to be used by PVRManager to open and read the stream */
518     int m_iClientEncryptionSystem = -1; /*!< the encryption system used by this channel. 0 for FreeToAir, -1 for unknown */
519     std::string m_strClientEncryptionName; /*!< the name of the encryption system used by this channel */
520     int m_iOrder = 0; /*!< the order from this channels currently selected group memeber */
521     //@}
522 
523     mutable CCriticalSection m_critSection;
524   };
525 }
526