• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/common/chrome_paths.h"
6 
7 #include "base/command_line.h"
8 #include "base/file_util.h"
9 #include "base/logging.h"
10 #include "base/path_service.h"
11 #include "base/string_util.h"
12 #include "base/sys_info.h"
13 #include "chrome/common/chrome_constants.h"
14 #include "chrome/common/chrome_paths_internal.h"
15 #include "chrome/common/chrome_switches.h"
16 
17 #if defined(OS_MACOSX)
18 #include "base/mac/mac_util.h"
19 #endif
20 
21 namespace {
22 
23 // File name of the internal Flash plugin on different platforms.
24 const FilePath::CharType kInternalFlashPluginFileName[] =
25 #if defined(OS_MACOSX)
26     FILE_PATH_LITERAL("Flash Player Plugin for Chrome.plugin");
27 #elif defined(OS_WIN)
28     FILE_PATH_LITERAL("gcswf32.dll");
29 #else  // OS_LINUX, etc.
30     FILE_PATH_LITERAL("libgcflashplayer.so");
31 #endif
32 
33 // File name of the internal PDF plugin on different platforms.
34 const FilePath::CharType kInternalPDFPluginFileName[] =
35 #if defined(OS_WIN)
36     FILE_PATH_LITERAL("pdf.dll");
37 #elif defined(OS_MACOSX)
38     FILE_PATH_LITERAL("PDF.plugin");
39 #else  // Linux and Chrome OS
40     FILE_PATH_LITERAL("libpdf.so");
41 #endif
42 
43 // File name of the internal NaCl plugin on different platforms.
44 const FilePath::CharType kInternalNaClPluginFileName[] =
45 #if defined(OS_WIN)
46     FILE_PATH_LITERAL("ppGoogleNaClPluginChrome.dll");
47 #elif defined(OS_MACOSX)
48     // TODO(noelallen) Please verify this extention name is correct.
49     FILE_PATH_LITERAL("ppGoogleNaClPluginChrome.plugin");
50 #else  // Linux and Chrome OS
51     FILE_PATH_LITERAL("libppGoogleNaClPluginChrome.so");
52 #endif
53 
54 }  // namespace
55 
56 namespace chrome {
57 
58 // Gets the path for internal plugins.
GetInternalPluginsDirectory(FilePath * result)59 bool GetInternalPluginsDirectory(FilePath* result) {
60 #if defined(OS_MACOSX)
61   // If called from Chrome, get internal plugins from a subdirectory of the
62   // framework.
63   if (base::mac::AmIBundled()) {
64     *result = chrome::GetFrameworkBundlePath();
65     DCHECK(!result->empty());
66     *result = result->Append("Internet Plug-Ins");
67     return true;
68   }
69   // In tests, just look in the module directory (below).
70 #endif
71 
72   // The rest of the world expects plugins in the module directory.
73   return PathService::Get(base::DIR_MODULE, result);
74 }
75 
PathProvider(int key,FilePath * result)76 bool PathProvider(int key, FilePath* result) {
77   // Some keys are just aliases...
78   switch (key) {
79     case chrome::DIR_APP:
80       return PathService::Get(base::DIR_MODULE, result);
81     case chrome::DIR_LOGS:
82 #ifdef NDEBUG
83       // Release builds write to the data dir
84       return PathService::Get(chrome::DIR_USER_DATA, result);
85 #else
86       // Debug builds write next to the binary (in the build tree)
87 #if defined(OS_MACOSX)
88       if (!PathService::Get(base::DIR_EXE, result))
89         return false;
90       if (base::mac::AmIBundled()) {
91         // If we're called from chrome, dump it beside the app (outside the
92         // app bundle), if we're called from a unittest, we'll already
93         // outside the bundle so use the exe dir.
94         // exe_dir gave us .../Chromium.app/Contents/MacOS/Chromium.
95         *result = result->DirName();
96         *result = result->DirName();
97         *result = result->DirName();
98       }
99       return true;
100 #else
101       return PathService::Get(base::DIR_EXE, result);
102 #endif  // defined(OS_MACOSX)
103 #endif  // NDEBUG
104     case chrome::FILE_RESOURCE_MODULE:
105       return PathService::Get(base::FILE_MODULE, result);
106   }
107 
108   // Assume that we will not need to create the directory if it does not exist.
109   // This flag can be set to true for the cases where we want to create it.
110   bool create_dir = false;
111 
112   FilePath cur;
113   switch (key) {
114     case chrome::DIR_USER_DATA:
115       if (!GetDefaultUserDataDirectory(&cur)) {
116         NOTREACHED();
117         return false;
118       }
119       create_dir = true;
120       break;
121     case chrome::DIR_USER_DOCUMENTS:
122       if (!GetUserDocumentsDirectory(&cur))
123         return false;
124       create_dir = true;
125       break;
126     case chrome::DIR_DEFAULT_DOWNLOADS_SAFE:
127 #if defined(OS_WIN)
128       if (!GetUserDownloadsDirectorySafe(&cur))
129         return false;
130       break;
131 #else
132       // Fall through for all other platforms.
133 #endif
134     case chrome::DIR_DEFAULT_DOWNLOADS:
135       if (!GetUserDownloadsDirectory(&cur))
136         return false;
137       // Do not create the download directory here, we have done it twice now
138       // and annoyed a lot of users.
139       break;
140     case chrome::DIR_CRASH_DUMPS:
141       // The crash reports are always stored relative to the default user data
142       // directory.  This avoids the problem of having to re-initialize the
143       // exception handler after parsing command line options, which may
144       // override the location of the app's profile directory.
145       if (!GetDefaultUserDataDirectory(&cur))
146         return false;
147       cur = cur.Append(FILE_PATH_LITERAL("Crash Reports"));
148       create_dir = true;
149       break;
150     case chrome::DIR_USER_DESKTOP:
151       if (!GetUserDesktop(&cur))
152         return false;
153       break;
154     case chrome::DIR_RESOURCES:
155 #if defined(OS_MACOSX)
156       cur = base::mac::MainAppBundlePath();
157       cur = cur.Append(FILE_PATH_LITERAL("Resources"));
158 #else
159       if (!PathService::Get(chrome::DIR_APP, &cur))
160         return false;
161       cur = cur.Append(FILE_PATH_LITERAL("resources"));
162 #endif
163       break;
164     case chrome::DIR_SHARED_RESOURCES:
165       if (!PathService::Get(chrome::DIR_RESOURCES, &cur))
166         return false;
167       cur = cur.Append(FILE_PATH_LITERAL("shared"));
168       break;
169     case chrome::DIR_INSPECTOR:
170       if (!PathService::Get(chrome::DIR_RESOURCES, &cur))
171         return false;
172       cur = cur.Append(FILE_PATH_LITERAL("inspector"));
173       break;
174     case chrome::DIR_APP_DICTIONARIES:
175 #if defined(OS_LINUX) || defined(OS_MACOSX)
176       // We can't write into the EXE dir on Linux, so keep dictionaries
177       // alongside the safe browsing database in the user data dir.
178       // And we don't want to write into the bundle on the Mac, so push
179       // it to the user data dir there also.
180       if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
181         return false;
182 #else
183       if (!PathService::Get(base::DIR_EXE, &cur))
184         return false;
185 #endif
186       cur = cur.Append(FILE_PATH_LITERAL("Dictionaries"));
187       create_dir = true;
188       break;
189     case chrome::DIR_USER_DATA_TEMP:
190       if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
191         return false;
192       cur = cur.Append(FILE_PATH_LITERAL("Temp"));
193       break;
194     case chrome::DIR_INTERNAL_PLUGINS:
195       if (!GetInternalPluginsDirectory(&cur))
196         return false;
197       break;
198     case chrome::DIR_MEDIA_LIBS:
199 #if defined(OS_MACOSX)
200       *result = base::mac::MainAppBundlePath();
201       *result = result->Append("Libraries");
202       return true;
203 #else
204       return PathService::Get(chrome::DIR_APP, result);
205 #endif
206     case chrome::FILE_LOCAL_STATE:
207       if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
208         return false;
209       cur = cur.Append(chrome::kLocalStateFilename);
210       break;
211     case chrome::FILE_RECORDED_SCRIPT:
212       if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
213         return false;
214       cur = cur.Append(FILE_PATH_LITERAL("script.log"));
215       break;
216     case chrome::FILE_FLASH_PLUGIN:
217       if (!GetInternalPluginsDirectory(&cur))
218         return false;
219       cur = cur.Append(kInternalFlashPluginFileName);
220       if (!file_util::PathExists(cur))
221         return false;
222       break;
223     case chrome::FILE_PDF_PLUGIN:
224       if (!GetInternalPluginsDirectory(&cur))
225         return false;
226       cur = cur.Append(kInternalPDFPluginFileName);
227       break;
228     case chrome::FILE_NACL_PLUGIN:
229       if (!GetInternalPluginsDirectory(&cur))
230         return false;
231       cur = cur.Append(kInternalNaClPluginFileName);
232       break;
233     case chrome::FILE_RESOURCES_PACK:
234 #if defined(OS_MACOSX)
235       if (base::mac::AmIBundled()) {
236         cur = base::mac::MainAppBundlePath();
237         cur = cur.Append(FILE_PATH_LITERAL("Resources"))
238                  .Append(FILE_PATH_LITERAL("resources.pak"));
239         break;
240       }
241       // If we're not bundled on mac, resources.pak should be next to the
242       // binary (e.g., for unit tests).
243 #endif
244       if (!PathService::Get(base::DIR_MODULE, &cur))
245         return false;
246       cur = cur.Append(FILE_PATH_LITERAL("resources.pak"));
247       break;
248 #if defined(OS_CHROMEOS)
249     case chrome::FILE_CHROMEOS_API:
250       if (!PathService::Get(base::DIR_MODULE, &cur))
251         return false;
252       cur = cur.Append(FILE_PATH_LITERAL("chromeos"));
253       cur = cur.Append(FILE_PATH_LITERAL("libcros.so"));
254       break;
255 #endif
256     // The following are only valid in the development environment, and
257     // will fail if executed from an installed executable (because the
258     // generated path won't exist).
259     case chrome::DIR_TEST_DATA:
260       if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
261         return false;
262       cur = cur.Append(FILE_PATH_LITERAL("chrome"));
263       cur = cur.Append(FILE_PATH_LITERAL("test"));
264       cur = cur.Append(FILE_PATH_LITERAL("data"));
265       if (!file_util::PathExists(cur))  // we don't want to create this
266         return false;
267       break;
268     case chrome::DIR_TEST_TOOLS:
269       if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
270         return false;
271       cur = cur.Append(FILE_PATH_LITERAL("chrome"));
272       cur = cur.Append(FILE_PATH_LITERAL("tools"));
273       cur = cur.Append(FILE_PATH_LITERAL("test"));
274       if (!file_util::PathExists(cur))  // we don't want to create this
275         return false;
276       break;
277 #if defined(OS_POSIX) && !defined(OS_MACOSX)
278     case chrome::DIR_POLICY_FILES: {
279 #if defined(GOOGLE_CHROME_BUILD)
280       cur = FilePath(FILE_PATH_LITERAL("/etc/opt/chrome/policies"));
281 #else
282       cur = FilePath(FILE_PATH_LITERAL("/etc/chromium/policies"));
283 #endif
284       if (!file_util::PathExists(cur))  // we don't want to create this
285         return false;
286       break;
287     }
288 #endif
289 #if defined(OS_MACOSX)
290     case chrome::DIR_MANAGED_PREFS: {
291       if (!GetLocalLibraryDirectory(&cur))
292         return false;
293       cur = cur.Append(FILE_PATH_LITERAL("Managed Preferences"));
294       char* login = getlogin();
295       if (!login)
296         return false;
297       cur = cur.AppendASCII(login);
298       if (!file_util::PathExists(cur))  // we don't want to create this
299         return false;
300       break;
301     }
302 #endif
303 #if defined(OS_CHROMEOS)
304     case chrome::DIR_USER_EXTERNAL_EXTENSIONS: {
305       if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
306         return false;
307       cur = cur.Append(FILE_PATH_LITERAL("External Extensions"));
308       break;
309     }
310 #endif
311     default:
312       return false;
313   }
314 
315   if (create_dir && !file_util::PathExists(cur) &&
316       !file_util::CreateDirectory(cur))
317     return false;
318 
319   *result = cur;
320   return true;
321 }
322 
323 // This cannot be done as a static initializer sadly since Visual Studio will
324 // eliminate this object file if there is no direct entry point into it.
RegisterPathProvider()325 void RegisterPathProvider() {
326   PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);
327 }
328 
329 }  // namespace chrome
330