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