bool CLanguageResource::FindLanguageAddonByName(const std::string &legacyLanguage, std::string &addonId, const VECADDONS &languageAddons /* = VECADDONS() */) { if (legacyLanguage.empty()) return false; VECADDONS addons; if (!languageAddons.empty()) addons = languageAddons; else if (!CAddonMgr::Get().GetAddons(ADDON_RESOURCE_LANGUAGE, addons, true) || addons.empty()) return false; // try to find a language that matches the old language in name or id for (VECADDONS::const_iterator addon = addons.begin(); addon != addons.end(); ++addon) { const CLanguageResource* languageAddon = static_cast<CLanguageResource*>(addon->get()); // check if the old language matches the language addon id, the language // locale or the language addon name if (legacyLanguage.compare((*addon)->ID()) == 0 || languageAddon->GetLocale().Equals(legacyLanguage) || StringUtils::EqualsNoCase(legacyLanguage, languageAddon->Name())) { addonId = (*addon)->ID(); return true; } } return false; }
void CGUIDialogSubtitles::FillServices() { ClearServices(); VECADDONS addons; ADDON::CAddonMgr::Get().GetAddons(ADDON_SUBTITLE_MODULE, addons, true); if (addons.empty()) { UpdateStatus(NO_SERVICES); return; } for (VECADDONS::const_iterator addonIt = addons.begin(); addonIt != addons.end(); addonIt++) { CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addonIt, "plugin://", false)); m_serviceItems->Add(item); } // Bind our services to the UI CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_SERVICELIST, 0, 0, m_serviceItems); OnMessage(msg); // TODO: Default service support will need to check through the items to find the CFileItem in the loop above. SetService(m_serviceItems->Get(0)->GetProperty("Addon.ID").asString()); }
bool CAddonMgr::GetAllOutdatedAddons(VECADDONS &addons, bool enabled /*= true*/) { CSingleLock lock(m_critSection); for (int i = ADDON_UNKNOWN+1; i < ADDON_VIZ_LIBRARY; ++i) { VECADDONS temp; if (CAddonMgr::Get().GetAddons((TYPE)i, temp, enabled)) { AddonPtr repoAddon; for (unsigned int j = 0; j < temp.size(); j++) { // Ignore duplicates due to add-ons with multiple extension points bool found = false; for (VECADDONS::const_iterator addonIt = addons.begin(); addonIt != addons.end(); addonIt++) { if ((*addonIt)->ID() == temp[j]->ID()) found = true; } if (found || !m_database.GetAddon(temp[j]->ID(), repoAddon)) continue; if (temp[j]->Version() < repoAddon->Version() && !m_database.IsAddonBlacklisted(temp[j]->ID(), repoAddon->Version().c_str())) addons.push_back(repoAddon); } } } return !addons.empty(); }
void CRepositoryUpdater::OnJobComplete(unsigned int jobID, bool success, CJob* job) { CSingleLock lock(m_criticalSection); m_jobs.erase(std::find(m_jobs.begin(), m_jobs.end(), job)); if (m_jobs.empty()) { CLog::Log(LOGDEBUG, "CRepositoryUpdater: done."); m_doneEvent.Set(); if (CSettings::GetInstance().GetInt(CSettings::SETTING_GENERAL_ADDONUPDATES) == AUTO_UPDATES_NOTIFY) { VECADDONS hasUpdate; if (CAddonMgr::GetInstance().GetAllOutdatedAddons(hasUpdate) && !hasUpdate.empty()) { if (hasUpdate.size() == 1) CGUIDialogKaiToast::QueueNotification( hasUpdate[0]->Icon(), hasUpdate[0]->Name(), g_localizeStrings.Get(24068), TOAST_DISPLAY_TIME, false, TOAST_DISPLAY_TIME); else CGUIDialogKaiToast::QueueNotification( "", g_localizeStrings.Get(24001), g_localizeStrings.Get(24061), TOAST_DISPLAY_TIME, false, TOAST_DISPLAY_TIME); } } if (CSettings::GetInstance().GetInt(CSettings::SETTING_GENERAL_ADDONUPDATES) == AUTO_UPDATES_ON) CAddonInstaller::GetInstance().InstallUpdates(); ScheduleUpdate(); CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE); g_windowManager.SendThreadMessage(msg); } }
void CRepositoryUpdater::CheckForUpdates(bool showProgress) { VECADDONS addons; if (CAddonMgr::GetInstance().GetAddons(ADDON_REPOSITORY, addons) && !addons.empty()) { CSingleLock lock(m_criticalSection); for (const auto& addon : addons) CheckForUpdates(std::static_pointer_cast<ADDON::CRepository>(addon), showProgress); } }
bool CAddonMgr::GetAllAddons(VECADDONS &addons, bool enabled /*= true*/, bool allowRepos /* = false */) { for (int i = ADDON_UNKNOWN+1; i < ADDON_VIZ_LIBRARY; ++i) { if (!allowRepos && ADDON_REPOSITORY == (TYPE)i) continue; VECADDONS temp; if (CAddonMgr::Get().GetAddons((TYPE)i, temp, enabled)) addons.insert(addons.end(), temp.begin(), temp.end()); } return !addons.empty(); }
void CAddonInstaller::InstallUpdates(bool includeBlacklisted /* = false */) { VECADDONS addons = CAddonMgr::GetInstance().GetOutdated(); if (addons.empty()) return; for (const auto& addon : addons) { if (includeBlacklisted || !CAddonMgr::GetInstance().IsBlacklisted(addon->ID())) CAddonInstaller::GetInstance().InstallOrUpdate(addon->ID()); } }
void CActiveAEDSP::UpdateAddons() { VECADDONS addons; AE_DSP_ADDON dspAddon; CAddonMgr::GetInstance().GetAddons(addons, ADDON_ADSPDLL); if (addons.empty()) return; for (auto &addon : addons) { bool bEnabled = !CAddonMgr::GetInstance().IsAddonDisabled(addon->ID()); if (bEnabled && (!IsKnownAudioDSPAddon(addon) || !IsReadyAudioDSPAddon(addon))) { std::hash<std::string> hasher; int iAddonId = static_cast<int>(hasher(addon->ID())); if (iAddonId < 0) iAddonId = -iAddonId; /* create and open database */ if (!m_databaseDSP.IsOpen()) m_databaseDSP.Open(); if (IsKnownAudioDSPAddon(addon)) { AE_DSP_ADDON dspAddon; GetAudioDSPAddon(iAddonId, dspAddon); dspAddon->Create(iAddonId); } else { AE_DSP_ADDON dspAddon = std::dynamic_pointer_cast<CActiveAEDSPAddon>(addon); if (!dspAddon) { CLog::Log(LOGERROR, "CActiveAEDSP::UpdateAndInitialiseAddons - severe error, incorrect add type"); continue; } dspAddon.get()->Create(iAddonId); // register the add-on if (m_addonMap.find(iAddonId) == m_addonMap.end()) { m_addonMap.insert(std::make_pair(iAddonId, dspAddon)); m_addonNameIds.insert(make_pair(addon->ID(), iAddonId)); } } } } TriggerModeUpdate(); }
void CPVRClients::UpdateAddons(void) { VECADDONS addons; PVR_CLIENT addon; CAddonMgr::GetInstance().GetAddons(addons, ADDON_PVRDLL); if (addons.empty()) return; for (auto &addon : addons) { bool bEnabled = !CAddonMgr::GetInstance().IsAddonDisabled(addon->ID()); if (bEnabled && (!IsKnownClient(addon) || !IsCreatedClient(addon))) { std::hash<std::string> hasher; int iClientId = static_cast<int>(hasher(addon->ID())); if (iClientId < 0) iClientId = -iClientId; if (IsKnownClient(addon)) { PVR_CLIENT client; GetClient(iClientId, client); client->Create(iClientId); } else { PVR_CLIENT pvrclient = std::dynamic_pointer_cast<CPVRClient>(addon); if (!pvrclient) { CLog::Log(LOGERROR, "CPVRClients::UpdateAndInitialiseClients - severe error, incorrect add type"); continue; } pvrclient.get()->Create(iClientId); // register the add-on if (m_clientMap.find(iClientId) == m_clientMap.end()) { m_clientMap.insert(std::make_pair(iClientId, pvrclient)); m_addonNameIds.insert(make_pair(addon->ID(), iClientId)); } } } else if (!bEnabled && IsCreatedClient(addon)) { StopClient(addon, false); } } g_PVRManager.Start(); }
bool CRepositoryUpdater::CheckForUpdates(bool showProgress) { VECADDONS addons; if (m_addonMgr.GetAddons(addons, ADDON_REPOSITORY) && !addons.empty()) { CSingleLock lock(m_criticalSection); for (const auto& addon : addons) CheckForUpdates(std::static_pointer_cast<ADDON::CRepository>(addon), showProgress); return true; } return false; }
void CRepositoryUpdater::OnJobComplete(unsigned int jobID, bool success, CJob* job) { CSingleLock lock(m_criticalSection); m_jobs.erase(std::find(m_jobs.begin(), m_jobs.end(), job)); if (m_jobs.empty()) { CLog::Log(LOGDEBUG, "CRepositoryUpdater: done."); m_doneEvent.Set(); VECADDONS updates = CAddonMgr::GetInstance().GetAvailableUpdates(); if (CSettings::GetInstance().GetInt(CSettings::SETTING_ADDONS_AUTOUPDATES) == AUTO_UPDATES_NOTIFY) { if (!updates.empty()) { if (updates.size() == 1) CGUIDialogKaiToast::QueueNotification( updates[0]->Icon(), updates[0]->Name(), g_localizeStrings.Get(24068), TOAST_DISPLAY_TIME, false, TOAST_DISPLAY_TIME); else CGUIDialogKaiToast::QueueNotification( "", g_localizeStrings.Get(24001), g_localizeStrings.Get(24061), TOAST_DISPLAY_TIME, false, TOAST_DISPLAY_TIME); for (const auto &addon : updates) CEventLog::GetInstance().Add(EventPtr(new CAddonManagementEvent(addon, 24068))); } } if (CSettings::GetInstance().GetInt(CSettings::SETTING_ADDONS_AUTOUPDATES) == AUTO_UPDATES_ON) { for (const auto& addon : updates) { if (!CAddonMgr::GetInstance().IsBlacklisted(addon->ID())) CAddonInstaller::GetInstance().InstallOrUpdate(addon->ID()); } } ScheduleUpdate(); m_events.Publish(RepositoryUpdated{}); } }
CDateTime CRepositoryUpdater::LastUpdated() const { VECADDONS repos; if (!CAddonMgr::GetInstance().GetAddons(repos, ADDON_REPOSITORY) || repos.empty()) return CDateTime(); CAddonDatabase db; db.Open(); std::vector<CDateTime> updateTimes; std::transform(repos.begin(), repos.end(), std::back_inserter(updateTimes), [&](const AddonPtr& repo) { auto lastCheck = db.LastChecked(repo->ID()); if (lastCheck.first.IsValid() && lastCheck.second == repo->Version()) return lastCheck.first; return CDateTime(); }); return *std::min_element(updateTimes.begin(), updateTimes.end()); }
bool CAddonMgr::GetAllOutdatedAddons(VECADDONS &addons, bool enabled /*= true*/) { CSingleLock lock(m_critSection); for (int i = ADDON_UNKNOWN+1; i < ADDON_VIZ_LIBRARY; ++i) { VECADDONS temp; if (CAddonMgr::Get().GetAddons((TYPE)i, temp, enabled)) { AddonPtr repoAddon; for (unsigned int j = 0; j < temp.size(); j++) { if (!m_database.GetAddon(temp[j]->ID(), repoAddon)) continue; if (temp[j]->Version() < repoAddon->Version()) addons.push_back(repoAddon); } } } return !addons.empty(); }
void CGUIDialogSubtitles::FillServices() { std::string previousService = m_currentService; ClearServices(); VECADDONS addons; ADDON::CAddonMgr::GetInstance().GetAddons(addons, ADDON_SUBTITLE_MODULE); if (addons.empty()) { UpdateStatus(NO_SERVICES); return; } std::string defaultService; const CFileItem &item = g_application.CurrentUnstackedItem(); if (item.GetVideoContentType() == VIDEODB_CONTENT_TVSHOWS || item.GetVideoContentType() == VIDEODB_CONTENT_EPISODES) // Set default service for tv shows defaultService = CSettings::GetInstance().GetString(CSettings::SETTING_SUBTITLES_TV); else // Set default service for filemode and movies defaultService = CSettings::GetInstance().GetString(CSettings::SETTING_SUBTITLES_MOVIE); std::string service = addons.front()->ID(); for (VECADDONS::const_iterator addonIt = addons.begin(); addonIt != addons.end(); ++addonIt) { CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addonIt, "plugin://" + (*addonIt)->ID(), false)); m_serviceItems->Add(item); // If we don't have used a previous service use the default service, otherwise use the previous service if ((previousService.empty() && (*addonIt)->ID() == defaultService) || (*addonIt)->ID() == previousService) service = (*addonIt)->ID(); } // Bind our services to the UI CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_SERVICELIST, 0, 0, m_serviceItems); OnMessage(msg); SetService(service); }
void CGUIDialogSubtitles::FillServices() { ClearServices(); VECADDONS addons; ADDON::CAddonMgr::Get().GetAddons(ADDON_SUBTITLE_MODULE, addons, true); if (addons.empty()) { UpdateStatus(NO_SERVICES); return; } std::string defaultService; const CFileItem &item = g_application.CurrentUnstackedItem(); if (item.GetVideoContentType() == VIDEODB_CONTENT_TVSHOWS || item.GetVideoContentType() == VIDEODB_CONTENT_EPISODES) // Set default service for tv shows defaultService = CSettings::Get().GetString("subtitles.tv"); else // Set default service for filemode and movies defaultService = CSettings::Get().GetString("subtitles.movie"); std::string service = addons.front()->ID(); for (VECADDONS::const_iterator addonIt = addons.begin(); addonIt != addons.end(); addonIt++) { CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addonIt, "plugin://", false)); m_serviceItems->Add(item); if ((*addonIt)->ID() == defaultService) service = (*addonIt)->ID(); } // Bind our services to the UI CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_SERVICELIST, 0, 0, m_serviceItems); OnMessage(msg); SetService(service); }
void CPVRDatabase::UpdateTables(int iVersion) { if (iVersion < 13) m_pDS->exec("ALTER TABLE channels ADD idEpg integer;"); if (iVersion < 20) m_pDS->exec("ALTER TABLE channels ADD bIsUserSetIcon bool"); if (iVersion < 21) m_pDS->exec("ALTER TABLE channelgroups ADD iGroupType integer"); if (iVersion < 22) m_pDS->exec("ALTER TABLE channels ADD bIsLocked bool"); if (iVersion < 23) m_pDS->exec("ALTER TABLE channelgroups ADD iLastWatched integer"); if (iVersion < 24) m_pDS->exec("ALTER TABLE channels ADD bIsUserSetName bool"); if (iVersion < 25) m_pDS->exec("DROP TABLE IF EXISTS channelsettings"); if (iVersion < 26) { m_pDS->exec("ALTER TABLE channels ADD iClientSubChannelNumber integer"); m_pDS->exec("UPDATE channels SET iClientSubChannelNumber = 0"); m_pDS->exec("ALTER TABLE map_channelgroups_channels ADD iSubChannelNumber integer"); m_pDS->exec("UPDATE map_channelgroups_channels SET iSubChannelNumber = 0"); } if (iVersion < 27) m_pDS->exec("ALTER TABLE channelgroups ADD bIsHidden bool"); if (iVersion < 28) { VECADDONS addons; CAddonDatabase database; if (database.Open() && CAddonMgr::Get().GetAddons(ADDON_PVRDLL, addons, true)) { /** find all old client IDs */ std::string strQuery(PrepareSQL("SELECT idClient, sUid FROM clients")); m_pDS->query(strQuery); while (!m_pDS->eof() && !addons.empty()) { /** try to find an add-on that matches the sUid */ for (VECADDONS::iterator it = addons.begin(); it != addons.end(); ++it) { if ((*it)->ID() == m_pDS->fv(1).get_asString()) { /** try to get the current ID from the database */ int iAddonId = database.GetAddonId(*it); /** register a new id if it didn't exist */ if (iAddonId <= 0) iAddonId = database.AddAddon(*it, 0); if (iAddonId > 0) { // this fails when an id becomes the id of one that's being replaced next iteration // but since almost everyone only has 1 add-on enabled... /** update the iClientId in the channels table */ strQuery = PrepareSQL("UPDATE channels SET iClientId = %u WHERE iClientId = %u", iAddonId, m_pDS->fv(0).get_asInt()); m_pDS->exec(strQuery); /** no need to check this add-on again */ it = addons.erase(it); break; } } } m_pDS->next(); } } m_pDS->exec("DROP TABLE clients"); } if (iVersion < 29) m_pDS->exec("ALTER TABLE channelgroups ADD iPosition integer"); }
int CGUIWindowAddonBrowser::SelectAddonID(const std::vector<ADDON::TYPE> &types, std::vector<std::string> &addonIDs, bool showNone /* = false */, bool showDetails /* = true */, bool multipleSelection /* = true */, bool showInstalled /* = true */, bool showInstallable /* = false */, bool showMore /* = true */) { // if we shouldn't show neither installed nor installable addons the list will be empty if (!showInstalled && !showInstallable) return -1; // can't show the "Get More" button if we already show installable addons if (showInstallable) showMore = false; CGUIDialogSelect *dialog = g_windowManager.GetWindow<CGUIDialogSelect>(); if (!dialog) return -1; // get rid of any invalid addon types std::vector<ADDON::TYPE> validTypes(types.size()); std::copy_if(types.begin(), types.end(), validTypes.begin(), [](ADDON::TYPE type) { return type != ADDON_UNKNOWN; }); if (validTypes.empty()) return -1; // get all addons to show VECADDONS addons; if (showInstalled) { for (std::vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) { VECADDONS typeAddons; if (*type == ADDON_AUDIO) CAddonsDirectory::GetScriptsAndPlugins("audio", typeAddons); else if (*type == ADDON_EXECUTABLE) CAddonsDirectory::GetScriptsAndPlugins("executable", typeAddons); else if (*type == ADDON_IMAGE) CAddonsDirectory::GetScriptsAndPlugins("image", typeAddons); else if (*type == ADDON_VIDEO) CAddonsDirectory::GetScriptsAndPlugins("video", typeAddons); else if (*type == ADDON_GAME) CAddonsDirectory::GetScriptsAndPlugins("game", typeAddons); else CAddonMgr::GetInstance().GetAddons(typeAddons, *type); addons.insert(addons.end(), typeAddons.begin(), typeAddons.end()); } } if (showInstallable || showMore) { VECADDONS installableAddons; if (CAddonMgr::GetInstance().GetInstallableAddons(installableAddons)) { for (ADDON::IVECADDONS addon = installableAddons.begin(); addon != installableAddons.end();) { AddonPtr pAddon = *addon; // check if the addon matches one of the provided addon types bool matchesType = false; for (std::vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) { if (pAddon->IsType(*type)) { matchesType = true; break; } } if (matchesType) { ++addon; continue; } addon = installableAddons.erase(addon); } if (showInstallable) addons.insert(addons.end(), installableAddons.begin(), installableAddons.end()); else if (showMore) showMore = !installableAddons.empty(); } } if (addons.empty() && !showNone) return -1; // turn the addons into items std::map<std::string, AddonPtr> addonMap; CFileItemList items; for (ADDON::IVECADDONS addon = addons.begin(); addon != addons.end(); ++addon) { CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addon, (*addon)->ID())); item->SetLabel2((*addon)->Summary()); if (!items.Contains(item->GetPath())) { items.Add(item); addonMap.insert(std::make_pair(item->GetPath(), *addon)); } } if (items.IsEmpty() && !showNone) return -1; std::string heading; for (std::vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) { if (!heading.empty()) heading += ", "; heading += TranslateType(*type, true); } dialog->SetHeading(CVariant{std::move(heading)}); dialog->Reset(); dialog->SetUseDetails(showDetails); if (multipleSelection) { showNone = false; showMore = false; dialog->EnableButton(true, 186); } else if (showMore) dialog->EnableButton(true, 21452); if (showNone) { CFileItemPtr item(new CFileItem("", false)); item->SetLabel(g_localizeStrings.Get(231)); item->SetLabel2(g_localizeStrings.Get(24040)); item->SetIconImage("DefaultAddonNone.png"); item->SetSpecialSort(SortSpecialOnTop); items.Add(item); } items.Sort(SortByLabel, SortOrderAscending); if (!addonIDs.empty()) { for (std::vector<std::string>::const_iterator it = addonIDs.begin(); it != addonIDs.end() ; ++it) { CFileItemPtr item = items.Get(*it); if (item) item->Select(true); } } dialog->SetItems(items); dialog->SetMultiSelection(multipleSelection); dialog->Open(); // if the "Get More" button has been pressed and we haven't shown the // installable addons so far show a list of installable addons if (showMore&& dialog->IsButtonPressed()) return SelectAddonID(types, addonIDs, showNone, showDetails, multipleSelection, false, true, false); if (!dialog->IsConfirmed()) return 0; addonIDs.clear(); for (int i : dialog->GetSelectedItems()) { const CFileItemPtr& item = items.Get(i); // check if one of the selected addons needs to be installed if (showInstallable) { std::map<std::string, AddonPtr>::const_iterator itAddon = addonMap.find(item->GetPath()); if (itAddon != addonMap.end()) { const AddonPtr& addon = itAddon->second; // if the addon isn't installed we need to install it if (!CAddonMgr::GetInstance().IsAddonInstalled(addon->ID())) { AddonPtr installedAddon; if (!CAddonInstaller::GetInstance().InstallModal(addon->ID(), installedAddon, false)) continue; } // if the addon is disabled we need to enable it if (CAddonMgr::GetInstance().IsAddonDisabled(addon->ID())) CAddonMgr::GetInstance().EnableAddon(addon->ID()); } } addonIDs.push_back(item->GetPath()); } return 1; }
bool CAddonDatabase::GetRepositoryContent(const std::string& id, VECADDONS& addons) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS.get()) return false; auto start = XbmcThreads::SystemClockMillis(); // Ensure that the repositories we fetch from are enabled and valid. std::vector<std::string> repoIds; { std::string sql = PrepareSQL( " SELECT repo.id FROM repo" " WHERE repo.checksum IS NOT NULL AND repo.checksum != ''" " AND EXISTS (SELECT * FROM installed WHERE installed.addonID=repo.addonID AND" " installed.enabled=1)"); if (!id.empty()) sql += PrepareSQL(" AND repo.addonId='%s'", id.c_str()); m_pDS->query(sql); while (!m_pDS->eof()) { repoIds.emplace_back(m_pDS->fv(0).get_asString()); m_pDS->next(); } } CLog::Log(LOGDEBUG, "CAddonDatabase: SELECT repo.id FROM repo .. took %d ms", XbmcThreads::SystemClockMillis() - start); if (repoIds.empty()) { CLog::Log(LOGDEBUG, "CAddonDatabase: no valid repository matching '%s'", id.c_str()); return false; } { std::string sql = PrepareSQL( " SELECT * FROM addons" " JOIN addonlinkrepo ON addons.id=addonlinkrepo.idAddon" " WHERE addonlinkrepo.idRepo IN (%s)" " ORDER BY addons.addonID", StringUtils::Join(repoIds, ",").c_str()); auto start = XbmcThreads::SystemClockMillis(); m_pDS->query(sql); CLog::Log(LOGDEBUG, "CAddonDatabase: query %s returned %d rows in %d ms", sql.c_str(), m_pDS->num_rows(), XbmcThreads::SystemClockMillis() - start); } VECADDONS result; while (!m_pDS->eof()) { std::string addonId = m_pDS->fv("addonID").get_asString(); AddonVersion version(m_pDS->fv("version").get_asString()); if (!result.empty() && result.back()->ID() == addonId && result.back()->Version() >= version) { // We already have a version of this addon in our list which is newer. m_pDS->next(); continue; } CAddonBuilder builder; builder.SetId(addonId); builder.SetVersion(version); builder.SetName(m_pDS->fv("name").get_asString()); builder.SetSummary(m_pDS->fv("summary").get_asString()); builder.SetDescription(m_pDS->fv("description").get_asString()); DeserializeMetadata(m_pDS->fv("metadata").get_asString(), builder); auto addon = builder.Build(); if (addon) { if (!result.empty() && result.back()->ID() == addonId) result.back() = std::move(addon); else result.push_back(std::move(addon)); } else CLog::Log(LOGWARNING, "CAddonDatabase: failed to build %s", addonId.c_str()); m_pDS->next(); } m_pDS->close(); addons = std::move(result); CLog::Log(LOGDEBUG, "CAddonDatabase::GetAddons took %i ms", XbmcThreads::SystemClockMillis() - start); return true; } catch (...) { CLog::Log(LOGERROR, "%s failed", __FUNCTION__); } return false; }
void CGUIControllerWindow::UpdateButtons(void) { using namespace ADDON; VECADDONS addons; CONTROL_ENABLE_ON_CONDITION(CONTROL_GET_MORE, CAddonMgr::GetInstance().GetInstallableAddons(addons, ADDON::ADDON_GAME_CONTROLLER) && !addons.empty()); }
void CPVRClients::UpdateAddons(void) { VECADDONS addons; CAddonMgr::GetInstance().GetInstalledAddons(addons, ADDON_PVRDLL); if (addons.empty()) return; for (auto &addon : addons) { bool bEnabled = !CAddonMgr::GetInstance().IsAddonDisabled(addon->ID()); if (bEnabled && (!IsKnownClient(addon) || !IsCreatedClient(addon))) { std::hash<std::string> hasher; int iClientId = static_cast<int>(hasher(addon->ID())); if (iClientId < 0) iClientId = -iClientId; ADDON_STATUS status; if (IsKnownClient(addon)) { PVR_CLIENT client; GetClient(iClientId, client); status = client->Create(iClientId); } else { PVR_CLIENT pvrclient = std::dynamic_pointer_cast<CPVRClient>(addon); if (!pvrclient) { CLog::Log(LOGERROR, "CPVRClients - %s - severe error, incorrect add-on type", __FUNCTION__); continue; } status = pvrclient.get()->Create(iClientId); // register the add-on if (m_clientMap.find(iClientId) == m_clientMap.end()) { m_clientMap.insert(std::make_pair(iClientId, pvrclient)); m_addonNameIds.insert(make_pair(addon->ID(), iClientId)); } } if (status != ADDON_STATUS_OK) { CLog::Log(LOGERROR, "%s - failed to create add-on %s, status = %d", __FUNCTION__, addon->Name().c_str(), status); if (status == ADDON_STATUS_PERMANENT_FAILURE) { CGUIDialogOK::ShowAndGetInput(CVariant{24070}, CVariant{16029}); CAddonMgr::GetInstance().DisableAddon(addon->ID()); } } } else if (IsCreatedClient(addon)) { // stop add-on if it's no longer enabled, restart add-on if it's still enabled StopClient(addon, bEnabled); } } g_PVRManager.Start(); }
bool CPVRClients::UpdateAndInitialiseClients(bool bInitialiseAllClients /* = false */) { bool bReturn(true); VECADDONS map; VECADDONS disableAddons; { CSingleLock lock(m_critSection); map = m_addons; } if (map.empty()) return false; for (VECADDONS::iterator it = map.begin(); it != map.end(); ++it) { bool bEnabled = !CAddonMgr::GetInstance().IsAddonDisabled((*it)->ID()); if (!bEnabled && IsKnownClient(*it)) { CSingleLock lock(m_critSection); /* stop the client and remove it from the db */ StopClient(*it, false); disableAddons.push_back(*it); } else if (bEnabled && (bInitialiseAllClients || !IsKnownClient(*it) || !IsConnectedClient(*it))) { bool bDisabled(false); // register the add-on in the pvr db, and create the CPVRClient instance int iClientId = RegisterClient(*it); if (iClientId <= 0) { // failed to register or create the add-on, disable it CLog::Log(LOGWARNING, "%s - failed to register add-on %s, disabling it", __FUNCTION__, (*it)->Name().c_str()); disableAddons.push_back(*it); bDisabled = true; } else { ADDON_STATUS status(ADDON_STATUS_UNKNOWN); PVR_CLIENT addon; { CSingleLock lock(m_critSection); if (!GetClient(iClientId, addon)) { CLog::Log(LOGWARNING, "%s - failed to find add-on %s, disabling it", __FUNCTION__, (*it)->Name().c_str()); disableAddons.push_back(*it); bDisabled = true; } } // throttle connection attempts, no more than 1 attempt per 5 seconds if (!bDisabled && !CAddonMgr::GetInstance().IsAddonDisabled(addon->ID())) { time_t now; CDateTime::GetCurrentDateTime().GetAsTime(now); std::map<int, time_t>::iterator it = m_connectionAttempts.find(iClientId); if (it != m_connectionAttempts.end() && now < it->second) continue; m_connectionAttempts[iClientId] = now + 5; } // re-check the enabled status. newly installed clients get disabled when they're added to the db if (!bDisabled && !CAddonMgr::GetInstance().IsAddonDisabled(addon->ID()) && (status = addon->Create(iClientId)) != ADDON_STATUS_OK) { CLog::Log(LOGWARNING, "%s - failed to create add-on %s, status = %d", __FUNCTION__, (*it)->Name().c_str(), status); if (!addon.get() || !addon->DllLoaded() || status == ADDON_STATUS_PERMANENT_FAILURE) { // failed to load the dll of this add-on, disable it CLog::Log(LOGWARNING, "%s - failed to load the dll for add-on %s, disabling it", __FUNCTION__, (*it)->Name().c_str()); disableAddons.push_back(*it); bDisabled = true; } } } if (bDisabled && (g_PVRManager.IsStarted() || g_PVRManager.IsInitialising())) CGUIDialogOK::ShowAndGetInput(CVariant{24070}, CVariant{16029}); } } // disable add-ons that failed to initialise if (!disableAddons.empty()) { CSingleLock lock(m_critSection); for (VECADDONS::iterator it = disableAddons.begin(); it != disableAddons.end(); ++it) { // disable in the add-on db CAddonMgr::GetInstance().DisableAddon((*it)->ID()); // remove from the pvr add-on list VECADDONS::iterator addonPtr = std::find(m_addons.begin(), m_addons.end(), *it); if (addonPtr != m_addons.end()) m_addons.erase(addonPtr); } } return bReturn; }
bool CActiveAEDSP::UpdateAndInitialiseAudioDSPAddons(bool bInitialiseAllAudioDSPAddons /* = false */) { bool bReturn(true); VECADDONS map; VECADDONS disableAddons; { CSingleLock lock(m_critUpdateSection); map = m_addons; } if (map.empty()) return false; for (unsigned iAddonPtr = 0; iAddonPtr < map.size(); ++iAddonPtr) { const AddonPtr dspAddon = map.at(iAddonPtr); bool bEnabled = !CAddonMgr::GetInstance().IsAddonDisabled(dspAddon->ID()); if (!bEnabled && IsKnownAudioDSPAddon(dspAddon)) { CSingleLock lock(m_critUpdateSection); /* stop the dsp addon and remove it from the db */ StopAudioDSPAddon(dspAddon, false); VECADDONS::iterator addonPtr = std::find(m_addons.begin(), m_addons.end(), dspAddon); if (addonPtr != m_addons.end()) m_addons.erase(addonPtr); } else if (bEnabled && (bInitialiseAllAudioDSPAddons || !IsKnownAudioDSPAddon(dspAddon) || !IsReadyAudioDSPAddon(dspAddon))) { bool bDisabled(false); /* register the add-on in the audio dsp db, and create the CActiveAEDSPAddon instance */ int iAddonId = RegisterAudioDSPAddon(dspAddon); if (iAddonId < 0) { /* failed to register or create the add-on, disable it */ CLog::Log(LOGWARNING, "ActiveAE DSP - %s - failed to register add-on %s, disabling it", __FUNCTION__, dspAddon->Name().c_str()); disableAddons.push_back(dspAddon); bDisabled = true; } else { ADDON_STATUS status(ADDON_STATUS_UNKNOWN); AE_DSP_ADDON addon; { CSingleLock lock(m_critUpdateSection); if (!GetAudioDSPAddon(iAddonId, addon)) { CLog::Log(LOGWARNING, "ActiveAE DSP - %s - failed to find add-on %s, disabling it", __FUNCTION__, dspAddon->Name().c_str()); disableAddons.push_back(dspAddon); bDisabled = true; } } /* re-check the enabled status. newly installed dsps get disabled when they're added to the db */ if (!bDisabled && !CAddonMgr::GetInstance().IsAddonDisabled(addon->ID()) && (status = addon->Create(iAddonId)) != ADDON_STATUS_OK) { CLog::Log(LOGWARNING, "ActiveAE DSP - %s - failed to create add-on %s, status = %d", __FUNCTION__, dspAddon->Name().c_str(), status); if (!addon.get() || !addon->DllLoaded() || status == ADDON_STATUS_PERMANENT_FAILURE) { /* failed to load the dll of this add-on, disable it */ CLog::Log(LOGWARNING, "ActiveAE DSP - %s - failed to load the dll for add-on %s, disabling it", __FUNCTION__, dspAddon->Name().c_str()); disableAddons.push_back(dspAddon); bDisabled = true; } } } if (bDisabled && IsActivated()) CGUIDialogOK::ShowAndGetInput(24070, 24071, 16029, 0); } } /* disable add-ons that failed to initialise */ if (!disableAddons.empty()) { CSingleLock lock(m_critUpdateSection); for (VECADDONS::iterator itr = disableAddons.begin(); itr != disableAddons.end(); ++itr) { /* disable in the add-on db */ CAddonMgr::GetInstance().DisableAddon((*itr)->ID()); /* remove from the audio dsp add-on list */ VECADDONS::iterator addonPtr = std::find(m_addons.begin(), m_addons.end(), *itr); if (addonPtr != m_addons.end()) m_addons.erase(addonPtr); } } return bReturn; }