From 9d11b08ad61b1f0d6d7023ce403285d8662efaed Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 4 Mar 2015 00:23:39 +0100 Subject: sync with upstream --- xbmc/addons/AddonDll.h | 572 ------------------------------------------------- 1 file changed, 572 deletions(-) delete mode 100644 xbmc/addons/AddonDll.h (limited to 'xbmc/addons/AddonDll.h') diff --git a/xbmc/addons/AddonDll.h b/xbmc/addons/AddonDll.h deleted file mode 100644 index d5e4e9e..0000000 --- a/xbmc/addons/AddonDll.h +++ /dev/null @@ -1,572 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ -#include -#include - -#include "Addon.h" -#include "DllAddon.h" -#include "AddonManager.h" -#include "AddonStatusHandler.h" -#include "AddonCallbacks.h" -#include "utils/URIUtils.h" -#include "filesystem/File.h" -#include "filesystem/SpecialProtocol.h" -#include "filesystem/Directory.h" -#include "utils/log.h" -#include "interfaces/IAnnouncer.h" -#include "interfaces/AnnouncementManager.h" -#include "utils/XMLUtils.h" -#include "Util.h" - -namespace ADDON -{ - template - class CAddonDll : public CAddon, public ANNOUNCEMENT::IAnnouncer - { - public: - CAddonDll(const AddonProps &props); - CAddonDll(const cp_extension_t *ext); - CAddonDll(const CAddonDll &rhs); - virtual ~CAddonDll(); - virtual AddonPtr Clone() const; - virtual ADDON_STATUS GetStatus(); - - // addon settings - virtual void SaveSettings(); - virtual std::string GetSetting(const std::string& key); - - ADDON_STATUS Create(); - virtual void Stop(); - virtual bool CheckAPIVersion(void) { return true; } - void Destroy(); - - bool DllLoaded(void) const; - - void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data); - - protected: - void HandleException(std::exception &e, const char* context); - bool Initialized() { return m_initialized; } - virtual void BuildLibName(const cp_extension_t *ext = NULL) {} - virtual bool LoadSettings(); - TheStruct* m_pStruct; - TheProps* m_pInfo; - CAddonCallbacks* m_pHelpers; - bool m_bIsChild; - - private: - TheDll* m_pDll; - bool m_initialized; - bool LoadDll(); - bool m_needsavedsettings; - - virtual ADDON_STATUS TransferSettings(); - TiXmlElement MakeSetting(DllSetting& setting) const; - - static void AddOnStatusCallback(void *userData, const ADDON_STATUS status, const char* msg); - static bool AddOnGetSetting(void *userData, const char *settingName, void *settingValue); - static void AddOnOpenSettings(const char *url, bool bReload); - static void AddOnOpenOwnSettings(void *userData, bool bReload); - static const char* AddOnGetAddonDirectory(void *userData); - static const char* AddOnGetUserDirectory(void *userData); - }; - -template -CAddonDll::CAddonDll(const cp_extension_t *ext) - : CAddon(ext), - m_bIsChild(false) -{ - // if library attribute isn't present, look for a system-dependent one - if (ext && m_strLibName.empty()) - { -#if defined(TARGET_ANDROID) - m_strLibName = CAddonMgr::Get().GetExtValue(ext->configuration, "@library_android"); -#elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD) - m_strLibName = CAddonMgr::Get().GetExtValue(ext->configuration, "@library_linux"); -#elif defined(TARGET_WINDOWS) && defined(HAS_DX) - m_strLibName = CAddonMgr::Get().GetExtValue(ext->configuration, "@library_windx"); -#elif defined(TARGET_DARWIN) - m_strLibName = CAddonMgr::Get().GetExtValue(ext->configuration, "@library_osx"); -#endif - } - - m_pStruct = NULL; - m_initialized = false; - m_pDll = NULL; - m_pInfo = NULL; - m_pHelpers = NULL; - m_needsavedsettings = false; -} - -template -CAddonDll::CAddonDll(const AddonProps &props) - : CAddon(props), - m_bIsChild(false) -{ - m_pStruct = NULL; - m_initialized = false; - m_pDll = NULL; - m_pInfo = NULL; - m_pHelpers = NULL; - m_needsavedsettings = false; -} - -template -CAddonDll::CAddonDll(const CAddonDll &rhs) - : CAddon(rhs), - m_bIsChild(true) -{ - m_pStruct = rhs.m_pStruct; - m_initialized = rhs.m_initialized; - m_pDll = rhs.m_pDll; - m_pInfo = rhs.m_pInfo; - m_pHelpers = rhs.m_pHelpers; - m_needsavedsettings = rhs.m_needsavedsettings; -} - -template -CAddonDll::~CAddonDll() -{ - if (m_initialized) - Destroy(); -} - -template -AddonPtr CAddonDll::Clone() const -{ - return AddonPtr(new CAddonDll(*this)); -} - -template -bool CAddonDll::LoadDll() -{ - std::string strFileName; - if (!m_bIsChild) - { - strFileName = LibPath(); - } - else - { //FIXME hack to load same Dll twice - std::string extension = URIUtils::GetExtension(m_strLibName); - strFileName = "special://temp/" + m_strLibName; - URIUtils::RemoveExtension(strFileName); - strFileName += "-" + ID() + extension; - - if (!XFILE::CFile::Exists(strFileName)) - XFILE::CFile::Copy(LibPath(), strFileName); - - CLog::Log(LOGNOTICE, "ADDON: Loaded virtual child addon %s", strFileName.c_str()); - } - - /* Check if lib being loaded exists, else check in XBMC binary location */ -#if defined(TARGET_ANDROID) - // Android libs MUST live in this path, else multi-arch will break. - // The usual soname requirements apply. no subdirs, and filename is ^lib.*\.so$ - if (!XFILE::CFile::Exists(strFileName)) - { - std::string tempbin = getenv("XBMC_ANDROID_LIBS"); - strFileName = tempbin + "/" + m_strLibName; - } -#endif - if (!XFILE::CFile::Exists(strFileName)) - { - std::string temp = CSpecialProtocol::TranslatePath("special://xbmc/"); - std::string tempbin = CSpecialProtocol::TranslatePath("special://xbmcbin/"); - strFileName.erase(0, temp.size()); - strFileName = tempbin + strFileName; - if (!XFILE::CFile::Exists(strFileName)) - { - CLog::Log(LOGERROR, "ADDON: Could not locate %s", m_strLibName.c_str()); - return false; - } - } - - /* Load the Dll */ - m_pDll = new TheDll; - m_pDll->SetFile(strFileName); - m_pDll->EnableDelayedUnload(false); - if (!m_pDll->Load()) - { - delete m_pDll; - m_pDll = NULL; - new CAddonStatusHandler(ID(), ADDON_STATUS_UNKNOWN, "Can't load Dll", false); - return false; - } - - m_pStruct = (TheStruct*)malloc(sizeof(TheStruct)); - if (m_pStruct) - { - ZeroMemory(m_pStruct, sizeof(TheStruct)); - m_pDll->GetAddon(m_pStruct); - return true; - } - - return false; -} - -template -ADDON_STATUS CAddonDll::Create() -{ - ADDON_STATUS status(ADDON_STATUS_UNKNOWN); - CLog::Log(LOGDEBUG, "ADDON: Dll Initializing - %s", Name().c_str()); - m_initialized = false; - - if (!LoadDll() || !CheckAPIVersion()) - return ADDON_STATUS_PERMANENT_FAILURE; - - /* Allocate the helper function class to allow crosstalk over - helper libraries */ - m_pHelpers = new CAddonCallbacks(this); - - /* Call Create to make connections, initializing data or whatever is - needed to become the AddOn running */ - try - { - status = m_pDll->Create(m_pHelpers->GetCallbacks(), m_pInfo); - if (status == ADDON_STATUS_OK) - { - m_initialized = true; - ANNOUNCEMENT::CAnnouncementManager::Get().AddAnnouncer(this); - } - else if ((status == ADDON_STATUS_NEED_SETTINGS) || (status == ADDON_STATUS_NEED_SAVEDSETTINGS)) - { - m_needsavedsettings = (status == ADDON_STATUS_NEED_SAVEDSETTINGS); - if ((status = TransferSettings()) == ADDON_STATUS_OK) - m_initialized = true; - else - new CAddonStatusHandler(ID(), status, "", false); - } - else - { // Addon failed initialization - CLog::Log(LOGERROR, "ADDON: Dll %s - Client returned bad status (%i) from Create and is not usable", Name().c_str(), status); - new CAddonStatusHandler(ID(), status, "", false); - } - } - catch (std::exception &e) - { - HandleException(e, "m_pDll->Create"); - } - - if (!m_initialized) - SAFE_DELETE(m_pHelpers); - - return status; -} - -template -void CAddonDll::Stop() -{ - /* Inform dll to stop all activities */ - try - { - if (m_needsavedsettings) // If the addon supports it we save some settings to settings.xml before stop - { - char str_id[64] = ""; - char str_value[1024]; - CAddon::LoadUserSettings(); - for (unsigned int i=0; (strcmp(str_id,"###End") != 0); i++) - { - strcpy(str_id, "###GetSavedSettings"); - sprintf (str_value, "%i", i); - ADDON_STATUS status = m_pDll->SetSetting((const char*)&str_id, (void*)&str_value); - - if (status == ADDON_STATUS_UNKNOWN) - break; - - if (strcmp(str_id,"###End") != 0) UpdateSetting(str_id, str_value); - } - CAddon::SaveSettings(); - } - if (m_pDll) - { - m_pDll->Stop(); - CLog::Log(LOGINFO, "ADDON: Dll Stopped - %s", Name().c_str()); - } - } - catch (std::exception &e) - { - HandleException(e, "m_pDll->Stop"); - } -} - -template -void CAddonDll::Destroy() -{ - ANNOUNCEMENT::CAnnouncementManager::Get().RemoveAnnouncer(this); - - /* Unload library file */ - try - { - if (m_pDll) - { - m_pDll->Destroy(); - m_pDll->Unload(); - } - } - catch (std::exception &e) - { - HandleException(e, "m_pDll->Unload"); - } - delete m_pHelpers; - m_pHelpers = NULL; - free(m_pStruct); - m_pStruct = NULL; - if (m_pDll) - { - delete m_pDll; - m_pDll = NULL; - CLog::Log(LOGINFO, "ADDON: Dll Destroyed - %s", Name().c_str()); - } - m_initialized = false; -} - -template -bool CAddonDll::DllLoaded(void) const -{ - return m_pDll != NULL; -} - -template -ADDON_STATUS CAddonDll::GetStatus() -{ - try - { - return m_pDll->GetStatus(); - } - catch (std::exception &e) - { - HandleException(e, "m_pDll->GetStatus()"); - } - return ADDON_STATUS_UNKNOWN; -} - -template -bool CAddonDll::LoadSettings() -{ - if (m_settingsLoaded) - return true; - - if (!LoadDll()) - return false; - - ADDON_StructSetting** sSet; - std::vector vSet; - unsigned entries = 0; - try - { - entries = m_pDll->GetSettings(&sSet); - DllUtils::StructToVec(entries, &sSet, &vSet); - m_pDll->FreeSettings(); - } - catch (std::exception &e) - { - HandleException(e, "m_pDll->GetSettings()"); - return false; - } - - if (vSet.size()) - { - // regenerate XML doc - m_addonXmlDoc.Clear(); - TiXmlElement node("settings"); - m_addonXmlDoc.InsertEndChild(node); - - for (unsigned i=0; i < entries; i++) - { - DllSetting& setting = vSet[i]; - m_addonXmlDoc.RootElement()->InsertEndChild(MakeSetting(setting)); - } - CAddon::SettingsFromXML(m_addonXmlDoc, true); - } - else - return CAddon::LoadSettings(); - - m_settingsLoaded = true; - CAddon::LoadUserSettings(); - return true; -} - -template -TiXmlElement CAddonDll::MakeSetting(DllSetting& setting) const -{ - TiXmlElement node("setting"); - - switch (setting.type) - { - case DllSetting::CHECK: - { - node.SetAttribute("id", setting.id); - node.SetAttribute("type", "bool"); - node.SetAttribute("label", setting.label); - break; - } - case DllSetting::SPIN: - { - node.SetAttribute("id", setting.id); - node.SetAttribute("type", "enum"); - node.SetAttribute("label", setting.label); - std::string values; - for (unsigned int i = 0; i < setting.entry.size(); i++) - { - values.append(setting.entry[i]); - values.append("|"); - } - node.SetAttribute("values", values.c_str()); - break; - } - default: - break; - } - - return node; -} - -template -void CAddonDll::SaveSettings() -{ - // must save first, as TransferSettings() reloads saved settings! - CAddon::SaveSettings(); - if (m_initialized) - TransferSettings(); -} - -template -std::string CAddonDll::GetSetting(const std::string& key) -{ - return CAddon::GetSetting(key); -} - -template -ADDON_STATUS CAddonDll::TransferSettings() -{ - bool restart = false; - ADDON_STATUS reportStatus = ADDON_STATUS_OK; - - CLog::Log(LOGDEBUG, "Calling TransferSettings for: %s", Name().c_str()); - - LoadSettings(); - - const TiXmlElement *category = m_addonXmlDoc.RootElement() ? m_addonXmlDoc.RootElement()->FirstChildElement("category") : NULL; - if (!category) - category = m_addonXmlDoc.RootElement(); // no categories - - while (category) - { - const TiXmlElement *setting = category->FirstChildElement("setting"); - while (setting) - { - ADDON_STATUS status = ADDON_STATUS_OK; - const char *id = setting->Attribute("id"); - const std::string type = XMLUtils::GetAttribute(setting, "type"); - const char *option = setting->Attribute("option"); - - if (id && !type.empty()) - { - if (type == "sep" || type == "lsep") - { - /* Don't propagate separators */ - } - else if (type == "text" || type == "ipaddress" || - type == "video" || type == "audio" || - type == "image" || type == "folder" || - type == "executable" || type == "file" || - type == "action" || type == "date" || - type == "time" || type == "select" || - type == "addon" || type == "labelenum" || - type == "fileenum" ) - { - status = m_pDll->SetSetting(id, (const char*) GetSetting(id).c_str()); - } - else if (type == "enum" || type =="integer" || - type == "labelenum" || type == "rangeofnum") - { - int tmp = atoi(GetSetting(id).c_str()); - status = m_pDll->SetSetting(id, (int*) &tmp); - } - else if (type == "bool") - { - bool tmp = (GetSetting(id) == "true") ? true : false; - status = m_pDll->SetSetting(id, (bool*) &tmp); - } - else if (type == "rangeofnum" || type == "slider" || - type == "number") - { - float tmpf = (float)atof(GetSetting(id).c_str()); - int tmpi; - - if (option && strcmpi(option,"int") == 0) - { - tmpi = (int)floor(tmpf); - status = m_pDll->SetSetting(id, (int*) &tmpi); - } - else - { - status = m_pDll->SetSetting(id, (float*) &tmpf); - } - } - else - { - /* Log unknowns as an error, but go ahead and transfer the string */ - CLog::Log(LOGERROR, "Unknown setting type '%s' for %s", type.c_str(), Name().c_str()); - status = m_pDll->SetSetting(id, (const char*) GetSetting(id).c_str()); - } - - if (status == ADDON_STATUS_NEED_RESTART) - restart = true; - else if (status != ADDON_STATUS_OK) - reportStatus = status; - } - setting = setting->NextSiblingElement("setting"); - } - category = category->NextSiblingElement("category"); - } - - if (restart || reportStatus != ADDON_STATUS_OK) - { - new CAddonStatusHandler(ID(), restart ? ADDON_STATUS_NEED_RESTART : reportStatus, "", true); - } - - return ADDON_STATUS_OK; -} - -template -void CAddonDll::Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) -{ - try - { - m_pDll->Announce(ANNOUNCEMENT::AnnouncementFlagToString(flag), sender, message, &data); - } - catch (std::exception &e) - { - HandleException(e, "m_pDll->Announce()"); - } -} - -template -void CAddonDll::HandleException(std::exception &e, const char* context) -{ - m_initialized = false; - m_pDll->Unload(); - CLog::Log(LOGERROR, "ADDON: Dll %s, throws an exception '%s' during %s. Contact developer '%s' with bug reports", Name().c_str(), e.what(), context, Author().c_str()); -} - -}; /* namespace ADDON */ - -- cgit v1.2.3