aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Sommerfeld <kai.sommerfeld@gmx.com>2022-09-08 10:34:53 +0200
committerGitHub <noreply@github.com>2022-09-08 10:34:53 +0200
commit95bd109ce09e2443f146d08b56ecd558216b844a (patch)
tree37182f5138395eac0cc4d07666292c3013e8c5bc
parent6686f0cd587a68c90a4567f585f04012d57481d5 (diff)
parent8a73af967e341413dc6cffc530fd8639073e47a7 (diff)
Merge pull request #21811 from ksooo/pvr-refactor-clients-code
[PVR] Refactor PVR Clients Code
-rw-r--r--xbmc/pvr/PVRManager.cpp9
-rw-r--r--xbmc/pvr/addons/CMakeLists.txt4
-rw-r--r--xbmc/pvr/addons/PVRClient.cpp111
-rw-r--r--xbmc/pvr/addons/PVRClient.h278
-rw-r--r--xbmc/pvr/addons/PVRClientCapabilities.cpp85
-rw-r--r--xbmc/pvr/addons/PVRClientCapabilities.h277
-rw-r--r--xbmc/pvr/addons/PVRClientUID.cpp33
-rw-r--r--xbmc/pvr/addons/PVRClientUID.h42
-rw-r--r--xbmc/pvr/addons/PVRClients.cpp336
-rw-r--r--xbmc/pvr/addons/PVRClients.h82
-rw-r--r--xbmc/pvr/channels/PVRChannelGroup.cpp5
-rw-r--r--xbmc/pvr/channels/PVRChannelGroups.cpp6
-rw-r--r--xbmc/pvr/channels/PVRChannelsPath.cpp14
-rw-r--r--xbmc/pvr/channels/PVRChannelsPath.h6
-rw-r--r--xbmc/pvr/channels/test/TestPVRChannelsPath.cpp32
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.cpp2
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp3
-rw-r--r--xbmc/pvr/guilib/PVRGUIActions.cpp3
-rw-r--r--xbmc/pvr/guilib/guiinfo/PVRGUIInfo.cpp12
19 files changed, 716 insertions, 624 deletions
diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp
index 20d90d480a..35ced6e03a 100644
--- a/xbmc/pvr/PVRManager.cpp
+++ b/xbmc/pvr/PVRManager.cpp
@@ -304,11 +304,7 @@ std::shared_ptr<CPVRClient> CPVRManager::GetClient(const CFileItem& item) const
std::shared_ptr<CPVRClient> CPVRManager::GetClient(int iClientId) const
{
- std::shared_ptr<CPVRClient> client;
- if (iClientId != PVR_INVALID_CLIENT_ID)
- m_addons->GetCreatedClient(iClientId, client);
-
- return client;
+ return m_addons->GetCreatedClient(iClientId);
}
std::shared_ptr<CPVRGUIActions> CPVRManager::GUIActions() const
@@ -682,8 +678,7 @@ bool CPVRManager::UpdateComponents(ManagerState stateToCheck,
const std::unique_ptr<CPVRGUIProgressHandler>& progressHandler)
{
// find clients which appeared since last check and update them
- CPVRClientMap clientMap;
- m_addons->GetCreatedClients(clientMap);
+ const CPVRClientMap clientMap = m_addons->GetCreatedClients();
if (clientMap.empty())
{
CLog::LogFC(LOGDEBUG, LOGPVR, "All created PVR clients gone!");
diff --git a/xbmc/pvr/addons/CMakeLists.txt b/xbmc/pvr/addons/CMakeLists.txt
index 67d6b8445e..e8a0a5129e 100644
--- a/xbmc/pvr/addons/CMakeLists.txt
+++ b/xbmc/pvr/addons/CMakeLists.txt
@@ -1,9 +1,13 @@
set(SOURCES PVRClient.cpp
+ PVRClientCapabilities.cpp
PVRClientMenuHooks.cpp
+ PVRClientUID.cpp
PVRClients.cpp)
set(HEADERS PVRClient.h
+ PVRClientCapabilities.h
PVRClientMenuHooks.h
+ PVRClientUID.h
PVRClients.h)
core_add_library(pvr_addons)
diff --git a/xbmc/pvr/addons/PVRClient.cpp b/xbmc/pvr/addons/PVRClient.cpp
index c3aff4f636..31328c0693 100644
--- a/xbmc/pvr/addons/PVRClient.cpp
+++ b/xbmc/pvr/addons/PVRClient.cpp
@@ -9,9 +9,9 @@
#include "PVRClient.h"
#include "ServiceBroker.h"
-#include "addons/kodi-dev-kit/include/kodi/addon-instance/PVR.h" // added for compile test on related sources only!
+#include "addons/AddonManager.h"
#include "cores/VideoPlayer/DVDDemuxers/DVDDemuxUtils.h"
-#include "dialogs/GUIDialogKaiToast.h"
+#include "dialogs/GUIDialogKaiToast.h" //! @todo get rid of GUI in core
#include "events/EventLog.h"
#include "events/NotificationEvent.h"
#include "filesystem/SpecialProtocol.h"
@@ -42,8 +42,6 @@
#include "utils/StringUtils.h"
#include "utils/log.h"
-#include <algorithm>
-#include <iterator>
#include <map>
#include <memory>
#include <mutex>
@@ -62,8 +60,10 @@ namespace PVR
#define DEFAULT_INFO_STRING_VALUE "unknown"
-CPVRClient::CPVRClient(const ADDON::AddonInfoPtr& addonInfo, ADDON::AddonInstanceId instanceId)
- : IAddonInstanceHandler(ADDON_INSTANCE_PVR, addonInfo, instanceId)
+CPVRClient::CPVRClient(const ADDON::AddonInfoPtr& addonInfo,
+ ADDON::AddonInstanceId instanceId,
+ int clientId)
+ : IAddonInstanceHandler(ADDON_INSTANCE_PVR, addonInfo, instanceId), m_iClientId(clientId)
{
// Create all interface parts independent to make API changes easier if
// something is added
@@ -92,7 +92,7 @@ void CPVRClient::StopRunningInstance()
{
// stop the pvr manager and stop and unload the running pvr addon. pvr manager will be restarted on demand.
CServiceBroker::GetPVRManager().Stop();
- CServiceBroker::GetPVRManager().Clients()->StopClient(ID(), InstanceId(), false);
+ CServiceBroker::GetPVRManager().Clients()->StopClient(m_iClientId, false);
}
void CPVRClient::OnPreInstall()
@@ -106,7 +106,7 @@ void CPVRClient::OnPreUnInstall()
StopRunningInstance();
}
-void CPVRClient::ResetProperties(int iClientId /* = PVR_INVALID_CLIENT_ID */)
+void CPVRClient::ResetProperties()
{
std::unique_lock<CCriticalSection> lock(m_critSection);
@@ -120,7 +120,6 @@ void CPVRClient::ResetProperties(int iClientId /* = PVR_INVALID_CLIENT_ID */)
m_connectionState = PVR_CONNECTION_STATE_UNKNOWN;
m_prevConnectionState = PVR_CONNECTION_STATE_UNKNOWN;
m_ignoreClient = false;
- m_iClientId = iClientId;
m_iPriority = 0;
m_bPriorityFetched = false;
m_strBackendVersion = DEFAULT_INFO_STRING_VALUE;
@@ -165,13 +164,11 @@ void CPVRClient::ResetProperties(int iClientId /* = PVR_INVALID_CLIENT_ID */)
memset(m_ifc.pvr->toAddon, 0, sizeof(KodiToAddonFuncTable_PVR));
}
-ADDON_STATUS CPVRClient::Create(int iClientId)
+ADDON_STATUS CPVRClient::Create()
{
ADDON_STATUS status(ADDON_STATUS_UNKNOWN);
- if (iClientId <= PVR_INVALID_CLIENT_ID)
- return status;
- ResetProperties(iClientId);
+ ResetProperties();
/* initialise the add-on */
CLog::LogFC(LOGDEBUG, LOGPVR, "Creating PVR add-on instance '{}'", ID());
@@ -222,11 +219,8 @@ void CPVRClient::Continue()
void CPVRClient::ReCreate()
{
- int iClientID(m_iClientId);
Destroy();
-
- /* recreate the instance */
- Create(iClientID);
+ Create();
}
bool CPVRClient::ReadyToUse() const
@@ -273,6 +267,21 @@ bool CPVRClient::IgnoreClient() const
return m_ignoreClient;
}
+bool CPVRClient::IsEnabled() const
+{
+ if (InstanceId() == ADDON_SINGLETON_INSTANCE_ID)
+ {
+ return !CServiceBroker::GetAddonMgr().IsAddonDisabled(ID());
+ }
+ else
+ {
+ bool instanceEnabled{false};
+ Addon()->ReloadSettings(InstanceId());
+ Addon()->GetSettingBool(ADDON_SETTING_INSTANCE_ENABLED_VALUE, instanceEnabled, InstanceId());
+ return instanceEnabled;
+ }
+}
+
int CPVRClient::GetID() const
{
return m_iClientId;
@@ -2134,72 +2143,4 @@ PVR_CODEC CPVRClient::cb_get_codec_by_name(const void* kodiInstance, const char*
return result;
}
-CPVRClientCapabilities::CPVRClientCapabilities(const CPVRClientCapabilities& other)
-{
- if (other.m_addonCapabilities)
- m_addonCapabilities.reset(new PVR_ADDON_CAPABILITIES(*other.m_addonCapabilities));
- InitRecordingsLifetimeValues();
-}
-
-const CPVRClientCapabilities& CPVRClientCapabilities::operator=(const CPVRClientCapabilities& other)
-{
- if (other.m_addonCapabilities)
- m_addonCapabilities.reset(new PVR_ADDON_CAPABILITIES(*other.m_addonCapabilities));
- InitRecordingsLifetimeValues();
- return *this;
-}
-
-const CPVRClientCapabilities& CPVRClientCapabilities::operator=(
- const PVR_ADDON_CAPABILITIES& addonCapabilities)
-{
- m_addonCapabilities.reset(new PVR_ADDON_CAPABILITIES(addonCapabilities));
- InitRecordingsLifetimeValues();
- return *this;
-}
-
-void CPVRClientCapabilities::clear()
-{
- m_recordingsLifetimeValues.clear();
- m_addonCapabilities.reset();
-}
-
-void CPVRClientCapabilities::InitRecordingsLifetimeValues()
-{
- m_recordingsLifetimeValues.clear();
- if (m_addonCapabilities && m_addonCapabilities->iRecordingsLifetimesSize > 0)
- {
- for (unsigned int i = 0; i < m_addonCapabilities->iRecordingsLifetimesSize; ++i)
- {
- int iValue = m_addonCapabilities->recordingsLifetimeValues[i].iValue;
- std::string strDescr(m_addonCapabilities->recordingsLifetimeValues[i].strDescription);
- if (strDescr.empty())
- {
- // No description given by addon. Create one from value.
- strDescr = std::to_string(iValue);
- }
- m_recordingsLifetimeValues.emplace_back(strDescr, iValue);
- }
- }
- else if (SupportsRecordingsLifetimeChange())
- {
- // No values given by addon, but lifetime supported. Use default values 1..365
- for (int i = 1; i < 366; ++i)
- {
- m_recordingsLifetimeValues.emplace_back(StringUtils::Format(g_localizeStrings.Get(17999), i),
- i); // "{} days"
- }
- }
- else
- {
- // No lifetime supported.
- }
-}
-
-void CPVRClientCapabilities::GetRecordingsLifetimeValues(
- std::vector<std::pair<std::string, int>>& list) const
-{
- std::copy(m_recordingsLifetimeValues.cbegin(), m_recordingsLifetimeValues.cend(),
- std::back_inserter(list));
-}
-
} // namespace PVR
diff --git a/xbmc/pvr/addons/PVRClient.h b/xbmc/pvr/addons/PVRClient.h
index 572d505272..ef411657e7 100644
--- a/xbmc/pvr/addons/PVRClient.h
+++ b/xbmc/pvr/addons/PVRClient.h
@@ -10,6 +10,7 @@
#include "addons/binary-addons/AddonInstanceHandler.h"
#include "addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr.h"
+#include "pvr/addons/PVRClientCapabilities.h"
#include "threads/Event.h"
#include <atomic>
@@ -41,262 +42,6 @@ class CPVRTimersContainer;
#define PVR_INVALID_CLIENT_ID (-2)
-class CPVRClientCapabilities
-{
-public:
- CPVRClientCapabilities() = default;
- virtual ~CPVRClientCapabilities() = default;
-
- CPVRClientCapabilities(const CPVRClientCapabilities& other);
- const CPVRClientCapabilities& operator=(const CPVRClientCapabilities& other);
-
- const CPVRClientCapabilities& operator=(const PVR_ADDON_CAPABILITIES& addonCapabilities);
-
- void clear();
-
- /////////////////////////////////////////////////////////////////////////////////
- //
- // Channels
- //
- /////////////////////////////////////////////////////////////////////////////////
-
- /*!
- * @brief Check whether this add-on supports TV channels.
- * @return True if supported, false otherwise.
- */
- bool SupportsTV() const { return m_addonCapabilities && m_addonCapabilities->bSupportsTV; }
-
- /*!
- * @brief Check whether this add-on supports radio channels.
- * @return True if supported, false otherwise.
- */
- bool SupportsRadio() const { return m_addonCapabilities && m_addonCapabilities->bSupportsRadio; }
-
- /*!
- * @brief Check whether this add-on supports providers.
- * @return True if supported, false otherwise.
- */
- bool SupportsProviders() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsProviders;
- }
-
- /*!
- * @brief Check whether this add-on supports channel groups.
- * @return True if supported, false otherwise.
- */
- bool SupportsChannelGroups() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsChannelGroups;
- }
-
- /*!
- * @brief Check whether this add-on supports scanning for new channels on the backend.
- * @return True if supported, false otherwise.
- */
- bool SupportsChannelScan() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsChannelScan;
- }
-
- /*!
- * @brief Check whether this add-on supports the following functions:
- * DeleteChannel, RenameChannel, DialogChannelSettings and DialogAddChannel.
- *
- * @return True if supported, false otherwise.
- */
- bool SupportsChannelSettings() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsChannelSettings;
- }
-
- /*!
- * @brief Check whether this add-on supports descramble information for playing channels.
- * @return True if supported, false otherwise.
- */
- bool SupportsDescrambleInfo() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsDescrambleInfo;
- }
-
- /////////////////////////////////////////////////////////////////////////////////
- //
- // EPG
- //
- /////////////////////////////////////////////////////////////////////////////////
-
- /*!
- * @brief Check whether this add-on provides EPG information.
- * @return True if supported, false otherwise.
- */
- bool SupportsEPG() const { return m_addonCapabilities && m_addonCapabilities->bSupportsEPG; }
-
- /*!
- * @brief Check whether this add-on supports asynchronous transfer of epg events.
- * @return True if supported, false otherwise.
- */
- bool SupportsAsyncEPGTransfer() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsAsyncEPGTransfer;
- }
-
- /////////////////////////////////////////////////////////////////////////////////
- //
- // Timers
- //
- /////////////////////////////////////////////////////////////////////////////////
-
- /*!
- * @brief Check whether this add-on supports the creation and editing of timers.
- * @return True if supported, false otherwise.
- */
- bool SupportsTimers() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsTimers;
- }
-
- /////////////////////////////////////////////////////////////////////////////////
- //
- // Recordings
- //
- /////////////////////////////////////////////////////////////////////////////////
-
- /*!
- * @brief Check whether this add-on supports recordings.
- * @return True if supported, false otherwise.
- */
- bool SupportsRecordings() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings;
- }
-
- /*!
- * @brief Check whether this add-on supports undelete of deleted recordings.
- * @return True if supported, false otherwise.
- */
- bool SupportsRecordingsUndelete() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
- m_addonCapabilities->bSupportsRecordingsUndelete;
- }
-
- /*!
- * @brief Check whether this add-on supports play count for recordings.
- * @return True if supported, false otherwise.
- */
- bool SupportsRecordingsPlayCount() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
- m_addonCapabilities->bSupportsRecordingPlayCount;
- }
-
- /*!
- * @brief Check whether this add-on supports store/retrieve of last played position for recordings..
- * @return True if supported, false otherwise.
- */
- bool SupportsRecordingsLastPlayedPosition() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
- m_addonCapabilities->bSupportsLastPlayedPosition;
- }
-
- /*!
- * @brief Check whether this add-on supports retrieving an edit decision list for recordings.
- * @return True if supported, false otherwise.
- */
- bool SupportsRecordingsEdl() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
- m_addonCapabilities->bSupportsRecordingEdl;
- }
-
- /*!
- * @brief Check whether this add-on supports retrieving an edit decision list for epg tags.
- * @return True if supported, false otherwise.
- */
- bool SupportsEpgTagEdl() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsEPG &&
- m_addonCapabilities->bSupportsEPGEdl;
- }
-
- /*!
- * @brief Check whether this add-on supports renaming recordings..
- * @return True if supported, false otherwise.
- */
- bool SupportsRecordingsRename() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
- m_addonCapabilities->bSupportsRecordingsRename;
- }
-
- /*!
- * @brief Check whether this add-on supports changing lifetime of recording.
- * @return True if supported, false otherwise.
- */
- bool SupportsRecordingsLifetimeChange() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
- m_addonCapabilities->bSupportsRecordingsLifetimeChange;
- }
-
- /*!
- * @brief Obtain a list with all possible values for recordings lifetime.
- * @param list out, the list with the values or an empty list, if lifetime is not supported.
- */
- void GetRecordingsLifetimeValues(std::vector<std::pair<std::string, int>>& list) const;
-
- /*!
- * @brief Check whether this add-on supports retrieving the size recordings..
- * @return True if supported, false otherwise.
- */
- bool SupportsRecordingsSize() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
- m_addonCapabilities->bSupportsRecordingSize;
- }
-
- /*!
- * @brief Check whether this add-on supports deleting recordings.
- * @return True if supported, false otherwise.
- */
- bool SupportsRecordingsDelete() const
- {
- return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
- m_addonCapabilities->bSupportsRecordingsDelete;
- }
-
- /////////////////////////////////////////////////////////////////////////////////
- //
- // Streams
- //
- /////////////////////////////////////////////////////////////////////////////////
-
- /*!
- * @brief Check whether this add-on provides an input stream. false if Kodi handles the stream.
- * @return True if supported, false otherwise.
- */
- bool HandlesInputStream() const
- {
- return m_addonCapabilities && m_addonCapabilities->bHandlesInputStream;
- }
-
- /*!
- * @brief Check whether this add-on demultiplexes packets.
- * @return True if supported, false otherwise.
- */
- bool HandlesDemuxing() const
- {
- return m_addonCapabilities && m_addonCapabilities->bHandlesDemuxing;
- }
-
-private:
- void InitRecordingsLifetimeValues();
-
- std::unique_ptr<PVR_ADDON_CAPABILITIES> m_addonCapabilities;
- std::vector<std::pair<std::string, int>> m_recordingsLifetimeValues;
-};
-
/*!
* Interface from Kodi to a PVR add-on.
*
@@ -305,7 +50,7 @@ private:
class CPVRClient : public ADDON::IAddonInstanceHandler
{
public:
- CPVRClient(const ADDON::AddonInfoPtr& addonInfo, ADDON::AddonInstanceId instanceId);
+ CPVRClient(const ADDON::AddonInfoPtr& addonInfo, ADDON::AddonInstanceId instanceId, int clientId);
~CPVRClient() override;
void OnPreInstall() override;
@@ -316,9 +61,8 @@ public:
/*!
* @brief Initialise the instance of this add-on.
- * @param iClientId The ID of this add-on.
*/
- ADDON_STATUS Create(int iClientId);
+ ADDON_STATUS Create();
/*!
* @brief Stop this add-on instance. No more client add-on access after this call.
@@ -364,12 +108,18 @@ public:
PVR_CONNECTION_STATE GetPreviousConnectionState() const;
/*!
- * @brief signal to PVRManager this client should be ignored
- * @return true if this client should be ignored
+ * @brief Check whether this client should be ignored.
+ * @return True if this client should be ignored, false otherwise.
*/
bool IgnoreClient() const;
/*!
+ * @brief Check whether this client is enabled, according to its instance/add-on configuration.
+ * @return True if this client is enabled, false otherwise.
+ */
+ bool IsEnabled() const;
+
+ /*!
* @return The ID of this instance.
*/
int GetID() const;
@@ -1039,9 +789,9 @@ public:
private:
/*!
- * @brief Resets all class members to their defaults. Called by the constructors.
+ * @brief Resets all class members to their defaults, accept the client id.
*/
- void ResetProperties(int iClientId = PVR_INVALID_CLIENT_ID);
+ void ResetProperties();
/*!
* @brief reads the client's properties.
@@ -1303,6 +1053,7 @@ private:
static PVR_CODEC cb_get_codec_by_name(const void* kodiInstance, const char* strCodecName);
//@}
+ const int m_iClientId; /*!< unique ID of the client */
std::atomic<bool>
m_bReadyToUse; /*!< true if this add-on is initialised (ADDON_Create returned true), false otherwise */
std::atomic<bool> m_bBlockAddonCalls; /*!< true if no add-on API calls are allowed */
@@ -1314,7 +1065,6 @@ private:
m_ignoreClient; /*!< signals to PVRManager to ignore this client until it has been connected */
std::vector<std::shared_ptr<CPVRTimerType>>
m_timertypes; /*!< timer types supported by this backend */
- int m_iClientId; /*!< unique ID of the client */
mutable int m_iPriority; /*!< priority of the client */
mutable bool m_bPriorityFetched;
diff --git a/xbmc/pvr/addons/PVRClientCapabilities.cpp b/xbmc/pvr/addons/PVRClientCapabilities.cpp
new file mode 100644
index 0000000000..8650465ce8
--- /dev/null
+++ b/xbmc/pvr/addons/PVRClientCapabilities.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2012-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "PVRClientCapabilities.h"
+
+#include "guilib/LocalizeStrings.h"
+#include "utils/StringUtils.h"
+
+#include <algorithm>
+#include <iterator>
+
+using namespace PVR;
+
+CPVRClientCapabilities::CPVRClientCapabilities(const CPVRClientCapabilities& other)
+{
+ if (other.m_addonCapabilities)
+ m_addonCapabilities.reset(new PVR_ADDON_CAPABILITIES(*other.m_addonCapabilities));
+ InitRecordingsLifetimeValues();
+}
+
+const CPVRClientCapabilities& CPVRClientCapabilities::operator=(const CPVRClientCapabilities& other)
+{
+ if (other.m_addonCapabilities)
+ m_addonCapabilities.reset(new PVR_ADDON_CAPABILITIES(*other.m_addonCapabilities));
+ InitRecordingsLifetimeValues();
+ return *this;
+}
+
+const CPVRClientCapabilities& CPVRClientCapabilities::operator=(
+ const PVR_ADDON_CAPABILITIES& addonCapabilities)
+{
+ m_addonCapabilities.reset(new PVR_ADDON_CAPABILITIES(addonCapabilities));
+ InitRecordingsLifetimeValues();
+ return *this;
+}
+
+void CPVRClientCapabilities::clear()
+{
+ m_recordingsLifetimeValues.clear();
+ m_addonCapabilities.reset();
+}
+
+void CPVRClientCapabilities::InitRecordingsLifetimeValues()
+{
+ m_recordingsLifetimeValues.clear();
+ if (m_addonCapabilities && m_addonCapabilities->iRecordingsLifetimesSize > 0)
+ {
+ for (unsigned int i = 0; i < m_addonCapabilities->iRecordingsLifetimesSize; ++i)
+ {
+ int iValue = m_addonCapabilities->recordingsLifetimeValues[i].iValue;
+ std::string strDescr(m_addonCapabilities->recordingsLifetimeValues[i].strDescription);
+ if (strDescr.empty())
+ {
+ // No description given by addon. Create one from value.
+ strDescr = std::to_string(iValue);
+ }
+ m_recordingsLifetimeValues.emplace_back(strDescr, iValue);
+ }
+ }
+ else if (SupportsRecordingsLifetimeChange())
+ {
+ // No values given by addon, but lifetime supported. Use default values 1..365
+ for (int i = 1; i < 366; ++i)
+ {
+ m_recordingsLifetimeValues.emplace_back(StringUtils::Format(g_localizeStrings.Get(17999), i),
+ i); // "{} days"
+ }
+ }
+ else
+ {
+ // No lifetime supported.
+ }
+}
+
+void CPVRClientCapabilities::GetRecordingsLifetimeValues(
+ std::vector<std::pair<std::string, int>>& list) const
+{
+ std::copy(m_recordingsLifetimeValues.cbegin(), m_recordingsLifetimeValues.cend(),
+ std::back_inserter(list));
+}
diff --git a/xbmc/pvr/addons/PVRClientCapabilities.h b/xbmc/pvr/addons/PVRClientCapabilities.h
new file mode 100644
index 0000000000..edf20900a0
--- /dev/null
+++ b/xbmc/pvr/addons/PVRClientCapabilities.h
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2012-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include "addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace PVR
+{
+
+class CPVRClientCapabilities
+{
+public:
+ CPVRClientCapabilities() = default;
+ virtual ~CPVRClientCapabilities() = default;
+
+ CPVRClientCapabilities(const CPVRClientCapabilities& other);
+ const CPVRClientCapabilities& operator=(const CPVRClientCapabilities& other);
+
+ const CPVRClientCapabilities& operator=(const PVR_ADDON_CAPABILITIES& addonCapabilities);
+
+ void clear();
+
+ /////////////////////////////////////////////////////////////////////////////////
+ //
+ // Channels
+ //
+ /////////////////////////////////////////////////////////////////////////////////
+
+ /*!
+ * @brief Check whether this add-on supports TV channels.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsTV() const { return m_addonCapabilities && m_addonCapabilities->bSupportsTV; }
+
+ /*!
+ * @brief Check whether this add-on supports radio channels.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsRadio() const { return m_addonCapabilities && m_addonCapabilities->bSupportsRadio; }
+
+ /*!
+ * @brief Check whether this add-on supports providers.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsProviders() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsProviders;
+ }
+
+ /*!
+ * @brief Check whether this add-on supports channel groups.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsChannelGroups() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsChannelGroups;
+ }
+
+ /*!
+ * @brief Check whether this add-on supports scanning for new channels on the backend.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsChannelScan() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsChannelScan;
+ }
+
+ /*!
+ * @brief Check whether this add-on supports the following functions:
+ * DeleteChannel, RenameChannel, DialogChannelSettings and DialogAddChannel.
+ *
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsChannelSettings() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsChannelSettings;
+ }
+
+ /*!
+ * @brief Check whether this add-on supports descramble information for playing channels.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsDescrambleInfo() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsDescrambleInfo;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////
+ //
+ // EPG
+ //
+ /////////////////////////////////////////////////////////////////////////////////
+
+ /*!
+ * @brief Check whether this add-on provides EPG information.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsEPG() const { return m_addonCapabilities && m_addonCapabilities->bSupportsEPG; }
+
+ /*!
+ * @brief Check whether this add-on supports asynchronous transfer of epg events.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsAsyncEPGTransfer() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsAsyncEPGTransfer;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////
+ //
+ // Timers
+ //
+ /////////////////////////////////////////////////////////////////////////////////
+
+ /*!
+ * @brief Check whether this add-on supports the creation and editing of timers.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsTimers() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsTimers;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////
+ //
+ // Recordings
+ //
+ /////////////////////////////////////////////////////////////////////////////////
+
+ /*!
+ * @brief Check whether this add-on supports recordings.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsRecordings() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings;
+ }
+
+ /*!
+ * @brief Check whether this add-on supports undelete of deleted recordings.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsRecordingsUndelete() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
+ m_addonCapabilities->bSupportsRecordingsUndelete;
+ }
+
+ /*!
+ * @brief Check whether this add-on supports play count for recordings.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsRecordingsPlayCount() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
+ m_addonCapabilities->bSupportsRecordingPlayCount;
+ }
+
+ /*!
+ * @brief Check whether this add-on supports store/retrieve of last played position for recordings..
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsRecordingsLastPlayedPosition() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
+ m_addonCapabilities->bSupportsLastPlayedPosition;
+ }
+
+ /*!
+ * @brief Check whether this add-on supports retrieving an edit decision list for recordings.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsRecordingsEdl() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
+ m_addonCapabilities->bSupportsRecordingEdl;
+ }
+
+ /*!
+ * @brief Check whether this add-on supports retrieving an edit decision list for epg tags.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsEpgTagEdl() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsEPG &&
+ m_addonCapabilities->bSupportsEPGEdl;
+ }
+
+ /*!
+ * @brief Check whether this add-on supports renaming recordings..
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsRecordingsRename() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
+ m_addonCapabilities->bSupportsRecordingsRename;
+ }
+
+ /*!
+ * @brief Check whether this add-on supports changing lifetime of recording.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsRecordingsLifetimeChange() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
+ m_addonCapabilities->bSupportsRecordingsLifetimeChange;
+ }
+
+ /*!
+ * @brief Obtain a list with all possible values for recordings lifetime.
+ * @param list out, the list with the values or an empty list, if lifetime is not supported.
+ */
+ void GetRecordingsLifetimeValues(std::vector<std::pair<std::string, int>>& list) const;
+
+ /*!
+ * @brief Check whether this add-on supports retrieving the size recordings..
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsRecordingsSize() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
+ m_addonCapabilities->bSupportsRecordingSize;
+ }
+
+ /*!
+ * @brief Check whether this add-on supports deleting recordings.
+ * @return True if supported, false otherwise.
+ */
+ bool SupportsRecordingsDelete() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bSupportsRecordings &&
+ m_addonCapabilities->bSupportsRecordingsDelete;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////
+ //
+ // Streams
+ //
+ /////////////////////////////////////////////////////////////////////////////////
+
+ /*!
+ * @brief Check whether this add-on provides an input stream. false if Kodi handles the stream.
+ * @return True if supported, false otherwise.
+ */
+ bool HandlesInputStream() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bHandlesInputStream;
+ }
+
+ /*!
+ * @brief Check whether this add-on demultiplexes packets.
+ * @return True if supported, false otherwise.
+ */
+ bool HandlesDemuxing() const
+ {
+ return m_addonCapabilities && m_addonCapabilities->bHandlesDemuxing;
+ }
+
+private:
+ void InitRecordingsLifetimeValues();
+
+ std::unique_ptr<PVR_ADDON_CAPABILITIES> m_addonCapabilities;
+ std::vector<std::pair<std::string, int>> m_recordingsLifetimeValues;
+};
+
+} // namespace PVR
diff --git a/xbmc/pvr/addons/PVRClientUID.cpp b/xbmc/pvr/addons/PVRClientUID.cpp
new file mode 100644
index 0000000000..87883851ea
--- /dev/null
+++ b/xbmc/pvr/addons/PVRClientUID.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012-2022 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "PVRClientUID.h"
+
+#include <functional>
+
+using namespace PVR;
+
+int CPVRClientUID::GetUID() const
+{
+ if (!m_uidCreated)
+ {
+ std::hash<std::string> hasher;
+
+ // Note: For database backwards compatibility reasons the hash of the first instance
+ // must be calculated just from the addonId, not from addonId and instanceId.
+ m_uid = static_cast<int>(hasher(
+ (m_instanceID > ADDON::ADDON_FIRST_INSTANCE_ID ? std::to_string(m_instanceID) + "@" : "") +
+ m_addonID));
+ if (m_uid < 0)
+ m_uid = -m_uid;
+
+ m_uidCreated = true;
+ }
+
+ return m_uid;
+}
diff --git a/xbmc/pvr/addons/PVRClientUID.h b/xbmc/pvr/addons/PVRClientUID.h
new file mode 100644
index 0000000000..5b5d1c0507
--- /dev/null
+++ b/xbmc/pvr/addons/PVRClientUID.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012-2022 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include "addons/IAddon.h"
+
+#include <string>
+
+namespace PVR
+{
+class CPVRClientUID final
+{
+public:
+ CPVRClientUID(const std::string& addonID, ADDON::AddonInstanceId instanceID)
+ : m_addonID(addonID), m_instanceID(instanceID)
+ {
+ }
+
+ virtual ~CPVRClientUID() = default;
+
+ /*!
+ * @brief Return the numeric UID.
+ * @return The numeric UID.
+ */
+ int GetUID() const;
+
+private:
+ CPVRClientUID() = delete;
+
+ std::string m_addonID;
+ ADDON::AddonInstanceId m_instanceID{ADDON::ADDON_SINGLETON_INSTANCE_ID};
+
+ mutable bool m_uidCreated{false};
+ mutable int m_uid{0};
+};
+} // namespace PVR
diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp
index 121bd1df02..2af39feeea 100644
--- a/xbmc/pvr/addons/PVRClients.cpp
+++ b/xbmc/pvr/addons/PVRClients.cpp
@@ -15,6 +15,7 @@
#include "pvr/PVRManager.h"
#include "pvr/PVRPlaybackState.h"
#include "pvr/addons/PVRClient.h"
+#include "pvr/addons/PVRClientUID.h"
#include "pvr/channels/PVRChannelGroupInternal.h"
#include "pvr/guilib/PVRGUIProgressHandler.h"
#include "utils/JobManager.h"
@@ -31,23 +32,6 @@
using namespace ADDON;
using namespace PVR;
-namespace
-{
-int ClientIdFromAddonIdAndInstanceId(const std::string& addonID, ADDON::AddonInstanceId instanceID)
-{
- std::hash<std::string> hasher;
-
- // Note: For database backwards compatibility reasons the hash of the first instance
- // must be calculated just from the addonId, not from addonId and instanceId.
- int iClientId = static_cast<int>(
- hasher((instanceID > ADDON::ADDON_FIRST_INSTANCE_ID ? std::to_string(instanceID) + "@" : "") +
- addonID));
- if (iClientId < 0)
- iClientId = -iClientId;
- return iClientId;
-}
-} // unnamed namespace
-
CPVRClients::CPVRClients()
{
CServiceBroker::GetAddonMgr().RegisterAddonMgrCallback(ADDON_PVRDLL, this);
@@ -67,7 +51,7 @@ CPVRClients::~CPVRClients()
void CPVRClients::Start()
{
- UpdateAddons();
+ UpdateClients();
}
void CPVRClients::Stop()
@@ -88,77 +72,43 @@ void CPVRClients::Continue()
}
}
-void CPVRClients::UpdateAddons(const std::string& changedAddonId /*= ""*/,
- ADDON::AddonInstanceId changedInstanceId /*= 0*/)
+void CPVRClients::UpdateClients(
+ const std::string& changedAddonId /* = "" */,
+ ADDON::AddonInstanceId changedInstanceId /* = ADDON::ADDON_SINGLETON_INSTANCE_ID */)
{
- std::vector<AddonInfoPtr> addons;
- CServiceBroker::GetAddonMgr().GetAddonInfos(addons, false, ADDON_PVRDLL);
-
- if (addons.empty())
- return;
-
- bool bFoundChangedAddon = changedAddonId.empty();
std::vector<std::pair<AddonInfoPtr, bool>> addonsWithStatus;
- for (const auto& addon : addons)
- {
- bool bEnabled = !CServiceBroker::GetAddonMgr().IsAddonDisabled(addon->ID());
- addonsWithStatus.emplace_back(std::make_pair(addon, bEnabled));
-
- if (!bFoundChangedAddon && addon->ID() == changedAddonId)
- bFoundChangedAddon = true;
- }
-
- if (!bFoundChangedAddon)
- return; // changed addon is not a known pvr client addon, so nothing to update
-
- addons.clear();
+ if (!GetAddonsWithStatus(changedAddonId, addonsWithStatus))
+ return;
- std::vector<std::pair<std::shared_ptr<CPVRClient>, int>> addonsToCreate;
- std::vector<std::pair<AddonInfoPtr, ADDON::AddonInstanceId>> addonsToReCreate;
- std::vector<std::pair<AddonInfoPtr, ADDON::AddonInstanceId>> addonsToDestroy;
+ std::vector<std::shared_ptr<CPVRClient>> clientsToCreate; // client
+ std::vector<std::pair<int, std::string>> clientsToReCreate; // client id, addon name
+ std::vector<int> clientsToDestroy; // client id
{
std::unique_lock<CCriticalSection> lock(m_critSection);
for (const auto& addonWithStatus : addonsWithStatus)
{
- AddonInfoPtr addon = addonWithStatus.first;
- bool bEnabled = addonWithStatus.second;
+ const AddonInfoPtr addon = addonWithStatus.first;
+ const std::vector<std::pair<ADDON::AddonInstanceId, bool>> instanceIdsWithStatus =
+ GetInstanceIdsWithStatus(addon, addonWithStatus.second);
- std::vector<std::pair<ADDON::AddonInstanceId, bool>> instanceIdsWithStatus;
+ for (const auto& instanceIdWithStatus : instanceIdsWithStatus)
{
- std::vector<ADDON::AddonInstanceId> instanceIds = addon->GetKnownInstanceIds();
- std::transform(instanceIds.cbegin(), instanceIds.cend(),
- std::back_inserter(instanceIdsWithStatus), [bEnabled](const auto& id) {
- return std::pair<ADDON::AddonInstanceId, bool>(id, bEnabled);
- });
- if (changedInstanceId != ADDON_SINGLETON_INSTANCE_ID && changedAddonId == addon->ID() &&
- std::find(instanceIds.begin(), instanceIds.end(), changedInstanceId) ==
- instanceIds.end())
- {
- // instance was removed
- instanceIdsWithStatus.emplace_back(
- std::pair<ADDON::AddonInstanceId, bool>(changedInstanceId, false));
- }
- }
-
- for (const auto& instanceInfo : instanceIdsWithStatus)
- {
- const ADDON::AddonInstanceId instanceId = instanceInfo.first;
- bool instanceEnabled = instanceInfo.second;
+ const ADDON::AddonInstanceId instanceId = instanceIdWithStatus.first;
+ bool instanceEnabled = instanceIdWithStatus.second;
+ const CPVRClientUID clientUID(addon->ID(), instanceId);
+ const int clientId = clientUID.GetUID();
- if (instanceEnabled &&
- (!IsKnownClient(addon->ID(), instanceId) || !IsCreatedClient(addon->ID(), instanceId)))
+ if (instanceEnabled && (!IsKnownClient(clientId) || !IsCreatedClient(clientId)))
{
- int iClientId = ClientIdFromAddonIdAndInstanceId(addon->ID(), instanceId);
-
std::shared_ptr<CPVRClient> client;
- if (IsKnownClient(addon->ID(), instanceId))
+ if (IsKnownClient(clientId))
{
- GetClient(iClientId, client);
+ client = GetClient(clientId);
}
else
{
- client = std::make_shared<CPVRClient>(addon, instanceId);
+ client = std::make_shared<CPVRClient>(addon, instanceId, clientId);
if (!client)
{
CLog::LogF(LOGERROR, "Severe error, incorrect add-on type");
@@ -168,41 +118,32 @@ void CPVRClients::UpdateAddons(const std::string& changedAddonId /*= ""*/,
// determine actual enabled state of instance
if (instanceId != ADDON_SINGLETON_INSTANCE_ID)
- client->Addon()->GetSettingBool(ADDON_SETTING_INSTANCE_ENABLED_VALUE, instanceEnabled,
- instanceId);
+ instanceEnabled = client->IsEnabled();
if (instanceEnabled)
- addonsToCreate.emplace_back(std::make_pair(client, iClientId));
+ clientsToCreate.emplace_back(client);
else
- addonsToDestroy.emplace_back(addon, instanceId);
+ clientsToDestroy.emplace_back(clientId);
}
- else if (IsCreatedClient(addon->ID(), instanceId))
+ else if (IsCreatedClient(clientId))
{
// determine actual enabled state of instance
if (instanceEnabled && instanceId != ADDON_SINGLETON_INSTANCE_ID)
{
- std::shared_ptr<CPVRClient> client;
- GetClient(GetClientId(addon->ID(), instanceId), client);
- if (client)
- {
- client->Addon()->ReloadSettings(instanceId);
- client->Addon()->GetSettingBool(ADDON_SETTING_INSTANCE_ENABLED_VALUE, instanceEnabled,
- instanceId);
- }
- else
- instanceEnabled = false;
+ const std::shared_ptr<CPVRClient> client = GetClient(clientId);
+ instanceEnabled = client ? client->IsEnabled() : false;
}
if (instanceEnabled)
- addonsToReCreate.emplace_back(addon, instanceId);
+ clientsToReCreate.emplace_back(clientId, addon->Name());
else
- addonsToDestroy.emplace_back(addon, instanceId);
+ clientsToDestroy.emplace_back(clientId);
}
}
}
}
- if (!addonsToCreate.empty() || !addonsToReCreate.empty() || !addonsToDestroy.empty())
+ if (!clientsToCreate.empty() || !clientsToReCreate.empty() || !clientsToDestroy.empty())
{
CServiceBroker::GetPVRManager().Stop();
@@ -210,54 +151,54 @@ void CPVRClients::UpdateAddons(const std::string& changedAddonId /*= ""*/,
g_localizeStrings.Get(19239)); // Creating PVR clients
unsigned int i = 0;
- for (const auto& addon : addonsToCreate)
+ for (const auto& client : clientsToCreate)
{
- progressHandler->UpdateProgress(addon.first->Name(), i++,
- addonsToCreate.size() + addonsToReCreate.size());
+ progressHandler->UpdateProgress(client->Name(), i++,
+ clientsToCreate.size() + clientsToReCreate.size());
- ADDON_STATUS status = addon.first->Create(addon.second);
+ const ADDON_STATUS status = client->Create();
if (status != ADDON_STATUS_OK)
{
- CLog::LogF(LOGERROR, "Failed to create add-on {}, status = {}", addon.first->ID(), status);
+ CLog::LogF(LOGERROR, "Failed to create add-on {}, status = {}", client->ID(), status);
if (status == ADDON_STATUS_PERMANENT_FAILURE)
{
- CServiceBroker::GetAddonMgr().DisableAddon(addon.first->ID(),
+ CServiceBroker::GetAddonMgr().DisableAddon(client->ID(),
AddonDisabledReason::PERMANENT_FAILURE);
- CServiceBroker::GetJobManager()->AddJob(
- new CPVREventLogJob(true, true, addon.first->Name(), g_localizeStrings.Get(24070),
- addon.first->Icon()),
- nullptr);
+ CServiceBroker::GetJobManager()->AddJob(new CPVREventLogJob(true, true, client->Name(),
+ g_localizeStrings.Get(24070),
+ client->Icon()),
+ nullptr);
}
}
}
- for (const auto& addon : addonsToReCreate)
+ for (const auto& clientInfo : clientsToReCreate)
{
- progressHandler->UpdateProgress(addon.first->Name(), i++,
- addonsToCreate.size() + addonsToReCreate.size());
+ progressHandler->UpdateProgress(clientInfo.second, i++,
+ clientsToCreate.size() + clientsToReCreate.size());
- // recreate client
- StopClient(addon.first->ID(), addon.second, true);
+ // stop and recreate client
+ StopClient(clientInfo.first, true /* restart */);
}
progressHandler.reset();
- for (const auto& addon : addonsToDestroy)
+ for (const auto& client : clientsToDestroy)
{
// destroy client
- StopClient(addon.first->ID(), addon.second, false);
+ StopClient(client, false /* no restart */);
}
- if (!addonsToCreate.empty())
+ if (!clientsToCreate.empty())
{
// update created clients map
std::unique_lock<CCriticalSection> lock(m_critSection);
- for (const auto& addon : addonsToCreate)
+ for (const auto& client : clientsToCreate)
{
- if (m_clientMap.find(addon.second) == m_clientMap.end())
+ if (m_clientMap.find(client->GetID()) == m_clientMap.end())
{
- m_clientMap.insert(std::make_pair(addon.second, addon.first));
+ m_clientMap.insert({client->GetID(), client});
}
}
}
@@ -271,15 +212,13 @@ bool CPVRClients::RequestRestart(const std::string& addonId,
bool bDataChanged)
{
CServiceBroker::GetJobManager()->Submit([this, addonId, instanceId] {
- UpdateAddons(addonId, instanceId);
+ UpdateClients(addonId, instanceId);
return true;
});
return true;
}
-bool CPVRClients::StopClient(const std::string& addonId,
- ADDON::AddonInstanceId instanceId,
- bool bRestart)
+bool CPVRClients::StopClient(int clientId, bool restart)
{
// stop playback if needed
if (CServiceBroker::GetPVRManager().PlaybackState()->IsPlaying())
@@ -287,21 +226,20 @@ bool CPVRClients::StopClient(const std::string& addonId,
std::unique_lock<CCriticalSection> lock(m_critSection);
- int iId = GetClientId(addonId, instanceId);
- std::shared_ptr<CPVRClient> mappedClient;
- if (GetClient(iId, mappedClient))
+ const std::shared_ptr<CPVRClient> client = GetClient(clientId);
+ if (client)
{
- if (bRestart)
+ if (restart)
{
- mappedClient->ReCreate();
+ client->ReCreate();
}
else
{
- const auto it = m_clientMap.find(iId);
+ const auto it = m_clientMap.find(clientId);
if (it != m_clientMap.end())
m_clientMap.erase(it);
- mappedClient->Destroy();
+ client->Destroy();
}
return true;
}
@@ -324,7 +262,7 @@ void CPVRClients::OnAddonEvent(const AddonEvent& event)
if (CServiceBroker::GetAddonMgr().HasType(addonId, ADDON_PVRDLL))
{
CServiceBroker::GetJobManager()->Submit([this, addonId, instanceId] {
- UpdateAddons(addonId, instanceId);
+ UpdateClients(addonId, instanceId);
return true;
});
}
@@ -335,31 +273,17 @@ void CPVRClients::OnAddonEvent(const AddonEvent& event)
// client access
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool CPVRClients::GetClient(int iClientId, std::shared_ptr<CPVRClient>& addon) const
+std::shared_ptr<CPVRClient> CPVRClients::GetClient(int clientId) const
{
- bool bReturn = false;
- if (iClientId <= PVR_INVALID_CLIENT_ID)
- return bReturn;
+ if (clientId <= PVR_INVALID_CLIENT_ID)
+ return {};
std::unique_lock<CCriticalSection> lock(m_critSection);
- const auto& itr = m_clientMap.find(iClientId);
- if (itr != m_clientMap.end())
- {
- addon = itr->second;
- bReturn = true;
- }
+ const auto it = m_clientMap.find(clientId);
+ if (it != m_clientMap.end())
+ return it->second;
- return bReturn;
-}
-
-int CPVRClients::GetClientId(const std::string& addonId, ADDON::AddonInstanceId instanceId) const
-{
- std::unique_lock<CCriticalSection> lock(m_critSection);
- const auto it = std::find_if(
- m_clientMap.cbegin(), m_clientMap.cend(), [&addonId, instanceId](const auto& entry) {
- return entry.second->ID() == addonId && entry.second->InstanceId() == instanceId;
- });
- return it != m_clientMap.cend() ? (*it).first : -1;
+ return {};
}
int CPVRClients::CreatedClientAmount() const
@@ -376,40 +300,32 @@ bool CPVRClients::HasCreatedClients() const
[](const auto& client) { return client.second->ReadyToUse(); });
}
-bool CPVRClients::IsKnownClient(const std::string& addonId, ADDON::AddonInstanceId instanceId) const
+bool CPVRClients::IsKnownClient(int clientId) const
{
+ std::unique_lock<CCriticalSection> lock(m_critSection);
+
// valid client IDs start at 1
- return GetClientId(addonId, instanceId) > 0;
+ const auto it = m_clientMap.find(clientId);
+ return (it != m_clientMap.end() && (*it).second->GetID() > 0);
}
bool CPVRClients::IsCreatedClient(int iClientId) const
{
- std::shared_ptr<CPVRClient> client;
- return GetCreatedClient(iClientId, client);
+ return GetCreatedClient(iClientId) != nullptr;
}
-bool CPVRClients::IsCreatedClient(const std::string& addonId,
- ADDON::AddonInstanceId instanceId) const
+std::shared_ptr<CPVRClient> CPVRClients::GetCreatedClient(int clientId) const
{
- std::unique_lock<CCriticalSection> lock(m_critSection);
- const auto it = std::find_if(
- m_clientMap.cbegin(), m_clientMap.cend(), [&addonId, instanceId](const auto& client) {
- return client.second->ID() == addonId && client.second->InstanceId() == instanceId;
- });
- return it != m_clientMap.cend() ? (*it).second->ReadyToUse() : false;
-}
-
-bool CPVRClients::GetCreatedClient(int iClientId, std::shared_ptr<CPVRClient>& addon) const
-{
- if (GetClient(iClientId, addon))
- return addon->ReadyToUse();
+ const std::shared_ptr<CPVRClient> client = GetClient(clientId);
+ if (client && client->ReadyToUse())
+ return client;
- return false;
+ return {};
}
-int CPVRClients::GetCreatedClients(CPVRClientMap& clients) const
+CPVRClientMap CPVRClients::GetCreatedClients() const
{
- int iReturn = 0;
+ CPVRClientMap clients;
std::unique_lock<CCriticalSection> lock(m_critSection);
for (const auto& client : m_clientMap)
@@ -417,11 +333,10 @@ int CPVRClients::GetCreatedClients(CPVRClientMap& clients) const
if (client.second->ReadyToUse())
{
clients.insert(std::make_pair(client.second->GetID(), client.second));
- ++iReturn;
}
}
- return iReturn;
+ return clients;
}
std::vector<CVariant> CPVRClients::GetClientProviderInfos() const
@@ -439,11 +354,7 @@ std::vector<CVariant> CPVRClients::GetClientProviderInfos() const
for (const auto& instanceId : instanceIds)
{
CVariant clientProviderInfo(CVariant::VariantTypeObject);
- if (IsKnownClient(addonInfo->ID(), instanceId))
- clientProviderInfo["clientid"] = GetClientId(addonInfo->ID(), instanceId);
- else
- clientProviderInfo["clientid"] =
- ClientIdFromAddonIdAndInstanceId(addonInfo->ID(), instanceId);
+ clientProviderInfo["clientid"] = CPVRClientUID(addonInfo->ID(), instanceId).GetUID();
clientProviderInfo["addonid"] = addonInfo->ID();
clientProviderInfo["instanceid"] = instanceId;
clientProviderInfo["enabled"] =
@@ -483,17 +394,16 @@ PVR_ERROR CPVRClients::GetCallableClients(CPVRClientMap& clientsReady,
std::vector<ADDON::AddonInstanceId> instanceIds = addon->GetKnownInstanceIds();
for (const auto& instanceId : instanceIds)
{
- int iClientId = ClientIdFromAddonIdAndInstanceId(addon->ID(), instanceId);
- std::shared_ptr<CPVRClient> client;
- GetClient(iClientId, client);
+ const int clientId = CPVRClientUID(addon->ID(), instanceId).GetUID();
+ const std::shared_ptr<CPVRClient> client = GetClient(clientId);
if (client && client->ReadyToUse() && !client->IgnoreClient())
{
- clientsReady.insert(std::make_pair(iClientId, client));
+ clientsReady.insert(std::make_pair(clientId, client));
}
else
{
- clientsNotReady.emplace_back(iClientId);
+ clientsNotReady.emplace_back(clientId);
}
}
}
@@ -517,8 +427,7 @@ int CPVRClients::EnabledClientAmount() const
bool CPVRClients::IsEnabledClient(int clientId) const
{
- std::shared_ptr<CPVRClient> client;
- GetClient(clientId, client);
+ const std::shared_ptr<CPVRClient> client = GetClient(clientId);
return client && !CServiceBroker::GetAddonMgr().IsAddonDisabled(client->ID());
}
@@ -569,6 +478,70 @@ bool CPVRClients::HasIgnoredClients() const
[](const auto& client) { return client.second->IgnoreClient(); });
}
+std::vector<ADDON::AddonInstanceId> CPVRClients::GetKnownInstanceIds(
+ const std::string& addonID) const
+{
+ std::vector<ADDON::AddonInstanceId> instanceIds;
+
+ std::unique_lock<CCriticalSection> lock(m_critSection);
+ for (const auto& entry : m_clientMap)
+ {
+ if (entry.second->ID() == addonID)
+ instanceIds.emplace_back(entry.second->InstanceId());
+ }
+
+ return instanceIds;
+}
+
+bool CPVRClients::GetAddonsWithStatus(
+ const std::string& changedAddonId,
+ std::vector<std::pair<AddonInfoPtr, bool>>& addonsWithStatus) const
+{
+ std::vector<AddonInfoPtr> addons;
+ CServiceBroker::GetAddonMgr().GetAddonInfos(addons, false, ADDON_PVRDLL);
+
+ if (addons.empty())
+ return false;
+
+ bool foundChangedAddon = changedAddonId.empty();
+ for (const auto& addon : addons)
+ {
+ bool enabled = !CServiceBroker::GetAddonMgr().IsAddonDisabled(addon->ID());
+ addonsWithStatus.emplace_back(std::make_pair(addon, enabled));
+
+ if (!foundChangedAddon && addon->ID() == changedAddonId)
+ foundChangedAddon = true;
+ }
+
+ return foundChangedAddon;
+}
+
+std::vector<std::pair<ADDON::AddonInstanceId, bool>> CPVRClients::GetInstanceIdsWithStatus(
+ const AddonInfoPtr& addon, bool addonIsEnabled) const
+{
+ std::vector<std::pair<ADDON::AddonInstanceId, bool>> instanceIdsWithStatus;
+
+ std::vector<ADDON::AddonInstanceId> instanceIds = addon->GetKnownInstanceIds();
+ std::transform(instanceIds.cbegin(), instanceIds.cend(),
+ std::back_inserter(instanceIdsWithStatus), [addonIsEnabled](const auto& id) {
+ return std::pair<ADDON::AddonInstanceId, bool>(id, addonIsEnabled);
+ });
+
+ // find removed instances
+ const std::vector<ADDON::AddonInstanceId> knownInstanceIds = GetKnownInstanceIds(addon->ID());
+ for (const auto& knownInstanceId : knownInstanceIds)
+ {
+ if (std::find(instanceIds.begin(), instanceIds.end(), knownInstanceId) == instanceIds.end())
+ {
+ // instance was removed
+ instanceIdsWithStatus.emplace_back(
+ std::pair<ADDON::AddonInstanceId, bool>(knownInstanceId, false));
+ }
+ }
+
+ return instanceIdsWithStatus;
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// client API calls
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -916,11 +889,10 @@ PVR_ERROR CPVRClients::ForCreatedClients(const char* strFunctionName,
if (!failedClients.empty())
{
+ std::shared_ptr<CPVRClient> client;
for (int id : failedClients)
{
- std::shared_ptr<CPVRClient> client;
- GetClient(id, client);
-
+ client = GetClient(id);
if (client)
LogClientWarning(strFunctionName, client);
}
diff --git a/xbmc/pvr/addons/PVRClients.h b/xbmc/pvr/addons/PVRClients.h
index 316c2461e4..8603688d36 100644
--- a/xbmc/pvr/addons/PVRClients.h
+++ b/xbmc/pvr/addons/PVRClients.h
@@ -77,12 +77,13 @@ namespace PVR
void Continue();
/*!
- * @brief Update add-ons from the AddonManager
+ * @brief Update all clients, sync with Addon Manager state (start, restart, shutdown clients).
* @param changedAddonId The id of the changed addon, empty string denotes 'any addon'.
* @param changedInstanceId The Identifier of the changed add-on instance
*/
- void UpdateAddons(const std::string& changedAddonId = "",
- ADDON::AddonInstanceId changedInstanceId = 0);
+ void UpdateClients(
+ const std::string& changedAddonId = "",
+ ADDON::AddonInstanceId changedInstanceId = ADDON::ADDON_SINGLETON_INSTANCE_ID);
/*!
* @brief Restart a single client add-on.
@@ -97,12 +98,11 @@ namespace PVR
/*!
* @brief Stop a client.
- * @param addonId The client to stop.
- * @param instance Identifier of the add-on instance.
- * @param bRestart If true, restart the client.
+ * @param clientId The id of the client to stop.
+ * @param restart If true, restart the client.
* @return True if the client was found, false otherwise.
*/
- bool StopClient(const std::string& addonId, ADDON::AddonInstanceId instance, bool bRestart);
+ bool StopClient(int clientId, bool restart);
/*!
* @brief Handle addon events (enable, disable, ...).
@@ -111,14 +111,6 @@ namespace PVR
void OnAddonEvent(const ADDON::AddonEvent& event);
/*!
- * @brief Get a client's numeric ID given its string ID.
- * @param addonId The string ID.
- * @param instance Identifier of the add-on instance.
- * @return The numeric ID matching the given string ID, -1 on error.
- */
- int GetClientId(const std::string& addonId, ADDON::AddonInstanceId instance) const;
-
- /*!
* @brief Get the number of created clients.
* @return The amount of created clients.
*/
@@ -138,25 +130,17 @@ namespace PVR
bool IsCreatedClient(int iClientId) const;
/*!
- * @brief Get the instance of the client, if it's created.
- * @param iClientId The ID of the client to get.
- * @param addon Will be filled with requested client on success, null otherwise.
- * @return True on success, false otherwise.
- */
- bool GetCreatedClient(int iClientId, std::shared_ptr<CPVRClient>& addon) const;
-
- /*!
- * @brief Get info required for providers. Include both enabled and disabled PVR add-ons
- * @return A list containing the information required to create client providers.
+ * @brief Get the the client for the given client id, if it is created.
+ * @param clientId The ID of the client to get.
+ * @return The client if found, nullptr otherwise.
*/
- std::vector<CVariant> GetClientProviderInfos() const;
+ std::shared_ptr<CPVRClient> GetCreatedClient(int clientId) const;
/*!
* @brief Get all created clients.
- * @param clients All created clients will be added to this map.
- * @return The amount of clients added to the map.
+ * @return All created clients.
*/
- int GetCreatedClients(CPVRClientMap& clients) const;
+ CPVRClientMap GetCreatedClients() const;
/*!
* @brief Get the ID of the first created client.
@@ -189,6 +173,12 @@ namespace PVR
*/
std::vector<CVariant> GetEnabledClientInfos() const;
+ /*!
+ * @brief Get info required for providers. Include both enabled and disabled PVR add-ons
+ * @return A list containing the information required to create client providers.
+ */
+ std::vector<CVariant> GetClientProviderInfos() const;
+
//@}
/*! @name general methods */
@@ -413,28 +403,32 @@ namespace PVR
private:
/*!
- * @brief Get the client instance for a given client id.
- * @param iClientId The id of the client to get.
- * @param addon The client.
- * @return True if the client was found, false otherwise.
+ * @brief Get the known instance ids for a given addon id.
+ * @param addonID The addon id.
+ * @return The list of known instance ids.
*/
- bool GetClient(int iClientId, std::shared_ptr<CPVRClient>& addon) const;
+ std::vector<ADDON::AddonInstanceId> GetKnownInstanceIds(const std::string& addonID) const;
+
+ bool GetAddonsWithStatus(
+ const std::string& changedAddonId,
+ std::vector<std::pair<ADDON::AddonInfoPtr, bool>>& addonsWithStatus) const;
+
+ std::vector<std::pair<ADDON::AddonInstanceId, bool>> GetInstanceIdsWithStatus(
+ const ADDON::AddonInfoPtr& addon, bool addonIsEnabled) const;
/*!
- * @brief Check whether a client is known.
- * @param addonId The add-on id to check.
- * @param instance Identifier of the add-on instance.
- * @return True if this client is known, false otherwise.
+ * @brief Get the client instance for a given client id.
+ * @param clientId The id of the client to get.
+ * @return The client if found, nullptr otherwise.
*/
- bool IsKnownClient(const std::string& addonId, ADDON::AddonInstanceId instance) const;
+ std::shared_ptr<CPVRClient> GetClient(int clientId) const;
/*!
- * @brief Check whether an given addon instance is a created pvr client.
- * @param addonId The add-on id.
- * @param instance Identifier of the add-on instance.
- * @return True if the the addon represents a created client, false otherwise.
+ * @brief Check whether a client is known.
+ * @param iClientId The id of the client to check.
+ * @return True if this client is known, false otherwise.
*/
- bool IsCreatedClient(const std::string& addonId, ADDON::AddonInstanceId instance) const;
+ bool IsKnownClient(int iClientId) const;
/*!
* @brief Get all created clients and clients not (yet) ready to use.
diff --git a/xbmc/pvr/channels/PVRChannelGroup.cpp b/xbmc/pvr/channels/PVRChannelGroup.cpp
index 0aa5c8781c..06674f8cdb 100644
--- a/xbmc/pvr/channels/PVRChannelGroup.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroup.cpp
@@ -246,8 +246,9 @@ bool CPVRChannelGroup::UpdateClientPriorities()
if (bUseBackendChannelOrder)
{
- std::shared_ptr<CPVRClient> client;
- if (!clients->GetCreatedClient(member->Channel()->ClientID(), client))
+ const std::shared_ptr<CPVRClient> client =
+ clients->GetCreatedClient(member->Channel()->ClientID());
+ if (!client)
continue;
iNewPriority = client->GetPriority();
diff --git a/xbmc/pvr/channels/PVRChannelGroups.cpp b/xbmc/pvr/channels/PVRChannelGroups.cpp
index 75f42be14c..77cc2b543f 100644
--- a/xbmc/pvr/channels/PVRChannelGroups.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroups.cpp
@@ -13,6 +13,7 @@
#include "pvr/PVRDatabase.h"
#include "pvr/PVRManager.h"
#include "pvr/addons/PVRClient.h"
+#include "pvr/addons/PVRClientUID.h"
#include "pvr/addons/PVRClients.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/channels/PVRChannelGroupInternal.h"
@@ -134,9 +135,8 @@ std::shared_ptr<CPVRChannelGroupMember> CPVRChannelGroups::GetChannelGroupMember
{
const std::shared_ptr<CPVRChannelGroup> group = GetByName(path.GetGroupName());
if (group)
- return group->GetByUniqueID({CServiceBroker::GetPVRManager().Clients()->GetClientId(
- path.GetClientID(), path.GetInstanceID()),
- path.GetChannelUID()});
+ return group->GetByUniqueID(
+ {CPVRClientUID(path.GetAddonID(), path.GetInstanceID()).GetUID(), path.GetChannelUID()});
}
return {};
diff --git a/xbmc/pvr/channels/PVRChannelsPath.cpp b/xbmc/pvr/channels/PVRChannelsPath.cpp
index 5fcb0fcf00..4ae2e28b00 100644
--- a/xbmc/pvr/channels/PVRChannelsPath.cpp
+++ b/xbmc/pvr/channels/PVRChannelsPath.cpp
@@ -73,12 +73,12 @@ CPVRChannelsPath::CPVRChannelsPath(const std::string& strPath)
if (instance.size() == 2)
{
m_instanceID = std::atoi(instance[0].c_str());
- m_clientID = instance[1];
+ m_addonID = instance[1];
}
else
{
m_instanceID = ADDON::ADDON_SINGLETON_INSTANCE_ID;
- m_clientID = tokens[0];
+ m_addonID = tokens[0];
}
tokens = StringUtils::Split(tokens[1], ".");
@@ -90,7 +90,7 @@ CPVRChannelsPath::CPVRChannelsPath(const std::string& strPath)
}
}
- if (!m_clientID.empty() && m_iChannelUID >= 0)
+ if (!m_addonID.empty() && m_iChannelUID >= 0)
{
m_kind = Kind::
CHANNEL; // pvr://channels/(tv|radio)/<groupname>/<instanceid>@<addonid>_<channeluid>.pvr
@@ -155,20 +155,20 @@ CPVRChannelsPath::CPVRChannelsPath(bool bRadio, const std::string& strGroupName)
CPVRChannelsPath::CPVRChannelsPath(bool bRadio,
const std::string& strGroupName,
- const std::string& strClientID,
+ const std::string& strAddonID,
ADDON::AddonInstanceId instanceID,
int iChannelUID)
: m_bRadio(bRadio)
{
- if (!strGroupName.empty() && !strClientID.empty() && iChannelUID >= 0)
+ if (!strGroupName.empty() && !strAddonID.empty() && iChannelUID >= 0)
{
m_kind = Kind::CHANNEL;
m_group = strGroupName;
- m_clientID = strClientID;
+ m_addonID = strAddonID;
m_instanceID = instanceID;
m_iChannelUID = iChannelUID;
m_path = StringUtils::Format("pvr://channels/{}/{}/{}@{}_{}.pvr", bRadio ? "radio" : "tv",
- CURL::Encode(m_group), m_instanceID, m_clientID, m_iChannelUID);
+ CURL::Encode(m_group), m_instanceID, m_addonID, m_iChannelUID);
}
}
diff --git a/xbmc/pvr/channels/PVRChannelsPath.h b/xbmc/pvr/channels/PVRChannelsPath.h
index 4f6d8a3058..7b825c19e0 100644
--- a/xbmc/pvr/channels/PVRChannelsPath.h
+++ b/xbmc/pvr/channels/PVRChannelsPath.h
@@ -25,7 +25,7 @@ namespace PVR
CPVRChannelsPath(bool bRadio, bool bHidden, const std::string& strGroupName);
CPVRChannelsPath(bool bRadio,
const std::string& strGroupName,
- const std::string& strClientID,
+ const std::string& strAddonID,
ADDON::AddonInstanceId instanceID,
int iChannelUID);
@@ -45,7 +45,7 @@ namespace PVR
bool IsRadio() const { return m_bRadio; }
const std::string& GetGroupName() const { return m_group; }
- const std::string& GetClientID() const { return m_clientID; }
+ const std::string& GetAddonID() const { return m_addonID; }
ADDON::AddonInstanceId GetInstanceID() const { return m_instanceID; }
int GetChannelUID() const { return m_iChannelUID; }
@@ -66,7 +66,7 @@ namespace PVR
bool m_bRadio = false;;
std::string m_path;
std::string m_group;
- std::string m_clientID;
+ std::string m_addonID;
ADDON::AddonInstanceId m_instanceID{ADDON::ADDON_SINGLETON_INSTANCE_ID};
int m_iChannelUID = -1;
};
diff --git a/xbmc/pvr/channels/test/TestPVRChannelsPath.cpp b/xbmc/pvr/channels/test/TestPVRChannelsPath.cpp
index b9239466bc..c7232dbdcf 100644
--- a/xbmc/pvr/channels/test/TestPVRChannelsPath.cpp
+++ b/xbmc/pvr/channels/test/TestPVRChannelsPath.cpp
@@ -56,7 +56,7 @@ TEST(TestPVRChannelsPath, Parse_TV_Root_1)
EXPECT_FALSE(path.IsHiddenChannelGroup());
EXPECT_FALSE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), "");
- EXPECT_EQ(path.GetClientID(), "");
+ EXPECT_EQ(path.GetAddonID(), "");
EXPECT_EQ(path.GetChannelUID(), -1);
}
@@ -73,7 +73,7 @@ TEST(TestPVRChannelsPath, Parse_TV_Root_2)
EXPECT_FALSE(path.IsHiddenChannelGroup());
EXPECT_FALSE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), "");
- EXPECT_EQ(path.GetClientID(), "");
+ EXPECT_EQ(path.GetAddonID(), "");
EXPECT_EQ(path.GetChannelUID(), -1);
}
@@ -90,7 +90,7 @@ TEST(TestPVRChannelsPath, Parse_Radio_Root_1)
EXPECT_FALSE(path.IsHiddenChannelGroup());
EXPECT_FALSE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), "");
- EXPECT_EQ(path.GetClientID(), "");
+ EXPECT_EQ(path.GetAddonID(), "");
EXPECT_EQ(path.GetChannelUID(), -1);
}
@@ -107,7 +107,7 @@ TEST(TestPVRChannelsPath, Parse_Radio_Root_2)
EXPECT_FALSE(path.IsHiddenChannelGroup());
EXPECT_FALSE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), "");
- EXPECT_EQ(path.GetClientID(), "");
+ EXPECT_EQ(path.GetAddonID(), "");
EXPECT_EQ(path.GetChannelUID(), -1);
}
@@ -131,7 +131,7 @@ TEST(TestPVRChannelsPath, Parse_TV_Group_1)
EXPECT_FALSE(path.IsHiddenChannelGroup());
EXPECT_FALSE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), "Group1");
- EXPECT_EQ(path.GetClientID(), "");
+ EXPECT_EQ(path.GetAddonID(), "");
EXPECT_EQ(path.GetChannelUID(), -1);
}
@@ -148,7 +148,7 @@ TEST(TestPVRChannelsPath, Parse_TV_Group_2)
EXPECT_FALSE(path.IsHiddenChannelGroup());
EXPECT_FALSE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), "Group1");
- EXPECT_EQ(path.GetClientID(), "");
+ EXPECT_EQ(path.GetAddonID(), "");
EXPECT_EQ(path.GetChannelUID(), -1);
}
@@ -165,7 +165,7 @@ TEST(TestPVRChannelsPath, Parse_Hidden_TV_Group)
EXPECT_TRUE(path.IsHiddenChannelGroup());
EXPECT_FALSE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), ".hidden");
- EXPECT_EQ(path.GetClientID(), "");
+ EXPECT_EQ(path.GetAddonID(), "");
EXPECT_EQ(path.GetChannelUID(), -1);
}
@@ -182,7 +182,7 @@ TEST(TestPVRChannelsPath, Parse_Special_TV_Group)
EXPECT_FALSE(path.IsHiddenChannelGroup());
EXPECT_FALSE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), "foo/bar baz");
- EXPECT_EQ(path.GetClientID(), "");
+ EXPECT_EQ(path.GetAddonID(), "");
EXPECT_EQ(path.GetChannelUID(), -1);
}
@@ -207,7 +207,7 @@ TEST(TestPVRChannelsPath, Parse_Radio_Group)
EXPECT_FALSE(path.IsHiddenChannelGroup());
EXPECT_FALSE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), "Group1");
- EXPECT_EQ(path.GetClientID(), "");
+ EXPECT_EQ(path.GetAddonID(), "");
EXPECT_EQ(path.GetChannelUID(), -1);
}
@@ -224,7 +224,7 @@ TEST(TestPVRChannelsPath, Parse_TV_Channel)
EXPECT_FALSE(path.IsHiddenChannelGroup());
EXPECT_TRUE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), "Group1");
- EXPECT_EQ(path.GetClientID(), "pvr.demo");
+ EXPECT_EQ(path.GetAddonID(), "pvr.demo");
EXPECT_EQ(path.GetInstanceID(), 5);
EXPECT_EQ(path.GetChannelUID(), 4711);
}
@@ -306,7 +306,7 @@ TEST(TestPVRChannelsPath, TV_Channelgroup)
EXPECT_FALSE(path.IsHiddenChannelGroup());
EXPECT_FALSE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), "Group1");
- EXPECT_EQ(path.GetClientID(), "");
+ EXPECT_EQ(path.GetAddonID(), "");
EXPECT_EQ(path.GetChannelUID(), -1);
}
@@ -323,7 +323,7 @@ TEST(TestPVRChannelsPath, Radio_Channelgroup)
EXPECT_FALSE(path.IsHiddenChannelGroup());
EXPECT_FALSE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), "Group1");
- EXPECT_EQ(path.GetClientID(), "");
+ EXPECT_EQ(path.GetAddonID(), "");
EXPECT_EQ(path.GetChannelUID(), -1);
}
@@ -340,7 +340,7 @@ TEST(TestPVRChannelsPath, Hidden_TV_Channelgroup)
EXPECT_TRUE(path.IsHiddenChannelGroup());
EXPECT_FALSE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), ".hidden");
- EXPECT_EQ(path.GetClientID(), "");
+ EXPECT_EQ(path.GetAddonID(), "");
EXPECT_EQ(path.GetChannelUID(), -1);
}
@@ -357,7 +357,7 @@ TEST(TestPVRChannelsPath, Hidden_Radio_Channelgroup)
EXPECT_TRUE(path.IsHiddenChannelGroup());
EXPECT_FALSE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), ".hidden");
- EXPECT_EQ(path.GetClientID(), "");
+ EXPECT_EQ(path.GetAddonID(), "");
EXPECT_EQ(path.GetChannelUID(), -1);
}
@@ -374,7 +374,7 @@ TEST(TestPVRChannelsPath, TV_Channel)
EXPECT_FALSE(path.IsHiddenChannelGroup());
EXPECT_TRUE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), "Group1");
- EXPECT_EQ(path.GetClientID(), "pvr.demo");
+ EXPECT_EQ(path.GetAddonID(), "pvr.demo");
EXPECT_EQ(path.GetChannelUID(), 4711);
}
@@ -391,7 +391,7 @@ TEST(TestPVRChannelsPath, Radio_Channel)
EXPECT_FALSE(path.IsHiddenChannelGroup());
EXPECT_TRUE(path.IsChannel());
EXPECT_EQ(path.GetGroupName(), "Group1");
- EXPECT_EQ(path.GetClientID(), "pvr.demo");
+ EXPECT_EQ(path.GetAddonID(), "pvr.demo");
EXPECT_EQ(path.GetChannelUID(), 4711);
}
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.cpp b/xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.cpp
index 0770efbf8a..ca83ba1298 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.cpp
@@ -67,7 +67,7 @@ void CGUIDialogPVRClientPriorities::InitializeSettings()
return;
}
- CServiceBroker::GetPVRManager().Clients()->GetCreatedClients(m_clients);
+ m_clients = CServiceBroker::GetPVRManager().Clients()->GetCreatedClients();
for (const auto& client : m_clients)
{
AddEdit(group, std::to_string(client.second->GetID()), 13205 /* Unknown */, SettingLevel::Basic,
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
index 9c5046d00a..39c1b35975 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
@@ -820,8 +820,7 @@ void CGUIDialogPVRTimerSettings::InitializeChannelsList()
int index = 0;
// Add special "any channel" entries - one for every client (used for epg-based timer rules).
- CPVRClientMap clients;
- CServiceBroker::GetPVRManager().Clients()->GetCreatedClients(clients);
+ const CPVRClientMap clients = CServiceBroker::GetPVRManager().Clients()->GetCreatedClients();
for (const auto& client : clients)
{
m_channelEntries.insert({index, ChannelDescriptor(PVR_CHANNEL_INVALID_UID,
diff --git a/xbmc/pvr/guilib/PVRGUIActions.cpp b/xbmc/pvr/guilib/PVRGUIActions.cpp
index 05ab2b160d..76dc2c9c4a 100644
--- a/xbmc/pvr/guilib/PVRGUIActions.cpp
+++ b/xbmc/pvr/guilib/PVRGUIActions.cpp
@@ -1698,8 +1698,7 @@ namespace PVR
bool CPVRGUIActions::ProcessSettingsMenuHooks()
{
- CPVRClientMap clients;
- CServiceBroker::GetPVRManager().Clients()->GetCreatedClients(clients);
+ const CPVRClientMap clients = CServiceBroker::GetPVRManager().Clients()->GetCreatedClients();
std::vector<std::pair<std::shared_ptr<CPVRClient>, CPVRClientMenuHook>> settingsHooks;
for (const auto& client : clients)
diff --git a/xbmc/pvr/guilib/guiinfo/PVRGUIInfo.cpp b/xbmc/pvr/guilib/guiinfo/PVRGUIInfo.cpp
index 5e2a867ae0..d023a001a7 100644
--- a/xbmc/pvr/guilib/guiinfo/PVRGUIInfo.cpp
+++ b/xbmc/pvr/guilib/guiinfo/PVRGUIInfo.cpp
@@ -215,9 +215,9 @@ void CPVRGUIInfo::UpdateQualityData()
const int channelUid = playbackState->GetPlayingChannelUniqueID();
if (channelUid > 0)
{
- std::shared_ptr<CPVRClient> client;
- CServiceBroker::GetPVRManager().Clients()->GetCreatedClient(playbackState->GetPlayingClientID(),
- client);
+ const std::shared_ptr<CPVRClient> client =
+ CServiceBroker::GetPVRManager().Clients()->GetCreatedClient(
+ playbackState->GetPlayingClientID());
if (client)
client->SignalQuality(channelUid, qualityInfo);
}
@@ -239,9 +239,9 @@ void CPVRGUIInfo::UpdateDescrambleData()
const int channelUid = playbackState->GetPlayingChannelUniqueID();
if (channelUid > 0)
{
- std::shared_ptr<CPVRClient> client;
- CServiceBroker::GetPVRManager().Clients()->GetCreatedClient(playbackState->GetPlayingClientID(),
- client);
+ const std::shared_ptr<CPVRClient> client =
+ CServiceBroker::GetPVRManager().Clients()->GetCreatedClient(
+ playbackState->GetPlayingClientID());
if (client)
client->GetDescrambleInfo(channelUid, descrambleInfo);
}