[Windows] Fix driver version detection of AMD RDNA+ GPU on Windows 10
[xbmc.git] / xbmc / settings / SettingsComponent.cpp
blob0f5f7ae8da75fd73cbaf950cf87ad69847783298
1 /*
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.
7 */
9 #include "SettingsComponent.h"
11 #include "CompileInfo.h"
12 #include "ServiceBroker.h"
13 #include "Util.h"
14 #include "application/AppParams.h"
15 #include "filesystem/Directory.h"
16 #include "filesystem/SpecialProtocol.h"
17 #ifdef TARGET_DARWIN_EMBEDDED
18 #include "platform/darwin/ios-common/DarwinEmbedUtils.h"
19 #endif
20 #ifdef TARGET_WINDOWS
21 #include "platform/Environment.h"
22 #endif
23 #include "profiles/ProfileManager.h"
24 #include "settings/AdvancedSettings.h"
25 #include "settings/Settings.h"
26 #include "settings/SubtitlesSettings.h"
27 #include "utils/StringUtils.h"
28 #include "utils/URIUtils.h"
29 #include "utils/log.h"
30 #ifdef TARGET_WINDOWS
31 #include "win32util.h"
32 #endif
34 CSettingsComponent::CSettingsComponent()
35 : m_settings(new CSettings()),
36 m_advancedSettings(new CAdvancedSettings()),
37 m_subtitlesSettings(new KODI::SUBTITLES::CSubtitlesSettings(m_settings)),
38 m_profileManager(new CProfileManager())
42 CSettingsComponent::~CSettingsComponent()
46 void CSettingsComponent::Initialize()
48 if (m_state == State::DEINITED)
50 const auto params = CServiceBroker::GetAppParams();
52 // only the InitDirectories* for the current platform should return true
53 bool inited = InitDirectoriesLinux(params->HasPlatformDirectories());
54 if (!inited)
55 inited = InitDirectoriesOSX(params->HasPlatformDirectories());
56 if (!inited)
57 inited = InitDirectoriesWin32(params->HasPlatformDirectories());
59 m_settings->Initialize();
61 m_advancedSettings->Initialize(*m_settings->GetSettingsManager());
62 URIUtils::RegisterAdvancedSettings(*m_advancedSettings);
64 m_profileManager->Initialize(m_settings);
66 m_state = State::INITED;
70 bool CSettingsComponent::Load()
72 if (m_state == State::INITED)
74 if (!m_profileManager->Load())
76 CLog::Log(LOGFATAL, "unable to load profile");
77 return false;
80 CSpecialProtocol::RegisterProfileManager(*m_profileManager);
81 XFILE::IDirectory::RegisterProfileManager(*m_profileManager);
83 if (!m_settings->Load())
85 CLog::Log(LOGFATAL, "unable to load settings");
86 return false;
89 m_settings->SetLoaded();
91 m_state = State::LOADED;
92 return true;
94 else if (m_state == State::LOADED)
96 return true;
98 else
100 return false;
104 void CSettingsComponent::Deinitialize()
106 if (m_state >= State::INITED)
108 if (m_state == State::LOADED)
110 m_subtitlesSettings.reset();
112 m_settings->Unload();
114 XFILE::IDirectory::UnregisterProfileManager();
115 CSpecialProtocol::UnregisterProfileManager();
117 m_profileManager->Uninitialize();
119 URIUtils::UnregisterAdvancedSettings();
120 m_advancedSettings->Uninitialize(*m_settings->GetSettingsManager());
122 m_settings->Uninitialize();
124 m_state = State::DEINITED;
127 std::shared_ptr<CSettings> CSettingsComponent::GetSettings()
129 return m_settings;
132 std::shared_ptr<CAdvancedSettings> CSettingsComponent::GetAdvancedSettings()
134 return m_advancedSettings;
137 std::shared_ptr<KODI::SUBTITLES::CSubtitlesSettings> CSettingsComponent::GetSubtitlesSettings()
139 return m_subtitlesSettings;
142 std::shared_ptr<CProfileManager> CSettingsComponent::GetProfileManager()
144 return m_profileManager;
147 bool CSettingsComponent::InitDirectoriesLinux(bool bPlatformDirectories)
150 The following is the directory mapping for Platform Specific Mode:
152 special://xbmc/ => [read-only] system directory (/usr/share/kodi)
153 special://home/ => [read-write] user's directory that will override special://kodi/ system-wide
154 installations like skins, screensavers, etc.
155 ($HOME/.kodi)
156 NOTE: XBMC will look in both special://xbmc/addons and special://home/addons for addons.
157 special://masterprofile/ => [read-write] userdata of master profile. It will by default be
158 mapped to special://home/userdata ($HOME/.kodi/userdata)
159 special://profile/ => [read-write] current profile's userdata directory.
160 Generally special://masterprofile for the master profile or
161 special://masterprofile/profiles/<profile_name> for other profiles.
163 NOTE: All these root directories are lowercase. Some of the sub-directories
164 might be mixed case.
167 #if defined(TARGET_POSIX) && !defined(TARGET_DARWIN)
168 std::string appPath;
169 std::string appName = CCompileInfo::GetAppName();
170 std::string dotLowerAppName = "." + appName;
171 StringUtils::ToLower(dotLowerAppName);
172 const char* envAppHome = "KODI_HOME";
173 const char* envAppBinHome = "KODI_BIN_HOME";
174 const char* envAppTemp = "KODI_TEMP";
176 std::string userHome;
177 if (getenv("KODI_DATA"))
178 userHome = getenv("KODI_DATA");
179 else if (getenv("HOME"))
181 userHome = getenv("HOME");
182 userHome.append("/" + dotLowerAppName);
184 else
186 userHome = "/root";
187 userHome.append("/" + dotLowerAppName);
190 std::string strTempPath;
191 if (getenv(envAppTemp))
192 strTempPath = getenv(envAppTemp);
193 else
194 strTempPath = userHome + "/temp";
197 std::string binaddonAltDir;
198 if (getenv("KODI_BINADDON_PATH"))
199 binaddonAltDir = getenv("KODI_BINADDON_PATH");
201 auto appBinPath = CUtil::GetHomePath(envAppBinHome);
202 // overridden by user
203 if (getenv(envAppHome))
204 appPath = getenv(envAppHome);
205 else
207 // use build time default
208 appPath = INSTALL_PATH;
209 /* Check if binaries and arch independent data files are being kept in
210 * separate locations. */
211 if (!XFILE::CDirectory::Exists(URIUtils::AddFileToFolder(appPath, "userdata")))
213 /* Attempt to locate arch independent data files. */
214 appPath = CUtil::GetHomePath(appBinPath);
215 if (!XFILE::CDirectory::Exists(URIUtils::AddFileToFolder(appPath, "userdata")))
217 fprintf(stderr, "Unable to find path to %s data files!\n", appName.c_str());
218 exit(1);
223 /* Set some environment variables */
224 setenv(envAppBinHome, appBinPath.c_str(), 0);
225 setenv(envAppHome, appPath.c_str(), 0);
227 if (bPlatformDirectories)
229 // map our special drives
230 CSpecialProtocol::SetXBMCBinPath(appBinPath);
231 CSpecialProtocol::SetXBMCAltBinAddonPath(binaddonAltDir);
232 CSpecialProtocol::SetXBMCPath(appPath);
233 CSpecialProtocol::SetHomePath(userHome);
234 CSpecialProtocol::SetMasterProfilePath(userHome + "/userdata");
235 CSpecialProtocol::SetTempPath(strTempPath);
236 CSpecialProtocol::SetLogPath(strTempPath);
238 CreateUserDirs();
241 else
243 URIUtils::AddSlashAtEnd(appPath);
245 CSpecialProtocol::SetXBMCBinPath(appBinPath);
246 CSpecialProtocol::SetXBMCAltBinAddonPath(binaddonAltDir);
247 CSpecialProtocol::SetXBMCPath(appPath);
248 CSpecialProtocol::SetHomePath(URIUtils::AddFileToFolder(appPath, "portable_data"));
249 CSpecialProtocol::SetMasterProfilePath(URIUtils::AddFileToFolder(appPath, "portable_data/userdata"));
251 std::string strTempPath = appPath;
252 strTempPath = URIUtils::AddFileToFolder(strTempPath, "portable_data/temp");
253 if (getenv(envAppTemp))
254 strTempPath = getenv(envAppTemp);
255 CSpecialProtocol::SetTempPath(strTempPath);
256 CSpecialProtocol::SetLogPath(strTempPath);
257 CreateUserDirs();
259 CSpecialProtocol::SetXBMCBinAddonPath(appBinPath + "/addons");
261 return true;
262 #else
263 return false;
264 #endif
267 bool CSettingsComponent::InitDirectoriesOSX(bool bPlatformDirectories)
269 #if defined(TARGET_DARWIN)
270 std::string userHome;
271 if (getenv("HOME"))
272 userHome = getenv("HOME");
273 else
274 userHome = "/root";
276 std::string binaddonAltDir;
277 if (getenv("KODI_BINADDON_PATH"))
278 binaddonAltDir = getenv("KODI_BINADDON_PATH");
280 std::string appPath = CUtil::GetHomePath();
281 setenv("KODI_HOME", appPath.c_str(), 0);
283 #if defined(TARGET_DARWIN_EMBEDDED)
284 std::string fontconfigPath;
285 fontconfigPath = appPath + "/system/players/VideoPlayer/etc/fonts/fonts.conf";
286 setenv("FONTCONFIG_FILE", fontconfigPath.c_str(), 0);
287 #endif
289 // setup path to our internal dylibs so loader can find them
290 std::string frameworksPath = CUtil::GetFrameworksPath();
291 CSpecialProtocol::SetXBMCFrameworksPath(frameworksPath);
293 if (bPlatformDirectories)
295 // map our special drives
296 CSpecialProtocol::SetXBMCBinPath(appPath);
297 CSpecialProtocol::SetXBMCAltBinAddonPath(binaddonAltDir);
298 CSpecialProtocol::SetXBMCPath(appPath);
299 #if defined(TARGET_DARWIN_EMBEDDED)
300 std::string appName = CCompileInfo::GetAppName();
301 CSpecialProtocol::SetHomePath(userHome + "/" + CDarwinEmbedUtils::GetAppRootFolder() + "/" +
302 appName);
303 CSpecialProtocol::SetMasterProfilePath(userHome + "/" + CDarwinEmbedUtils::GetAppRootFolder() +
304 "/" + appName + "/userdata");
305 #else
306 std::string appName = CCompileInfo::GetAppName();
307 CSpecialProtocol::SetHomePath(userHome + "/Library/Application Support/" + appName);
308 CSpecialProtocol::SetMasterProfilePath(userHome + "/Library/Application Support/" + appName + "/userdata");
309 #endif
311 std::string dotLowerAppName = "." + appName;
312 StringUtils::ToLower(dotLowerAppName);
313 // location for temp files
314 #if defined(TARGET_DARWIN_EMBEDDED)
315 std::string strTempPath = URIUtils::AddFileToFolder(
316 userHome, std::string(CDarwinEmbedUtils::GetAppRootFolder()) + "/" + appName + "/temp");
317 #else
318 std::string strTempPath = URIUtils::AddFileToFolder(userHome, dotLowerAppName + "/");
319 XFILE::CDirectory::Create(strTempPath);
320 strTempPath = URIUtils::AddFileToFolder(userHome, dotLowerAppName + "/temp");
321 #endif
322 CSpecialProtocol::SetTempPath(strTempPath);
324 // xbmc.log file location
325 #if defined(TARGET_DARWIN_EMBEDDED)
326 strTempPath = userHome + "/" + std::string(CDarwinEmbedUtils::GetAppRootFolder());
327 #else
328 strTempPath = userHome + "/Library/Logs";
329 #endif
330 CSpecialProtocol::SetLogPath(strTempPath);
331 CreateUserDirs();
333 else
335 URIUtils::AddSlashAtEnd(appPath);
337 CSpecialProtocol::SetXBMCBinPath(appPath);
338 CSpecialProtocol::SetXBMCAltBinAddonPath(binaddonAltDir);
339 CSpecialProtocol::SetXBMCPath(appPath);
340 CSpecialProtocol::SetHomePath(URIUtils::AddFileToFolder(appPath, "portable_data"));
341 CSpecialProtocol::SetMasterProfilePath(URIUtils::AddFileToFolder(appPath, "portable_data/userdata"));
343 std::string strTempPath = URIUtils::AddFileToFolder(appPath, "portable_data/temp");
344 CSpecialProtocol::SetTempPath(strTempPath);
345 CSpecialProtocol::SetLogPath(strTempPath);
346 CreateUserDirs();
348 CSpecialProtocol::SetXBMCBinAddonPath(appPath + "/addons");
349 return true;
350 #else
351 return false;
352 #endif
355 bool CSettingsComponent::InitDirectoriesWin32(bool bPlatformDirectories)
357 #ifdef TARGET_WINDOWS
358 std::string xbmcPath = CUtil::GetHomePath();
359 CEnvironment::setenv("KODI_HOME", xbmcPath);
360 CSpecialProtocol::SetXBMCBinPath(xbmcPath);
361 CSpecialProtocol::SetXBMCPath(xbmcPath);
362 CSpecialProtocol::SetXBMCBinAddonPath(xbmcPath + "/addons");
364 std::string strWin32UserFolder = CWIN32Util::GetProfilePath(bPlatformDirectories);
365 CSpecialProtocol::SetLogPath(strWin32UserFolder);
366 CSpecialProtocol::SetHomePath(strWin32UserFolder);
367 CSpecialProtocol::SetMasterProfilePath(URIUtils::AddFileToFolder(strWin32UserFolder, "userdata"));
368 CSpecialProtocol::SetTempPath(URIUtils::AddFileToFolder(strWin32UserFolder,"cache"));
370 CEnvironment::setenv("KODI_PROFILE_USERDATA", CSpecialProtocol::TranslatePath("special://masterprofile/"));
372 CreateUserDirs();
374 return true;
375 #else
376 return false;
377 #endif
380 void CSettingsComponent::CreateUserDirs() const
382 XFILE::CDirectory::Create("special://home/");
383 XFILE::CDirectory::Create("special://home/addons");
384 XFILE::CDirectory::Create("special://home/addons/packages");
385 XFILE::CDirectory::Create("special://home/addons/temp");
386 XFILE::CDirectory::Create("special://home/media");
387 XFILE::CDirectory::Create("special://home/system");
388 XFILE::CDirectory::Create("special://masterprofile/");
389 XFILE::CDirectory::Create("special://temp/");
390 XFILE::CDirectory::Create("special://logpath");
391 XFILE::CDirectory::Create("special://temp/temp"); // temp directory for python and dllGetTempPathA
393 //Let's clear our archive cache before starting up anything more
394 auto archiveCachePath = CSpecialProtocol::TranslatePath("special://temp/archive_cache/");
395 if (XFILE::CDirectory::Exists(archiveCachePath))
396 if (!XFILE::CDirectory::RemoveRecursive(archiveCachePath))
397 CLog::Log(LOGWARNING, "Failed to remove the archive cache at {}", archiveCachePath);
398 XFILE::CDirectory::Create(archiveCachePath);