[Windows] Fix driver version detection of AMD RDNA+ GPU on Windows 10
[xbmc.git] / xbmc / addons / AddonManager.h
blobfd7ee70f6698307be53e02f57b61e1443352ce5c
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #pragma once
11 #include "threads/CriticalSection.h"
12 #include "utils/EventStream.h"
14 #include <map>
15 #include <memory>
16 #include <mutex>
17 #include <set>
18 #include <string>
19 #include <utility>
20 #include <vector>
22 namespace ADDON
24 enum class AddonDisabledReason;
25 enum class AddonOriginType;
26 enum class AddonType;
27 enum class AddonUpdateRule;
28 enum class AllowCheckForUpdates : bool;
30 class CAddonDatabase;
31 class CAddonUpdateRules;
32 class CAddonVersion;
33 class IAddonMgrCallback;
35 class CAddonInfo;
36 using AddonInfoPtr = std::shared_ptr<CAddonInfo>;
37 using ADDON_INFO_LIST = std::map<std::string, AddonInfoPtr>;
39 class IAddon;
40 using AddonPtr = std::shared_ptr<IAddon>;
41 using AddonWithUpdate = std::pair<std::shared_ptr<IAddon>, std::shared_ptr<IAddon>>;
42 using VECADDONS = std::vector<AddonPtr>;
44 struct AddonEvent;
45 struct DependencyInfo;
46 struct RepositoryDirInfo;
48 using AddonInstanceId = uint32_t;
50 enum class AddonCheckType : bool
52 OUTDATED_ADDONS,
53 AVAILABLE_UPDATES,
56 enum class OnlyEnabled : bool
58 CHOICE_YES = true,
59 CHOICE_NO = false,
62 enum class OnlyEnabledRootAddon : bool
64 CHOICE_YES = true,
65 CHOICE_NO = false,
68 enum class CheckIncompatible : bool
70 CHOICE_YES = true,
71 CHOICE_NO = false,
74 /**
75 * Class - CAddonMgr
76 * Holds references to all addons, enabled or
77 * otherwise. Services the generic callbacks available
78 * to all addon variants.
80 class CAddonMgr
82 public:
83 bool ReInit()
85 DeInit();
86 return Init();
88 bool Init();
89 void DeInit();
91 CAddonMgr();
92 CAddonMgr(const CAddonMgr&) = delete;
93 virtual ~CAddonMgr();
95 CEventStream<AddonEvent>& Events() { return m_events; }
96 CEventStream<AddonEvent>& UnloadEvents() { return m_unloadEvents; }
98 IAddonMgrCallback* GetCallbackForType(AddonType type);
99 bool RegisterAddonMgrCallback(AddonType type, IAddonMgrCallback* cb);
100 void UnregisterAddonMgrCallback(AddonType type);
102 /*! \brief Retrieve a specific addon (of a specific type)
103 \param id the id of the addon to retrieve.
104 \param addon[out] the retrieved addon pointer - only use if the function returns true.
105 \param type type of addon to retrieve - defaults to any type.
106 \param onlyEnabled whether we only want enabled addons - set to false to allow both enabled and disabled addons - defaults to true.
107 \return true if an addon matching the id of the given type is available and is enabled (if onlyEnabled is true).
109 bool GetAddon(const std::string& id,
110 AddonPtr& addon,
111 AddonType type,
112 OnlyEnabled onlyEnabled) const;
114 /*! \brief Retrieve a specific addon (of no specific type)
115 \param id the id of the addon to retrieve.
116 \param addon[out] the retrieved addon pointer - only use if the function returns true.
117 \param onlyEnabled whether we only want enabled addons - set to false to allow both enabled and disabled addons - defaults to true.
118 \return true if an addon matching the id of any type is available and is enabled (if onlyEnabled is true).
120 bool GetAddon(const std::string& id, AddonPtr& addon, OnlyEnabled onlyEnabled) const;
122 bool HasType(const std::string& id, AddonType type);
124 bool HasAddons(AddonType type);
126 bool HasInstalledAddons(AddonType type);
128 /*! Returns all installed, enabled and incompatible (and disabled) add-ons. */
129 bool GetAddonsForUpdate(VECADDONS& addons) const;
131 /*! Returns all installed, enabled add-ons. */
132 bool GetAddons(VECADDONS& addons) const;
134 /*! Returns enabled add-ons with given type. */
135 bool GetAddons(VECADDONS& addons, AddonType type);
137 /*! Returns all installed, including disabled. */
138 bool GetInstalledAddons(VECADDONS& addons);
140 /*! Returns installed add-ons, including disabled, with given type. */
141 bool GetInstalledAddons(VECADDONS& addons, AddonType type);
143 bool GetDisabledAddons(VECADDONS& addons);
145 bool GetDisabledAddons(VECADDONS& addons, AddonType type);
147 /*! Get all installable addons */
148 bool GetInstallableAddons(VECADDONS& addons);
150 bool GetInstallableAddons(VECADDONS& addons, AddonType type);
152 /*! \brief Get the installable addon depending on install rules
153 * or fall back to highest version.
154 * \note This function gets called in different contexts. If it's
155 * called for checking possible updates for already installed addons
156 * our update restriction rules apply.
157 * If it's called to (for example) populate an addon-select-dialog
158 * the addon is not installed yet, and we have to fall back to the
159 * highest version.
160 * \param addonId addon to check for update or installation
161 * \param addon[out] the retrieved addon pointer - only use if the function returns true.
162 * \return true if an addon matching the id is available.
164 bool FindInstallableById(const std::string& addonId, AddonPtr& addon);
166 void AddToUpdateableAddons(AddonPtr& pAddon);
167 void RemoveFromUpdateableAddons(AddonPtr& pAddon);
168 bool ReloadSettings(const std::string& addonId, AddonInstanceId instanceId);
170 /*! Get addons with available updates */
171 std::vector<std::shared_ptr<IAddon>> GetAvailableUpdates() const;
173 /*! Get addons that are outdated */
174 std::vector<std::shared_ptr<IAddon>> GetOutdatedAddons() const;
176 /*! Returns true if there is any addon with available updates, otherwise false */
177 bool HasAvailableUpdates();
180 * \brief Checks if the passed in addon is an orphaned dependency
181 * \param addon the add-on/dependency to check
182 * \param allAddons vector of all installed add-ons
183 * \return true or false
185 bool IsOrphaned(const std::shared_ptr<IAddon>& addon,
186 const std::vector<std::shared_ptr<IAddon>>& allAddons) const;
188 /*! \brief Checks for new / updated add-ons
189 \return True if everything went ok, false otherwise
191 bool FindAddons();
193 /*! \brief Checks whether given addon with given origin/version is installed
194 * \param addonId addon to check
195 * \param origin origin to check
196 * \param addonVersion version to check
197 * \return True if installed, false otherwise
199 bool FindAddon(const std::string& addonId,
200 const std::string& origin,
201 const CAddonVersion& addonVersion);
204 * @brief Fills the the provided vector with the list of incompatible
205 * enabled addons and returns if there's any.
207 * @param[out] incompatible List of incompatible addons
208 * @return true if there are incompatible addons
210 bool GetIncompatibleEnabledAddonInfos(std::vector<AddonInfoPtr>& incompatible) const;
213 * Migrate all the addons (updates all addons that have an update pending and disables those
214 * that got incompatible)
216 * @return list of all addons (infos) that were modified.
218 std::vector<AddonInfoPtr> MigrateAddons();
221 * @brief Try to disable addons in the given list.
223 * @param[in] incompatible List of incompatible addon infos
224 * @return list of all addon Infos that were disabled
226 std::vector<AddonInfoPtr> DisableIncompatibleAddons(
227 const std::vector<AddonInfoPtr>& incompatible);
230 * Install available addon updates, if any.
231 * @param wait If kodi should wait for all updates to download and install before returning
233 void CheckAndInstallAddonUpdates(bool wait) const;
236 * @note: should only be called by AddonInstaller
238 * Unload addon from the system. Returns true if it was unloaded, otherwise false.
240 bool UnloadAddon(const std::string& addonId);
243 * @note: should only be called by AddonInstaller
245 * Returns true if the addon was successfully loaded and enabled; otherwise false.
247 bool LoadAddon(const std::string& addonId,
248 const std::string& origin,
249 const CAddonVersion& addonVersion);
251 /*! @note: should only be called by AddonInstaller
253 * Hook for clearing internal state after uninstall.
255 void OnPostUnInstall(const std::string& id);
257 /*! \brief Disable an addon. Returns true on success, false on failure. */
258 bool DisableAddon(const std::string& ID, AddonDisabledReason disabledReason);
260 /*! \brief Updates reason for a disabled addon. Returns true on success, false on failure. */
261 bool UpdateDisabledReason(const std::string& id, AddonDisabledReason newDisabledReason);
263 /*! \brief Enable an addon. Returns true on success, false on failure. */
264 bool EnableAddon(const std::string& ID);
266 /* \brief Check whether an addon has been disabled via DisableAddon.
267 In case the disabled cache does not know about the current state the database routine will be used.
268 \param ID id of the addon
269 \sa DisableAddon
271 bool IsAddonDisabled(const std::string& ID) const;
274 * @brief Check whether an addon has been disabled via DisableAddon except for a particular
275 * reason In case the disabled cache does not know about the current state the database routine
276 * will be used.
277 * @param[in] ID id of the addon
278 * @param[in] disabledReason the reason that will be an exception to being disabled
279 * @return true if the addon was disabled except for the specified reason
280 * @sa DisableAddon
282 bool IsAddonDisabledExcept(const std::string& ID, AddonDisabledReason disabledReason) const;
284 /* \brief Checks whether an addon can be disabled via DisableAddon.
285 \param ID id of the addon
286 \sa DisableAddon
288 bool CanAddonBeDisabled(const std::string& ID);
290 bool CanAddonBeEnabled(const std::string& id);
292 /* \brief Checks whether an addon is installed.
293 \param ID id of the addon
295 bool IsAddonInstalled(const std::string& ID);
297 /* \brief Checks whether an addon is installed from a
298 * particular origin repo
299 * \note if checked for an origin defined as official (i.e. repository.xbmc.org)
300 * this function will return true even if the addon is a shipped system add-on
301 * \param ID id of the addon
302 * \param origin origin repository id
304 bool IsAddonInstalled(const std::string& ID, const std::string& origin) const;
306 /* \brief Checks whether an addon is installed from a
307 * particular origin repo and version
308 * \note if checked for an origin defined as official (i.e. repository.xbmc.org)
309 * this function will return true even if the addon is a shipped system add-on
310 * \param ID id of the addon
311 * \param origin origin repository id
312 * \param version the version of the addon
314 bool IsAddonInstalled(const std::string& ID,
315 const std::string& origin,
316 const CAddonVersion& version);
318 /* \brief Checks whether an addon can be installed. Broken addons can't be installed.
319 \param addon addon to be checked
321 bool CanAddonBeInstalled(const AddonPtr& addon);
323 bool CanUninstall(const AddonPtr& addon);
326 * @brief Checks whether an addon is a bundled addon
328 * @param[in] id id of the addon
329 * @return true if addon is bundled addon, false otherwise.
331 bool IsBundledAddon(const std::string& id);
334 * @brief Checks whether an addon is a system addon
336 * @param[in] id id of the addon
337 * @return true if addon is system addon, false otherwise.
339 bool IsSystemAddon(const std::string& id);
342 * @brief Checks whether an addon is a required system addon
344 * @param[in] id id of the addon
345 * @return true if addon is a required system addon, false otherwise.
347 bool IsRequiredSystemAddon(const std::string& id);
350 * @brief Checks whether an addon is an optional system addon
352 * @param[in] id id of the addon
353 * @return true if addon is an optional system addon, false otherwise.
355 bool IsOptionalSystemAddon(const std::string& id);
358 * @brief Addon update rules.
360 * member functions for handling and querying add-on update rules
362 * @warning This should be never used from other places outside of addon
363 * system directory.
366 /*@{{{*/
368 /* \brief Add a single update rule to the list for an addon
369 * \sa CAddonUpdateRules::AddUpdateRuleToList()
371 bool AddUpdateRuleToList(const std::string& id, AddonUpdateRule updateRule);
373 /* \brief Remove all rules from update rules list for an addon
374 * \sa CAddonUpdateRules::RemoveAllUpdateRulesFromList()
376 bool RemoveAllUpdateRulesFromList(const std::string& id);
378 /* \brief Remove a specific rule from update rules list for an addon
379 * \sa CAddonUpdateRules::RemoveUpdateRuleFromList()
381 bool RemoveUpdateRuleFromList(const std::string& id, AddonUpdateRule updateRule);
383 /* \brief Check if an addon version is auto-updateable
384 * \param id addon id to be checked
385 * \return true is addon is auto-updateable, false otherwise
386 * \sa CAddonUpdateRules::IsAutoUpdateable()
388 bool IsAutoUpdateable(const std::string& id) const;
390 /*@}}}*/
392 /* \brief Launches event AddonEvent::AutoUpdateStateChanged
393 * \param id addon id to pass through
394 * \sa CGUIDialogAddonInfo::OnToggleAutoUpdates()
396 void PublishEventAutoUpdateStateChanged(const std::string& id);
397 void UpdateLastUsed(const std::string& id);
400 * \brief Launches event @ref AddonEvent::InstanceAdded
402 * This is called when a new instance is added in add-on settings.
404 * \param[in] addonId Add-on id to pass through
405 * \param[in] instanceId Identifier of the add-on instance
407 void PublishInstanceAdded(const std::string& addonId, AddonInstanceId instanceId);
410 * \brief Launches event @ref AddonEvent::InstanceRemoved
412 * This is called when an instance is removed in add-on settings.
414 * \param[in] addonId Add-on id to pass through
415 * \param[in] instanceId Identifier of the add-on instance
417 void PublishInstanceRemoved(const std::string& addonId, AddonInstanceId instanceId);
419 /*! \brief Load the addon in the given path
420 This loads the addon using c-pluff which parses the addon descriptor file.
421 \param path folder that contains the addon.
422 \param addon [out] returned addon.
423 \return true if addon is set, false otherwise.
425 bool LoadAddonDescription(const std::string& path, AddonPtr& addon);
427 bool ServicesHasStarted() const;
430 * @brief Check if given addon is compatible with Kodi.
432 * @param[in] addon Addon to check
433 * @return true if compatible, false if not
435 bool IsCompatible(const std::shared_ptr<const IAddon>& addon) const;
438 * @brief Check given addon information is compatible with Kodi.
440 * @param[in] addonInfo Addon information to check
441 * @return true if compatible, false if not
443 bool IsCompatible(const AddonInfoPtr& addonInfo) const;
445 /*! \brief Recursively get dependencies for an add-on
446 * \param id the id of the root addon
447 * \param onlyEnabledRootAddon whether look for enabled root add-ons only
449 std::vector<DependencyInfo> GetDepsRecursive(const std::string& id,
450 OnlyEnabledRootAddon onlyEnabledRootAddon);
453 * @brief Get a list of add-on's with info's for the on system available
454 * ones.
456 * @param[out] addonInfos list where finded addon information becomes stored
457 * @param[in] onlyEnabled If true are only enabled ones given back,
458 * if false all on system available. Default is true.
459 * @param[in] type The requested type, with "ADDON_UNKNOWN" are all add-on
460 * types given back who match the case with value before.
461 * If a type id becomes added are only add-ons returned who
462 * match them. Default is for all types.
463 * @return true if the list contains entries
465 bool GetAddonInfos(std::vector<AddonInfoPtr>& addonInfos, bool onlyEnabled, AddonType type) const;
468 * @brief Get a list of add-on's with info's for the on system available
469 * ones.
471 * @param[in] onlyEnabled If true are only enabled ones given back,
472 * if false all on system available. Default is true.
473 * @param[in] types List about requested types.
474 * @return List where finded addon information becomes returned.
476 * @note @ref ADDON_UNKNOWN should not used for here!
478 std::vector<AddonInfoPtr> GetAddonInfos(bool onlyEnabled,
479 const std::vector<AddonType>& types) const;
482 * @brief Get a list of disabled add-on's with info's
484 * @param[out] addonInfos list where finded addon information becomes stored
485 * @param[in] type The requested type, with "ADDON_UNKNOWN"
486 * are all add-on types given back who match the case
487 * with value before.
488 * If a type id becomes added are only add-ons
489 * returned who match them. Default is for all types.
490 * @return true if the list contains entries
492 bool GetDisabledAddonInfos(std::vector<AddonInfoPtr>& addonInfos, AddonType type) const;
495 * @brief Get a list of disabled add-on's with info's for the on system
496 * available ones with a specific disabled reason.
498 * @param[out] addonInfos list where finded addon information becomes stored
499 * @param[in] type The requested type, with "ADDON_UNKNOWN"
500 * are all add-on types given back who match the case
501 * with value before.
502 * If a type id becomes added are only add-ons
503 * returned who match them. Default is for all types.
504 * @param[in] disabledReason To get all disabled addons use the value
505 * "AddonDiasbledReason::NONE". If any other value
506 * is supplied only addons with that reason will be
507 * returned.
508 * @return true if the list contains entries
510 bool GetDisabledAddonInfos(std::vector<AddonInfoPtr>& addonInfos,
511 AddonType type,
512 AddonDisabledReason disabledReason) const;
514 const AddonInfoPtr GetAddonInfo(const std::string& id, AddonType type) const;
517 * @brief Get the path where temporary add-on files are stored
519 * @return the base path used for temporary addon paths
521 * @warning the folder and its contents are deleted when Kodi is closed
523 const std::string& GetTempAddonBasePath() { return m_tempAddonBasePath; }
525 AddonOriginType GetAddonOriginType(const AddonPtr& addon) const;
528 * \brief Check whether an addon has been disabled with a special reason.
529 * \param ID id of the addon
530 * \param disabledReason reason we want to check for (NONE, USER, INCOMPATIBLE, PERMANENT_FAILURE)
531 * \return true or false
533 bool IsAddonDisabledWithReason(const std::string& ID, AddonDisabledReason disabledReason) const;
536 * @brief Addon update and install management.
538 * Parts inside here are used for changes about addon system.
540 * @warning This should be never used from other places outside of addon
541 * system directory.
543 /*@{{{*/
546 * @brief Update addon origin data.
548 * This becomes called from @ref CAddonInstallJob to set the source repo and
549 * if update, to set also the date.
551 * @note This must be called after the addon manager has inserted a new addon
552 * with @ref FindAddons() into database.
554 * @param[in] addonId Identifier of addon
555 * @param[in] repoAddonId Identifier of related repository addon
556 * @param[in] isUpdate If call becomes done on already installed addon and
557 * update only.
558 * @return True if successfully done, otherwise false
560 * Currently listed call sources:
561 * - @ref CAddonInstallJob::DoWork
563 bool SetAddonOrigin(const std::string& addonId, const std::string& repoAddonId, bool isUpdate);
566 * @brief Parse a repository XML file for addons and load their descriptors.
568 * A repository XML is essentially a concatenated list of addon descriptors.
570 * @param[in] repo The repository info.
571 * @param[in] xml The XML document from repository.
572 * @param[out] addons returned list of addons.
573 * @return true if the repository XML file is parsed, false otherwise.
575 * Currently listed call sources:
576 * - @ref CRepository::FetchIndex
578 bool AddonsFromRepoXML(const RepositoryDirInfo& repo,
579 const std::string& xml,
580 std::vector<AddonInfoPtr>& addons);
582 /*@}}}*/
585 * \brief Retrieves list of outdated addons as well as their related
586 * available updates and stores them into map.
587 * \return map of outdated addons with their update
589 std::map<std::string, AddonWithUpdate> GetAddonsWithAvailableUpdate() const;
592 * \brief Retrieves list of compatible addon versions of all origins
593 * \param[in] addonId addon to look up
594 * \return vector containing compatible addon versions
596 std::vector<std::shared_ptr<IAddon>> GetCompatibleVersions(const std::string& addonId) const;
599 * \brief Return number of available updates formatted as string
600 * this can be used as a lightweight method of retrieving the number of updates
601 * rather than using the expensive GetAvailableUpdates call
602 * \return number of available updates
604 const std::string& GetLastAvailableUpdatesCountAsString() const;
607 * \brief returns a vector with all found orphaned dependencies.
608 * \return the vector
610 std::vector<std::shared_ptr<IAddon>> GetOrphanedDependencies() const;
612 private:
613 CAddonMgr& operator=(CAddonMgr const&) = delete;
615 VECADDONS m_updateableAddons;
618 * \brief returns a vector with either available updates or outdated addons.
619 * usually called by its wrappers GetAvailableUpdates() or
620 * GetOutdatedAddons()
621 * \param[in] true to return outdated addons, false to return available updates
622 * \return vector filled with either available updates or outdated addons
624 std::vector<std::shared_ptr<IAddon>> GetAvailableUpdatesOrOutdatedAddons(
625 AddonCheckType addonCheckType) const;
627 bool GetAddonsInternal(AddonType type,
628 VECADDONS& addons,
629 OnlyEnabled onlyEnabled,
630 CheckIncompatible checkIncompatible) const;
632 bool EnableSingle(const std::string& id);
634 void FindAddons(ADDON_INFO_LIST& addonmap, const std::string& path);
637 * @brief Fills the the provided vector with the list of incompatible
638 * addons and returns if there's any.
640 * @param[out] incompatible List of incompatible addons
641 * @param[in] whether or not to include incompatible addons that are disabled
642 * @return true if there are incompatible addons
644 bool GetIncompatibleAddonInfos(std::vector<AddonInfoPtr>& incompatible,
645 bool includeDisabled) const;
648 * Get the list of of available updates
649 * \param[in,out] updates the vector of addons to be filled with addons that need to be updated (not blacklisted)
650 * \return if there are any addons needing updates
652 bool GetAddonUpdateCandidates(VECADDONS& updates) const;
654 /*!\brief Sort a list of addons for installation, i.e., defines the order of installation depending
655 * of each addon dependencies.
656 * \param[in,out] updates the vector of addons to sort
658 void SortByDependencies(VECADDONS& updates) const;
661 * Install the list of addon updates via AddonInstaller
662 * \param[in,out] updates the vector of addons to install (will be sorted)
663 * \param wait if the process should wait for all addons to install
664 * \param allowCheckForUpdates indicates if content update checks are allowed
665 * after installation of a repository addon from the list
667 void InstallAddonUpdates(VECADDONS& updates,
668 bool wait,
669 AllowCheckForUpdates allowCheckForUpdates) const;
671 // This guards the addon installation process to make sure
672 // addon updates are not installed concurrently
673 // while the migration is running. Addon updates can be triggered
674 // as a result of a repository update event.
675 // (migration will install any available update anyway)
676 mutable std::mutex m_installAddonsMutex;
678 std::map<std::string, AddonDisabledReason> m_disabled;
679 static std::map<AddonType, IAddonMgrCallback*> m_managers;
680 mutable CCriticalSection m_critSection;
681 std::unique_ptr<CAddonDatabase> m_database;
682 std::unique_ptr<CAddonUpdateRules> m_updateRules;
683 CEventSource<AddonEvent> m_events;
684 CBlockingEventSource<AddonEvent> m_unloadEvents;
685 std::set<std::string> m_systemAddons;
686 std::set<std::string> m_optionalSystemAddons;
687 ADDON_INFO_LIST m_installedAddons;
689 // Temporary path given to add-ons, whose content is deleted when Kodi is stopped
690 const std::string m_tempAddonBasePath = "special://temp/addons";
693 * latest count of available updates
695 mutable std::string m_lastAvailableUpdatesCountAsString;
696 mutable std::mutex m_lastAvailableUpdatesCountMutex;
699 }; /* namespace ADDON */