[Windows] Fix driver version detection of AMD RDNA+ GPU on Windows 10
[xbmc.git] / xbmc / pvr / filesystem / PVRGUIDirectory.cpp
blob2b154283472affd667c31c23382ac24fc87c21af
1 /*
2 * Copyright (C) 2012-2019 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.
7 */
9 #include "PVRGUIDirectory.h"
11 #include "FileItem.h"
12 #include "FileItemList.h"
13 #include "ServiceBroker.h"
14 #include "guilib/LocalizeStrings.h"
15 #include "guilib/WindowIDs.h"
16 #include "input/WindowTranslator.h"
17 #include "pvr/PVRManager.h"
18 #include "pvr/addons/PVRClients.h"
19 #include "pvr/channels/PVRChannel.h"
20 #include "pvr/channels/PVRChannelGroupMember.h"
21 #include "pvr/channels/PVRChannelGroups.h"
22 #include "pvr/channels/PVRChannelGroupsContainer.h"
23 #include "pvr/channels/PVRChannelsPath.h"
24 #include "pvr/epg/EpgContainer.h"
25 #include "pvr/epg/EpgSearchFilter.h"
26 #include "pvr/epg/EpgSearchPath.h"
27 #include "pvr/recordings/PVRRecording.h"
28 #include "pvr/recordings/PVRRecordings.h"
29 #include "pvr/recordings/PVRRecordingsPath.h"
30 #include "pvr/timers/PVRTimerInfoTag.h"
31 #include "pvr/timers/PVRTimers.h"
32 #include "pvr/timers/PVRTimersPath.h"
33 #include "settings/Settings.h"
34 #include "settings/SettingsComponent.h"
35 #include "utils/StringUtils.h"
36 #include "utils/URIUtils.h"
37 #include "utils/log.h"
39 #include <memory>
40 #include <set>
41 #include <string>
42 #include <vector>
44 using namespace PVR;
46 bool CPVRGUIDirectory::Exists() const
48 if (!CServiceBroker::GetPVRManager().IsStarted())
49 return false;
51 return m_url.IsProtocol("pvr") && StringUtils::StartsWith(m_url.GetFileName(), "recordings");
54 bool CPVRGUIDirectory::SupportsWriteFileOperations() const
56 if (!CServiceBroker::GetPVRManager().IsStarted())
57 return false;
59 const std::string filename = m_url.GetFileName();
60 return URIUtils::IsPVRRecording(filename);
63 namespace
66 bool GetRootDirectory(bool bRadio, CFileItemList& results)
68 std::shared_ptr<CFileItem> item;
70 const std::shared_ptr<const CPVRClients> clients = CServiceBroker::GetPVRManager().Clients();
72 // EPG
73 const bool bAnyClientSupportingEPG = clients->AnyClientSupportingEPG();
74 if (bAnyClientSupportingEPG)
76 item = std::make_shared<CFileItem>(
77 StringUtils::Format("pvr://guide/{}/", bRadio ? "radio" : "tv"), true);
78 item->SetLabel(g_localizeStrings.Get(19069)); // Guide
79 item->SetProperty("node.target", CWindowTranslator::TranslateWindow(bRadio ? WINDOW_RADIO_GUIDE
80 : WINDOW_TV_GUIDE));
81 item->SetArt("icon", "DefaultPVRGuide.png");
82 results.Add(item);
85 // Channels
86 item = std::make_shared<CFileItem>(
87 bRadio ? CPVRChannelsPath::PATH_RADIO_CHANNELS : CPVRChannelsPath::PATH_TV_CHANNELS, true);
88 item->SetLabel(g_localizeStrings.Get(19019)); // Channels
89 item->SetProperty("node.target", CWindowTranslator::TranslateWindow(bRadio ? WINDOW_RADIO_CHANNELS
90 : WINDOW_TV_CHANNELS));
91 item->SetArt("icon", "DefaultPVRChannels.png");
92 results.Add(item);
94 // Recordings
95 if (clients->AnyClientSupportingRecordings())
97 item = std::make_shared<CFileItem>(bRadio ? CPVRRecordingsPath::PATH_ACTIVE_RADIO_RECORDINGS
98 : CPVRRecordingsPath::PATH_ACTIVE_TV_RECORDINGS,
99 true);
100 item->SetLabel(g_localizeStrings.Get(19017)); // Recordings
101 item->SetProperty("node.target", CWindowTranslator::TranslateWindow(
102 bRadio ? WINDOW_RADIO_RECORDINGS : WINDOW_TV_RECORDINGS));
103 item->SetArt("icon", "DefaultPVRRecordings.png");
104 results.Add(item);
107 // Timers/Timer rules
108 // - always present, because Reminders are always available, no client support needed for this
109 item = std::make_shared<CFileItem>(
110 bRadio ? CPVRTimersPath::PATH_RADIO_TIMERS : CPVRTimersPath::PATH_TV_TIMERS, true);
111 item->SetLabel(g_localizeStrings.Get(19040)); // Timers
112 item->SetProperty("node.target", CWindowTranslator::TranslateWindow(bRadio ? WINDOW_RADIO_TIMERS
113 : WINDOW_TV_TIMERS));
114 item->SetArt("icon", "DefaultPVRTimers.png");
115 results.Add(item);
117 item = std::make_shared<CFileItem>(
118 bRadio ? CPVRTimersPath::PATH_RADIO_TIMER_RULES : CPVRTimersPath::PATH_TV_TIMER_RULES, true);
119 item->SetLabel(g_localizeStrings.Get(19138)); // Timer rules
120 item->SetProperty("node.target", CWindowTranslator::TranslateWindow(
121 bRadio ? WINDOW_RADIO_TIMER_RULES : WINDOW_TV_TIMER_RULES));
122 item->SetArt("icon", "DefaultPVRTimerRules.png");
123 results.Add(item);
125 // Search
126 if (bAnyClientSupportingEPG)
128 item = std::make_shared<CFileItem>(
129 bRadio ? CPVREpgSearchPath::PATH_RADIO_SEARCH : CPVREpgSearchPath::PATH_TV_SEARCH, true);
130 item->SetLabel(g_localizeStrings.Get(137)); // Search
131 item->SetProperty("node.target", CWindowTranslator::TranslateWindow(bRadio ? WINDOW_RADIO_SEARCH
132 : WINDOW_TV_SEARCH));
133 item->SetArt("icon", "DefaultPVRSearch.png");
134 results.Add(item);
137 return true;
140 } // unnamed namespace
142 bool CPVRGUIDirectory::GetDirectory(CFileItemList& results) const
144 std::string base = m_url.Get();
145 URIUtils::RemoveSlashAtEnd(base);
147 std::string fileName = m_url.GetFileName();
148 URIUtils::RemoveSlashAtEnd(fileName);
150 results.SetCacheToDisc(CFileItemList::CACHE_NEVER);
152 if (fileName.empty())
154 if (CServiceBroker::GetPVRManager().IsStarted())
156 std::shared_ptr<CFileItem> item;
158 item = std::make_shared<CFileItem>(base + "channels/", true);
159 item->SetLabel(g_localizeStrings.Get(19019)); // Channels
160 item->SetLabelPreformatted(true);
161 results.Add(item);
163 item = std::make_shared<CFileItem>(base + "recordings/active/", true);
164 item->SetLabel(g_localizeStrings.Get(19017)); // Recordings
165 item->SetLabelPreformatted(true);
166 results.Add(item);
168 item = std::make_shared<CFileItem>(base + "recordings/deleted/", true);
169 item->SetLabel(g_localizeStrings.Get(19184)); // Deleted recordings
170 item->SetLabelPreformatted(true);
171 results.Add(item);
173 // Sort by name only. Labels are preformatted.
174 results.AddSortMethod(SortByLabel, 551 /* Name */, LABEL_MASKS("%L", "", "%L", ""));
176 return true;
178 else if (StringUtils::StartsWith(fileName, "tv"))
180 if (CServiceBroker::GetPVRManager().IsStarted())
182 return GetRootDirectory(false, results);
184 return true;
186 else if (StringUtils::StartsWith(fileName, "radio"))
188 if (CServiceBroker::GetPVRManager().IsStarted())
190 return GetRootDirectory(true, results);
192 return true;
194 else if (StringUtils::StartsWith(fileName, "recordings"))
196 if (CServiceBroker::GetPVRManager().IsStarted())
198 return GetRecordingsDirectory(results);
200 return true;
202 else if (StringUtils::StartsWith(fileName, "channels"))
204 if (CServiceBroker::GetPVRManager().IsStarted())
206 return GetChannelsDirectory(results);
208 return true;
210 else if (StringUtils::StartsWith(fileName, "timers"))
212 if (CServiceBroker::GetPVRManager().IsStarted())
214 return GetTimersDirectory(results);
216 return true;
219 const CPVREpgSearchPath path(m_url.Get());
220 if (path.IsValid())
222 if (CServiceBroker::GetPVRManager().IsStarted())
224 if (path.IsSavedSearchesRoot())
225 return GetSavedSearchesDirectory(path.IsRadio(), results);
227 return true;
230 return false;
233 bool CPVRGUIDirectory::HasTVRecordings()
235 return CServiceBroker::GetPVRManager().IsStarted() &&
236 CServiceBroker::GetPVRManager().Recordings()->GetNumTVRecordings() > 0;
239 bool CPVRGUIDirectory::HasDeletedTVRecordings()
241 return CServiceBroker::GetPVRManager().IsStarted() &&
242 CServiceBroker::GetPVRManager().Recordings()->HasDeletedTVRecordings();
245 bool CPVRGUIDirectory::HasRadioRecordings()
247 return CServiceBroker::GetPVRManager().IsStarted() &&
248 CServiceBroker::GetPVRManager().Recordings()->GetNumRadioRecordings() > 0;
251 bool CPVRGUIDirectory::HasDeletedRadioRecordings()
253 return CServiceBroker::GetPVRManager().IsStarted() &&
254 CServiceBroker::GetPVRManager().Recordings()->HasDeletedRadioRecordings();
257 namespace
260 std::string TrimSlashes(const std::string& strOrig)
262 std::string strReturn = strOrig;
263 while (strReturn[0] == '/')
264 strReturn.erase(0, 1);
266 URIUtils::RemoveSlashAtEnd(strReturn);
267 return strReturn;
270 bool IsDirectoryMember(const std::string& strDirectory,
271 const std::string& strEntryDirectory,
272 bool bGrouped)
274 const std::string strUseDirectory = TrimSlashes(strDirectory);
275 const std::string strUseEntryDirectory = TrimSlashes(strEntryDirectory);
277 // Case-insensitive comparison since sub folders are created with case-insensitive matching (GetSubDirectories)
278 if (bGrouped)
279 return StringUtils::EqualsNoCase(strUseDirectory, strUseEntryDirectory);
280 else
281 return StringUtils::StartsWithNoCase(strUseEntryDirectory, strUseDirectory);
284 void GetSubDirectories(const CPVRRecordingsPath& recParentPath,
285 const std::vector<std::shared_ptr<CPVRRecording>>& recordings,
286 CFileItemList& results)
288 // Only active recordings are fetched to provide sub directories.
289 // Not applicable for deleted view which is supposed to be flattened.
290 std::set<std::shared_ptr<CFileItem>> unwatchedFolders;
291 bool bRadio = recParentPath.IsRadio();
293 for (const auto& recording : recordings)
295 if (recording->IsDeleted())
296 continue;
298 if (recording->IsRadio() != bRadio)
299 continue;
301 const std::string strCurrent =
302 recParentPath.GetUnescapedSubDirectoryPath(recording->Directory());
303 if (strCurrent.empty())
304 continue;
306 CPVRRecordingsPath recChildPath(recParentPath);
307 recChildPath.AppendSegment(strCurrent);
308 const std::string strFilePath = recChildPath;
310 std::shared_ptr<CFileItem> item;
311 if (!results.Contains(strFilePath))
313 item = std::make_shared<CFileItem>(strCurrent, true);
314 item->SetPath(strFilePath);
315 item->SetLabel(strCurrent);
316 item->SetLabelPreformatted(true);
317 item->m_dateTime = recording->RecordingTimeAsLocalTime();
318 item->SetProperty("totalepisodes", 0);
319 item->SetProperty("watchedepisodes", 0);
320 item->SetProperty("unwatchedepisodes", 0);
321 item->SetProperty("inprogressepisodes", 0);
322 item->SetProperty("sizeinbytes", UINT64_C(0));
324 // Assume all folders are watched, we'll change the overlay later
325 item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_WATCHED);
326 results.Add(item);
328 else
330 item = results.Get(strFilePath);
331 if (item->m_dateTime < recording->RecordingTimeAsLocalTime())
332 item->m_dateTime = recording->RecordingTimeAsLocalTime();
335 item->IncrementProperty("totalepisodes", 1);
336 if (recording->GetPlayCount() == 0)
338 unwatchedFolders.insert(item);
339 item->IncrementProperty("unwatchedepisodes", 1);
341 else
343 item->IncrementProperty("watchedepisodes", 1);
345 if (recording->GetResumePoint().IsPartWay())
347 item->IncrementProperty("inprogressepisodes", 1);
349 item->IncrementProperty("sizeinbytes", recording->GetSizeInBytes());
352 // Replace the incremental size of the recordings with a string equivalent
353 for (auto& item : results.GetList())
355 int64_t size = item->GetProperty("sizeinbytes").asInteger();
356 item->ClearProperty("sizeinbytes");
357 item->m_dwSize = size; // We'll also sort recording folders by size
358 if (size > 0)
359 item->SetProperty("recordingsize", StringUtils::SizeToString(size));
362 // Change the watched overlay to unwatched for folders containing unwatched entries
363 for (auto& item : unwatchedFolders)
364 item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED);
367 } // unnamed namespace
369 bool CPVRGUIDirectory::GetRecordingsDirectory(CFileItemList& results) const
371 results.SetContent("recordings");
373 bool bGrouped = false;
374 const std::vector<std::shared_ptr<CPVRRecording>> recordings =
375 CServiceBroker::GetPVRManager().Recordings()->GetAll();
377 if (m_url.HasOption("view"))
379 const std::string view = m_url.GetOption("view");
380 if (view == "grouped")
381 bGrouped = true;
382 else if (view == "flat")
383 bGrouped = false;
384 else
386 CLog::LogF(LOGERROR, "Unsupported value '{}' for url parameter 'view'", view);
387 return false;
390 else
392 bGrouped = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
393 CSettings::SETTING_PVRRECORD_GROUPRECORDINGS);
396 const CPVRRecordingsPath recPath(m_url.GetWithoutOptions());
397 if (recPath.IsValid())
399 // Get the directory structure if in non-flatten mode
400 // Deleted view is always flatten. So only for an active view
401 const std::string strDirectory = recPath.GetUnescapedDirectoryPath();
402 if (!recPath.IsDeleted() && bGrouped)
403 GetSubDirectories(recPath, recordings, results);
405 // get all files of the current directory or recursively all files starting at the current directory if in flatten mode
406 std::shared_ptr<CFileItem> item;
407 for (const auto& recording : recordings)
409 // Omit recordings not matching criteria
410 if (recording->IsDeleted() != recPath.IsDeleted() ||
411 recording->IsRadio() != recPath.IsRadio() ||
412 !IsDirectoryMember(strDirectory, recording->Directory(), bGrouped))
413 continue;
415 item = std::make_shared<CFileItem>(recording);
416 item->SetOverlayImage(recording->GetPlayCount() > 0 ? CGUIListItem::ICON_OVERLAY_WATCHED
417 : CGUIListItem::ICON_OVERLAY_UNWATCHED);
418 results.Add(item);
422 return recPath.IsValid();
425 bool CPVRGUIDirectory::GetSavedSearchesDirectory(bool bRadio, CFileItemList& results) const
427 const std::vector<std::shared_ptr<CPVREpgSearchFilter>> searches =
428 CServiceBroker::GetPVRManager().EpgContainer().GetSavedSearches(bRadio);
430 for (const auto& search : searches)
432 results.Add(std::make_shared<CFileItem>(search));
434 return true;
437 bool CPVRGUIDirectory::GetChannelGroupsDirectory(bool bRadio,
438 bool bExcludeHidden,
439 CFileItemList& results)
441 const CPVRChannelGroups* channelGroups =
442 CServiceBroker::GetPVRManager().ChannelGroups()->Get(bRadio);
443 if (channelGroups)
445 std::shared_ptr<CFileItem> item;
446 const std::vector<std::shared_ptr<CPVRChannelGroup>> groups =
447 channelGroups->GetMembers(bExcludeHidden);
448 for (const auto& group : groups)
450 item = std::make_shared<CFileItem>(group->GetPath(), true);
451 item->m_strTitle = group->GroupName();
452 item->SetLabel(group->GroupName());
453 results.Add(item);
455 return true;
457 return false;
460 namespace
462 std::shared_ptr<CPVRChannelGroupMember> GetLastWatchedChannelGroupMember(
463 const std::shared_ptr<CPVRChannel>& channel)
465 const int lastGroupId{channel->LastWatchedGroupId()};
466 if (lastGroupId != PVR_GROUP_ID_UNNKOWN)
468 const std::shared_ptr<const CPVRChannelGroup> lastGroup{
469 CServiceBroker::GetPVRManager().ChannelGroups()->GetByIdFromAll(lastGroupId)};
470 if (lastGroup && !lastGroup->IsHidden() && !lastGroup->IsDeleted())
471 return lastGroup->GetByUniqueID(channel->StorageId());
473 return {};
476 std::shared_ptr<CPVRChannelGroupMember> GetFirstMatchingGroupMember(
477 const std::shared_ptr<CPVRChannel>& channel)
479 CPVRChannelGroups* groups{
480 CServiceBroker::GetPVRManager().ChannelGroups()->Get(channel->IsRadio())};
481 if (groups)
483 const std::vector<std::shared_ptr<CPVRChannelGroup>> channelGroups{
484 groups->GetMembers(true /* exclude hidden */)};
486 for (const auto& channelGroup : channelGroups)
488 if (channelGroup->IsDeleted())
489 continue;
491 std::shared_ptr<CPVRChannelGroupMember> groupMember{
492 channelGroup->GetByUniqueID(channel->StorageId())};
493 if (groupMember)
494 return groupMember;
497 return {};
500 std::vector<std::shared_ptr<CPVRChannelGroupMember>> GetChannelGroupMembers(
501 const CPVRChannelsPath& path)
503 const std::string& groupName{path.GetGroupName()};
505 std::shared_ptr<CPVRChannelGroup> group;
506 if (path.IsHiddenChannelGroup()) // hidden channels from the 'all channels' group
508 group = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(path.IsRadio());
510 else if (groupName == "*") // all channels across all groups
512 group = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(path.IsRadio());
513 if (group)
515 std::vector<std::shared_ptr<CPVRChannelGroupMember>> result;
517 const std::vector<std::shared_ptr<CPVRChannelGroupMember>> allGroupMembers{
518 group->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE)};
519 for (const auto& allGroupMember : allGroupMembers)
521 std::shared_ptr<CPVRChannelGroupMember> member{
522 GetLastWatchedChannelGroupMember(allGroupMember->Channel())};
523 if (member)
525 result.emplace_back(member);
526 continue; // Process next 'All channels' group member.
529 if (group->IsHidden())
531 // Very special case. 'All channels' group is hidden. Let's see what we get iterating all
532 // non-hidden / non-deleted groups. We must not return any 'All channels' group members,
533 // because their path is invalid (it contains the group).
534 member = GetFirstMatchingGroupMember(allGroupMember->Channel());
535 if (member)
536 result.emplace_back(member);
538 else
540 // Use the 'All channels' group member.
541 result.emplace_back(allGroupMember);
544 return result;
547 else
549 group = CServiceBroker::GetPVRManager()
550 .ChannelGroups()
551 ->Get(path.IsRadio())
552 ->GetByName(groupName, path.GetGroupClientID());
555 if (group)
556 return group->GetMembers(CPVRChannelGroup::Include::ALL);
558 CLog::LogF(LOGERROR, "Unable to obtain members for channel group '{}'", groupName);
559 return {};
561 } // unnamed namespace
563 bool CPVRGUIDirectory::GetChannelsDirectory(CFileItemList& results) const
565 const CPVRChannelsPath path(m_url.GetWithoutOptions());
566 if (path.IsValid())
568 if (path.IsEmpty())
570 std::shared_ptr<CFileItem> item;
572 // all tv channels
573 item = std::make_shared<CFileItem>(CPVRChannelsPath::PATH_TV_CHANNELS, true);
574 item->SetLabel(g_localizeStrings.Get(19020)); // TV
575 item->SetLabelPreformatted(true);
576 results.Add(item);
578 // all radio channels
579 item = std::make_shared<CFileItem>(CPVRChannelsPath::PATH_RADIO_CHANNELS, true);
580 item->SetLabel(g_localizeStrings.Get(19021)); // Radio
581 item->SetLabelPreformatted(true);
582 results.Add(item);
584 return true;
586 else if (path.IsChannelsRoot())
588 return GetChannelGroupsDirectory(path.IsRadio(), true, results);
590 else if (path.IsChannelGroup())
592 const bool playedOnly{(m_url.HasOption("view") && (m_url.GetOption("view") == "lastplayed"))};
593 const bool showHiddenChannels{path.IsHiddenChannelGroup()};
594 const std::vector<std::shared_ptr<CPVRChannelGroupMember>> groupMembers{
595 GetChannelGroupMembers(path)};
596 for (const auto& groupMember : groupMembers)
598 if (showHiddenChannels != groupMember->Channel()->IsHidden())
599 continue;
601 if (playedOnly && !groupMember->Channel()->LastWatched())
602 continue;
604 results.Add(std::make_shared<CFileItem>(groupMember));
606 return true;
609 return false;
612 namespace
615 bool GetTimersRootDirectory(const CPVRTimersPath& path,
616 bool bHideDisabled,
617 const std::vector<std::shared_ptr<CPVRTimerInfoTag>>& timers,
618 CFileItemList& results)
620 bool bRadio = path.IsRadio();
621 bool bRules = path.IsRules();
623 for (const auto& timer : timers)
625 if ((bRadio == timer->IsRadio() ||
626 (bRules && timer->ClientChannelUID() == PVR_TIMER_ANY_CHANNEL)) &&
627 (bRules == timer->IsTimerRule()) && (!bHideDisabled || !timer->IsDisabled()))
629 const auto item = std::make_shared<CFileItem>(timer);
630 const CPVRTimersPath timersPath(path.GetPath(), timer->ClientID(), timer->ClientIndex());
631 item->SetPath(timersPath.GetPath());
632 results.Add(item);
635 return true;
638 bool GetTimersSubDirectory(const CPVRTimersPath& path,
639 bool bHideDisabled,
640 const std::vector<std::shared_ptr<CPVRTimerInfoTag>>& timers,
641 CFileItemList& results)
643 bool bRadio = path.IsRadio();
644 int iParentId = path.GetParentId();
645 int iClientId = path.GetClientId();
647 std::shared_ptr<CFileItem> item;
649 for (const auto& timer : timers)
651 if ((timer->IsRadio() == bRadio) && timer->HasParent() && (timer->ClientID() == iClientId) &&
652 (timer->ParentClientIndex() == iParentId) && (!bHideDisabled || !timer->IsDisabled()))
654 item = std::make_shared<CFileItem>(timer);
655 const CPVRTimersPath timersPath(path.GetPath(), timer->ClientID(), timer->ClientIndex());
656 item->SetPath(timersPath.GetPath());
657 results.Add(item);
660 return true;
663 } // unnamed namespace
665 bool CPVRGUIDirectory::GetTimersDirectory(CFileItemList& results) const
667 const CPVRTimersPath path(m_url.GetWithoutOptions());
668 if (path.IsValid() && (path.IsTimersRoot() || path.IsTimerRule()))
670 bool bHideDisabled = false;
671 if (m_url.HasOption("view"))
673 const std::string view = m_url.GetOption("view");
674 if (view == "hidedisabled")
676 bHideDisabled = true;
678 else
680 CLog::LogF(LOGERROR, "Unsupported value '{}' for url parameter 'view'", view);
681 return false;
684 else
686 bHideDisabled = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
687 CSettings::SETTING_PVRTIMERS_HIDEDISABLEDTIMERS);
690 const std::vector<std::shared_ptr<CPVRTimerInfoTag>> timers =
691 CServiceBroker::GetPVRManager().Timers()->GetAll();
693 if (path.IsTimersRoot())
695 /* Root folder containing either timer rules or timers. */
696 return GetTimersRootDirectory(path, bHideDisabled, timers, results);
698 else if (path.IsTimerRule())
700 /* Sub folder containing the timers scheduled by the given timer rule. */
701 return GetTimersSubDirectory(path, bHideDisabled, timers, results);
705 return false;