#include "libcef/common/resource_util.h"
#if BUILDFLAG(IS_LINUX)
#include <dlfcn.h>
#endif
#include "libcef/features/runtime.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/notreached.h"
#include "base/path_service.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "ui/base/layout.h"
#if BUILDFLAG(IS_MAC)
#include "base/mac/foundation_util.h"
#include "libcef/common/util_mac.h"
#endif
#if BUILDFLAG(IS_LINUX)
#include "base/environment.h"
#include "base/nix/xdg_util.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "base/win/registry.h"
#endif
namespace resource_util {
namespace {
#if BUILDFLAG(IS_LINUX)
bool GetDefaultUserDataDirectory(base::FilePath* result) {
std::unique_ptr<base::Environment> env(base::Environment::Create());
base::FilePath config_dir(base::nix::GetXDGDirectory(
env.get(), base::nix::kXdgConfigHomeEnvVar, base::nix::kDotConfigDir));
*result = config_dir.Append(FILE_PATH_LITERAL("cef_user_data"));
return true;
}
#elif BUILDFLAG(IS_MAC)
bool GetDefaultUserDataDirectory(base::FilePath* result) {
if (!base::PathService::Get(base::DIR_APP_DATA, result))
return false;
*result = result->Append(FILE_PATH_LITERAL("CEF"));
*result = result->Append(FILE_PATH_LITERAL("User Data"));
return true;
}
#elif BUILDFLAG(IS_WIN)
bool GetDefaultUserDataDirectory(base::FilePath* result) {
if (!base::PathService::Get(base::DIR_LOCAL_APP_DATA, result))
return false;
*result = result->Append(FILE_PATH_LITERAL("CEF"));
*result = result->Append(FILE_PATH_LITERAL("User Data"));
return true;
}
#endif
base::FilePath GetUserDataPath(CefSettings* settings,
const base::CommandLine* command_line) {
if (settings) {
CefString user_data_path;
if (cef::IsChromeRuntimeEnabled() && settings->root_cache_path.length > 0) {
user_data_path = CefString(&settings->root_cache_path);
}
if (user_data_path.empty() && settings->user_data_path.length > 0) {
user_data_path = CefString(&settings->user_data_path);
}
if (!user_data_path.empty()) {
return base::FilePath(user_data_path);
}
}
base::FilePath result =
command_line->GetSwitchValuePath(switches::kUserDataDir);
if (!result.empty())
return result;
if (GetDefaultUserDataDirectory(&result))
return result;
if (base::PathService::Get(base::DIR_TEMP, &result))
return result;
NOTREACHED();
return result;
}
bool DownloadPathIsDangerous(const base::FilePath& download_path) {
#if BUILDFLAG(IS_LINUX)
base::FilePath home_dir = base::GetHomeDir();
if (download_path == home_dir) {
return true;
}
#endif
base::FilePath desktop_dir;
if (!base::PathService::Get(base::DIR_USER_DESKTOP, &desktop_dir)) {
NOTREACHED();
return false;
}
return (download_path == desktop_dir);
}
bool GetDefaultDownloadDirectory(base::FilePath* result) {
return chrome::GetUserDownloadsDirectory(result);
}
bool GetDefaultDownloadSafeDirectory(base::FilePath* result) {
if (!GetDefaultDownloadDirectory(result))
return false;
if (DownloadPathIsDangerous(*result)) {
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
return chrome::GetUserDownloadsDirectorySafe(result);
#else
return false;
#endif
}
return true;
}
}
#if BUILDFLAG(IS_MAC)
base::FilePath GetResourcesDir() {
return util_mac::GetFrameworkResourcesDirectory();
}
base::FilePath GetDefaultLogFilePath() {
std::string exe_name = util_mac::GetMainProcessPath().BaseName().value();
return base::mac::GetUserLibraryPath()
.Append(FILE_PATH_LITERAL("Logs"))
.Append(FILE_PATH_LITERAL(exe_name + "_debug.log"));
}
#else
base::FilePath GetResourcesDir() {
base::FilePath pak_dir;
base::PathService::Get(base::DIR_ASSETS, &pak_dir);
return pak_dir;
}
base::FilePath GetDefaultLogFilePath() {
base::FilePath log_path;
base::PathService::Get(base::DIR_EXE, &log_path);
return log_path.Append(FILE_PATH_LITERAL("debug.log"));
}
#endif
void OverrideDefaultDownloadDir() {
base::FilePath dir_default_download;
base::FilePath dir_default_download_safe;
if (GetDefaultDownloadDirectory(&dir_default_download)) {
base::PathService::Override(chrome::DIR_DEFAULT_DOWNLOADS,
dir_default_download);
}
if (GetDefaultDownloadSafeDirectory(&dir_default_download_safe)) {
base::PathService::Override(chrome::DIR_DEFAULT_DOWNLOADS_SAFE,
dir_default_download_safe);
}
}
void OverrideUserDataDir(CefSettings* settings,
const base::CommandLine* command_line) {
const base::FilePath& user_data_path =
GetUserDataPath(settings, command_line);
base::PathService::Override(chrome::DIR_USER_DATA, user_data_path);
base::PathService::Override(chrome::DIR_CRASH_DUMPS, user_data_path);
base::PathService::OverrideAndCreateIfNeeded(
chrome::DIR_APP_DICTIONARIES,
user_data_path.Append(FILE_PATH_LITERAL("Dictionaries")),
false,
true);
}
bool IsScaleFactorSupported(ui::ResourceScaleFactor scale_factor) {
const auto& supported_scale_factors = ui::GetSupportedResourceScaleFactors();
return std::find(supported_scale_factors.begin(),
supported_scale_factors.end(),
scale_factor) != supported_scale_factors.end();
}
#if BUILDFLAG(IS_LINUX)
void OverrideAssetPath() {
Dl_info dl_info;
if (dladdr(reinterpret_cast<const void*>(&OverrideAssetPath), &dl_info)) {
base::FilePath path = base::FilePath(dl_info.dli_fname).DirName();
base::PathService::Override(base::DIR_ASSETS, path);
}
}
#endif
}