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