[Windows] Fix driver version detection of AMD RDNA+ GPU on Windows 10
[xbmc.git] / xbmc / addons / ExtsMimeSupportList.cpp
blob88c6d493771aeaf41277c23779f9e40318a3306b
1 /*
2 * Copyright (C) 2013 Arne Morten Kvarving
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 * See LICENSES/README.md for more information.
6 */
8 #include "ExtsMimeSupportList.h"
10 #include "ServiceBroker.h"
11 #include "addons/AddonEvents.h"
12 #include "addons/AddonManager.h"
13 #include "addons/addoninfo/AddonInfo.h"
14 #include "addons/addoninfo/AddonType.h"
15 #include "addons/kodi-dev-kit/include/kodi/addon-instance/AudioDecoder.h"
16 #include "guilib/LocalizeStrings.h"
17 #include "utils/URIUtils.h"
18 #include "utils/log.h"
20 #include <mutex>
22 using namespace ADDON;
23 using namespace KODI::ADDONS;
25 CExtsMimeSupportList::CExtsMimeSupportList(CAddonMgr& addonMgr) : m_addonMgr(addonMgr)
27 m_addonMgr.Events().Subscribe(this, &CExtsMimeSupportList::OnEvent);
29 // Load all available audio decoder addons during Kodi start
30 const std::vector<AddonType> types = {AddonType::AUDIODECODER, AddonType::IMAGEDECODER};
31 const auto addonInfos = m_addonMgr.GetAddonInfos(true, types);
32 for (const auto& addonInfo : addonInfos)
33 m_supportedList.emplace_back(ScanAddonProperties(addonInfo->MainType(), addonInfo));
36 CExtsMimeSupportList::~CExtsMimeSupportList()
38 m_addonMgr.Events().Unsubscribe(this);
41 void CExtsMimeSupportList::OnEvent(const AddonEvent& event)
43 if (typeid(event) == typeid(AddonEvents::Enabled) ||
44 typeid(event) == typeid(AddonEvents::Disabled) ||
45 typeid(event) == typeid(AddonEvents::ReInstalled))
47 if (m_addonMgr.HasType(event.addonId, AddonType::AUDIODECODER) ||
48 m_addonMgr.HasType(event.addonId, AddonType::IMAGEDECODER))
49 Update(event.addonId);
51 else if (typeid(event) == typeid(AddonEvents::UnInstalled))
53 Update(event.addonId);
57 void CExtsMimeSupportList::Update(const std::string& id)
59 // Stop used instance if present, otherwise the new becomes created on already created addon base one.
61 std::unique_lock<CCriticalSection> lock(m_critSection);
63 const auto itAddon =
64 std::find_if(m_supportedList.begin(), m_supportedList.end(),
65 [&id](const SupportValues& addon) { return addon.m_addonInfo->ID() == id; });
67 if (itAddon != m_supportedList.end())
69 m_supportedList.erase(itAddon);
73 // Create and init the new addon instance
74 std::shared_ptr<CAddonInfo> addonInfo = m_addonMgr.GetAddonInfo(id, AddonType::UNKNOWN);
75 if (addonInfo && !m_addonMgr.IsAddonDisabled(id))
77 if (addonInfo->HasType(AddonType::AUDIODECODER) || addonInfo->HasType(AddonType::IMAGEDECODER))
79 SupportValues values = ScanAddonProperties(addonInfo->MainType(), addonInfo);
81 std::unique_lock<CCriticalSection> lock(m_critSection);
82 m_supportedList.emplace_back(values);
88 CExtsMimeSupportList::SupportValues CExtsMimeSupportList::ScanAddonProperties(
89 AddonType type, const std::shared_ptr<CAddonInfo>& addonInfo)
91 SupportValues values;
93 values.m_addonType = type;
94 values.m_addonInfo = addonInfo;
95 if (type == AddonType::AUDIODECODER)
97 values.m_codecName = addonInfo->Type(type)->GetValue("@name").asString();
98 values.m_hasTags = addonInfo->Type(type)->GetValue("@tags").asBoolean();
99 values.m_hasTracks = addonInfo->Type(type)->GetValue("@tracks").asBoolean();
102 const auto support = addonInfo->Type(type)->GetElement("support");
103 if (support)
105 // Scan here about complete defined xml groups with description and maybe icon
106 // e.g.
107 // `<extension name=".zwdsp">`
108 // ` <description>30246</description>`
109 // `</extension>`
110 for (const auto& i : support->GetElements())
112 std::string name = i.second.GetValue("@name").asString();
113 if (name.empty())
114 continue;
116 const int description = i.second.GetValue("description").asInteger();
117 const std::string icon =
118 !i.second.GetValue("icon").empty()
119 ? URIUtils::AddFileToFolder(addonInfo->Path(), i.second.GetValue("icon").asString())
120 : "";
122 if (i.first == "extension")
124 if (name[0] != '.')
125 name.insert(name.begin(), '.');
126 values.m_supportedExtensions.emplace(name, SupportValue(description, icon));
128 else if (i.first == "mimetype")
130 values.m_supportedMimetypes.emplace(name, SupportValue(description, icon));
131 const std::string extension = i.second.GetValue("extension").asString();
132 if (!extension.empty())
133 values.m_supportedExtensions.emplace(extension, SupportValue(description, icon));
137 // Scan here about small defined xml groups without anything
138 // e.g. `<extension name=".adp"/>`
139 for (const auto& i : support->GetValues())
141 for (const auto& j : i.second)
143 std::string name = j.second.asString();
144 if (j.first == "extension@name")
146 if (name[0] != '.')
147 name.insert(name.begin(), '.');
148 values.m_supportedExtensions.emplace(name, SupportValue(-1, ""));
150 else if (j.first == "mimetype@name")
151 values.m_supportedMimetypes.emplace(name, SupportValue(-1, ""));
156 // Check addons support tracks, if yes add extension about related entry names
157 // By them addon no more need to add itself on his addon.xml
158 if (values.m_hasTracks)
159 values.m_supportedExtensions.emplace(
160 "." + values.m_codecName + KODI_ADDON_AUDIODECODER_TRACK_EXT, SupportValue(-1, ""));
163 return values;
166 std::vector<CExtsMimeSupportList::SupportValues> CExtsMimeSupportList::GetSupportedAddonInfos(
167 FilterSelect select)
169 std::vector<SupportValues> addonInfos;
171 std::unique_lock<CCriticalSection> lock(m_critSection);
173 for (const auto& entry : m_supportedList)
175 if (select == FilterSelect::all || (select == FilterSelect::hasTags && entry.m_hasTags) ||
176 (select == FilterSelect::hasTracks && entry.m_hasTracks))
177 addonInfos.emplace_back(entry);
180 return addonInfos;
183 bool CExtsMimeSupportList::IsExtensionSupported(const std::string& ext)
185 std::unique_lock<CCriticalSection> lock(m_critSection);
187 for (const auto& entry : m_supportedList)
189 const auto it = std::find_if(
190 entry.m_supportedExtensions.begin(), entry.m_supportedExtensions.end(),
191 [ext](const std::pair<std::string, SupportValue>& v) { return v.first == ext; });
192 if (it != entry.m_supportedExtensions.end())
193 return true;
196 return false;
199 std::vector<std::pair<AddonType, std::shared_ptr<ADDON::CAddonInfo>>> CExtsMimeSupportList::
200 GetExtensionSupportedAddonInfos(const std::string& ext, FilterSelect select)
202 std::vector<std::pair<AddonType, std::shared_ptr<CAddonInfo>>> addonInfos;
204 std::unique_lock<CCriticalSection> lock(m_critSection);
206 for (const auto& entry : m_supportedList)
208 const auto it = std::find_if(
209 entry.m_supportedExtensions.begin(), entry.m_supportedExtensions.end(),
210 [ext](const std::pair<std::string, SupportValue>& v) { return v.first == ext; });
211 if (it != entry.m_supportedExtensions.end() &&
212 (select == FilterSelect::all || (select == FilterSelect::hasTags && entry.m_hasTags) ||
213 (select == FilterSelect::hasTracks && entry.m_hasTracks)))
214 addonInfos.emplace_back(entry.m_addonType, entry.m_addonInfo);
217 return addonInfos;
220 bool CExtsMimeSupportList::IsMimetypeSupported(const std::string& mimetype)
222 std::unique_lock<CCriticalSection> lock(m_critSection);
224 for (const auto& entry : m_supportedList)
227 const auto it = std::find_if(
228 entry.m_supportedMimetypes.begin(), entry.m_supportedMimetypes.end(),
229 [mimetype](const std::pair<std::string, SupportValue>& v) { return v.first == mimetype; });
230 if (it != entry.m_supportedMimetypes.end())
231 return true;
234 return false;
237 std::vector<std::pair<AddonType, std::shared_ptr<CAddonInfo>>> CExtsMimeSupportList::
238 GetMimetypeSupportedAddonInfos(const std::string& mimetype, FilterSelect select)
240 std::vector<std::pair<AddonType, std::shared_ptr<CAddonInfo>>> addonInfos;
242 std::unique_lock<CCriticalSection> lock(m_critSection);
244 for (const auto& entry : m_supportedList)
246 const auto it = std::find_if(
247 entry.m_supportedMimetypes.begin(), entry.m_supportedMimetypes.end(),
248 [mimetype](const std::pair<std::string, SupportValue>& v) { return v.first == mimetype; });
249 if (it != entry.m_supportedMimetypes.end() &&
250 (select == FilterSelect::all || (select == FilterSelect::hasTags && entry.m_hasTags) ||
251 (select == FilterSelect::hasTracks && entry.m_hasTracks)))
252 addonInfos.emplace_back(entry.m_addonType, entry.m_addonInfo);
255 return addonInfos;
258 std::vector<AddonSupportEntry> CExtsMimeSupportList::GetSupportedExtsAndMimeTypes(
259 const std::string& addonId)
261 std::vector<AddonSupportEntry> list;
263 const auto it =
264 std::find_if(m_supportedList.begin(), m_supportedList.end(),
265 [addonId](const SupportValues& v) { return v.m_addonInfo->ID() == addonId; });
266 if (it == m_supportedList.end())
267 return list;
269 for (const auto& entry : it->m_supportedExtensions)
271 AddonSupportEntry supportEntry;
272 supportEntry.m_type = AddonSupportType::Extension;
273 supportEntry.m_name = entry.first;
274 supportEntry.m_description =
275 g_localizeStrings.GetAddonString(addonId, entry.second.m_description);
276 supportEntry.m_icon = entry.second.m_icon;
277 list.emplace_back(supportEntry);
279 for (const auto& entry : it->m_supportedMimetypes)
281 AddonSupportEntry supportEntry;
282 supportEntry.m_type = AddonSupportType::Mimetype;
283 supportEntry.m_name = entry.first;
284 supportEntry.m_description =
285 g_localizeStrings.GetAddonString(addonId, entry.second.m_description);
286 supportEntry.m_icon = entry.second.m_icon;
287 list.emplace_back(supportEntry);
290 return list;