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 #include "PVRChannel.h"
10
11 #include "ServiceBroker.h"
12 #include "XBDateTime.h"
13 #include "guilib/LocalizeStrings.h"
14 #include "pvr/PVRDatabase.h"
15 #include "pvr/PVRManager.h"
16 #include "pvr/addons/PVRClient.h"
17 #include "pvr/channels/PVRChannelsPath.h"
18 #include "pvr/epg/Epg.h"
19 #include "pvr/epg/EpgChannelData.h"
20 #include "pvr/epg/EpgContainer.h"
21 #include "pvr/epg/EpgInfoTag.h"
22 #include "threads/SingleLock.h"
23 #include "utils/StringUtils.h"
24 #include "utils/Variant.h"
25 #include "utils/log.h"
26
27 #include <memory>
28 #include <string>
29
30 using namespace PVR;
31
operator ==(const CPVRChannel & right) const32 bool CPVRChannel::operator==(const CPVRChannel& right) const
33 {
34 return (m_bIsRadio == right.m_bIsRadio &&
35 m_iUniqueId == right.m_iUniqueId &&
36 m_iClientId == right.m_iClientId);
37 }
38
operator !=(const CPVRChannel & right) const39 bool CPVRChannel::operator!=(const CPVRChannel& right) const
40 {
41 return !(*this == right);
42 }
43
CPVRChannel()44 CPVRChannel::CPVRChannel()
45 {
46 UpdateEncryptionName();
47 }
48
CPVRChannel(bool bRadio)49 CPVRChannel::CPVRChannel(bool bRadio)
50 : m_bIsRadio(bRadio)
51 {
52 UpdateEncryptionName();
53 }
54
CPVRChannel(const PVR_CHANNEL & channel,unsigned int iClientId)55 CPVRChannel::CPVRChannel(const PVR_CHANNEL& channel, unsigned int iClientId)
56 : m_bIsRadio(channel.bIsRadio),
57 m_bIsHidden(channel.bIsHidden),
58 m_strIconPath(channel.strIconPath),
59 m_strChannelName(channel.strChannelName),
60 m_bHasArchive(channel.bHasArchive),
61 m_bEPGEnabled(!channel.bIsHidden),
62 m_iUniqueId(channel.iUniqueId),
63 m_iClientId(iClientId),
64 m_clientChannelNumber(channel.iChannelNumber, channel.iSubChannelNumber),
65 m_strClientChannelName(channel.strChannelName),
66 m_strMimeType(channel.strMimeType),
67 m_iClientEncryptionSystem(channel.iEncryptionSystem)
68 {
69 if (m_strChannelName.empty())
70 m_strChannelName = StringUtils::Format("%s %d", g_localizeStrings.Get(19029).c_str(), m_iUniqueId);
71
72 UpdateEncryptionName();
73 }
74
~CPVRChannel()75 CPVRChannel::~CPVRChannel()
76 {
77 ResetEPG();
78 }
79
Serialize(CVariant & value) const80 void CPVRChannel::Serialize(CVariant& value) const
81 {
82 value["channelid"] = m_iChannelId;
83 value["channeltype"] = m_bIsRadio ? "radio" : "tv";
84 value["hidden"] = m_bIsHidden;
85 value["locked"] = m_bIsLocked;
86 value["icon"] = m_strIconPath;
87 value["channel"] = m_strChannelName;
88 value["uniqueid"] = m_iUniqueId;
89 CDateTime lastPlayed(m_iLastWatched);
90 value["lastplayed"] = lastPlayed.IsValid() ? lastPlayed.GetAsDBDate() : "";
91 value["channelnumber"] = m_channelNumber.GetChannelNumber();
92 value["subchannelnumber"] = m_channelNumber.GetSubChannelNumber();
93
94 std::shared_ptr<CPVREpgInfoTag> epg = GetEPGNow();
95 if (epg)
96 {
97 // add the properties of the current EPG item to the main object
98 epg->Serialize(value);
99 // and add an extra sub-object with only the current EPG details
100 epg->Serialize(value["broadcastnow"]);
101 }
102
103 epg = GetEPGNext();
104 if (epg)
105 epg->Serialize(value["broadcastnext"]);
106
107 value["hasarchive"] = m_bHasArchive;
108 value["clientid"] = m_iClientId;
109 }
110
QueueDelete()111 bool CPVRChannel::QueueDelete()
112 {
113 bool bReturn = false;
114 const std::shared_ptr<CPVRDatabase> database = CServiceBroker::GetPVRManager().GetTVDatabase();
115 if (!database)
116 return bReturn;
117
118 const std::shared_ptr<CPVREpg> epg = GetEPG();
119 if (epg)
120 ResetEPG();
121
122 bReturn = database->QueueDeleteQuery(*this);
123 return bReturn;
124 }
125
GetEPG() const126 std::shared_ptr<CPVREpg> CPVRChannel::GetEPG() const
127 {
128 const_cast<CPVRChannel*>(this)->CreateEPG();
129
130 CSingleLock lock(m_critSection);
131 if (!m_bIsHidden && m_bEPGEnabled)
132 return m_epg;
133
134 return {};
135 }
136
CreateEPG()137 bool CPVRChannel::CreateEPG()
138 {
139 CSingleLock lock(m_critSection);
140 if (!m_epg)
141 {
142 m_epg = CServiceBroker::GetPVRManager().EpgContainer().CreateChannelEpg(m_iEpgId,
143 m_strEPGScraper,
144 std::make_shared<CPVREpgChannelData>(*this));
145 if (m_epg)
146 {
147 if (m_epg->EpgID() != m_iEpgId)
148 {
149 m_iEpgId = m_epg->EpgID();
150 m_bChanged = true;
151 }
152
153 // Subscribe for EPG delete event
154 m_epg->Events().Subscribe(this, &CPVRChannel::Notify);
155 return true;
156 }
157 }
158 return false;
159 }
160
Notify(const PVREvent & event)161 void CPVRChannel::Notify(const PVREvent& event)
162 {
163 if (event == PVREvent::EpgDeleted)
164 {
165 ResetEPG();
166 }
167 }
168
ResetEPG()169 void CPVRChannel::ResetEPG()
170 {
171 std::shared_ptr<CPVREpg> epgToUnsubscribe;
172 {
173 CSingleLock lock(m_critSection);
174 if (m_epg)
175 {
176 epgToUnsubscribe = m_epg;
177 m_epg.reset();
178 }
179 }
180
181 if (epgToUnsubscribe)
182 epgToUnsubscribe->Events().Unsubscribe(this);
183 }
184
UpdateFromClient(const std::shared_ptr<CPVRChannel> & channel)185 bool CPVRChannel::UpdateFromClient(const std::shared_ptr<CPVRChannel>& channel)
186 {
187 SetClientID(channel->ClientID());
188
189 CSingleLock lock(m_critSection);
190
191 if (m_clientChannelNumber != channel->m_clientChannelNumber ||
192 m_strMimeType != channel->MimeType() ||
193 m_iClientEncryptionSystem != channel->EncryptionSystem() ||
194 m_strClientChannelName != channel->ClientChannelName() ||
195 m_bHasArchive != channel->HasArchive())
196 {
197 m_clientChannelNumber = channel->m_clientChannelNumber;
198 m_strMimeType = channel->MimeType();
199 m_iClientEncryptionSystem = channel->EncryptionSystem();
200 m_strClientChannelName = channel->ClientChannelName();
201 m_bHasArchive = channel->HasArchive();
202
203 UpdateEncryptionName();
204
205 m_bChanged = true;
206 }
207
208 // only update the channel name and icon if the user hasn't changed them manually
209 if (m_strChannelName.empty() || !IsUserSetName())
210 SetChannelName(channel->ClientChannelName());
211 if (m_strIconPath.empty() || !IsUserSetIcon())
212 SetIconPath(channel->IconPath());
213
214 return m_bChanged;
215 }
216
Persist()217 bool CPVRChannel::Persist()
218 {
219 {
220 // not changed
221 CSingleLock lock(m_critSection);
222 if (!m_bChanged && m_iChannelId > 0)
223 return true;
224 }
225
226 const std::shared_ptr<CPVRDatabase> database = CServiceBroker::GetPVRManager().GetTVDatabase();
227 if (database)
228 {
229 bool bReturn = database->Persist(*this, true);
230
231 CSingleLock lock(m_critSection);
232 m_bChanged = !bReturn;
233 return bReturn;
234 }
235
236 return false;
237 }
238
SetChannelID(int iChannelId)239 bool CPVRChannel::SetChannelID(int iChannelId)
240 {
241 CSingleLock lock(m_critSection);
242 if (m_iChannelId != iChannelId)
243 {
244 m_iChannelId = iChannelId;
245
246 const std::shared_ptr<CPVREpg> epg = GetEPG();
247 if (epg)
248 epg->GetChannelData()->SetChannelId(m_iChannelId);
249
250 m_bChanged = true;
251 return true;
252 }
253
254 return false;
255 }
256
ChannelNumber() const257 const CPVRChannelNumber& CPVRChannel::ChannelNumber() const
258 {
259 CSingleLock lock(m_critSection);
260 return m_channelNumber;
261 }
262
SetHidden(bool bIsHidden)263 bool CPVRChannel::SetHidden(bool bIsHidden)
264 {
265 CSingleLock lock(m_critSection);
266
267 if (m_bIsHidden != bIsHidden)
268 {
269 m_bIsHidden = bIsHidden;
270 m_bEPGEnabled = !bIsHidden;
271
272 const std::shared_ptr<CPVREpg> epg = GetEPG();
273 if (epg)
274 {
275 epg->GetChannelData()->SetHidden(m_bIsHidden);
276 epg->GetChannelData()->SetEPGEnabled(m_bEPGEnabled);
277 }
278
279 m_bChanged = true;
280 return true;
281 }
282
283 return false;
284 }
285
SetLocked(bool bIsLocked)286 bool CPVRChannel::SetLocked(bool bIsLocked)
287 {
288 CSingleLock lock(m_critSection);
289
290 if (m_bIsLocked != bIsLocked)
291 {
292 m_bIsLocked = bIsLocked;
293
294 const std::shared_ptr<CPVREpg> epg = GetEPG();
295 if (epg)
296 epg->GetChannelData()->SetLocked(m_bIsLocked);
297
298 m_bChanged = true;
299 return true;
300 }
301
302 return false;
303 }
304
GetRadioRDSInfoTag() const305 std::shared_ptr<CPVRRadioRDSInfoTag> CPVRChannel::GetRadioRDSInfoTag() const
306 {
307 CSingleLock lock(m_critSection);
308 return m_rdsTag;
309 }
310
SetRadioRDSInfoTag(const std::shared_ptr<CPVRRadioRDSInfoTag> & tag)311 void CPVRChannel::SetRadioRDSInfoTag(const std::shared_ptr<CPVRRadioRDSInfoTag>& tag)
312 {
313 CSingleLock lock(m_critSection);
314 m_rdsTag = tag;
315 }
316
HasArchive() const317 bool CPVRChannel::HasArchive() const
318 {
319 CSingleLock lock(m_critSection);
320 return m_bHasArchive;
321 }
322
SetIconPath(const std::string & strIconPath,bool bIsUserSetIcon)323 bool CPVRChannel::SetIconPath(const std::string& strIconPath, bool bIsUserSetIcon /* = false */)
324 {
325 CSingleLock lock(m_critSection);
326 if (m_strIconPath != strIconPath)
327 {
328 m_strIconPath = StringUtils::Format("%s", strIconPath.c_str());
329
330 m_bChanged = true;
331 m_bIsUserSetIcon = bIsUserSetIcon && !m_strIconPath.empty();
332 return true;
333 }
334
335 return false;
336 }
337
SetChannelName(const std::string & strChannelName,bool bIsUserSetName)338 bool CPVRChannel::SetChannelName(const std::string& strChannelName, bool bIsUserSetName /*= false*/)
339 {
340 std::string strName(strChannelName);
341
342 if (strName.empty())
343 strName = StringUtils::Format(g_localizeStrings.Get(19085).c_str(), m_clientChannelNumber.FormattedChannelNumber().c_str());
344
345 CSingleLock lock(m_critSection);
346 if (m_strChannelName != strName)
347 {
348 m_strChannelName = strName;
349 m_bIsUserSetName = bIsUserSetName;
350
351 /* if the user changes the name manually to an empty string we reset the
352 flag and use the name from the client instead */
353 if (bIsUserSetName && strChannelName.empty())
354 {
355 m_bIsUserSetName = false;
356 m_strChannelName = ClientChannelName();
357 }
358
359 const std::shared_ptr<CPVREpg> epg = GetEPG();
360 if (epg)
361 epg->GetChannelData()->SetChannelName(m_strChannelName);
362
363 m_bChanged = true;
364 return true;
365 }
366
367 return false;
368 }
369
SetLastWatched(time_t iLastWatched)370 bool CPVRChannel::SetLastWatched(time_t iLastWatched)
371 {
372 {
373 CSingleLock lock(m_critSection);
374 m_iLastWatched = iLastWatched;
375 }
376
377 const std::shared_ptr<CPVRDatabase> database = CServiceBroker::GetPVRManager().GetTVDatabase();
378 if (database)
379 return database->UpdateLastWatched(*this);
380
381 return false;
382 }
383
IsEmpty() const384 bool CPVRChannel::IsEmpty() const
385 {
386 CSingleLock lock(m_critSection);
387 return m_strFileNameAndPath.empty();
388 }
389
390 /********** Client related channel methods **********/
391
SetClientID(int iClientId)392 bool CPVRChannel::SetClientID(int iClientId)
393 {
394 CSingleLock lock(m_critSection);
395
396 if (m_iClientId != iClientId)
397 {
398 m_iClientId = iClientId;
399 m_bChanged = true;
400 return true;
401 }
402
403 return false;
404 }
405
UpdatePath(const std::string & channelGroup)406 void CPVRChannel::UpdatePath(const std::string& channelGroup)
407 {
408 const std::shared_ptr<CPVRClient> client = CServiceBroker::GetPVRManager().GetClient(m_iClientId);
409 if (client)
410 {
411 CSingleLock lock(m_critSection);
412 const std::string strFileNameAndPath = CPVRChannelsPath(m_bIsRadio, channelGroup, client->ID(), m_iUniqueId);
413 if (m_strFileNameAndPath != strFileNameAndPath)
414 m_strFileNameAndPath = strFileNameAndPath;
415 }
416 }
417
GetEncryptionName(int iCaid)418 std::string CPVRChannel::GetEncryptionName(int iCaid)
419 {
420 // http://www.dvb.org/index.php?id=174
421 // http://en.wikipedia.org/wiki/Conditional_access_system
422 std::string strName(g_localizeStrings.Get(13205)); /* Unknown */
423
424 if ( iCaid == 0x0000)
425 strName = g_localizeStrings.Get(19013); /* Free To Air */
426 else if (iCaid >= 0x0001 &&
427 iCaid <= 0x009F)
428 strName = g_localizeStrings.Get(19014); /* Fixed */
429 else if (iCaid >= 0x00A0 &&
430 iCaid<= 0x00A1)
431 strName = g_localizeStrings.Get(338); /* Analog */
432 else if (iCaid >= 0x00A2 &&
433 iCaid <= 0x00FF)
434 strName = g_localizeStrings.Get(19014); /* Fixed */
435 else if (iCaid >= 0x0100 &&
436 iCaid <= 0x01FF)
437 strName = "SECA Mediaguard";
438 else if (iCaid == 0x0464)
439 strName = "EuroDec";
440 else if (iCaid >= 0x0500 &&
441 iCaid <= 0x05FF)
442 strName = "Viaccess";
443 else if (iCaid >= 0x0600 &&
444 iCaid <= 0x06FF)
445 strName = "Irdeto";
446 else if (iCaid >= 0x0900 &&
447 iCaid <= 0x09FF)
448 strName = "NDS Videoguard";
449 else if (iCaid >= 0x0B00 &&
450 iCaid <= 0x0BFF)
451 strName = "Conax";
452 else if (iCaid >= 0x0D00 &&
453 iCaid <= 0x0DFF)
454 strName = "CryptoWorks";
455 else if (iCaid >= 0x0E00 &&
456 iCaid <= 0x0EFF)
457 strName = "PowerVu";
458 else if (iCaid == 0x1000)
459 strName = "RAS";
460 else if (iCaid >= 0x1200 &&
461 iCaid <= 0x12FF)
462 strName = "NagraVision";
463 else if (iCaid >= 0x1700 &&
464 iCaid <= 0x17FF)
465 strName = "BetaCrypt";
466 else if (iCaid >= 0x1800 &&
467 iCaid <= 0x18FF)
468 strName = "NagraVision";
469 else if (iCaid == 0x22F0)
470 strName = "Codicrypt";
471 else if (iCaid == 0x2600)
472 strName = "BISS";
473 else if (iCaid == 0x4347)
474 strName = "CryptOn";
475 else if (iCaid == 0x4800)
476 strName = "Accessgate";
477 else if (iCaid == 0x4900)
478 strName = "China Crypt";
479 else if (iCaid == 0x4A10)
480 strName = "EasyCas";
481 else if (iCaid == 0x4A20)
482 strName = "AlphaCrypt";
483 else if (iCaid == 0x4A70)
484 strName = "DreamCrypt";
485 else if (iCaid == 0x4A60)
486 strName = "SkyCrypt";
487 else if (iCaid == 0x4A61)
488 strName = "Neotioncrypt";
489 else if (iCaid == 0x4A62)
490 strName = "SkyCrypt";
491 else if (iCaid == 0x4A63)
492 strName = "Neotion SHL";
493 else if (iCaid >= 0x4A64 &&
494 iCaid <= 0x4A6F)
495 strName = "SkyCrypt";
496 else if (iCaid == 0x4A80)
497 strName = "ThalesCrypt";
498 else if (iCaid == 0x4AA1)
499 strName = "KeyFly";
500 else if (iCaid == 0x4ABF)
501 strName = "DG-Crypt";
502 else if (iCaid >= 0x4AD0 &&
503 iCaid <= 0x4AD1)
504 strName = "X-Crypt";
505 else if (iCaid == 0x4AD4)
506 strName = "OmniCrypt";
507 else if (iCaid == 0x4AE0)
508 strName = "RossCrypt";
509 else if (iCaid == 0x5500)
510 strName = "Z-Crypt";
511 else if (iCaid == 0x5501)
512 strName = "Griffin";
513 else if (iCaid == 0x5601)
514 strName = "Verimatrix";
515
516 if (iCaid >= 0)
517 strName += StringUtils::Format(" (%04X)", iCaid);
518
519 return strName;
520 }
521
UpdateEncryptionName()522 void CPVRChannel::UpdateEncryptionName()
523 {
524 CSingleLock lock(m_critSection);
525 m_strClientEncryptionName = GetEncryptionName(m_iClientEncryptionSystem);
526 }
527
528 /********** EPG methods **********/
529
GetEpgTags() const530 std::vector<std::shared_ptr<CPVREpgInfoTag>> CPVRChannel::GetEpgTags() const
531 {
532 const std::shared_ptr<CPVREpg> epg = GetEPG();
533 if (!epg)
534 {
535 CLog::LogFC(LOGDEBUG, LOGPVR, "Cannot get EPG for channel '{}'", m_strChannelName);
536 return {};
537 }
538
539 return epg->GetTags();
540 }
541
GetEPGTimeline(const CDateTime & timelineStart,const CDateTime & timelineEnd,const CDateTime & minEventEnd,const CDateTime & maxEventStart) const542 std::vector<std::shared_ptr<CPVREpgInfoTag>> CPVRChannel::GetEPGTimeline(
543 const CDateTime& timelineStart,
544 const CDateTime& timelineEnd,
545 const CDateTime& minEventEnd,
546 const CDateTime& maxEventStart) const
547 {
548 const std::shared_ptr<CPVREpg> epg = GetEPG();
549 if (epg)
550 {
551 return epg->GetTimeline(timelineStart, timelineEnd, minEventEnd, maxEventStart);
552 }
553 else
554 {
555 // return single gap tag spanning whole timeline
556 return std::vector<std::shared_ptr<CPVREpgInfoTag>>{
557 CreateEPGGapTag(timelineStart, timelineEnd)};
558 }
559 }
560
CreateEPGGapTag(const CDateTime & start,const CDateTime & end) const561 std::shared_ptr<CPVREpgInfoTag> CPVRChannel::CreateEPGGapTag(const CDateTime& start,
562 const CDateTime& end) const
563 {
564 const std::shared_ptr<CPVREpg> epg = GetEPG();
565 if (epg)
566 return std::make_shared<CPVREpgInfoTag>(epg->GetChannelData(), epg->EpgID(), start, end, true);
567 else
568 return std::make_shared<CPVREpgInfoTag>(std::make_shared<CPVREpgChannelData>(*this), -1, start,
569 end, true);
570 }
571
ClearEPG() const572 bool CPVRChannel::ClearEPG() const
573 {
574 const std::shared_ptr<CPVREpg> epg = GetEPG();
575 if (epg)
576 epg->Clear();
577
578 return true;
579 }
580
GetEPGNow() const581 std::shared_ptr<CPVREpgInfoTag> CPVRChannel::GetEPGNow() const
582 {
583 std::shared_ptr<CPVREpgInfoTag> tag;
584 const std::shared_ptr<CPVREpg> epg = GetEPG();
585 if (epg)
586 tag = epg->GetTagNow();
587
588 return tag;
589 }
590
GetEPGNext() const591 std::shared_ptr<CPVREpgInfoTag> CPVRChannel::GetEPGNext() const
592 {
593 std::shared_ptr<CPVREpgInfoTag> tag;
594 const std::shared_ptr<CPVREpg> epg = GetEPG();
595 if (epg)
596 tag = epg->GetTagNext();
597
598 return tag;
599 }
600
GetEPGPrevious() const601 std::shared_ptr<CPVREpgInfoTag> CPVRChannel::GetEPGPrevious() const
602 {
603 std::shared_ptr<CPVREpgInfoTag> tag;
604 const std::shared_ptr<CPVREpg> epg = GetEPG();
605 if (epg)
606 tag = epg->GetTagPrevious();
607
608 return tag;
609 }
610
SetEPGEnabled(bool bEPGEnabled)611 bool CPVRChannel::SetEPGEnabled(bool bEPGEnabled)
612 {
613 CSingleLock lock(m_critSection);
614
615 if (m_bEPGEnabled != bEPGEnabled)
616 {
617 m_bEPGEnabled = bEPGEnabled;
618
619 const std::shared_ptr<CPVREpg> epg = GetEPG();
620 if (epg)
621 epg->GetChannelData()->SetEPGEnabled(m_bEPGEnabled);
622
623 m_bChanged = true;
624
625 /* clear the previous EPG entries if needed */
626 if (!m_bEPGEnabled && m_epg)
627 ClearEPG();
628
629 return true;
630 }
631
632 return false;
633 }
634
SetEPGScraper(const std::string & strScraper)635 bool CPVRChannel::SetEPGScraper(const std::string& strScraper)
636 {
637 CSingleLock lock(m_critSection);
638
639 if (m_strEPGScraper != strScraper)
640 {
641 bool bCleanEPG = !m_strEPGScraper.empty() || strScraper.empty();
642
643 m_strEPGScraper = StringUtils::Format("%s", strScraper.c_str());
644 m_bChanged = true;
645
646 /* clear the previous EPG entries if needed */
647 if (bCleanEPG && m_bEPGEnabled && m_epg)
648 ClearEPG();
649
650 return true;
651 }
652
653 return false;
654 }
655
SetChannelNumber(const CPVRChannelNumber & channelNumber)656 void CPVRChannel::SetChannelNumber(const CPVRChannelNumber& channelNumber)
657 {
658 CSingleLock lock(m_critSection);
659 m_channelNumber = channelNumber;
660 }
661
SetClientChannelNumber(const CPVRChannelNumber & clientChannelNumber)662 void CPVRChannel::SetClientChannelNumber(const CPVRChannelNumber& clientChannelNumber)
663 {
664 CSingleLock lock(m_critSection);
665 m_clientChannelNumber = clientChannelNumber;
666 }
667
ToSortable(SortItem & sortable,Field field) const668 void CPVRChannel::ToSortable(SortItem& sortable, Field field) const
669 {
670 CSingleLock lock(m_critSection);
671 if (field == FieldChannelName)
672 sortable[FieldChannelName] = m_strChannelName;
673 else if (field == FieldChannelNumber)
674 sortable[FieldChannelNumber] = m_channelNumber.SortableChannelNumber();
675 else if (field == FieldClientChannelOrder)
676 {
677 if (m_iOrder)
678 sortable[FieldClientChannelOrder] = m_iOrder;
679 else
680 sortable[FieldClientChannelOrder] = m_clientChannelNumber.SortableChannelNumber();
681 }
682 else if (field == FieldLastPlayed)
683 {
684 const CDateTime lastWatched(m_iLastWatched);
685 sortable[FieldLastPlayed] = lastWatched.IsValid() ? lastWatched.GetAsDBDateTime() : StringUtils::Empty;
686 }
687 }
688
ChannelID() const689 int CPVRChannel::ChannelID() const
690 {
691 CSingleLock lock(m_critSection);
692 return m_iChannelId;
693 }
694
IsNew() const695 bool CPVRChannel::IsNew() const
696 {
697 CSingleLock lock(m_critSection);
698 return m_iChannelId <= 0;
699 }
700
IsHidden() const701 bool CPVRChannel::IsHidden() const
702 {
703 CSingleLock lock(m_critSection);
704 return m_bIsHidden;
705 }
706
IsLocked() const707 bool CPVRChannel::IsLocked() const
708 {
709 CSingleLock lock(m_critSection);
710 return m_bIsLocked;
711 }
712
IconPath() const713 std::string CPVRChannel::IconPath() const
714 {
715 CSingleLock lock(m_critSection);
716 return m_strIconPath;
717 }
718
IsUserSetIcon() const719 bool CPVRChannel::IsUserSetIcon() const
720 {
721 CSingleLock lock(m_critSection);
722 return m_bIsUserSetIcon;
723 }
724
IsUserSetName() const725 bool CPVRChannel::IsUserSetName() const
726 {
727 CSingleLock lock(m_critSection);
728 return m_bIsUserSetName;
729 }
730
ChannelName() const731 std::string CPVRChannel::ChannelName() const
732 {
733 CSingleLock lock(m_critSection);
734 return m_strChannelName;
735 }
736
LastWatched() const737 time_t CPVRChannel::LastWatched() const
738 {
739 CSingleLock lock(m_critSection);
740 return m_iLastWatched;
741 }
742
IsChanged() const743 bool CPVRChannel::IsChanged() const
744 {
745 CSingleLock lock(m_critSection);
746 return m_bChanged;
747 }
748
Persisted()749 void CPVRChannel::Persisted()
750 {
751 CSingleLock lock(m_critSection);
752 m_bChanged = false;
753 }
754
UniqueID() const755 int CPVRChannel::UniqueID() const
756 {
757 return m_iUniqueId;
758 }
759
ClientID() const760 int CPVRChannel::ClientID() const
761 {
762 CSingleLock lock(m_critSection);
763 return m_iClientId;
764 }
765
ClientChannelNumber() const766 const CPVRChannelNumber& CPVRChannel::ClientChannelNumber() const
767 {
768 CSingleLock lock(m_critSection);
769 return m_clientChannelNumber;
770 }
771
ClientChannelName() const772 std::string CPVRChannel::ClientChannelName() const
773 {
774 CSingleLock lock(m_critSection);
775 return m_strClientChannelName;
776 }
777
MimeType() const778 std::string CPVRChannel::MimeType() const
779 {
780 CSingleLock lock(m_critSection);
781 return m_strMimeType;
782 }
783
Path() const784 std::string CPVRChannel::Path() const
785 {
786 CSingleLock lock(m_critSection);
787 return m_strFileNameAndPath;
788 }
789
IsEncrypted() const790 bool CPVRChannel::IsEncrypted() const
791 {
792 CSingleLock lock(m_critSection);
793 return m_iClientEncryptionSystem > 0;
794 }
795
EncryptionSystem() const796 int CPVRChannel::EncryptionSystem() const
797 {
798 CSingleLock lock(m_critSection);
799 return m_iClientEncryptionSystem;
800 }
801
EncryptionName() const802 std::string CPVRChannel::EncryptionName() const
803 {
804 CSingleLock lock(m_critSection);
805 return m_strClientEncryptionName;
806 }
807
EpgID() const808 int CPVRChannel::EpgID() const
809 {
810 CSingleLock lock(m_critSection);
811 return m_iEpgId;
812 }
813
EPGEnabled() const814 bool CPVRChannel::EPGEnabled() const
815 {
816 CSingleLock lock(m_critSection);
817 return m_bEPGEnabled;
818 }
819
EPGScraper() const820 std::string CPVRChannel::EPGScraper() const
821 {
822 CSingleLock lock(m_critSection);
823 return m_strEPGScraper;
824 }
825
CanRecord() const826 bool CPVRChannel::CanRecord() const
827 {
828 const std::shared_ptr<CPVRClient> client = CServiceBroker::GetPVRManager().GetClient(m_iClientId);
829 return client && client->GetClientCapabilities().SupportsRecordings();
830 }
831
SetClientOrder(int iOrder)832 void CPVRChannel::SetClientOrder(int iOrder)
833 {
834 CSingleLock lock(m_critSection);
835 m_iOrder = iOrder;
836 }
837