PageRenderTime 65ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/xbmc/addons/binary-addons/AddonInstanceHandler.cpp

https://gitlab.com/h.udo/xbmc
C++ | 374 lines | 297 code | 68 blank | 9 comment | 63 complexity | 20dfdb55415ee513379505b129e77a0a MD5 | raw file
  1. /*
  2. * Copyright (C) 2005-2018 Team Kodi
  3. * This file is part of Kodi - https://kodi.tv
  4. *
  5. * SPDX-License-Identifier: GPL-2.0-or-later
  6. * See LICENSES/README.md for more information.
  7. */
  8. #include "AddonInstanceHandler.h"
  9. #include "ServiceBroker.h"
  10. #include "addons/settings/AddonSettings.h"
  11. #include "filesystem/Directory.h"
  12. #include "filesystem/SpecialProtocol.h"
  13. #include "utils/StringUtils.h"
  14. #include "utils/log.h"
  15. namespace ADDON
  16. {
  17. CCriticalSection IAddonInstanceHandler::m_cdSec;
  18. IAddonInstanceHandler::IAddonInstanceHandler(ADDON_TYPE type,
  19. const AddonInfoPtr& addonInfo,
  20. KODI_HANDLE parentInstance /* = nullptr*/,
  21. const std::string& instanceID /* = ""*/)
  22. : m_type(type), m_parentInstance(parentInstance), m_addonInfo(addonInfo)
  23. {
  24. // if no special instance ID is given generate one from class pointer (is
  25. // faster as unique id and also safe enough for them).
  26. m_instanceId = !instanceID.empty() ? instanceID : StringUtils::Format("{}", fmt::ptr(this));
  27. m_addonBase = CServiceBroker::GetBinaryAddonManager().GetAddonBase(addonInfo, this, m_addon);
  28. KODI_ADDON_INSTANCE_INFO* info = new KODI_ADDON_INSTANCE_INFO();
  29. info->number = 0;
  30. info->id = m_instanceId.c_str();
  31. info->version = kodi::addon::GetTypeVersion(m_type);
  32. info->type = m_type;
  33. info->kodi = this;
  34. info->parent = m_parentInstance;
  35. info->first_instance = m_addon && !m_addon->Initialized();
  36. info->functions = new KODI_ADDON_INSTANCE_FUNC_CB();
  37. info->functions->get_instance_user_path = get_instance_user_path;
  38. info->functions->is_instance_setting_using_default = is_instance_setting_using_default;
  39. info->functions->get_instance_setting_bool = get_instance_setting_bool;
  40. info->functions->get_instance_setting_int = get_instance_setting_int;
  41. info->functions->get_instance_setting_float = get_instance_setting_float;
  42. info->functions->get_instance_setting_string = get_instance_setting_string;
  43. info->functions->set_instance_setting_bool = set_instance_setting_bool;
  44. info->functions->set_instance_setting_int = set_instance_setting_int;
  45. info->functions->set_instance_setting_float = set_instance_setting_float;
  46. info->functions->set_instance_setting_string = set_instance_setting_string;
  47. m_ifc.info = info;
  48. m_ifc.functions = new KODI_ADDON_INSTANCE_FUNC();
  49. }
  50. IAddonInstanceHandler::~IAddonInstanceHandler()
  51. {
  52. CServiceBroker::GetBinaryAddonManager().ReleaseAddonBase(m_addonBase, this);
  53. delete m_ifc.functions;
  54. if (m_ifc.info)
  55. delete m_ifc.info->functions;
  56. delete m_ifc.info;
  57. }
  58. std::string IAddonInstanceHandler::ID() const
  59. {
  60. return m_addon ? m_addon->ID() : "";
  61. }
  62. std::string IAddonInstanceHandler::Name() const
  63. {
  64. return m_addon ? m_addon->Name() : "";
  65. }
  66. std::string IAddonInstanceHandler::Author() const
  67. {
  68. return m_addon ? m_addon->Author() : "";
  69. }
  70. std::string IAddonInstanceHandler::Icon() const
  71. {
  72. return m_addon ? m_addon->Icon() : "";
  73. }
  74. std::string IAddonInstanceHandler::Path() const
  75. {
  76. return m_addon ? m_addon->Path() : "";
  77. }
  78. std::string IAddonInstanceHandler::Profile() const
  79. {
  80. return m_addon ? m_addon->Profile() : "";
  81. }
  82. AddonVersion IAddonInstanceHandler::Version() const
  83. {
  84. return m_addon ? m_addon->Version() : AddonVersion();
  85. }
  86. ADDON_STATUS IAddonInstanceHandler::CreateInstance()
  87. {
  88. if (!m_addon)
  89. return ADDON_STATUS_UNKNOWN;
  90. CSingleLock lock(m_cdSec);
  91. ADDON_STATUS status = m_addon->CreateInstance(&m_ifc);
  92. if (status != ADDON_STATUS_OK)
  93. {
  94. CLog::Log(LOGERROR,
  95. "IAddonInstanceHandler::{}: {} returned bad status \"{}\" during instance creation",
  96. __func__, m_addon->ID(), kodi::addon::TranslateAddonStatus(status));
  97. }
  98. return status;
  99. }
  100. void IAddonInstanceHandler::DestroyInstance()
  101. {
  102. CSingleLock lock(m_cdSec);
  103. if (m_addon)
  104. m_addon->DestroyInstance(&m_ifc);
  105. }
  106. std::shared_ptr<CSetting> IAddonInstanceHandler::GetSetting(const std::string& setting)
  107. {
  108. if (!m_addon->HasSettings())
  109. {
  110. CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - couldn't get settings for add-on '{}'",
  111. __func__, Name());
  112. return nullptr;
  113. }
  114. auto value = m_addon->GetSettings()->GetSetting(setting);
  115. if (value == nullptr)
  116. {
  117. CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - can't find setting '{}' in '{}'", __func__,
  118. setting, Name());
  119. return nullptr;
  120. }
  121. return value;
  122. }
  123. char* IAddonInstanceHandler::get_instance_user_path(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl)
  124. {
  125. IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
  126. if (!instance)
  127. return nullptr;
  128. const std::string path = CSpecialProtocol::TranslatePath(instance->m_addon->Profile());
  129. XFILE::CDirectory::Create(path);
  130. return strdup(path.c_str());
  131. }
  132. bool IAddonInstanceHandler::is_instance_setting_using_default(
  133. const KODI_ADDON_INSTANCE_BACKEND_HDL hdl, const char* id)
  134. {
  135. IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
  136. if (!instance || !id)
  137. return false;
  138. auto setting = instance->GetSetting(id);
  139. if (setting == nullptr)
  140. return false;
  141. return setting->IsDefault();
  142. }
  143. bool IAddonInstanceHandler::get_instance_setting_bool(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
  144. const char* id,
  145. bool* value)
  146. {
  147. IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
  148. if (!instance || !id || !value)
  149. return false;
  150. auto setting = instance->GetSetting(id);
  151. if (setting == nullptr)
  152. return false;
  153. if (setting->GetType() != SettingType::Boolean)
  154. {
  155. CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - setting '{}' is not a boolean in '{}'",
  156. __func__, id, instance->Name());
  157. return false;
  158. }
  159. *value = std::static_pointer_cast<CSettingBool>(setting)->GetValue();
  160. return true;
  161. }
  162. bool IAddonInstanceHandler::get_instance_setting_int(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
  163. const char* id,
  164. int* value)
  165. {
  166. IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
  167. if (!instance || !id || !value)
  168. return false;
  169. auto setting = instance->GetSetting(id);
  170. if (setting == nullptr)
  171. return false;
  172. if (setting->GetType() != SettingType::Integer && setting->GetType() != SettingType::Number)
  173. {
  174. CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - setting '{}' is not a integer in '{}'",
  175. __func__, id, instance->Name());
  176. return false;
  177. }
  178. if (setting->GetType() == SettingType::Integer)
  179. *value = std::static_pointer_cast<CSettingInt>(setting)->GetValue();
  180. else
  181. *value = static_cast<int>(std::static_pointer_cast<CSettingNumber>(setting)->GetValue());
  182. return true;
  183. }
  184. bool IAddonInstanceHandler::get_instance_setting_float(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
  185. const char* id,
  186. float* value)
  187. {
  188. IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
  189. if (!instance || !id || !value)
  190. return false;
  191. auto setting = instance->GetSetting(id);
  192. if (setting == nullptr)
  193. return false;
  194. if (setting->GetType() != SettingType::Number)
  195. {
  196. CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - setting '{}' is not a number in '{}'",
  197. __func__, id, instance->Name());
  198. return false;
  199. }
  200. *value = static_cast<float>(std::static_pointer_cast<CSettingNumber>(setting)->GetValue());
  201. return true;
  202. }
  203. bool IAddonInstanceHandler::get_instance_setting_string(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
  204. const char* id,
  205. char** value)
  206. {
  207. IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
  208. if (!instance || !id || !value)
  209. return false;
  210. auto setting = instance->GetSetting(id);
  211. if (setting == nullptr)
  212. return false;
  213. if (setting->GetType() != SettingType::String)
  214. {
  215. CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - setting '{}' is not a string in '{}'",
  216. __func__, id, instance->Name());
  217. return false;
  218. }
  219. *value = strdup(std::static_pointer_cast<CSettingString>(setting)->GetValue().c_str());
  220. return true;
  221. }
  222. bool IAddonInstanceHandler::set_instance_setting_bool(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
  223. const char* id,
  224. bool value)
  225. {
  226. IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
  227. if (!instance || !id)
  228. return false;
  229. if (Interface_Base::UpdateSettingInActiveDialog(instance->m_addon.get(), id,
  230. value ? "true" : "false"))
  231. return true;
  232. if (!instance->m_addon->UpdateSettingBool(id, value))
  233. {
  234. CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - invalid setting type", __func__);
  235. return false;
  236. }
  237. instance->m_addon->SaveSettings();
  238. return true;
  239. }
  240. bool IAddonInstanceHandler::set_instance_setting_int(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
  241. const char* id,
  242. int value)
  243. {
  244. IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
  245. if (!instance || !id)
  246. {
  247. CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - invalid data (instance='{}', id='{}')",
  248. __func__, hdl, static_cast<const void*>(id));
  249. return false;
  250. }
  251. if (Interface_Base::UpdateSettingInActiveDialog(instance->m_addon.get(), id,
  252. std::to_string(value)))
  253. return true;
  254. if (!instance->m_addon->UpdateSettingInt(id, value))
  255. {
  256. CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - invalid setting type", __func__);
  257. return false;
  258. }
  259. instance->m_addon->SaveSettings();
  260. return true;
  261. }
  262. bool IAddonInstanceHandler::set_instance_setting_float(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
  263. const char* id,
  264. float value)
  265. {
  266. IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
  267. if (!instance || !id)
  268. {
  269. CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - invalid data (instance='{}', id='{}')",
  270. __func__, hdl, static_cast<const void*>(id));
  271. return false;
  272. }
  273. if (Interface_Base::UpdateSettingInActiveDialog(instance->m_addon.get(), id,
  274. StringUtils::Format("{:f}", value)))
  275. return true;
  276. if (!instance->m_addon->UpdateSettingNumber(id, static_cast<double>(value)))
  277. {
  278. CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - invalid setting type", __func__);
  279. return false;
  280. }
  281. instance->m_addon->SaveSettings();
  282. return true;
  283. }
  284. bool IAddonInstanceHandler::set_instance_setting_string(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl,
  285. const char* id,
  286. const char* value)
  287. {
  288. IAddonInstanceHandler* instance = static_cast<IAddonInstanceHandler*>(hdl);
  289. if (!instance || !id || !value)
  290. {
  291. CLog::Log(LOGERROR,
  292. "IAddonInstanceHandler::{} - invalid data (instance='{}', id='{}', value='{}')",
  293. __func__, hdl, static_cast<const void*>(id), static_cast<const void*>(value));
  294. return false;
  295. }
  296. if (Interface_Base::UpdateSettingInActiveDialog(instance->m_addon.get(), id, value))
  297. return true;
  298. if (!instance->m_addon->UpdateSettingString(id, value))
  299. {
  300. CLog::Log(LOGERROR, "IAddonInstanceHandler::{} - invalid setting type", __func__);
  301. return false;
  302. }
  303. instance->m_addon->SaveSettings();
  304. return true;
  305. }
  306. } /* namespace ADDON */