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_general.h" 12 #include "interfaces/IAnnouncer.h" 13 #include "pvr/epg/EpgContainer.h" 14 #include "pvr/guilib/PVRGUIActionListener.h" 15 #include "pvr/settings/PVRSettings.h" 16 #include "threads/CriticalSection.h" 17 #include "threads/Event.h" 18 #include "threads/Thread.h" 19 #include "utils/EventStream.h" 20 21 #include <memory> 22 #include <string> 23 #include <vector> 24 25 class CFileItem; 26 class CStopWatch; 27 28 namespace PVR 29 { 30 class CPVRChannel; 31 class CPVRChannelGroup; 32 class CPVRChannelGroupsContainer; 33 class CPVRClient; 34 class CPVRClients; 35 class CPVRDatabase; 36 class CPVRGUIActions; 37 class CPVRGUIInfo; 38 class CPVRGUIProgressHandler; 39 class CPVRManagerJobQueue; 40 class CPVRPlaybackState; 41 class CPVRRecording; 42 class CPVRRecordings; 43 class CPVRTimers; 44 45 enum class PVREvent 46 { 47 // PVR Manager states 48 ManagerError = 0, 49 ManagerStopped, 50 ManagerStarting, 51 ManagerStopping, 52 ManagerInterrupted, 53 ManagerStarted, 54 55 // Channel events 56 ChannelPlaybackStopped, 57 58 // Channel group events 59 ChannelGroup, 60 ChannelGroupInvalidated, 61 ChannelGroupsInvalidated, 62 ChannelGroupsLoaded, 63 64 // Recording events 65 RecordingsInvalidated, 66 67 // Timer events 68 AnnounceReminder, 69 Timers, 70 TimersInvalidated, 71 72 // EPG events 73 Epg, 74 EpgActiveItem, 75 EpgContainer, 76 EpgItemUpdate, 77 EpgUpdatePending, 78 EpgDeleted, 79 80 // Item events 81 CurrentItem, 82 83 // Syetem events 84 SystemSleep, 85 SystemWake, 86 }; 87 88 class CPVRManager : private CThread, public ANNOUNCEMENT::IAnnouncer 89 { 90 public: 91 /*! 92 * @brief Create a new CPVRManager instance, which handles all PVR related operations in XBMC. 93 */ 94 CPVRManager(); 95 96 /*! 97 * @brief Stop the PVRManager and destroy all objects it created. 98 */ 99 ~CPVRManager() override; 100 101 void Announce(ANNOUNCEMENT::AnnouncementFlag flag, 102 const std::string& sender, 103 const std::string& message, 104 const CVariant& data) override; 105 106 /*! 107 * @brief Get the channel groups container. 108 * @return The groups container. 109 */ 110 std::shared_ptr<CPVRChannelGroupsContainer> ChannelGroups() const; 111 112 /*! 113 * @brief Get the recordings container. 114 * @return The recordings container. 115 */ 116 std::shared_ptr<CPVRRecordings> Recordings() const; 117 118 /*! 119 * @brief Get the timers container. 120 * @return The timers container. 121 */ 122 std::shared_ptr<CPVRTimers> Timers() const; 123 124 /*! 125 * @brief Get the timers container. 126 * @return The timers container. 127 */ 128 std::shared_ptr<CPVRClients> Clients() const; 129 130 /*! 131 * @brief Get the instance of a client that matches the given item. 132 * @param item The item containing a PVR recording, a PVR channel, a PVR timer or a PVR EPG event. 133 * @return the requested client on success, nullptr otherwise. 134 */ 135 std::shared_ptr<CPVRClient> GetClient(const CFileItem& item) const; 136 137 /*! 138 * @brief Get the instance of a client that matches the given id. 139 * @param iClientId The id of a PVR client. 140 * @return the requested client on success, nullptr otherwise. 141 */ 142 std::shared_ptr<CPVRClient> GetClient(int iClientId) const; 143 144 /*! 145 * @brief Get access to the pvr gui actions. 146 * @return The gui actions. 147 */ 148 std::shared_ptr<CPVRGUIActions> GUIActions() const; 149 150 /*! 151 * @brief Get access to the pvr playback state. 152 * @return The playback state. 153 */ 154 std::shared_ptr<CPVRPlaybackState> PlaybackState() const; 155 156 /*! 157 * @brief Get access to the epg container. 158 * @return The epg container. 159 */ 160 CPVREpgContainer& EpgContainer(); 161 162 /*! 163 * @brief Init PVRManager. 164 */ 165 void Init(); 166 167 /*! 168 * @brief Start the PVRManager, which loads all PVR data and starts some threads to update the PVR data. 169 */ 170 void Start(); 171 172 /*! 173 * @brief Stop PVRManager. 174 */ 175 void Stop(bool bRestart = false); 176 177 /*! 178 * @brief Stop PVRManager, unload data. 179 */ 180 void Unload(); 181 182 /*! 183 * @brief Deinit PVRManager, unload data, unload addons. 184 */ 185 void Deinit(); 186 187 /*! 188 * @brief Propagate event on system sleep 189 */ 190 void OnSleep(); 191 192 /*! 193 * @brief Propagate event on system wake 194 */ 195 void OnWake(); 196 197 /*! 198 * @brief Get the TV database. 199 * @return The TV database. 200 */ 201 std::shared_ptr<CPVRDatabase> GetTVDatabase() const; 202 203 /*! 204 * @return True while the PVRManager is initialising. 205 */ IsInitialising()206 inline bool IsInitialising() const 207 { 208 return GetState() == ManagerStateStarting; 209 } 210 211 /*! 212 * @brief Check whether the PVRManager has fully started. 213 * @return True if started, false otherwise. 214 */ IsStarted()215 inline bool IsStarted() const 216 { 217 return GetState() == ManagerStateStarted; 218 } 219 220 /*! 221 * @brief Check whether the PVRManager is stopping 222 * @return True while the PVRManager is stopping. 223 */ IsStopping()224 inline bool IsStopping() const 225 { 226 return GetState() == ManagerStateStopping; 227 } 228 229 /*! 230 * @brief Check whether the PVRManager has been stopped. 231 * @return True if stopped, false otherwise. 232 */ IsStopped()233 inline bool IsStopped() const 234 { 235 return GetState() == ManagerStateStopped; 236 } 237 238 /*! 239 * @brief Check whether EPG tags for channels have been created. 240 * @return True if EPG tags have been created, false otherwise. 241 */ 242 bool EpgsCreated() const; 243 244 /*! 245 * @brief Inform PVR manager that playback of an item just started. 246 * @param item The item that started to play. 247 */ 248 void OnPlaybackStarted(const std::shared_ptr<CFileItem>& item); 249 250 /*! 251 * @brief Inform PVR manager that playback of an item was stopped due to user interaction. 252 * @param item The item that stopped to play. 253 */ 254 void OnPlaybackStopped(const std::shared_ptr<CFileItem>& item); 255 256 /*! 257 * @brief Inform PVR manager that playback of an item has stopped without user interaction. 258 * @param item The item that ended to play. 259 */ 260 void OnPlaybackEnded(const std::shared_ptr<CFileItem>& item); 261 262 /*! 263 * @brief Let the background thread create epg tags for all channels. 264 */ 265 void TriggerEpgsCreate(); 266 267 /*! 268 * @brief Let the background thread update the recordings list. 269 */ 270 void TriggerRecordingsUpdate(); 271 272 /*! 273 * @brief Let the background thread update the size for any in progress recordings. 274 */ 275 void TriggerRecordingsSizeInProgressUpdate(); 276 277 /*! 278 * @brief Let the background thread update the timer list. 279 */ 280 void TriggerTimersUpdate(); 281 282 /*! 283 * @brief Let the background thread update the channel list. 284 */ 285 void TriggerChannelsUpdate(); 286 287 /*! 288 * @brief Let the background thread update the channel groups list. 289 */ 290 void TriggerChannelGroupsUpdate(); 291 292 /*! 293 * @brief Let the background thread search for all missing channel icons. 294 */ 295 void TriggerSearchMissingChannelIcons(); 296 297 /*! 298 * @brief Let the background thread search for missing channel icons for channels contained in the given group. 299 * @param group The channel group. 300 */ 301 void TriggerSearchMissingChannelIcons(const std::shared_ptr<CPVRChannelGroup>& group); 302 303 /*! 304 * @brief Check whether names are still correct after the language settings changed. 305 */ 306 void LocalizationChanged(); 307 308 /*! 309 * @brief Check if parental lock is overridden at the given moment. 310 * @param channel The channel to check. 311 * @return True if parental lock is overridden, false otherwise. 312 */ 313 bool IsParentalLocked(const std::shared_ptr<CPVRChannel>& channel) const; 314 315 /*! 316 * @brief Check if parental lock is overridden at the given moment. 317 * @param epgTag The epg tag to check. 318 * @return True if parental lock is overridden, false otherwise. 319 */ 320 bool IsParentalLocked(const std::shared_ptr<CPVREpgInfoTag>& epgTag) const; 321 322 /*! 323 * @brief Restart the parental timer. 324 */ 325 void RestartParentalTimer(); 326 327 /*! 328 * @brief Create EPG tags for all channels in internal channel groups 329 * @return True if EPG tags where created successfully, false otherwise 330 */ 331 bool CreateChannelEpgs(); 332 333 /*! 334 * @brief Signal a connection change of a client 335 */ 336 void ConnectionStateChange(CPVRClient* client, 337 const std::string& connectString, 338 PVR_CONNECTION_STATE state, 339 const std::string& message); 340 341 /*! 342 * @brief Query the events available for CEventStream 343 */ Events()344 CEventStream<PVREvent>& Events() { return m_events; } 345 346 /*! 347 * @brief Publish an event 348 * @param state the event 349 */ 350 void PublishEvent(PVREvent state); 351 352 protected: 353 /*! 354 * @brief PVR update and control thread. 355 */ 356 void Process() override; 357 358 private: 359 /*! 360 * @brief Executes "pvrpowermanagement.setwakeupcmd" 361 */ 362 bool SetWakeupCommand(); 363 364 /*! 365 * @brief Load at least one client and load all other PVR data (channelgroups, timers, recordings) after loading the client. 366 * @param progressHandler The progress handler to use for showing the different load stages. 367 * @return If at least one client and all pvr data was loaded, false otherwise. 368 */ 369 bool LoadComponents(CPVRGUIProgressHandler* progressHandler); 370 371 /*! 372 * @brief Unload all PVR data (recordings, timers, channelgroups). 373 */ 374 void UnloadComponents(); 375 376 /*! 377 * @brief Reset all properties. 378 */ 379 void ResetProperties(); 380 381 /*! 382 * @brief Destroy PVRManager's objects. 383 */ 384 void Clear(); 385 386 /*! 387 * @brief Continue playback on the last played channel. 388 */ 389 void TriggerPlayChannelOnStartup(); 390 391 enum ManagerState 392 { 393 ManagerStateError = 0, 394 ManagerStateStopped, 395 ManagerStateStarting, 396 ManagerStateStopping, 397 ManagerStateInterrupted, 398 ManagerStateStarted 399 }; 400 401 /*! 402 * @brief Get the current state of the PVR manager. 403 * @return the state. 404 */ 405 ManagerState GetState() const; 406 407 /*! 408 * @brief Set the current state of the PVR manager. 409 * @param state the new state. 410 */ 411 void SetState(ManagerState state); 412 413 bool IsCurrentlyParentalLocked(const std::shared_ptr<CPVRChannel>& channel, bool bGenerallyLocked) const; 414 415 /** @name containers */ 416 //@{ 417 std::shared_ptr<CPVRChannelGroupsContainer> m_channelGroups; /*!< pointer to the channel groups container */ 418 std::shared_ptr<CPVRRecordings> m_recordings; /*!< pointer to the recordings container */ 419 std::shared_ptr<CPVRTimers> m_timers; /*!< pointer to the timers container */ 420 std::shared_ptr<CPVRClients> m_addons; /*!< pointer to the pvr addon container */ 421 std::unique_ptr<CPVRGUIInfo> m_guiInfo; /*!< pointer to the guiinfo data */ 422 std::shared_ptr<CPVRGUIActions> m_guiActions; /*!< pointer to the pvr gui actions */ 423 CPVREpgContainer m_epgContainer; /*!< the epg container */ 424 //@} 425 426 std::unique_ptr<CPVRManagerJobQueue> m_pendingUpdates; /*!< vector of pending pvr updates */ 427 std::shared_ptr<CPVRDatabase> m_database; /*!< the database for all PVR related data */ 428 mutable CCriticalSection m_critSection; /*!< critical section for all changes to this class, except for changes to triggers */ 429 bool m_bFirstStart = true; /*!< true when the PVR manager was started first, false otherwise */ 430 bool m_bEpgsCreated = false; /*!< true if epg data for channels has been created */ 431 432 mutable CCriticalSection m_managerStateMutex; 433 ManagerState m_managerState = ManagerStateStopped; 434 std::unique_ptr<CStopWatch> m_parentalTimer; 435 436 CCriticalSection m_startStopMutex; // mutex for protecting pvr manager's start/restart/stop sequence */ 437 438 CEventSource<PVREvent> m_events; 439 440 const std::shared_ptr<CPVRPlaybackState> m_playbackState; 441 442 CPVRGUIActionListener m_actionListener; 443 CPVRSettings m_settings; 444 }; 445 } 446