1 /*
2 * Copyright (C) 2013-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
9 #include "SettingConditions.h"
10 #include "Application.h"
11 #include "LockType.h"
12 #include "Util.h"
13 #include "addons/AddonManager.h"
14 #include "addons/Skin.h"
15 #if defined(TARGET_ANDROID)
16 #include "platform/android/activity/AndroidFeatures.h"
17 #endif // defined(TARGET_ANDROID)
18 #include "cores/AudioEngine/Engines/ActiveAE/ActiveAESettings.h"
19 #include "ServiceBroker.h"
20 #include "GUIPassword.h"
21 #if defined(HAS_WEB_SERVER)
22 #include "network/WebServer.h"
23 #endif
24 #include "peripherals/Peripherals.h"
25 #include "profiles/ProfileManager.h"
26 #include "settings/SettingAddon.h"
27 #include "settings/SettingsComponent.h"
28 #include "utils/StringUtils.h"
29 #include "windowing/WinSystem.h"
30
AddonHasSettings(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)31 bool AddonHasSettings(const std::string& condition,
32 const std::string& value,
33 const SettingConstPtr& setting,
34 void* data)
35 {
36 if (setting == NULL)
37 return false;
38
39 std::shared_ptr<const CSettingAddon> settingAddon = std::dynamic_pointer_cast<const CSettingAddon>(setting);
40 if (settingAddon == NULL)
41 return false;
42
43 ADDON::AddonPtr addon;
44 if (!CServiceBroker::GetAddonMgr().GetAddon(
45 settingAddon->GetValue(), addon, settingAddon->GetAddonType(), ADDON::OnlyEnabled::YES) ||
46 addon == NULL)
47 return false;
48
49 if (addon->Type() == ADDON::ADDON_SKIN)
50 return ((ADDON::CSkinInfo*)addon.get())->HasSkinFile("SkinSettings.xml");
51
52 return addon->HasSettings();
53 }
54
CheckMasterLock(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)55 bool CheckMasterLock(const std::string& condition,
56 const std::string& value,
57 const SettingConstPtr& setting,
58 void* data)
59 {
60 return g_passwordManager.IsMasterLockUnlocked(StringUtils::EqualsNoCase(value, "true"));
61 }
62
HasPeripherals(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)63 bool HasPeripherals(const std::string& condition,
64 const std::string& value,
65 const SettingConstPtr& setting,
66 void* data)
67 {
68 return CServiceBroker::GetPeripherals().GetNumberOfPeripherals() > 0;
69 }
70
HasPeripheralLibraries(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)71 bool HasPeripheralLibraries(const std::string& condition,
72 const std::string& value,
73 const SettingConstPtr& setting,
74 void* data)
75 {
76 return CServiceBroker::GetAddonMgr().HasInstalledAddons(ADDON::ADDON_PERIPHERALDLL);
77 }
78
HasRumbleFeature(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)79 bool HasRumbleFeature(const std::string& condition,
80 const std::string& value,
81 const SettingConstPtr& setting,
82 void* data)
83 {
84 return CServiceBroker::GetPeripherals().SupportsFeature(PERIPHERALS::FEATURE_RUMBLE);
85 }
86
HasRumbleController(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)87 bool HasRumbleController(const std::string& condition,
88 const std::string& value,
89 const SettingConstPtr& setting,
90 void* data)
91 {
92 return CServiceBroker::GetPeripherals().HasPeripheralWithFeature(PERIPHERALS::FEATURE_RUMBLE);
93 }
94
HasPowerOffFeature(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)95 bool HasPowerOffFeature(const std::string& condition,
96 const std::string& value,
97 const SettingConstPtr& setting,
98 void* data)
99 {
100 return CServiceBroker::GetPeripherals().SupportsFeature(PERIPHERALS::FEATURE_POWER_OFF);
101 }
102
IsFullscreen(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)103 bool IsFullscreen(const std::string& condition,
104 const std::string& value,
105 const SettingConstPtr& setting,
106 void* data)
107 {
108 return CServiceBroker::GetWinSystem()->IsFullScreen();
109 }
110
IsHDRDisplay(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)111 bool IsHDRDisplay(const std::string& condition,
112 const std::string& value,
113 const SettingConstPtr& setting,
114 void* data)
115 {
116 return CServiceBroker::GetWinSystem()->IsHDRDisplay();
117 }
118
IsMasterUser(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)119 bool IsMasterUser(const std::string& condition,
120 const std::string& value,
121 const SettingConstPtr& setting,
122 void* data)
123 {
124 return g_passwordManager.bMasterUser;
125 }
126
IsUsingTTFSubtitles(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)127 bool IsUsingTTFSubtitles(const std::string& condition,
128 const std::string& value,
129 const SettingConstPtr& setting,
130 void* data)
131 {
132 return CUtil::IsUsingTTFSubtitles();
133 }
134
ProfileCanWriteDatabase(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)135 bool ProfileCanWriteDatabase(const std::string& condition,
136 const std::string& value,
137 const SettingConstPtr& setting,
138 void* data)
139 {
140 return CSettingConditions::GetCurrentProfile().canWriteDatabases();
141 }
142
ProfileCanWriteSources(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)143 bool ProfileCanWriteSources(const std::string& condition,
144 const std::string& value,
145 const SettingConstPtr& setting,
146 void* data)
147 {
148 return CSettingConditions::GetCurrentProfile().canWriteSources();
149 }
150
ProfileHasAddons(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)151 bool ProfileHasAddons(const std::string& condition,
152 const std::string& value,
153 const SettingConstPtr& setting,
154 void* data)
155 {
156 return CSettingConditions::GetCurrentProfile().hasAddons();
157 }
158
ProfileHasDatabase(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)159 bool ProfileHasDatabase(const std::string& condition,
160 const std::string& value,
161 const SettingConstPtr& setting,
162 void* data)
163 {
164 return CSettingConditions::GetCurrentProfile().hasDatabases();
165 }
166
ProfileHasSources(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)167 bool ProfileHasSources(const std::string& condition,
168 const std::string& value,
169 const SettingConstPtr& setting,
170 void* data)
171 {
172 return CSettingConditions::GetCurrentProfile().hasSources();
173 }
174
ProfileHasAddonManagerLocked(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)175 bool ProfileHasAddonManagerLocked(const std::string& condition,
176 const std::string& value,
177 const SettingConstPtr& setting,
178 void* data)
179 {
180 return CSettingConditions::GetCurrentProfile().addonmanagerLocked();
181 }
182
ProfileHasFilesLocked(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)183 bool ProfileHasFilesLocked(const std::string& condition,
184 const std::string& value,
185 const SettingConstPtr& setting,
186 void* data)
187 {
188 return CSettingConditions::GetCurrentProfile().filesLocked();
189 }
190
ProfileHasMusicLocked(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)191 bool ProfileHasMusicLocked(const std::string& condition,
192 const std::string& value,
193 const SettingConstPtr& setting,
194 void* data)
195 {
196 return CSettingConditions::GetCurrentProfile().musicLocked();
197 }
198
ProfileHasPicturesLocked(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)199 bool ProfileHasPicturesLocked(const std::string& condition,
200 const std::string& value,
201 const SettingConstPtr& setting,
202 void* data)
203 {
204 return CSettingConditions::GetCurrentProfile().picturesLocked();
205 }
206
ProfileHasProgramsLocked(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)207 bool ProfileHasProgramsLocked(const std::string& condition,
208 const std::string& value,
209 const SettingConstPtr& setting,
210 void* data)
211 {
212 return CSettingConditions::GetCurrentProfile().programsLocked();
213 }
214
ProfileHasSettingsLocked(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)215 bool ProfileHasSettingsLocked(const std::string& condition,
216 const std::string& value,
217 const SettingConstPtr& setting,
218 void* data)
219 {
220 LOCK_LEVEL::SETTINGS_LOCK slValue=LOCK_LEVEL::ALL;
221 if (StringUtils::EqualsNoCase(value, "none"))
222 slValue = LOCK_LEVEL::NONE;
223 else if (StringUtils::EqualsNoCase(value, "standard"))
224 slValue = LOCK_LEVEL::STANDARD;
225 else if (StringUtils::EqualsNoCase(value, "advanced"))
226 slValue = LOCK_LEVEL::ADVANCED;
227 else if (StringUtils::EqualsNoCase(value, "expert"))
228 slValue = LOCK_LEVEL::EXPERT;
229 return slValue <= CSettingConditions::GetCurrentProfile().settingsLockLevel();
230 }
231
ProfileHasVideosLocked(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)232 bool ProfileHasVideosLocked(const std::string& condition,
233 const std::string& value,
234 const SettingConstPtr& setting,
235 void* data)
236 {
237 return CSettingConditions::GetCurrentProfile().videoLocked();
238 }
239
ProfileLockMode(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)240 bool ProfileLockMode(const std::string& condition,
241 const std::string& value,
242 const SettingConstPtr& setting,
243 void* data)
244 {
245 char *tmp = NULL;
246 LockType lock = (LockType)strtol(value.c_str(), &tmp, 0);
247 if (tmp != NULL && *tmp != '\0')
248 return false;
249
250 return CSettingConditions::GetCurrentProfile().getLockMode() == lock;
251 }
252
GreaterThan(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)253 bool GreaterThan(const std::string& condition,
254 const std::string& value,
255 const SettingConstPtr& setting,
256 void* data)
257 {
258 if (setting == NULL)
259 return false;
260
261 std::shared_ptr<const CSettingInt> settingInt = std::dynamic_pointer_cast<const CSettingInt>(setting);
262 if (settingInt == NULL)
263 return false;
264
265 char *tmp = NULL;
266
267 int lhs = settingInt->GetValue();
268 int rhs = StringUtils::IsInteger(value) ? (int)strtol(value.c_str(), &tmp, 0) : 0;
269
270 return lhs > rhs;
271 }
272
GreaterThanOrEqual(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)273 bool GreaterThanOrEqual(const std::string& condition,
274 const std::string& value,
275 const SettingConstPtr& setting,
276 void* data)
277 {
278 if (setting == NULL)
279 return false;
280
281 std::shared_ptr<const CSettingInt> settingInt = std::dynamic_pointer_cast<const CSettingInt>(setting);
282 if (settingInt == NULL)
283 return false;
284
285 char *tmp = NULL;
286
287 int lhs = settingInt->GetValue();
288 int rhs = StringUtils::IsInteger(value) ? (int)strtol(value.c_str(), &tmp, 0) : 0;
289
290 return lhs >= rhs;
291 }
292
LessThan(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)293 bool LessThan(const std::string& condition,
294 const std::string& value,
295 const SettingConstPtr& setting,
296 void* data)
297 {
298 if (setting == NULL)
299 return false;
300
301 std::shared_ptr<const CSettingInt> settingInt = std::dynamic_pointer_cast<const CSettingInt>(setting);
302 if (settingInt == NULL)
303 return false;
304
305 char *tmp = NULL;
306
307 int lhs = settingInt->GetValue();
308 int rhs = StringUtils::IsInteger(value) ? (int)strtol(value.c_str(), &tmp, 0) : 0;
309
310 return lhs < rhs;
311 }
312
LessThanOrEqual(const std::string & condition,const std::string & value,const SettingConstPtr & setting,void * data)313 bool LessThanOrEqual(const std::string& condition,
314 const std::string& value,
315 const SettingConstPtr& setting,
316 void* data)
317 {
318 if (setting == NULL)
319 return false;
320
321 std::shared_ptr<const CSettingInt> settingInt = std::dynamic_pointer_cast<const CSettingInt>(setting);
322 if (settingInt == NULL)
323 return false;
324
325 char *tmp = NULL;
326
327 int lhs = settingInt->GetValue();
328 int rhs = StringUtils::IsInteger(value) ? (int)strtol(value.c_str(), &tmp, 0) : 0;
329
330 return lhs <= rhs;
331 }
332
333 const CProfileManager *CSettingConditions::m_profileManager = nullptr;
334 std::set<std::string> CSettingConditions::m_simpleConditions;
335 std::map<std::string, SettingConditionCheck> CSettingConditions::m_complexConditions;
336
Initialize()337 void CSettingConditions::Initialize()
338 {
339 if (!m_simpleConditions.empty())
340 return;
341
342 // add simple conditions
343 m_simpleConditions.insert("true");
344 #ifdef HAS_UPNP
345 m_simpleConditions.insert("has_upnp");
346 #endif
347 #ifdef HAS_AIRPLAY
348 m_simpleConditions.insert("has_airplay");
349 #endif
350 #ifdef HAVE_X11
351 m_simpleConditions.insert("have_x11");
352 #endif
353 #ifdef HAVE_WAYLAND
354 m_simpleConditions.insert("have_wayland");
355 #endif
356 #ifdef HAS_GL
357 m_simpleConditions.insert("has_gl");
358 #endif
359 #ifdef HAS_GLES
360 m_simpleConditions.insert("has_gles");
361 #endif
362 #if HAS_GLES >= 2
363 m_simpleConditions.insert("has_glesv2");
364 #endif
365 #ifdef HAS_TIME_SERVER
366 m_simpleConditions.insert("has_time_server");
367 #endif
368 #ifdef HAS_WEB_SERVER
369 m_simpleConditions.insert("has_web_server");
370 #endif
371 #ifdef HAS_FILESYSTEM_SMB
372 m_simpleConditions.insert("has_filesystem_smb");
373 #endif
374 #ifdef HAS_ZEROCONF
375 m_simpleConditions.insert("has_zeroconf");
376 #endif
377 #ifdef HAVE_LIBVA
378 m_simpleConditions.insert("have_libva");
379 #endif
380 #ifdef HAVE_LIBVDPAU
381 m_simpleConditions.insert("have_libvdpau");
382 #endif
383 #ifdef TARGET_ANDROID
384 m_simpleConditions.insert("has_mediacodec");
385 #endif
386 #ifdef TARGET_DARWIN
387 m_simpleConditions.insert("HasVTB");
388 #endif
389 #ifdef TARGET_DARWIN_OSX
390 m_simpleConditions.insert("have_osx");
391 #endif
392 #ifdef TARGET_DARWIN_IOS
393 m_simpleConditions.insert("have_ios");
394 #endif
395 #ifdef TARGET_DARWIN_TVOS
396 m_simpleConditions.insert("have_tvos");
397 #endif
398 #if defined(TARGET_WINDOWS)
399 m_simpleConditions.insert("has_dx");
400 m_simpleConditions.insert("hasdxva2");
401 #endif
402 #ifdef HAVE_LCMS2
403 m_simpleConditions.insert("have_lcms2");
404 #endif
405
406 #ifdef TARGET_ANDROID
407 m_simpleConditions.insert("isstandalone");
408 #else
409 if (g_application.IsStandAlone())
410 m_simpleConditions.insert("isstandalone");
411 #endif
412
413 m_simpleConditions.insert("has_ae_quality_levels");
414
415 #ifdef HAS_WEB_SERVER
416 if(CWebServer::WebServerSupportsSSL())
417 m_simpleConditions.insert("webserver_has_ssl");
418 #endif
419
420 // add complex conditions
421 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("addonhassettings", AddonHasSettings));
422 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("checkmasterlock", CheckMasterLock));
423 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("hasperipherals", HasPeripherals));
424 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("hasperipherallibraries", HasPeripheralLibraries));
425 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("hasrumblefeature", HasRumbleFeature));
426 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("hasrumblecontroller", HasRumbleController));
427 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("haspowerofffeature", HasPowerOffFeature));
428 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("isfullscreen", IsFullscreen));
429 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("ishdrdisplay", IsHDRDisplay));
430 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("ismasteruser", IsMasterUser));
431 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("isusingttfsubtitles", IsUsingTTFSubtitles));
432 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("profilecanwritedatabase", ProfileCanWriteDatabase));
433 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("profilecanwritesources", ProfileCanWriteSources));
434 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("profilehasaddons", ProfileHasAddons));
435 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("profilehasdatabase", ProfileHasDatabase));
436 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("profilehassources", ProfileHasSources));
437 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("profilehasaddonmanagerlocked", ProfileHasAddonManagerLocked));
438 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("profilehasfileslocked", ProfileHasFilesLocked));
439 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("profilehasmusiclocked", ProfileHasMusicLocked));
440 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("profilehaspictureslocked", ProfileHasPicturesLocked));
441 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("profilehasprogramslocked", ProfileHasProgramsLocked));
442 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("profilehassettingslocked", ProfileHasSettingsLocked));
443 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("profilehasvideoslocked", ProfileHasVideosLocked));
444 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("profilelockmode", ProfileLockMode));
445 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("aesettingvisible", ActiveAE::CActiveAESettings::IsSettingVisible));
446 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("gt", GreaterThan));
447 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("gte", GreaterThanOrEqual));
448 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("lt", LessThan));
449 m_complexConditions.insert(std::pair<std::string, SettingConditionCheck>("lte", LessThanOrEqual));
450 }
451
Deinitialize()452 void CSettingConditions::Deinitialize()
453 {
454 m_profileManager = nullptr;
455 }
456
GetCurrentProfile()457 const CProfile& CSettingConditions::GetCurrentProfile()
458 {
459 if (!m_profileManager)
460 m_profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager().get();
461
462 if (m_profileManager)
463 return m_profileManager->GetCurrentProfile();
464
465 static CProfile emptyProfile;
466 return emptyProfile;
467 }
468
Check(const std::string & condition,const std::string & value,const SettingConstPtr & setting)469 bool CSettingConditions::Check(const std::string& condition,
470 const std::string& value /* = "" */,
471 const SettingConstPtr& setting /* = NULL */)
472 {
473 if (m_simpleConditions.find(condition) != m_simpleConditions.end())
474 return true;
475
476 std::map<std::string, SettingConditionCheck>::const_iterator itCondition = m_complexConditions.find(condition);
477 if (itCondition != m_complexConditions.end())
478 return itCondition->second(condition, value, setting, NULL);
479
480 return Check(condition);
481 }
482