diff options
| author | manuel <manuel@mausz.at> | 2015-03-04 00:23:39 +0100 |
|---|---|---|
| committer | manuel <manuel@mausz.at> | 2015-03-04 00:23:39 +0100 |
| commit | 9d11b08ad61b1f0d6d7023ce403285d8662efaed (patch) | |
| tree | 5bc0c947d9e10d3e8c9dc1e6b26f3d6599f0cea1 /xbmc/addons/AddonManager.cpp | |
| parent | c159d9f91f1573901868100a9464527a5a71575b (diff) | |
| download | kodi-pvr-build-9d11b08ad61b1f0d6d7023ce403285d8662efaed.tar.gz kodi-pvr-build-9d11b08ad61b1f0d6d7023ce403285d8662efaed.tar.bz2 kodi-pvr-build-9d11b08ad61b1f0d6d7023ce403285d8662efaed.zip | |
sync with upstream
Diffstat (limited to 'xbmc/addons/AddonManager.cpp')
| -rw-r--r-- | xbmc/addons/AddonManager.cpp | 1030 |
1 files changed, 0 insertions, 1030 deletions
diff --git a/xbmc/addons/AddonManager.cpp b/xbmc/addons/AddonManager.cpp deleted file mode 100644 index 9ab5c31..0000000 --- a/xbmc/addons/AddonManager.cpp +++ /dev/null | |||
| @@ -1,1030 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005-2013 Team XBMC | ||
| 3 | * http://xbmc.org | ||
| 4 | * | ||
| 5 | * This Program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 8 | * any later version. | ||
| 9 | * | ||
| 10 | * This Program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with XBMC; see the file COPYING. If not, see | ||
| 17 | * <http://www.gnu.org/licenses/>. | ||
| 18 | * | ||
| 19 | */ | ||
| 20 | #include "AddonManager.h" | ||
| 21 | #include "Addon.h" | ||
| 22 | #include "AudioEncoder.h" | ||
| 23 | #include "DllLibCPluff.h" | ||
| 24 | #include "utils/StringUtils.h" | ||
| 25 | #include "utils/JobManager.h" | ||
| 26 | #include "threads/SingleLock.h" | ||
| 27 | #include "FileItem.h" | ||
| 28 | #include "LangInfo.h" | ||
| 29 | #include "settings/AdvancedSettings.h" | ||
| 30 | #include "settings/Settings.h" | ||
| 31 | #include "utils/log.h" | ||
| 32 | #include "utils/XBMCTinyXML.h" | ||
| 33 | #ifdef HAS_VISUALISATION | ||
| 34 | #include "Visualisation.h" | ||
| 35 | #endif | ||
| 36 | #ifdef HAS_SCREENSAVER | ||
| 37 | #include "ScreenSaver.h" | ||
| 38 | #endif | ||
| 39 | #ifdef HAS_PVRCLIENTS | ||
| 40 | #include "DllPVRClient.h" | ||
| 41 | #include "pvr/addons/PVRClient.h" | ||
| 42 | #endif | ||
| 43 | //#ifdef HAS_SCRAPERS | ||
| 44 | #include "Scraper.h" | ||
| 45 | //#endif | ||
| 46 | #include "PluginSource.h" | ||
| 47 | #include "Repository.h" | ||
| 48 | #include "Skin.h" | ||
| 49 | #include "Service.h" | ||
| 50 | #include "ContextItemAddon.h" | ||
| 51 | #include "Util.h" | ||
| 52 | #include "addons/Webinterface.h" | ||
| 53 | |||
| 54 | using namespace std; | ||
| 55 | using namespace XFILE; | ||
| 56 | |||
| 57 | namespace ADDON | ||
| 58 | { | ||
| 59 | |||
| 60 | cp_log_severity_t clog_to_cp(int lvl); | ||
| 61 | void cp_fatalErrorHandler(const char *msg); | ||
| 62 | void cp_logger(cp_log_severity_t level, const char *msg, const char *apid, void *user_data); | ||
| 63 | |||
| 64 | /********************************************************** | ||
| 65 | * CAddonMgr | ||
| 66 | * | ||
| 67 | */ | ||
| 68 | |||
| 69 | map<TYPE, IAddonMgrCallback*> CAddonMgr::m_managers; | ||
| 70 | |||
| 71 | AddonPtr CAddonMgr::Factory(const cp_extension_t *props) | ||
| 72 | { | ||
| 73 | if (!PlatformSupportsAddon(props->plugin)) | ||
| 74 | return AddonPtr(); | ||
| 75 | |||
| 76 | /* Check if user directories need to be created */ | ||
| 77 | const cp_cfg_element_t *settings = GetExtElement(props->configuration, "settings"); | ||
| 78 | if (settings) | ||
| 79 | CheckUserDirs(settings); | ||
| 80 | |||
| 81 | const TYPE type = TranslateType(props->ext_point_id); | ||
| 82 | switch (type) | ||
| 83 | { | ||
| 84 | case ADDON_PLUGIN: | ||
| 85 | case ADDON_SCRIPT: | ||
| 86 | return AddonPtr(new CPluginSource(props)); | ||
| 87 | case ADDON_SCRIPT_LIBRARY: | ||
| 88 | case ADDON_SCRIPT_LYRICS: | ||
| 89 | case ADDON_SCRIPT_MODULE: | ||
| 90 | case ADDON_SUBTITLE_MODULE: | ||
| 91 | return AddonPtr(new CAddon(props)); | ||
| 92 | case ADDON_WEB_INTERFACE: | ||
| 93 | return AddonPtr(new CWebinterface(props)); | ||
| 94 | case ADDON_SCRIPT_WEATHER: | ||
| 95 | { | ||
| 96 | // Eden (API v2.0) broke old weather add-ons | ||
| 97 | AddonPtr result(new CAddon(props)); | ||
| 98 | AddonVersion ver1 = result->GetDependencyVersion("xbmc.python"); | ||
| 99 | AddonVersion ver2 = AddonVersion("2.0"); | ||
| 100 | if (ver1 < ver2) | ||
| 101 | { | ||
| 102 | CLog::Log(LOGINFO,"%s: Weather add-ons for api < 2.0 unsupported (%s)",__FUNCTION__,result->ID().c_str()); | ||
| 103 | return AddonPtr(); | ||
| 104 | } | ||
| 105 | return result; | ||
| 106 | } | ||
| 107 | case ADDON_SERVICE: | ||
| 108 | return AddonPtr(new CService(props)); | ||
| 109 | case ADDON_SCRAPER_ALBUMS: | ||
| 110 | case ADDON_SCRAPER_ARTISTS: | ||
| 111 | case ADDON_SCRAPER_MOVIES: | ||
| 112 | case ADDON_SCRAPER_MUSICVIDEOS: | ||
| 113 | case ADDON_SCRAPER_TVSHOWS: | ||
| 114 | case ADDON_SCRAPER_LIBRARY: | ||
| 115 | return AddonPtr(new CScraper(props)); | ||
| 116 | case ADDON_VIZ: | ||
| 117 | case ADDON_SCREENSAVER: | ||
| 118 | case ADDON_PVRDLL: | ||
| 119 | case ADDON_AUDIOENCODER: | ||
| 120 | { // begin temporary platform handling for Dlls | ||
| 121 | // ideally platforms issues will be handled by C-Pluff | ||
| 122 | // this is not an attempt at a solution | ||
| 123 | std::string value; | ||
| 124 | if (type == ADDON_SCREENSAVER && 0 == strnicmp(props->plugin->identifier, "screensaver.xbmc.builtin.", 25)) | ||
| 125 | { // built in screensaver | ||
| 126 | return AddonPtr(new CAddon(props)); | ||
| 127 | } | ||
| 128 | if (type == ADDON_SCREENSAVER) | ||
| 129 | { // Python screensaver | ||
| 130 | std::string library = CAddonMgr::Get().GetExtValue(props->configuration, "@library"); | ||
| 131 | if (URIUtils::HasExtension(library, ".py")) | ||
| 132 | return AddonPtr(new CScreenSaver(props)); | ||
| 133 | } | ||
| 134 | if (type == ADDON_AUDIOENCODER && 0 == strncmp(props->plugin->identifier, | ||
| 135 | "audioencoder.xbmc.builtin.", 26)) | ||
| 136 | { // built in audio encoder | ||
| 137 | return AddonPtr(new CAudioEncoder(props)); | ||
| 138 | } | ||
| 139 | std::string tograb; | ||
| 140 | #if defined(TARGET_ANDROID) | ||
| 141 | tograb = "@library_android"; | ||
| 142 | #elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD) | ||
| 143 | tograb = "@library_linux"; | ||
| 144 | #elif defined(TARGET_WINDOWS) && defined(HAS_DX) | ||
| 145 | tograb = "@library_windx"; | ||
| 146 | #elif defined(TARGET_DARWIN) | ||
| 147 | tograb = "@library_osx"; | ||
| 148 | #endif | ||
| 149 | value = GetExtValue(props->plugin->extensions->configuration, tograb.c_str()); | ||
| 150 | if (value.empty()) | ||
| 151 | break; | ||
| 152 | if (type == ADDON_VIZ) | ||
| 153 | { | ||
| 154 | #if defined(HAS_VISUALISATION) | ||
| 155 | return AddonPtr(new CVisualisation(props)); | ||
| 156 | #endif | ||
| 157 | } | ||
| 158 | else if (type == ADDON_PVRDLL) | ||
| 159 | { | ||
| 160 | #ifdef HAS_PVRCLIENTS | ||
| 161 | return AddonPtr(new PVR::CPVRClient(props)); | ||
| 162 | #endif | ||
| 163 | } | ||
| 164 | else if (type == ADDON_AUDIOENCODER) | ||
| 165 | return AddonPtr(new CAudioEncoder(props)); | ||
| 166 | else | ||
| 167 | return AddonPtr(new CScreenSaver(props)); | ||
| 168 | } | ||
| 169 | case ADDON_SKIN: | ||
| 170 | return AddonPtr(new CSkinInfo(props)); | ||
| 171 | case ADDON_VIZ_LIBRARY: | ||
| 172 | return AddonPtr(new CAddonLibrary(props)); | ||
| 173 | case ADDON_REPOSITORY: | ||
| 174 | return AddonPtr(new CRepository(props)); | ||
| 175 | case ADDON_CONTEXT_ITEM: | ||
| 176 | return AddonPtr(new CContextItemAddon(props)); | ||
| 177 | default: | ||
| 178 | break; | ||
| 179 | } | ||
| 180 | return AddonPtr(); | ||
| 181 | } | ||
| 182 | |||
| 183 | bool CAddonMgr::CheckUserDirs(const cp_cfg_element_t *settings) | ||
| 184 | { | ||
| 185 | if (!settings) | ||
| 186 | return false; | ||
| 187 | |||
| 188 | const cp_cfg_element_t *userdirs = GetExtElement((cp_cfg_element_t *)settings, "userdirs"); | ||
| 189 | if (!userdirs) | ||
| 190 | return false; | ||
| 191 | |||
| 192 | ELEMENTS elements; | ||
| 193 | if (!GetExtElements((cp_cfg_element_t *)userdirs, "userdir", elements)) | ||
| 194 | return false; | ||
| 195 | |||
| 196 | ELEMENTS::iterator itr = elements.begin(); | ||
| 197 | while (itr != elements.end()) | ||
| 198 | { | ||
| 199 | std::string path = GetExtValue(*itr++, "@path"); | ||
| 200 | if (!CDirectory::Exists(path)) | ||
| 201 | { | ||
| 202 | if (!CUtil::CreateDirectoryEx(path)) | ||
| 203 | { | ||
| 204 | CLog::Log(LOGERROR, "CAddonMgr::CheckUserDirs: Unable to create directory %s.", path.c_str()); | ||
| 205 | return false; | ||
| 206 | } | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | return true; | ||
| 211 | } | ||
| 212 | |||
| 213 | CAddonMgr::CAddonMgr() | ||
| 214 | { | ||
| 215 | m_cpluff = NULL; | ||
| 216 | } | ||
| 217 | |||
| 218 | CAddonMgr::~CAddonMgr() | ||
| 219 | { | ||
| 220 | DeInit(); | ||
| 221 | } | ||
| 222 | |||
| 223 | CAddonMgr &CAddonMgr::Get() | ||
| 224 | { | ||
| 225 | static CAddonMgr sAddonMgr; | ||
| 226 | return sAddonMgr; | ||
| 227 | } | ||
| 228 | |||
| 229 | IAddonMgrCallback* CAddonMgr::GetCallbackForType(TYPE type) | ||
| 230 | { | ||
| 231 | if (m_managers.find(type) == m_managers.end()) | ||
| 232 | return NULL; | ||
| 233 | else | ||
| 234 | return m_managers[type]; | ||
| 235 | } | ||
| 236 | |||
| 237 | bool CAddonMgr::RegisterAddonMgrCallback(const TYPE type, IAddonMgrCallback* cb) | ||
| 238 | { | ||
| 239 | if (cb == NULL) | ||
| 240 | return false; | ||
| 241 | |||
| 242 | m_managers.erase(type); | ||
| 243 | m_managers[type] = cb; | ||
| 244 | |||
| 245 | return true; | ||
| 246 | } | ||
| 247 | |||
| 248 | void CAddonMgr::UnregisterAddonMgrCallback(TYPE type) | ||
| 249 | { | ||
| 250 | m_managers.erase(type); | ||
| 251 | } | ||
| 252 | |||
| 253 | bool CAddonMgr::Init() | ||
| 254 | { | ||
| 255 | m_cpluff = new DllLibCPluff; | ||
| 256 | m_cpluff->Load(); | ||
| 257 | |||
| 258 | m_database.Open(); | ||
| 259 | |||
| 260 | if (!m_cpluff->IsLoaded()) | ||
| 261 | { | ||
| 262 | CLog::Log(LOGERROR, "ADDONS: Fatal Error, could not load libcpluff"); | ||
| 263 | return false; | ||
| 264 | } | ||
| 265 | |||
| 266 | m_cpluff->set_fatal_error_handler(cp_fatalErrorHandler); | ||
| 267 | |||
| 268 | cp_status_t status; | ||
| 269 | status = m_cpluff->init(); | ||
| 270 | if (status != CP_OK) | ||
| 271 | { | ||
| 272 | CLog::Log(LOGERROR, "ADDONS: Fatal Error, cp_init() returned status: %i", status); | ||
| 273 | return false; | ||
| 274 | } | ||
| 275 | |||
| 276 | //TODO could separate addons into different contexts | ||
| 277 | // would allow partial unloading of addon framework | ||
| 278 | m_cp_context = m_cpluff->create_context(&status); | ||
| 279 | assert(m_cp_context); | ||
| 280 | status = m_cpluff->register_pcollection(m_cp_context, CSpecialProtocol::TranslatePath("special://home/addons").c_str()); | ||
| 281 | if (status != CP_OK) | ||
| 282 | { | ||
| 283 | CLog::Log(LOGERROR, "ADDONS: Fatal Error, cp_register_pcollection() returned status: %i", status); | ||
| 284 | return false; | ||
| 285 | } | ||
| 286 | |||
| 287 | status = m_cpluff->register_pcollection(m_cp_context, CSpecialProtocol::TranslatePath("special://xbmc/addons").c_str()); | ||
| 288 | if (status != CP_OK) | ||
| 289 | { | ||
| 290 | CLog::Log(LOGERROR, "ADDONS: Fatal Error, cp_register_pcollection() returned status: %i", status); | ||
| 291 | return false; | ||
| 292 | } | ||
| 293 | |||
| 294 | status = m_cpluff->register_pcollection(m_cp_context, CSpecialProtocol::TranslatePath("special://xbmcbin/addons").c_str()); | ||
| 295 | if (status != CP_OK) | ||
| 296 | { | ||
| 297 | CLog::Log(LOGERROR, "ADDONS: Fatal Error, cp_register_pcollection() returned status: %i", status); | ||
| 298 | return false; | ||
| 299 | } | ||
| 300 | |||
| 301 | status = m_cpluff->register_logger(m_cp_context, cp_logger, | ||
| 302 | &CAddonMgr::Get(), clog_to_cp(g_advancedSettings.m_logLevel)); | ||
| 303 | if (status != CP_OK) | ||
| 304 | { | ||
| 305 | CLog::Log(LOGERROR, "ADDONS: Fatal Error, cp_register_logger() returned status: %i", status); | ||
| 306 | return false; | ||
| 307 | } | ||
| 308 | |||
| 309 | FindAddons(); | ||
| 310 | |||
| 311 | VECADDONS repos; | ||
| 312 | if (GetAddons(ADDON_REPOSITORY, repos)) | ||
| 313 | { | ||
| 314 | VECADDONS::iterator it = repos.begin(); | ||
| 315 | for (;it != repos.end(); ++it) | ||
| 316 | CLog::Log(LOGNOTICE, "ADDONS: Using repository %s", (*it)->ID().c_str()); | ||
| 317 | } | ||
| 318 | |||
| 319 | return true; | ||
| 320 | } | ||
| 321 | |||
| 322 | void CAddonMgr::DeInit() | ||
| 323 | { | ||
| 324 | if (m_cpluff) | ||
| 325 | m_cpluff->destroy(); | ||
| 326 | delete m_cpluff; | ||
| 327 | m_cpluff = NULL; | ||
| 328 | m_database.Close(); | ||
| 329 | m_disabled.clear(); | ||
| 330 | } | ||
| 331 | |||
| 332 | bool CAddonMgr::HasAddons(const TYPE &type, bool enabled /*= true*/) | ||
| 333 | { | ||
| 334 | // TODO: This isn't particularly efficient as we create an addon type for each addon using the Factory, just so | ||
| 335 | // we can check addon dependencies in the addon constructor. | ||
| 336 | VECADDONS addons; | ||
| 337 | return GetAddons(type, addons, enabled); | ||
| 338 | } | ||
| 339 | |||
| 340 | bool CAddonMgr::GetAllAddons(VECADDONS &addons, bool enabled /*= true*/, bool allowRepos /* = false */) | ||
| 341 | { | ||
| 342 | for (int i = ADDON_UNKNOWN+1; i < ADDON_MAX; ++i) | ||
| 343 | { | ||
| 344 | if (!allowRepos && ADDON_REPOSITORY == (TYPE)i) | ||
| 345 | continue; | ||
| 346 | VECADDONS temp; | ||
| 347 | if (CAddonMgr::Get().GetAddons((TYPE)i, temp, enabled)) | ||
| 348 | addons.insert(addons.end(), temp.begin(), temp.end()); | ||
| 349 | } | ||
| 350 | return !addons.empty(); | ||
| 351 | } | ||
| 352 | |||
| 353 | void CAddonMgr::AddToUpdateableAddons(AddonPtr &pAddon) | ||
| 354 | { | ||
| 355 | CSingleLock lock(m_critSection); | ||
| 356 | m_updateableAddons.push_back(pAddon); | ||
| 357 | } | ||
| 358 | |||
| 359 | void CAddonMgr::RemoveFromUpdateableAddons(AddonPtr &pAddon) | ||
| 360 | { | ||
| 361 | CSingleLock lock(m_critSection); | ||
| 362 | VECADDONS::iterator it = std::find(m_updateableAddons.begin(), m_updateableAddons.end(), pAddon); | ||
| 363 | |||
| 364 | if(it != m_updateableAddons.end()) | ||
| 365 | { | ||
| 366 | m_updateableAddons.erase(it); | ||
| 367 | } | ||
| 368 | } | ||
| 369 | |||
| 370 | struct AddonIdFinder | ||
| 371 | { | ||
| 372 | AddonIdFinder(const std::string& id) | ||
| 373 | : m_id(id) | ||
| 374 | {} | ||
| 375 | |||
| 376 | bool operator()(const AddonPtr& addon) | ||
| 377 | { | ||
| 378 | return m_id == addon->ID(); | ||
| 379 | } | ||
| 380 | private: | ||
| 381 | std::string m_id; | ||
| 382 | }; | ||
| 383 | |||
| 384 | bool CAddonMgr::ReloadSettings(const std::string &id) | ||
| 385 | { | ||
| 386 | CSingleLock lock(m_critSection); | ||
| 387 | VECADDONS::iterator it = std::find_if(m_updateableAddons.begin(), m_updateableAddons.end(), AddonIdFinder(id)); | ||
| 388 | |||
| 389 | if( it != m_updateableAddons.end()) | ||
| 390 | { | ||
| 391 | return (*it)->ReloadSettings(); | ||
| 392 | } | ||
| 393 | return false; | ||
| 394 | } | ||
| 395 | |||
| 396 | bool CAddonMgr::GetAllOutdatedAddons(VECADDONS &addons, bool getLocalVersion /*= false*/) | ||
| 397 | { | ||
| 398 | CSingleLock lock(m_critSection); | ||
| 399 | for (int i = ADDON_UNKNOWN+1; i < ADDON_MAX; ++i) | ||
| 400 | { | ||
| 401 | VECADDONS temp; | ||
| 402 | if (CAddonMgr::Get().GetAddons((TYPE)i, temp, true)) | ||
| 403 | { | ||
| 404 | AddonPtr repoAddon; | ||
| 405 | for (unsigned int j = 0; j < temp.size(); j++) | ||
| 406 | { | ||
| 407 | // Ignore duplicates due to add-ons with multiple extension points | ||
| 408 | bool found = false; | ||
| 409 | for (VECADDONS::const_iterator addonIt = addons.begin(); addonIt != addons.end(); ++addonIt) | ||
| 410 | { | ||
| 411 | if ((*addonIt)->ID() == temp[j]->ID()) | ||
| 412 | found = true; | ||
| 413 | } | ||
| 414 | |||
| 415 | if (found || !m_database.GetAddon(temp[j]->ID(), repoAddon)) | ||
| 416 | continue; | ||
| 417 | |||
| 418 | if (temp[j]->Version() < repoAddon->Version() && | ||
| 419 | !m_database.IsAddonBlacklisted(temp[j]->ID(), | ||
| 420 | repoAddon->Version().asString().c_str())) | ||
| 421 | { | ||
| 422 | if (getLocalVersion) | ||
| 423 | repoAddon->Props().version = temp[j]->Version(); | ||
| 424 | addons.push_back(repoAddon); | ||
| 425 | } | ||
| 426 | } | ||
| 427 | } | ||
| 428 | } | ||
| 429 | return !addons.empty(); | ||
| 430 | } | ||
| 431 | |||
| 432 | bool CAddonMgr::HasOutdatedAddons() | ||
| 433 | { | ||
| 434 | VECADDONS dummy; | ||
| 435 | return GetAllOutdatedAddons(dummy); | ||
| 436 | } | ||
| 437 | |||
| 438 | bool CAddonMgr::GetAddons(const TYPE &type, VECADDONS &addons, bool enabled /* = true */) | ||
| 439 | { | ||
| 440 | CSingleLock lock(m_critSection); | ||
| 441 | addons.clear(); | ||
| 442 | if (!m_cp_context) | ||
| 443 | return false; | ||
| 444 | cp_status_t status; | ||
| 445 | int num; | ||
| 446 | std::string ext_point(TranslateType(type)); | ||
| 447 | cp_extension_t **exts = m_cpluff->get_extensions_info(m_cp_context, ext_point.c_str(), &status, &num); | ||
| 448 | for(int i=0; i <num; i++) | ||
| 449 | { | ||
| 450 | const cp_extension_t *props = exts[i]; | ||
| 451 | if (IsAddonDisabled(props->plugin->identifier) != enabled) | ||
| 452 | { | ||
| 453 | AddonPtr addon(Factory(props)); | ||
| 454 | if (addon) | ||
| 455 | { | ||
| 456 | if (enabled) | ||
| 457 | { | ||
| 458 | // if the addon has a running instance, grab that | ||
| 459 | AddonPtr runningAddon = addon->GetRunningInstance(); | ||
| 460 | if (runningAddon) | ||
| 461 | addon = runningAddon; | ||
| 462 | } | ||
| 463 | addons.push_back(addon); | ||
| 464 | } | ||
| 465 | } | ||
| 466 | } | ||
| 467 | m_cpluff->release_info(m_cp_context, exts); | ||
| 468 | return addons.size() > 0; | ||
| 469 | } | ||
| 470 | |||
| 471 | bool CAddonMgr::GetAddon(const std::string &str, AddonPtr &addon, const TYPE &type/*=ADDON_UNKNOWN*/, bool enabledOnly /*= true*/) | ||
| 472 | { | ||
| 473 | CSingleLock lock(m_critSection); | ||
| 474 | |||
| 475 | cp_status_t status; | ||
| 476 | cp_plugin_info_t *cpaddon = m_cpluff->get_plugin_info(m_cp_context, str.c_str(), &status); | ||
| 477 | if (status == CP_OK && cpaddon) | ||
| 478 | { | ||
| 479 | addon = GetAddonFromDescriptor(cpaddon, type==ADDON_UNKNOWN?"":TranslateType(type)); | ||
| 480 | m_cpluff->release_info(m_cp_context, cpaddon); | ||
| 481 | |||
| 482 | if (addon) | ||
| 483 | { | ||
| 484 | if (enabledOnly && IsAddonDisabled(addon->ID())) | ||
| 485 | return false; | ||
| 486 | |||
| 487 | // if the addon has a running instance, grab that | ||
| 488 | AddonPtr runningAddon = addon->GetRunningInstance(); | ||
| 489 | if (runningAddon) | ||
| 490 | addon = runningAddon; | ||
| 491 | } | ||
| 492 | return NULL != addon.get(); | ||
| 493 | } | ||
| 494 | if (cpaddon) | ||
| 495 | m_cpluff->release_info(m_cp_context, cpaddon); | ||
| 496 | |||
| 497 | return false; | ||
| 498 | } | ||
| 499 | |||
| 500 | //TODO handle all 'default' cases here, not just scrapers & vizs | ||
| 501 | bool CAddonMgr::GetDefault(const TYPE &type, AddonPtr &addon) | ||
| 502 | { | ||
| 503 | std::string setting; | ||
| 504 | switch (type) | ||
| 505 | { | ||
| 506 | case ADDON_VIZ: | ||
| 507 | setting = CSettings::Get().GetString("musicplayer.visualisation"); | ||
| 508 | break; | ||
| 509 | case ADDON_SCREENSAVER: | ||
| 510 | setting = CSettings::Get().GetString("screensaver.mode"); | ||
| 511 | break; | ||
| 512 | case ADDON_SCRAPER_ALBUMS: | ||
| 513 | setting = CSettings::Get().GetString("musiclibrary.albumsscraper"); | ||
| 514 | break; | ||
| 515 | case ADDON_SCRAPER_ARTISTS: | ||
| 516 | setting = CSettings::Get().GetString("musiclibrary.artistsscraper"); | ||
| 517 | break; | ||
| 518 | case ADDON_SCRAPER_MOVIES: | ||
| 519 | setting = CSettings::Get().GetString("scrapers.moviesdefault"); | ||
| 520 | break; | ||
| 521 | case ADDON_SCRAPER_MUSICVIDEOS: | ||
| 522 | setting = CSettings::Get().GetString("scrapers.musicvideosdefault"); | ||
| 523 | break; | ||
| 524 | case ADDON_SCRAPER_TVSHOWS: | ||
| 525 | setting = CSettings::Get().GetString("scrapers.tvshowsdefault"); | ||
| 526 | break; | ||
| 527 | case ADDON_WEB_INTERFACE: | ||
| 528 | setting = CSettings::Get().GetString("services.webskin"); | ||
| 529 | break; | ||
| 530 | default: | ||
| 531 | return false; | ||
| 532 | } | ||
| 533 | return GetAddon(setting, addon, type); | ||
| 534 | } | ||
| 535 | |||
| 536 | bool CAddonMgr::SetDefault(const TYPE &type, const std::string &addonID) | ||
| 537 | { | ||
| 538 | switch (type) | ||
| 539 | { | ||
| 540 | case ADDON_VIZ: | ||
| 541 | CSettings::Get().SetString("musicplayer.visualisation",addonID); | ||
| 542 | break; | ||
| 543 | case ADDON_SCREENSAVER: | ||
| 544 | CSettings::Get().SetString("screensaver.mode",addonID); | ||
| 545 | break; | ||
| 546 | case ADDON_SCRAPER_ALBUMS: | ||
| 547 | CSettings::Get().SetString("musiclibrary.albumsscraper",addonID); | ||
| 548 | break; | ||
| 549 | case ADDON_SCRAPER_ARTISTS: | ||
| 550 | CSettings::Get().SetString("musiclibrary.artistsscraper",addonID); | ||
| 551 | break; | ||
| 552 | case ADDON_SCRAPER_MOVIES: | ||
| 553 | CSettings::Get().SetString("scrapers.moviesdefault",addonID); | ||
| 554 | break; | ||
| 555 | case ADDON_SCRAPER_MUSICVIDEOS: | ||
| 556 | CSettings::Get().SetString("scrapers.musicvideosdefault",addonID); | ||
| 557 | break; | ||
| 558 | case ADDON_SCRAPER_TVSHOWS: | ||
| 559 | CSettings::Get().SetString("scrapers.tvshowsdefault",addonID); | ||
| 560 | break; | ||
| 561 | default: | ||
| 562 | return false; | ||
| 563 | } | ||
| 564 | |||
| 565 | return true; | ||
| 566 | } | ||
| 567 | |||
| 568 | std::string CAddonMgr::GetString(const std::string &id, const int number) | ||
| 569 | { | ||
| 570 | AddonPtr addon; | ||
| 571 | if (GetAddon(id, addon)) | ||
| 572 | return addon->GetString(number); | ||
| 573 | |||
| 574 | return ""; | ||
| 575 | } | ||
| 576 | |||
| 577 | void CAddonMgr::FindAddons() | ||
| 578 | { | ||
| 579 | { | ||
| 580 | CSingleLock lock(m_critSection); | ||
| 581 | if (m_cpluff && m_cp_context) | ||
| 582 | { | ||
| 583 | m_cpluff->scan_plugins(m_cp_context, CP_SP_UPGRADE); | ||
| 584 | SetChanged(); | ||
| 585 | } | ||
| 586 | } | ||
| 587 | NotifyObservers(ObservableMessageAddons); | ||
| 588 | } | ||
| 589 | |||
| 590 | void CAddonMgr::RemoveAddon(const std::string& ID) | ||
| 591 | { | ||
| 592 | if (m_cpluff && m_cp_context) | ||
| 593 | { | ||
| 594 | m_cpluff->uninstall_plugin(m_cp_context,ID.c_str()); | ||
| 595 | SetChanged(); | ||
| 596 | NotifyObservers(ObservableMessageAddons); | ||
| 597 | } | ||
| 598 | } | ||
| 599 | |||
| 600 | bool CAddonMgr::DisableAddon(const std::string& ID, bool disable) | ||
| 601 | { | ||
| 602 | CSingleLock lock(m_critSection); | ||
| 603 | if (m_database.DisableAddon(ID, disable)) | ||
| 604 | { | ||
| 605 | m_disabled[ID] = disable; | ||
| 606 | return true; | ||
| 607 | } | ||
| 608 | |||
| 609 | return false; | ||
| 610 | } | ||
| 611 | |||
| 612 | bool CAddonMgr::IsAddonDisabled(const std::string& ID) | ||
| 613 | { | ||
| 614 | CSingleLock lock(m_critSection); | ||
| 615 | std::map<std::string, bool>::const_iterator it = m_disabled.find(ID); | ||
| 616 | if (it != m_disabled.end()) | ||
| 617 | return it->second; | ||
| 618 | |||
| 619 | bool ret = m_database.IsAddonDisabled(ID); | ||
| 620 | m_disabled.insert(pair<std::string, bool>(ID, ret)); | ||
| 621 | |||
| 622 | return ret; | ||
| 623 | } | ||
| 624 | |||
| 625 | bool CAddonMgr::CanAddonBeDisabled(const std::string& ID) | ||
| 626 | { | ||
| 627 | if (ID.empty()) | ||
| 628 | return false; | ||
| 629 | |||
| 630 | CSingleLock lock(m_critSection); | ||
| 631 | AddonPtr localAddon; | ||
| 632 | // can't disable an addon that isn't installed | ||
| 633 | if (!IsAddonInstalled(ID, localAddon)) | ||
| 634 | return false; | ||
| 635 | |||
| 636 | // can't disable an addon that is in use | ||
| 637 | if (localAddon->IsInUse()) | ||
| 638 | return false; | ||
| 639 | |||
| 640 | // installed PVR addons can always be disabled | ||
| 641 | if (localAddon->Type() == ADDON_PVRDLL) | ||
| 642 | return true; | ||
| 643 | |||
| 644 | std::string systemAddonsPath = CSpecialProtocol::TranslatePath("special://xbmc/addons"); | ||
| 645 | // can't disable system addons | ||
| 646 | if (StringUtils::StartsWith(localAddon->Path(), systemAddonsPath)) | ||
| 647 | return false; | ||
| 648 | |||
| 649 | return true; | ||
| 650 | } | ||
| 651 | |||
| 652 | bool CAddonMgr::IsAddonInstalled(const std::string& ID) | ||
| 653 | { | ||
| 654 | AddonPtr tmp; | ||
| 655 | return IsAddonInstalled(ID, tmp); | ||
| 656 | } | ||
| 657 | |||
| 658 | bool CAddonMgr::IsAddonInstalled(const std::string& ID, AddonPtr& addon) | ||
| 659 | { | ||
| 660 | return GetAddon(ID, addon, ADDON_UNKNOWN, false); | ||
| 661 | } | ||
| 662 | |||
| 663 | bool CAddonMgr::CanAddonBeInstalled(const std::string& ID) | ||
| 664 | { | ||
| 665 | if (ID.empty()) | ||
| 666 | return false; | ||
| 667 | |||
| 668 | CSingleLock lock(m_critSection); | ||
| 669 | // can't install already installed addon | ||
| 670 | if (IsAddonInstalled(ID)) | ||
| 671 | return false; | ||
| 672 | |||
| 673 | // can't install broken addons | ||
| 674 | if (!m_database.IsAddonBroken(ID).empty()) | ||
| 675 | return false; | ||
| 676 | |||
| 677 | return true; | ||
| 678 | } | ||
| 679 | |||
| 680 | bool CAddonMgr::CanAddonBeInstalled(const AddonPtr& addon) | ||
| 681 | { | ||
| 682 | if (addon == NULL) | ||
| 683 | return false; | ||
| 684 | |||
| 685 | CSingleLock lock(m_critSection); | ||
| 686 | // can't install already installed addon | ||
| 687 | if (IsAddonInstalled(addon->ID())) | ||
| 688 | return false; | ||
| 689 | |||
| 690 | // can't install broken addons | ||
| 691 | if (!addon->Props().broken.empty()) | ||
| 692 | return false; | ||
| 693 | |||
| 694 | return true; | ||
| 695 | } | ||
| 696 | |||
| 697 | std::string CAddonMgr::GetTranslatedString(const cp_cfg_element_t *root, const char *tag) | ||
| 698 | { | ||
| 699 | if (!root) | ||
| 700 | return ""; | ||
| 701 | |||
| 702 | const cp_cfg_element_t *eng = NULL; | ||
| 703 | for (unsigned int i = 0; i < root->num_children; i++) | ||
| 704 | { | ||
| 705 | const cp_cfg_element_t &child = root->children[i]; | ||
| 706 | if (strcmp(tag, child.name) == 0) | ||
| 707 | { // see if we have a "lang" attribute | ||
| 708 | const char *lang = m_cpluff->lookup_cfg_value((cp_cfg_element_t*)&child, "@lang"); | ||
| 709 | if (lang && 0 == strcmp(lang,g_langInfo.GetLanguageLocale().c_str())) | ||
| 710 | return child.value ? child.value : ""; | ||
| 711 | if (!lang || 0 == strcmp(lang, "en")) | ||
| 712 | eng = &child; | ||
| 713 | } | ||
| 714 | } | ||
| 715 | return (eng && eng->value) ? eng->value : ""; | ||
| 716 | } | ||
| 717 | |||
| 718 | AddonPtr CAddonMgr::AddonFromProps(AddonProps& addonProps) | ||
| 719 | { | ||
| 720 | switch (addonProps.type) | ||
| 721 | { | ||
| 722 | case ADDON_PLUGIN: | ||
| 723 | case ADDON_SCRIPT: | ||
| 724 | return AddonPtr(new CPluginSource(addonProps)); | ||
| 725 | case ADDON_SCRIPT_LIBRARY: | ||
| 726 | case ADDON_SCRIPT_LYRICS: | ||
| 727 | case ADDON_SCRIPT_WEATHER: | ||
| 728 | case ADDON_SCRIPT_MODULE: | ||
| 729 | case ADDON_SUBTITLE_MODULE: | ||
| 730 | return AddonPtr(new CAddon(addonProps)); | ||
| 731 | case ADDON_WEB_INTERFACE: | ||
| 732 | return AddonPtr(new CWebinterface(addonProps)); | ||
| 733 | case ADDON_SERVICE: | ||
| 734 | return AddonPtr(new CService(addonProps)); | ||
| 735 | case ADDON_SCRAPER_ALBUMS: | ||
| 736 | case ADDON_SCRAPER_ARTISTS: | ||
| 737 | case ADDON_SCRAPER_MOVIES: | ||
| 738 | case ADDON_SCRAPER_MUSICVIDEOS: | ||
| 739 | case ADDON_SCRAPER_TVSHOWS: | ||
| 740 | case ADDON_SCRAPER_LIBRARY: | ||
| 741 | return AddonPtr(new CScraper(addonProps)); | ||
| 742 | case ADDON_SKIN: | ||
| 743 | return AddonPtr(new CSkinInfo(addonProps)); | ||
| 744 | #if defined(HAS_VISUALISATION) | ||
| 745 | case ADDON_VIZ: | ||
| 746 | return AddonPtr(new CVisualisation(addonProps)); | ||
| 747 | #endif | ||
| 748 | case ADDON_SCREENSAVER: | ||
| 749 | return AddonPtr(new CScreenSaver(addonProps)); | ||
| 750 | case ADDON_VIZ_LIBRARY: | ||
| 751 | return AddonPtr(new CAddonLibrary(addonProps)); | ||
| 752 | case ADDON_PVRDLL: | ||
| 753 | return AddonPtr(new PVR::CPVRClient(addonProps)); | ||
| 754 | case ADDON_AUDIOENCODER: | ||
| 755 | return AddonPtr(new CAudioEncoder(addonProps)); | ||
| 756 | case ADDON_REPOSITORY: | ||
| 757 | return AddonPtr(new CRepository(addonProps)); | ||
| 758 | case ADDON_CONTEXT_ITEM: | ||
| 759 | return AddonPtr(new CContextItemAddon(addonProps)); | ||
| 760 | default: | ||
| 761 | break; | ||
| 762 | } | ||
| 763 | return AddonPtr(); | ||
| 764 | } | ||
| 765 | |||
| 766 | /* | ||
| 767 | * libcpluff interaction | ||
| 768 | */ | ||
| 769 | |||
| 770 | bool CAddonMgr::PlatformSupportsAddon(const cp_plugin_info_t *plugin) const | ||
| 771 | { | ||
| 772 | if (!plugin || !plugin->num_extensions) | ||
| 773 | return false; | ||
| 774 | const cp_extension_t *metadata = GetExtension(plugin, "xbmc.addon.metadata"); //<! backword compatibilty | ||
| 775 | if (!metadata) | ||
| 776 | metadata = CAddonMgr::Get().GetExtension(plugin, "kodi.addon.metadata"); | ||
| 777 | if (!metadata) | ||
| 778 | return false; | ||
| 779 | |||
| 780 | vector<std::string> platforms; | ||
| 781 | if (CAddonMgr::Get().GetExtList(metadata->configuration, "platform", platforms)) | ||
| 782 | { | ||
| 783 | for (vector<std::string>::const_iterator platform = platforms.begin(); platform != platforms.end(); ++platform) | ||
| 784 | { | ||
| 785 | if (*platform == "all") | ||
| 786 | return true; | ||
| 787 | #if defined(TARGET_ANDROID) | ||
| 788 | if (*platform == "android") | ||
| 789 | #elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD) | ||
| 790 | if (*platform == "linux") | ||
| 791 | #elif defined(TARGET_WINDOWS) && defined(HAS_DX) | ||
| 792 | if (*platform == "windx") | ||
| 793 | #elif defined(TARGET_DARWIN_OSX) | ||
| 794 | // Remove this after Frodo and add an architecture filter | ||
| 795 | // in addition to platform. | ||
| 796 | #if defined(__x86_64__) | ||
| 797 | if (*platform == "osx64" || *platform == "osx") | ||
| 798 | #else | ||
| 799 | if (*platform == "osx32" || *platform == "osx") | ||
| 800 | #endif | ||
| 801 | #elif defined(TARGET_DARWIN_IOS) | ||
| 802 | if (*platform == "ios") | ||
| 803 | #endif | ||
| 804 | return true; | ||
| 805 | } | ||
| 806 | return false; // no <platform> works for us | ||
| 807 | } | ||
| 808 | return true; // assume no <platform> is equivalent to <platform>all</platform> | ||
| 809 | } | ||
| 810 | |||
| 811 | const cp_cfg_element_t *CAddonMgr::GetExtElement(cp_cfg_element_t *base, const char *path) | ||
| 812 | { | ||
| 813 | const cp_cfg_element_t *element = NULL; | ||
| 814 | if (base) | ||
| 815 | element = m_cpluff->lookup_cfg_element(base, path); | ||
| 816 | return element; | ||
| 817 | } | ||
| 818 | |||
| 819 | bool CAddonMgr::GetExtElements(cp_cfg_element_t *base, const char *path, ELEMENTS &elements) | ||
| 820 | { | ||
| 821 | if (!base || !path) | ||
| 822 | return false; | ||
| 823 | |||
| 824 | for (unsigned int i = 0; i < base->num_children; i++) | ||
| 825 | { | ||
| 826 | std::string temp = base->children[i].name; | ||
| 827 | if (!temp.compare(path)) | ||
| 828 | elements.push_back(&base->children[i]); | ||
| 829 | } | ||
| 830 | |||
| 831 | return !elements.empty(); | ||
| 832 | } | ||
| 833 | |||
| 834 | const cp_extension_t *CAddonMgr::GetExtension(const cp_plugin_info_t *props, const char *extension) const | ||
| 835 | { | ||
| 836 | if (!props) | ||
| 837 | return NULL; | ||
| 838 | for (unsigned int i = 0; i < props->num_extensions; ++i) | ||
| 839 | { | ||
| 840 | if (0 == strcmp(props->extensions[i].ext_point_id, extension)) | ||
| 841 | return &props->extensions[i]; | ||
| 842 | } | ||
| 843 | return NULL; | ||
| 844 | } | ||
| 845 | |||
| 846 | std::string CAddonMgr::GetExtValue(cp_cfg_element_t *base, const char *path) | ||
| 847 | { | ||
| 848 | const char *value = ""; | ||
| 849 | if (base && (value = m_cpluff->lookup_cfg_value(base, path))) | ||
| 850 | return value; | ||
| 851 | else | ||
| 852 | return ""; | ||
| 853 | } | ||
| 854 | |||
| 855 | bool CAddonMgr::GetExtList(cp_cfg_element_t *base, const char *path, vector<std::string> &result) const | ||
| 856 | { | ||
| 857 | result.clear(); | ||
| 858 | if (!base || !path) | ||
| 859 | return false; | ||
| 860 | const char *all = m_cpluff->lookup_cfg_value(base, path); | ||
| 861 | if (!all || *all == 0) | ||
| 862 | return false; | ||
| 863 | StringUtils::Tokenize(all, result, ' '); | ||
| 864 | return true; | ||
| 865 | } | ||
| 866 | |||
| 867 | AddonPtr CAddonMgr::GetAddonFromDescriptor(const cp_plugin_info_t *info, | ||
| 868 | const std::string& type) | ||
| 869 | { | ||
| 870 | if (!info) | ||
| 871 | return AddonPtr(); | ||
| 872 | |||
| 873 | if (!info->extensions && type.empty()) | ||
| 874 | { // no extensions, so we need only the dep information | ||
| 875 | return AddonPtr(new CAddon(info)); | ||
| 876 | } | ||
| 877 | |||
| 878 | // grab a relevant extension point, ignoring our kodi.addon.metadata extension point | ||
| 879 | for (unsigned int i = 0; i < info->num_extensions; ++i) | ||
| 880 | { | ||
| 881 | if (0 != strcmp("xbmc.addon.metadata" , info->extensions[i].ext_point_id) && //<! backword compatibilty | ||
| 882 | 0 != strcmp("kodi.addon.metadata" , info->extensions[i].ext_point_id) && | ||
| 883 | (type.empty() || 0 == strcmp(type.c_str(), info->extensions[i].ext_point_id))) | ||
| 884 | { // note that Factory takes care of whether or not we have platform support | ||
| 885 | return Factory(&info->extensions[i]); | ||
| 886 | } | ||
| 887 | } | ||
| 888 | return AddonPtr(); | ||
| 889 | } | ||
| 890 | |||
| 891 | // FIXME: This function may not be required | ||
| 892 | bool CAddonMgr::LoadAddonDescription(const std::string &path, AddonPtr &addon) | ||
| 893 | { | ||
| 894 | cp_status_t status; | ||
| 895 | cp_plugin_info_t *info = m_cpluff->load_plugin_descriptor(m_cp_context, CSpecialProtocol::TranslatePath(path).c_str(), &status); | ||
| 896 | if (info) | ||
| 897 | { | ||
| 898 | addon = GetAddonFromDescriptor(info); | ||
| 899 | m_cpluff->release_info(m_cp_context, info); | ||
| 900 | return NULL != addon.get(); | ||
| 901 | } | ||
| 902 | return false; | ||
| 903 | } | ||
| 904 | |||
| 905 | bool CAddonMgr::AddonsFromRepoXML(const TiXmlElement *root, VECADDONS &addons) | ||
| 906 | { | ||
| 907 | // create a context for these addons | ||
| 908 | cp_status_t status; | ||
| 909 | cp_context_t *context = m_cpluff->create_context(&status); | ||
| 910 | if (!root || !context) | ||
| 911 | return false; | ||
| 912 | |||
| 913 | // each addon XML should have a UTF-8 declaration | ||
| 914 | TiXmlDeclaration decl("1.0", "UTF-8", ""); | ||
| 915 | const TiXmlElement *element = root->FirstChildElement("addon"); | ||
| 916 | while (element) | ||
| 917 | { | ||
| 918 | // dump the XML back to text | ||
| 919 | std::string xml; | ||
| 920 | xml << decl; | ||
| 921 | xml << *element; | ||
| 922 | cp_status_t status; | ||
| 923 | cp_plugin_info_t *info = m_cpluff->load_plugin_descriptor_from_memory(context, xml.c_str(), xml.size(), &status); | ||
| 924 | if (info) | ||
| 925 | { | ||
| 926 | AddonPtr addon = GetAddonFromDescriptor(info); | ||
| 927 | if (addon.get()) | ||
| 928 | addons.push_back(addon); | ||
| 929 | m_cpluff->release_info(context, info); | ||
| 930 | } | ||
| 931 | element = element->NextSiblingElement("addon"); | ||
| 932 | } | ||
| 933 | m_cpluff->destroy_context(context); | ||
| 934 | return true; | ||
| 935 | } | ||
| 936 | |||
| 937 | bool CAddonMgr::LoadAddonDescriptionFromMemory(const TiXmlElement *root, AddonPtr &addon) | ||
| 938 | { | ||
| 939 | // create a context for these addons | ||
| 940 | cp_status_t status; | ||
| 941 | cp_context_t *context = m_cpluff->create_context(&status); | ||
| 942 | if (!root || !context) | ||
| 943 | return false; | ||
| 944 | |||
| 945 | // dump the XML back to text | ||
| 946 | std::string xml; | ||
| 947 | xml << TiXmlDeclaration("1.0", "UTF-8", ""); | ||
| 948 | xml << *root; | ||
| 949 | cp_plugin_info_t *info = m_cpluff->load_plugin_descriptor_from_memory(context, xml.c_str(), xml.size(), &status); | ||
| 950 | if (info) | ||
| 951 | { | ||
| 952 | addon = GetAddonFromDescriptor(info); | ||
| 953 | m_cpluff->release_info(context, info); | ||
| 954 | } | ||
| 955 | m_cpluff->destroy_context(context); | ||
| 956 | return addon != NULL; | ||
| 957 | } | ||
| 958 | |||
| 959 | bool CAddonMgr::StartServices(const bool beforelogin) | ||
| 960 | { | ||
| 961 | CLog::Log(LOGDEBUG, "ADDON: Starting service addons."); | ||
| 962 | |||
| 963 | VECADDONS services; | ||
| 964 | if (!GetAddons(ADDON_SERVICE, services)) | ||
| 965 | return false; | ||
| 966 | |||
| 967 | bool ret = true; | ||
| 968 | for (IVECADDONS it = services.begin(); it != services.end(); ++it) | ||
| 969 | { | ||
| 970 | std::shared_ptr<CService> service = std::dynamic_pointer_cast<CService>(*it); | ||
| 971 | if (service) | ||
| 972 | { | ||
| 973 | if ( (beforelogin && service->GetStartOption() == CService::STARTUP) | ||
| 974 | || (!beforelogin && service->GetStartOption() == CService::LOGIN) ) | ||
| 975 | ret &= service->Start(); | ||
| 976 | } | ||
| 977 | } | ||
| 978 | |||
| 979 | return ret; | ||
| 980 | } | ||
| 981 | |||
| 982 | void CAddonMgr::StopServices(const bool onlylogin) | ||
| 983 | { | ||
| 984 | CLog::Log(LOGDEBUG, "ADDON: Stopping service addons."); | ||
| 985 | |||
| 986 | VECADDONS services; | ||
| 987 | if (!GetAddons(ADDON_SERVICE, services)) | ||
| 988 | return; | ||
| 989 | |||
| 990 | for (IVECADDONS it = services.begin(); it != services.end(); ++it) | ||
| 991 | { | ||
| 992 | std::shared_ptr<CService> service = std::dynamic_pointer_cast<CService>(*it); | ||
| 993 | if (service) | ||
| 994 | { | ||
| 995 | if ( (onlylogin && service->GetStartOption() == CService::LOGIN) | ||
| 996 | || (!onlylogin) ) | ||
| 997 | service->Stop(); | ||
| 998 | } | ||
| 999 | } | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | int cp_to_clog(cp_log_severity_t lvl) | ||
| 1003 | { | ||
| 1004 | if (lvl >= CP_LOG_ERROR) | ||
| 1005 | return LOGINFO; | ||
| 1006 | return LOGDEBUG; | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | cp_log_severity_t clog_to_cp(int lvl) | ||
| 1010 | { | ||
| 1011 | if (lvl >= LOG_LEVEL_DEBUG) | ||
| 1012 | return CP_LOG_INFO; | ||
| 1013 | return CP_LOG_ERROR; | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | void cp_fatalErrorHandler(const char *msg) | ||
| 1017 | { | ||
| 1018 | CLog::Log(LOGERROR, "ADDONS: CPluffFatalError(%s)", msg); | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | void cp_logger(cp_log_severity_t level, const char *msg, const char *apid, void *user_data) | ||
| 1022 | { | ||
| 1023 | if(!apid) | ||
| 1024 | CLog::Log(cp_to_clog(level), "ADDON: cpluff: '%s'", msg); | ||
| 1025 | else | ||
| 1026 | CLog::Log(cp_to_clog(level), "ADDON: cpluff: '%s' reports '%s'", apid, msg); | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | } /* namespace ADDON */ | ||
| 1030 | |||
