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 "XBDateTime.h" 12 #include "pvr/settings/PVRSettings.h" 13 #include "threads/Thread.h" 14 15 #include <map> 16 #include <memory> 17 #include <queue> 18 #include <vector> 19 20 namespace PVR 21 { 22 enum class TimerOperationResult; 23 enum class PVREvent; 24 25 class CPVRChannel; 26 class CPVREpgInfoTag; 27 class CPVRTimerInfoTag; 28 class CPVRTimersPath; 29 30 class CPVRTimersContainer 31 { 32 public: 33 /*! 34 * @brief Add a timer tag to this container or update the tag if already present in this container. 35 * @param The timer tag 36 * @return True, if the update was successful. False, otherwise. 37 */ 38 bool UpdateFromClient(const std::shared_ptr<CPVRTimerInfoTag>& timer); 39 40 /*! 41 * @brief Get the timer tag denoted by given client id and timer id. 42 * @param iClientId The client id. 43 * @param iClientIndex The timer id. 44 * @return the timer tag if found, null otherwise. 45 */ 46 std::shared_ptr<CPVRTimerInfoTag> GetByClient(int iClientId, int iClientIndex) const; 47 48 typedef std::vector<std::shared_ptr<CPVRTimerInfoTag>> VecTimerInfoTag; 49 typedef std::map<CDateTime, VecTimerInfoTag> MapTags; 50 51 /*! 52 * @brief Get the timertags map. 53 * @return The map. 54 */ GetTags()55 const MapTags& GetTags() const { return m_tags; } 56 57 protected: 58 void InsertEntry(const std::shared_ptr<CPVRTimerInfoTag>& newTimer); 59 60 mutable CCriticalSection m_critSection; 61 unsigned int m_iLastId = 0; 62 MapTags m_tags; 63 }; 64 65 class CPVRTimers : public CPVRTimersContainer, private CThread 66 { 67 public: 68 CPVRTimers(); 69 ~CPVRTimers() override = default; 70 71 /** 72 * @brief start the timer update thread. 73 */ 74 void Start(); 75 76 /** 77 * @brief stop the timer update thread. 78 */ 79 void Stop(); 80 81 /** 82 * @brief (re)load the timers from the clients. 83 * @return True if loaded successfully, false otherwise. 84 */ 85 bool Load(); 86 87 /** 88 * @brief unload all timers. 89 */ 90 void Unload(); 91 92 /** 93 * @brief refresh the timer list from the clients. 94 */ 95 bool Update(); 96 97 /** 98 * @brief load the local timers from database. 99 * @return True if loaded successfully, false otherwise. 100 */ 101 bool LoadFromDatabase(); 102 103 /*! 104 * @param bIgnoreReminders include or ignore reminders 105 * @return The tv or radio timer that will be active next (state scheduled), or an empty fileitemptr if none. 106 */ 107 std::shared_ptr<CPVRTimerInfoTag> GetNextActiveTimer(bool bIgnoreReminders = true) const; 108 109 /*! 110 * @return The tv timer that will be active next (state scheduled), or nullptr if none. 111 */ 112 std::shared_ptr<CPVRTimerInfoTag> GetNextActiveTVTimer() const; 113 114 /*! 115 * @return The radio timer that will be active next (state scheduled), or nullptr if none. 116 */ 117 std::shared_ptr<CPVRTimerInfoTag> GetNextActiveRadioTimer() const; 118 119 /*! 120 * @return All timers that are active (states scheduled or recording) 121 */ 122 std::vector<std::shared_ptr<CPVRTimerInfoTag>> GetActiveTimers() const; 123 124 /*! 125 * @return Next due reminder, if any. Removes it from the queue of due reminders. 126 */ 127 std::shared_ptr<CPVRTimerInfoTag> GetNextReminderToAnnnounce(); 128 129 /*! 130 * Get all timers 131 * @return The list of all timers 132 */ 133 std::vector<std::shared_ptr<CPVRTimerInfoTag>> GetAll() const; 134 135 /*! 136 * @return The amount of tv and radio timers that are active (states scheduled or recording) 137 */ 138 int AmountActiveTimers() const; 139 140 /*! 141 * @return The amount of tv timers that are active (states scheduled or recording) 142 */ 143 int AmountActiveTVTimers() const; 144 145 /*! 146 * @return The amount of radio timers that are active (states scheduled or recording) 147 */ 148 int AmountActiveRadioTimers() const; 149 150 /*! 151 * @return All tv and radio timers that are recording 152 */ 153 std::vector<std::shared_ptr<CPVRTimerInfoTag>> GetActiveRecordings() const; 154 155 /*! 156 * @return All tv timers that are recording 157 */ 158 std::vector<std::shared_ptr<CPVRTimerInfoTag>> GetActiveTVRecordings() const; 159 160 /*! 161 * @return All radio timers that are recording 162 */ 163 std::vector<std::shared_ptr<CPVRTimerInfoTag>> GetActiveRadioRecordings() const; 164 165 /*! 166 * @return True when recording, false otherwise. 167 */ 168 bool IsRecording() const; 169 170 /*! 171 * @brief Check if a recording is running on the given channel. 172 * @param channel The channel to check. 173 * @return True when recording, false otherwise. 174 */ 175 bool IsRecordingOnChannel(const CPVRChannel& channel) const; 176 177 /*! 178 * @brief Obtain the active timer for a given channel. 179 * @param channel The channel to check. 180 * @return the timer, null otherwise. 181 */ 182 std::shared_ptr<CPVRTimerInfoTag> GetActiveTimerForChannel(const std::shared_ptr<CPVRChannel>& channel) const; 183 184 /*! 185 * @return The amount of tv and radio timers that are currently recording 186 */ 187 int AmountActiveRecordings() const; 188 189 /*! 190 * @return The amount of tv timers that are currently recording 191 */ 192 int AmountActiveTVRecordings() const; 193 194 /*! 195 * @return The amount of radio timers that are currently recording 196 */ 197 int AmountActiveRadioRecordings() const; 198 199 /*! 200 * @brief Delete all timers on a channel. 201 * @param channel The channel to delete the timers for. 202 * @param bDeleteTimerRules True to delete timer rules too, false otherwise. 203 * @param bCurrentlyActiveOnly True to delete timers that are currently running only. 204 * @return True if timers any were deleted, false otherwise. 205 */ 206 bool DeleteTimersOnChannel(const std::shared_ptr<CPVRChannel>& channel, bool bDeleteTimerRules = true, bool bCurrentlyActiveOnly = false); 207 208 /*! 209 * @return Next event time (timer or daily wake up) 210 */ 211 CDateTime GetNextEventTime() const; 212 213 /*! 214 * @brief Add a timer to the client. Doesn't add the timer to the container. The backend will do this. 215 * @param tag The timer to add. 216 * @return True if timer add request was sent correctly, false if not. 217 */ 218 bool AddTimer(const std::shared_ptr<CPVRTimerInfoTag>& tag); 219 220 /*! 221 * @brief Delete a timer on the client. Doesn't delete the timer from the container. The backend will do this. 222 * @param tag The timer to delete. 223 * @param bForce Control what to do in case the timer is currently recording. 224 * True to force to delete the timer, false to return TimerDeleteResult::RECORDING. 225 * @param bDeleteRule Also delete the timer rule that scheduled the timer instead of single timer only. 226 * @return The result. 227 */ 228 TimerOperationResult DeleteTimer(const std::shared_ptr<CPVRTimerInfoTag>& tag, bool bForce = false, bool bDeleteRule = false); 229 230 /*! 231 * @brief Update the timer on the client. Doesn't update the timer in the container. The backend will do this. 232 * @param tag The timer to update. 233 * @return True if timer update request was sent correctly, false if not. 234 */ 235 bool UpdateTimer(const std::shared_ptr<CPVRTimerInfoTag>& tag); 236 237 /*! 238 * @brief Get the timer tag that matches the given epg tag. 239 * @param epgTag The epg tag. 240 * @return The requested timer tag, or nullptr if none was found. 241 */ 242 std::shared_ptr<CPVRTimerInfoTag> GetTimerForEpgTag(const std::shared_ptr<CPVREpgInfoTag>& epgTag) const; 243 244 /*! 245 * @brief Get the timer rule for a given timer tag 246 * @param timer The timer to query the timer rule for 247 * @return The timer rule, or nullptr if none was found. 248 */ 249 std::shared_ptr<CPVRTimerInfoTag> GetTimerRule(const std::shared_ptr<CPVRTimerInfoTag>& timer) const; 250 251 /*! 252 * @brief Update the channel pointers. 253 */ 254 void UpdateChannels(); 255 256 /*! 257 * @brief CEventStream callback for PVR events. 258 * @param event The event. 259 */ 260 void Notify(const PVREvent& event); 261 262 /*! 263 * @brief Get a timer tag given it's unique ID 264 * @param iTimerId The ID to find 265 * @return The tag, or an empty one when not found 266 */ 267 std::shared_ptr<CPVRTimerInfoTag> GetById(unsigned int iTimerId) const; 268 269 private: 270 void Process() override; 271 272 void RemoveEntry(const std::shared_ptr<CPVRTimerInfoTag>& tag); 273 bool UpdateEntries(const CPVRTimersContainer& timers, const std::vector<int>& failedClients); 274 bool UpdateEntries(int iMaxNotificationDelay); 275 std::shared_ptr<CPVRTimerInfoTag> UpdateEntry(const std::shared_ptr<CPVRTimerInfoTag>& timer); 276 277 bool AddLocalTimer(const std::shared_ptr<CPVRTimerInfoTag>& tag, bool bNotify); 278 bool DeleteLocalTimer(const std::shared_ptr<CPVRTimerInfoTag>& tag, bool bNotify); 279 bool UpdateLocalTimer(const std::shared_ptr<CPVRTimerInfoTag>& tag); 280 std::shared_ptr<CPVRTimerInfoTag> PersistAndUpdateLocalTimer(const std::shared_ptr<CPVRTimerInfoTag>& timer, 281 const std::shared_ptr<CPVRTimerInfoTag>& parentTimer); 282 void NotifyTimersEvent(bool bAddedOrDeleted = true); 283 284 enum TimerKind 285 { 286 TimerKindAny = 0, 287 TimerKindTV, 288 TimerKindRadio 289 }; 290 291 bool KindMatchesTag(const TimerKind& eKind, const std::shared_ptr<CPVRTimerInfoTag>& tag) const; 292 293 std::shared_ptr<CPVRTimerInfoTag> GetNextActiveTimer(const TimerKind& eKind, bool bIgnoreReminders) const; 294 int AmountActiveTimers(const TimerKind& eKind) const; 295 std::vector<std::shared_ptr<CPVRTimerInfoTag>> GetActiveRecordings(const TimerKind& eKind) const; 296 int AmountActiveRecordings(const TimerKind& eKind) const; 297 298 bool CheckAndAppendTimerNotification( 299 std::vector<std::pair<int, std::string>>& timerNotifications, 300 const std::shared_ptr<CPVRTimerInfoTag>& tag, 301 bool bDeleted) const; 302 303 bool m_bIsUpdating = false; 304 CPVRSettings m_settings; 305 std::queue<std::shared_ptr<CPVRTimerInfoTag>> m_remindersToAnnounce; 306 bool m_bReminderRulesUpdatePending = false; 307 308 bool m_bFirstUpdate = true; 309 std::vector<int> m_failedClients; 310 }; 311 } 312