2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "AddonInstanceHandler.h"
11 #include "ServiceBroker.h"
12 #include "addons/AddonVersion.h"
13 #include "addons/binary-addons/AddonDll.h"
14 #include "addons/binary-addons/BinaryAddonManager.h"
15 #include "addons/interfaces/AddonBase.h"
16 #include "addons/kodi-dev-kit/include/kodi/AddonBase.h"
17 #include "addons/settings/AddonSettings.h"
18 #include "filesystem/Directory.h"
19 #include "filesystem/SpecialProtocol.h"
20 #include "settings/lib/Setting.h"
21 #include "utils/StringUtils.h"
22 #include "utils/log.h"
29 CCriticalSection
IAddonInstanceHandler::m_cdSec
;
31 IAddonInstanceHandler::IAddonInstanceHandler(
33 const AddonInfoPtr
& addonInfo
,
34 AddonInstanceId instanceId
/* = ADDON_INSTANCE_ID_UNUSED */,
35 KODI_HANDLE parentInstance
/* = nullptr*/,
36 const std::string
& uniqueWorkID
/* = ""*/)
37 : m_type(type
), m_instanceId(instanceId
), m_parentInstance(parentInstance
), m_addonInfo(addonInfo
)
39 // if no special instance ID is given generate one from class pointer (is
40 // faster as unique id and also safe enough for them).
41 m_uniqueWorkID
= !uniqueWorkID
.empty() ? uniqueWorkID
: StringUtils::Format("{}", fmt::ptr(this));
42 m_addonBase
= CServiceBroker::GetBinaryAddonManager().GetAddonBase(addonInfo
, this, m_addon
);
44 KODI_ADDON_INSTANCE_INFO
* info
= new KODI_ADDON_INSTANCE_INFO();
45 info
->number
= m_instanceId
; // @todo change within next big API change to "instance_id"
46 info
->id
= m_uniqueWorkID
.c_str(); // @todo change within next big API change to "unique_work_id"
47 info
->version
= kodi::addon::GetTypeVersion(m_type
);
50 info
->parent
= m_parentInstance
;
51 info
->first_instance
= m_addon
&& !m_addon
->Initialized();
52 info
->functions
= new KODI_ADDON_INSTANCE_FUNC_CB();
53 info
->functions
->get_instance_user_path
= get_instance_user_path
;
54 info
->functions
->is_instance_setting_using_default
= is_instance_setting_using_default
;
55 info
->functions
->get_instance_setting_bool
= get_instance_setting_bool
;
56 info
->functions
->get_instance_setting_int
= get_instance_setting_int
;
57 info
->functions
->get_instance_setting_float
= get_instance_setting_float
;
58 info
->functions
->get_instance_setting_string
= get_instance_setting_string
;
59 info
->functions
->set_instance_setting_bool
= set_instance_setting_bool
;
60 info
->functions
->set_instance_setting_int
= set_instance_setting_int
;
61 info
->functions
->set_instance_setting_float
= set_instance_setting_float
;
62 info
->functions
->set_instance_setting_string
= set_instance_setting_string
;
64 m_ifc
.functions
= new KODI_ADDON_INSTANCE_FUNC();
67 IAddonInstanceHandler::~IAddonInstanceHandler()
69 CServiceBroker::GetBinaryAddonManager().ReleaseAddonBase(m_addonBase
, this);
71 delete m_ifc
.functions
;
73 delete m_ifc
.info
->functions
;
77 std::string
IAddonInstanceHandler::ID() const
79 return m_addon
? m_addon
->ID() : "";
82 std::string
IAddonInstanceHandler::Name() const
84 return m_addon
? m_addon
->Name() : "";
87 std::string
IAddonInstanceHandler::Author() const
89 return m_addon
? m_addon
->Author() : "";
92 std::string
IAddonInstanceHandler::Icon() const
94 return m_addon
? m_addon
->Icon() : "";
97 std::string
IAddonInstanceHandler::Path() const
99 return m_addon
? m_addon
->Path() : "";
102 std::string
IAddonInstanceHandler::Profile() const
104 return m_addon
? m_addon
->Profile() : "";
107 CAddonVersion
IAddonInstanceHandler::Version() const
109 return m_addon
? m_addon
->Version() : CAddonVersion();
112 ADDON_STATUS
IAddonInstanceHandler::CreateInstance()
115 return ADDON_STATUS_UNKNOWN
;
117 std::unique_lock
<CCriticalSection
> lock(m_cdSec
);
119 ADDON_STATUS status
= m_addon
->CreateInstance(&m_ifc
);
120 if (status
!= ADDON_STATUS_OK
)
123 "IAddonInstanceHandler::{}: {} returned bad status \"{}\" during instance creation",
124 __func__
, m_addon
->ID(), kodi::addon::TranslateAddonStatus(status
));
129 void IAddonInstanceHandler::DestroyInstance()
131 std::unique_lock
<CCriticalSection
> lock(m_cdSec
);
133 m_addon
->DestroyInstance(&m_ifc
);
136 std::shared_ptr
<CSetting
> IAddonInstanceHandler::GetSetting(const std::string
& setting
)
138 if (!m_addon
->HasSettings(m_instanceId
))
140 CLog::Log(LOGERROR
, "IAddonInstanceHandler::{} - couldn't get settings for add-on '{}'",
145 auto value
= m_addon
->GetSettings(m_instanceId
)->GetSetting(setting
);
146 if (value
== nullptr)
148 CLog::Log(LOGERROR
, "IAddonInstanceHandler::{} - can't find setting '{}' in '{}'", __func__
,
156 char* IAddonInstanceHandler::get_instance_user_path(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl
)
158 IAddonInstanceHandler
* instance
= static_cast<IAddonInstanceHandler
*>(hdl
);
162 const std::string path
= CSpecialProtocol::TranslatePath(instance
->m_addon
->Profile());
164 XFILE::CDirectory::Create(path
);
165 return strdup(path
.c_str());
168 bool IAddonInstanceHandler::is_instance_setting_using_default(
169 const KODI_ADDON_INSTANCE_BACKEND_HDL hdl
, const char* id
)
171 IAddonInstanceHandler
* instance
= static_cast<IAddonInstanceHandler
*>(hdl
);
172 if (!instance
|| !id
)
175 auto setting
= instance
->GetSetting(id
);
176 if (setting
== nullptr)
179 return setting
->IsDefault();
182 bool IAddonInstanceHandler::get_instance_setting_bool(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl
,
186 IAddonInstanceHandler
* instance
= static_cast<IAddonInstanceHandler
*>(hdl
);
187 if (!instance
|| !id
|| !value
)
190 auto setting
= instance
->GetSetting(id
);
191 if (setting
== nullptr)
194 if (setting
->GetType() != SettingType::Boolean
)
196 CLog::Log(LOGERROR
, "IAddonInstanceHandler::{} - setting '{}' is not a boolean in '{}'",
197 __func__
, id
, instance
->Name());
201 *value
= std::static_pointer_cast
<CSettingBool
>(setting
)->GetValue();
205 bool IAddonInstanceHandler::get_instance_setting_int(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl
,
209 IAddonInstanceHandler
* instance
= static_cast<IAddonInstanceHandler
*>(hdl
);
210 if (!instance
|| !id
|| !value
)
213 auto setting
= instance
->GetSetting(id
);
214 if (setting
== nullptr)
217 if (setting
->GetType() != SettingType::Integer
&& setting
->GetType() != SettingType::Number
)
219 CLog::Log(LOGERROR
, "IAddonInstanceHandler::{} - setting '{}' is not a integer in '{}'",
220 __func__
, id
, instance
->Name());
224 if (setting
->GetType() == SettingType::Integer
)
225 *value
= std::static_pointer_cast
<CSettingInt
>(setting
)->GetValue();
227 *value
= static_cast<int>(std::static_pointer_cast
<CSettingNumber
>(setting
)->GetValue());
231 bool IAddonInstanceHandler::get_instance_setting_float(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl
,
235 IAddonInstanceHandler
* instance
= static_cast<IAddonInstanceHandler
*>(hdl
);
236 if (!instance
|| !id
|| !value
)
239 auto setting
= instance
->GetSetting(id
);
240 if (setting
== nullptr)
243 if (setting
->GetType() != SettingType::Number
)
245 CLog::Log(LOGERROR
, "IAddonInstanceHandler::{} - setting '{}' is not a number in '{}'",
246 __func__
, id
, instance
->Name());
250 *value
= static_cast<float>(std::static_pointer_cast
<CSettingNumber
>(setting
)->GetValue());
254 bool IAddonInstanceHandler::get_instance_setting_string(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl
,
258 IAddonInstanceHandler
* instance
= static_cast<IAddonInstanceHandler
*>(hdl
);
259 if (!instance
|| !id
|| !value
)
262 auto setting
= instance
->GetSetting(id
);
263 if (setting
== nullptr)
266 if (setting
->GetType() != SettingType::String
)
268 CLog::Log(LOGERROR
, "IAddonInstanceHandler::{} - setting '{}' is not a string in '{}'",
269 __func__
, id
, instance
->Name());
273 *value
= strdup(std::static_pointer_cast
<CSettingString
>(setting
)->GetValue().c_str());
277 bool IAddonInstanceHandler::set_instance_setting_bool(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl
,
281 IAddonInstanceHandler
* instance
= static_cast<IAddonInstanceHandler
*>(hdl
);
282 if (!instance
|| !id
)
285 if (Interface_Base::UpdateSettingInActiveDialog(instance
->m_addon
.get(), instance
->m_instanceId
,
286 id
, value
? "true" : "false"))
289 if (!instance
->m_addon
->UpdateSettingBool(id
, value
, instance
->m_instanceId
))
291 CLog::Log(LOGERROR
, "IAddonInstanceHandler::{} - invalid setting type", __func__
);
295 instance
->m_addon
->SaveSettings(instance
->m_instanceId
);
300 bool IAddonInstanceHandler::set_instance_setting_int(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl
,
304 IAddonInstanceHandler
* instance
= static_cast<IAddonInstanceHandler
*>(hdl
);
305 if (!instance
|| !id
)
307 CLog::Log(LOGERROR
, "IAddonInstanceHandler::{} - invalid data (instance='{}', id='{}')",
308 __func__
, hdl
, static_cast<const void*>(id
));
313 if (Interface_Base::UpdateSettingInActiveDialog(instance
->m_addon
.get(), instance
->m_instanceId
,
314 id
, std::to_string(value
)))
317 if (!instance
->m_addon
->UpdateSettingInt(id
, value
, instance
->m_instanceId
))
319 CLog::Log(LOGERROR
, "IAddonInstanceHandler::{} - invalid setting type", __func__
);
323 instance
->m_addon
->SaveSettings(instance
->m_instanceId
);
328 bool IAddonInstanceHandler::set_instance_setting_float(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl
,
332 IAddonInstanceHandler
* instance
= static_cast<IAddonInstanceHandler
*>(hdl
);
333 if (!instance
|| !id
)
335 CLog::Log(LOGERROR
, "IAddonInstanceHandler::{} - invalid data (instance='{}', id='{}')",
336 __func__
, hdl
, static_cast<const void*>(id
));
341 if (Interface_Base::UpdateSettingInActiveDialog(instance
->m_addon
.get(), instance
->m_instanceId
,
342 id
, StringUtils::Format("{:f}", value
)))
345 if (!instance
->m_addon
->UpdateSettingNumber(id
, static_cast<double>(value
),
346 instance
->m_instanceId
))
348 CLog::Log(LOGERROR
, "IAddonInstanceHandler::{} - invalid setting type", __func__
);
352 instance
->m_addon
->SaveSettings(instance
->m_instanceId
);
357 bool IAddonInstanceHandler::set_instance_setting_string(const KODI_ADDON_INSTANCE_BACKEND_HDL hdl
,
361 IAddonInstanceHandler
* instance
= static_cast<IAddonInstanceHandler
*>(hdl
);
362 if (!instance
|| !id
|| !value
)
365 "IAddonInstanceHandler::{} - invalid data (instance='{}', id='{}', value='{}')",
366 __func__
, hdl
, static_cast<const void*>(id
), static_cast<const void*>(value
));
371 if (Interface_Base::UpdateSettingInActiveDialog(instance
->m_addon
.get(), instance
->m_instanceId
,
375 if (!instance
->m_addon
->UpdateSettingString(id
, value
, instance
->m_instanceId
))
377 CLog::Log(LOGERROR
, "IAddonInstanceHandler::{} - invalid setting type", __func__
);
381 instance
->m_addon
->SaveSettings(instance
->m_instanceId
);
386 } /* namespace ADDON */