• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium Embedded Framework Authors. Portions copyright
2 // 2011 The Chromium Authors. All rights reserved. Use of this source code is
3 // governed by a BSD-style license that can be found in the LICENSE file.
4 
5 #include "libcef/common/resource_util.h"
6 
7 #if BUILDFLAG(IS_LINUX)
8 #include <dlfcn.h>
9 #endif
10 
11 #include "libcef/features/runtime.h"
12 
13 #include "base/command_line.h"
14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h"
16 #include "base/notreached.h"
17 #include "base/path_service.h"
18 #include "chrome/common/chrome_constants.h"
19 #include "chrome/common/chrome_paths.h"
20 #include "chrome/common/chrome_paths_internal.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "ui/base/layout.h"
23 
24 #if BUILDFLAG(IS_MAC)
25 #include "base/mac/foundation_util.h"
26 #include "libcef/common/util_mac.h"
27 #endif
28 
29 #if BUILDFLAG(IS_LINUX)
30 #include "base/environment.h"
31 #include "base/nix/xdg_util.h"
32 #endif
33 
34 #if BUILDFLAG(IS_WIN)
35 #include "base/win/registry.h"
36 #endif
37 
38 namespace resource_util {
39 
40 namespace {
41 
42 #if BUILDFLAG(IS_LINUX)
43 
44 // Based on chrome/common/chrome_paths_linux.cc.
45 // See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
46 // for a spec on where config files go. The net result on most systems is that
47 // we use "~/.config/cef_user_data".
GetDefaultUserDataDirectory(base::FilePath * result)48 bool GetDefaultUserDataDirectory(base::FilePath* result) {
49   std::unique_ptr<base::Environment> env(base::Environment::Create());
50   base::FilePath config_dir(base::nix::GetXDGDirectory(
51       env.get(), base::nix::kXdgConfigHomeEnvVar, base::nix::kDotConfigDir));
52   *result = config_dir.Append(FILE_PATH_LITERAL("cef_user_data"));
53   return true;
54 }
55 
56 #elif BUILDFLAG(IS_MAC)
57 
58 // Based on chrome/common/chrome_paths_mac.mm.
59 bool GetDefaultUserDataDirectory(base::FilePath* result) {
60   if (!base::PathService::Get(base::DIR_APP_DATA, result))
61     return false;
62   *result = result->Append(FILE_PATH_LITERAL("CEF"));
63   *result = result->Append(FILE_PATH_LITERAL("User Data"));
64   return true;
65 }
66 
67 #elif BUILDFLAG(IS_WIN)
68 
69 // Based on chrome/common/chrome_paths_win.cc.
70 bool GetDefaultUserDataDirectory(base::FilePath* result) {
71   if (!base::PathService::Get(base::DIR_LOCAL_APP_DATA, result))
72     return false;
73   *result = result->Append(FILE_PATH_LITERAL("CEF"));
74   *result = result->Append(FILE_PATH_LITERAL("User Data"));
75   return true;
76 }
77 
78 #endif
79 
GetUserDataPath(CefSettings * settings,const base::CommandLine * command_line)80 base::FilePath GetUserDataPath(CefSettings* settings,
81                                const base::CommandLine* command_line) {
82   // |settings| will be non-nullptr in the main process only.
83   if (settings) {
84     // With the Chrome runtime Profile paths must always be relative to the
85     // user data directory, so defaulting to |root_cache_path| first is
86     // appropriate.
87     CefString user_data_path;
88     if (cef::IsChromeRuntimeEnabled() && settings->root_cache_path.length > 0) {
89       user_data_path = CefString(&settings->root_cache_path);
90     }
91     if (user_data_path.empty() && settings->user_data_path.length > 0) {
92       user_data_path = CefString(&settings->user_data_path);
93     }
94     if (!user_data_path.empty()) {
95       return base::FilePath(user_data_path);
96     }
97   }
98 
99   // This may be set for sub-processes.
100   base::FilePath result =
101       command_line->GetSwitchValuePath(switches::kUserDataDir);
102   if (!result.empty())
103     return result;
104 
105   if (GetDefaultUserDataDirectory(&result))
106     return result;
107 
108   if (base::PathService::Get(base::DIR_TEMP, &result))
109     return result;
110 
111   NOTREACHED();
112   return result;
113 }
114 
115 // Consider downloads 'dangerous' if they go to the home directory on Linux and
116 // to the desktop on any platform.
117 // From chrome/browser/download/download_prefs.cc.
DownloadPathIsDangerous(const base::FilePath & download_path)118 bool DownloadPathIsDangerous(const base::FilePath& download_path) {
119 #if BUILDFLAG(IS_LINUX)
120   base::FilePath home_dir = base::GetHomeDir();
121   if (download_path == home_dir) {
122     return true;
123   }
124 #endif
125 
126   base::FilePath desktop_dir;
127   if (!base::PathService::Get(base::DIR_USER_DESKTOP, &desktop_dir)) {
128     NOTREACHED();
129     return false;
130   }
131   return (download_path == desktop_dir);
132 }
133 
GetDefaultDownloadDirectory(base::FilePath * result)134 bool GetDefaultDownloadDirectory(base::FilePath* result) {
135   // This will return the safe download directory if necessary.
136   return chrome::GetUserDownloadsDirectory(result);
137 }
138 
GetDefaultDownloadSafeDirectory(base::FilePath * result)139 bool GetDefaultDownloadSafeDirectory(base::FilePath* result) {
140   // Start with the default download directory.
141   if (!GetDefaultDownloadDirectory(result))
142     return false;
143 
144   if (DownloadPathIsDangerous(*result)) {
145 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
146     // Explicitly switch to the safe download directory.
147     return chrome::GetUserDownloadsDirectorySafe(result);
148 #else
149     // No viable alternative on macOS.
150     return false;
151 #endif
152   }
153 
154   return true;
155 }
156 
157 }  // namespace
158 
159 #if BUILDFLAG(IS_MAC)
160 
GetResourcesDir()161 base::FilePath GetResourcesDir() {
162   return util_mac::GetFrameworkResourcesDirectory();
163 }
164 
165 // Use a "~/Library/Logs/<app name>_debug.log" file where <app name> is the name
166 // of the running executable.
GetDefaultLogFilePath()167 base::FilePath GetDefaultLogFilePath() {
168   std::string exe_name = util_mac::GetMainProcessPath().BaseName().value();
169   return base::mac::GetUserLibraryPath()
170       .Append(FILE_PATH_LITERAL("Logs"))
171       .Append(FILE_PATH_LITERAL(exe_name + "_debug.log"));
172 }
173 
174 #else  // !BUILDFLAG(IS_MAC)
175 
GetResourcesDir()176 base::FilePath GetResourcesDir() {
177   base::FilePath pak_dir;
178   base::PathService::Get(base::DIR_ASSETS, &pak_dir);
179   return pak_dir;
180 }
181 
182 // Use a "debug.log" file in the running executable's directory.
GetDefaultLogFilePath()183 base::FilePath GetDefaultLogFilePath() {
184   base::FilePath log_path;
185   base::PathService::Get(base::DIR_EXE, &log_path);
186   return log_path.Append(FILE_PATH_LITERAL("debug.log"));
187 }
188 
189 #endif  // !BUILDFLAG(IS_MAC)
190 
OverrideDefaultDownloadDir()191 void OverrideDefaultDownloadDir() {
192   base::FilePath dir_default_download;
193   base::FilePath dir_default_download_safe;
194   if (GetDefaultDownloadDirectory(&dir_default_download)) {
195     base::PathService::Override(chrome::DIR_DEFAULT_DOWNLOADS,
196                                 dir_default_download);
197   }
198   if (GetDefaultDownloadSafeDirectory(&dir_default_download_safe)) {
199     base::PathService::Override(chrome::DIR_DEFAULT_DOWNLOADS_SAFE,
200                                 dir_default_download_safe);
201   }
202 }
203 
OverrideUserDataDir(CefSettings * settings,const base::CommandLine * command_line)204 void OverrideUserDataDir(CefSettings* settings,
205                          const base::CommandLine* command_line) {
206   const base::FilePath& user_data_path =
207       GetUserDataPath(settings, command_line);
208   base::PathService::Override(chrome::DIR_USER_DATA, user_data_path);
209 
210   // Path used for crash dumps.
211   base::PathService::Override(chrome::DIR_CRASH_DUMPS, user_data_path);
212 
213   // Path used for spell checking dictionary files.
214   base::PathService::OverrideAndCreateIfNeeded(
215       chrome::DIR_APP_DICTIONARIES,
216       user_data_path.Append(FILE_PATH_LITERAL("Dictionaries")),
217       false,  // May not be an absolute path.
218       true);  // Create if necessary.
219 }
220 
221 // Same as ui::ResourceBundle::IsScaleFactorSupported.
IsScaleFactorSupported(ui::ResourceScaleFactor scale_factor)222 bool IsScaleFactorSupported(ui::ResourceScaleFactor scale_factor) {
223   const auto& supported_scale_factors = ui::GetSupportedResourceScaleFactors();
224   return std::find(supported_scale_factors.begin(),
225                    supported_scale_factors.end(),
226                    scale_factor) != supported_scale_factors.end();
227 }
228 
229 #if BUILDFLAG(IS_LINUX)
OverrideAssetPath()230 void OverrideAssetPath() {
231   Dl_info dl_info;
232   if (dladdr(reinterpret_cast<const void*>(&OverrideAssetPath), &dl_info)) {
233     base::FilePath path = base::FilePath(dl_info.dli_fname).DirName();
234     base::PathService::Override(base::DIR_ASSETS, path);
235   }
236 }
237 #endif
238 
239 }  // namespace resource_util
240