1 // Copyright (c) 2012 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/files/file_util.h"
8 #include "base/logging.h"
9 #include "base/native_library.h"
10 #include "base/no_destructor.h"
11 #include "base/notreached.h"
12 #include "base/path_service.h"
13 #include "base/strings/string_util.h"
14 #include "base/system/sys_info.h"
15 #include "base/threading/thread_restrictions.h"
16 #include "base/version.h"
17 #include "build/build_config.h"
18 #include "chrome/common/buildflags.h"
19 #include "chrome/common/chrome_constants.h"
20 #include "chrome/common/chrome_paths_internal.h"
21 #include "media/media_buildflags.h"
22 #include "third_party/widevine/cdm/buildflags.h"
23
24 #if defined(OS_ANDROID)
25 #include "base/android/path_utils.h"
26 #include "base/base_paths_android.h"
27 // ui/base must only be used on Android. See BUILD.gn for dependency info.
28 #include "ui/base/ui_base_paths.h" // nogncheck
29 #endif
30
31 #if defined(OS_MAC)
32 #include "base/mac/bundle_locations.h"
33 #include "base/mac/foundation_util.h"
34 #endif
35
36 #if defined(OS_WIN)
37 #include "base/win/registry.h"
38 #endif
39
40 #if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && BUILDFLAG(ENABLE_WIDEVINE)
41 #include "third_party/widevine/cdm/widevine_cdm_common.h" // nogncheck
42 #endif
43
44 namespace {
45
46 // The Pepper Flash plugins are in a directory with this name.
47 const base::FilePath::CharType kPepperFlashBaseDirectory[] =
48 FILE_PATH_LITERAL("PepperFlash");
49
50 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
51 // The path to the external extension <id>.json files.
52 // /usr/share seems like a good choice, see: http://www.pathname.com/fhs/
53 const base::FilePath::CharType kFilepathSinglePrefExtensions[] =
54 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
55 #if defined(OS_BSD)
56 FILE_PATH_LITERAL("/usr/local/share/google-chrome/extensions");
57 #else
58 FILE_PATH_LITERAL("/usr/share/google-chrome/extensions");
59 #endif
60 #else
61 #if defined(OS_BSD)
62 FILE_PATH_LITERAL("/usr/local/share/chromium/extensions");
63 #else
64 FILE_PATH_LITERAL("/usr/share/chromium/extensions");
65 #endif
66 #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
67
68 // The path to the hint file that tells the pepper plugin loader
69 // where it can find the latest component updated flash.
70 const base::FilePath::CharType kComponentUpdatedFlashHint[] =
71 FILE_PATH_LITERAL("latest-component-updated-flash");
72 #endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
73
74 #if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && \
75 BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
76 // The name of the hint file that tells the latest component updated Widevine
77 // CDM directory. This file name should not be changed as otherwise existing
78 // Widevine CDMs might not be loaded.
79 const base::FilePath::CharType kComponentUpdatedWidevineCdmHint[] =
80 FILE_PATH_LITERAL("latest-component-updated-widevine-cdm");
81 #endif // (defined(OS_LINUX) || defined(OS_CHROMEOS)) &&
82 // BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
83
84 #if defined(OS_CHROMEOS)
85 const base::FilePath::CharType kChromeOSTPMFirmwareUpdateLocation[] =
86 FILE_PATH_LITERAL("/run/tpm_firmware_update_location");
87 const base::FilePath::CharType kChromeOSTPMFirmwareUpdateSRKVulnerableROCA[] =
88 FILE_PATH_LITERAL("/run/tpm_firmware_update_srk_vulnerable_roca");
89 #endif // defined(OS_CHROMEOS)
90
GetInvalidSpecifiedUserDataDirInternal()91 base::FilePath& GetInvalidSpecifiedUserDataDirInternal() {
92 static base::NoDestructor<base::FilePath> s;
93 return *s;
94 }
95
96 // Gets the path for internal plugins.
GetInternalPluginsDirectory(base::FilePath * result)97 bool GetInternalPluginsDirectory(base::FilePath* result) {
98 #if defined(OS_MAC)
99 // If called from Chrome, get internal plugins from a subdirectory of the
100 // framework.
101 if (base::mac::AmIBundled()) {
102 *result = chrome::GetFrameworkBundlePath();
103 DCHECK(!result->empty());
104 *result = result->Append("Internet Plug-Ins");
105 return true;
106 }
107 // In tests, just look in the module directory (below).
108 #endif
109
110 // The rest of the world expects plugins in the module directory.
111 return base::PathService::Get(base::DIR_MODULE, result);
112 }
113
114 // Gets the path for bundled implementations of components. Note that these
115 // implementations should not be used if higher-versioned component-updated
116 // implementations are available in DIR_USER_DATA.
GetComponentDirectory(base::FilePath * result)117 bool GetComponentDirectory(base::FilePath* result) {
118 #if defined(OS_MAC)
119 // If called from Chrome, return the framework's Libraries directory.
120 if (base::mac::AmIBundled()) {
121 *result = chrome::GetFrameworkBundlePath();
122 DCHECK(!result->empty());
123 *result = result->Append("Libraries");
124 return true;
125 }
126 // In tests, just look in the module directory (below).
127 #endif
128
129 // The rest of the world expects components in the module directory.
130 return base::PathService::Get(base::DIR_MODULE, result);
131 }
132
133 } // namespace
134
135 namespace chrome {
136
PathProvider(int key,base::FilePath * result)137 bool PathProvider(int key, base::FilePath* result) {
138 // Some keys are just aliases...
139 switch (key) {
140 case chrome::DIR_APP:
141 return base::PathService::Get(base::DIR_MODULE, result);
142 case chrome::DIR_LOGS:
143 #ifdef NDEBUG
144 // Release builds write to the data dir
145 return base::PathService::Get(chrome::DIR_USER_DATA, result);
146 #else
147 // Debug builds write next to the binary (in the build tree)
148 #if defined(OS_MAC)
149 // Apps may not write into their own bundle.
150 if (base::mac::AmIBundled()) {
151 return base::PathService::Get(chrome::DIR_USER_DATA, result);
152 }
153 return base::PathService::Get(base::DIR_EXE, result);
154 #else
155 return base::PathService::Get(base::DIR_EXE, result);
156 #endif // defined(OS_MAC)
157 #endif // NDEBUG
158 case chrome::FILE_RESOURCE_MODULE:
159 return base::PathService::Get(base::FILE_MODULE, result);
160 }
161
162 // Assume that we will not need to create the directory if it does not exist.
163 // This flag can be set to true for the cases where we want to create it.
164 bool create_dir = false;
165
166 base::FilePath cur;
167 switch (key) {
168 case chrome::DIR_USER_DATA:
169 if (!GetDefaultUserDataDirectory(&cur)) {
170 NOTREACHED();
171 return false;
172 }
173 create_dir = true;
174 break;
175 case chrome::DIR_USER_DOCUMENTS:
176 if (!GetUserDocumentsDirectory(&cur))
177 return false;
178 create_dir = true;
179 break;
180 case chrome::DIR_USER_MUSIC:
181 if (!GetUserMusicDirectory(&cur))
182 return false;
183 break;
184 case chrome::DIR_USER_PICTURES:
185 if (!GetUserPicturesDirectory(&cur))
186 return false;
187 break;
188 case chrome::DIR_USER_VIDEOS:
189 if (!GetUserVideosDirectory(&cur))
190 return false;
191 break;
192 case chrome::DIR_DEFAULT_DOWNLOADS_SAFE:
193 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
194 if (!GetUserDownloadsDirectorySafe(&cur))
195 return false;
196 break;
197 #else
198 // Fall through for all other platforms.
199 #endif
200 case chrome::DIR_DEFAULT_DOWNLOADS:
201 #if defined(OS_ANDROID)
202 if (!base::android::GetDownloadsDirectory(&cur))
203 return false;
204 #else
205 if (!GetUserDownloadsDirectory(&cur))
206 return false;
207 // Do not create the download directory here, we have done it twice now
208 // and annoyed a lot of users.
209 #endif
210 break;
211 case chrome::DIR_CRASH_DUMPS:
212 #if defined(OS_CHROMEOS)
213 // ChromeOS uses a separate directory. See http://crosbug.com/25089
214 cur = base::FilePath("/var/log/chrome");
215 #elif defined(OS_ANDROID)
216 if (!base::android::GetCacheDirectory(&cur))
217 return false;
218 #else
219 // The crash reports are always stored relative to the default user data
220 // directory. This avoids the problem of having to re-initialize the
221 // exception handler after parsing command line options, which may
222 // override the location of the app's profile directory.
223 // TODO(scottmg): Consider supporting --user-data-dir. See
224 // https://crbug.com/565446.
225 if (!GetDefaultUserDataDirectory(&cur))
226 return false;
227 #endif
228 #if defined(OS_MAC) || defined(OS_WIN) || defined(OS_ANDROID)
229 cur = cur.Append(FILE_PATH_LITERAL("Crashpad"));
230 #else
231 cur = cur.Append(FILE_PATH_LITERAL("Crash Reports"));
232 #endif
233 create_dir = true;
234 break;
235 #if defined(OS_WIN)
236 case chrome::DIR_WATCHER_DATA:
237 // The watcher data is always stored relative to the default user data
238 // directory. This allows the watcher to be initialized before
239 // command-line options have been parsed.
240 if (!GetDefaultUserDataDirectory(&cur))
241 return false;
242 cur = cur.Append(FILE_PATH_LITERAL("Diagnostics"));
243 break;
244 case chrome::DIR_ROAMING_USER_DATA:
245 if (!GetDefaultRoamingUserDataDirectory(&cur)) {
246 NOTREACHED();
247 return false;
248 }
249 create_dir = true;
250 break;
251 #endif
252 case chrome::DIR_RESOURCES:
253 #if defined(OS_MAC)
254 cur = base::mac::FrameworkBundlePath();
255 cur = cur.Append(FILE_PATH_LITERAL("Resources"));
256 #else
257 if (!base::PathService::Get(chrome::DIR_APP, &cur))
258 return false;
259 cur = cur.Append(FILE_PATH_LITERAL("resources"));
260 #endif
261 break;
262 case chrome::DIR_APP_DICTIONARIES:
263 #if defined(OS_POSIX)
264 // We can't write into the EXE dir on Linux, so keep dictionaries
265 // alongside the safe browsing database in the user data dir.
266 // And we don't want to write into the bundle on the Mac, so push
267 // it to the user data dir there also.
268 if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
269 return false;
270 #else
271 if (!base::PathService::Get(base::DIR_EXE, &cur))
272 return false;
273 #endif
274 cur = cur.Append(FILE_PATH_LITERAL("Dictionaries"));
275 create_dir = true;
276 break;
277 case chrome::DIR_INTERNAL_PLUGINS:
278 if (!GetInternalPluginsDirectory(&cur))
279 return false;
280 break;
281 case chrome::DIR_COMPONENTS:
282 if (!GetComponentDirectory(&cur))
283 return false;
284 break;
285 case chrome::DIR_PEPPER_FLASH_PLUGIN:
286 if (!GetInternalPluginsDirectory(&cur))
287 return false;
288 cur = cur.Append(kPepperFlashBaseDirectory);
289 break;
290 case chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN:
291 if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
292 return false;
293 cur = cur.Append(kPepperFlashBaseDirectory);
294 break;
295 case chrome::FILE_LOCAL_STATE:
296 if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
297 return false;
298 cur = cur.Append(chrome::kLocalStateFilename);
299 break;
300 case chrome::FILE_RECORDED_SCRIPT:
301 if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
302 return false;
303 cur = cur.Append(FILE_PATH_LITERAL("script.log"));
304 break;
305 case chrome::FILE_PEPPER_FLASH_PLUGIN:
306 if (!base::PathService::Get(chrome::DIR_PEPPER_FLASH_PLUGIN, &cur))
307 return false;
308 break;
309 // PNaCl is currenly installable via the component updater or by being
310 // simply built-in. DIR_PNACL_BASE is used as the base directory for
311 // installation via component updater. DIR_PNACL_COMPONENT will be
312 // the final location of pnacl, which is a subdir of DIR_PNACL_BASE.
313 case chrome::DIR_PNACL_BASE:
314 if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
315 return false;
316 cur = cur.Append(FILE_PATH_LITERAL("pnacl"));
317 break;
318 // Where PNaCl files are ultimately located. The default finds the files
319 // inside the InternalPluginsDirectory / build directory, as if it
320 // was shipped along with chrome. The value can be overridden
321 // if it is installed via component updater.
322 case chrome::DIR_PNACL_COMPONENT:
323 #if defined(OS_MAC)
324 // PNaCl really belongs in the InternalPluginsDirectory but actually
325 // copying it there would result in the files also being shipped, which
326 // we don't want yet. So for now, just find them in the directory where
327 // they get built.
328 if (!base::PathService::Get(base::DIR_EXE, &cur))
329 return false;
330 if (base::mac::AmIBundled()) {
331 // If we're called from chrome, it's beside the app (outside the
332 // app bundle), if we're called from a unittest, we'll already be
333 // outside the bundle so use the exe dir.
334 // exe_dir gave us .../Chromium.app/Contents/MacOS/Chromium.
335 cur = cur.DirName();
336 cur = cur.DirName();
337 cur = cur.DirName();
338 }
339 #else
340 if (!GetInternalPluginsDirectory(&cur))
341 return false;
342 #endif
343 cur = cur.Append(FILE_PATH_LITERAL("pnacl"));
344 break;
345
346 #if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && \
347 BUILDFLAG(BUNDLE_WIDEVINE_CDM)
348 case chrome::DIR_BUNDLED_WIDEVINE_CDM:
349 if (!GetComponentDirectory(&cur))
350 return false;
351 #if !defined(OS_CHROMEOS)
352 // TODO(crbug.com/971433): Move Widevine CDM to a separate folder on
353 // ChromeOS so that the manifest can be included.
354 cur = cur.AppendASCII(kWidevineCdmBaseDirectory);
355 #endif // !defined(OS_CHROMEOS)
356 break;
357 #endif // (defined(OS_LINUX) || defined(OS_CHROMEOS)) &&
358 // BUILDFLAG(BUNDLE_WIDEVINE_CDM)
359
360 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && \
361 BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
362 case chrome::DIR_COMPONENT_UPDATED_WIDEVINE_CDM:
363 if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
364 return false;
365 cur = cur.Append(kWidevineCdmBaseDirectory);
366 break;
367 case chrome::FILE_COMPONENT_WIDEVINE_CDM_HINT:
368 if (!base::PathService::Get(chrome::DIR_COMPONENT_UPDATED_WIDEVINE_CDM,
369 &cur))
370 return false;
371 cur = cur.Append(kComponentUpdatedWidevineCdmHint);
372 break;
373 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) &&
374 // BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
375
376 case chrome::FILE_RESOURCES_PACK: // Falls through.
377 case chrome::FILE_DEV_UI_RESOURCES_PACK:
378 #if defined(OS_MAC)
379 cur = base::mac::FrameworkBundlePath();
380 cur = cur.Append(FILE_PATH_LITERAL("Resources"))
381 .Append(FILE_PATH_LITERAL("resources.pak"));
382 break;
383 #elif defined(OS_ANDROID)
384 if (!base::PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &cur))
385 return false;
386 if (key == chrome::FILE_DEV_UI_RESOURCES_PACK) {
387 cur = cur.Append(FILE_PATH_LITERAL("dev_ui_resources.pak"));
388 } else {
389 DCHECK_EQ(chrome::FILE_RESOURCES_PACK, key);
390 cur = cur.Append(FILE_PATH_LITERAL("resources.pak"));
391 }
392 #else
393 // If we're not bundled on mac or Android, resources.pak should be next
394 // to the binary (e.g., for unit tests).
395 if (!base::PathService::Get(base::DIR_MODULE, &cur))
396 return false;
397 cur = cur.Append(FILE_PATH_LITERAL("resources.pak"));
398 #endif
399 break;
400
401 #if defined(OS_CHROMEOS)
402 case chrome::DIR_CHROMEOS_WALLPAPERS:
403 if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
404 return false;
405 cur = cur.Append(FILE_PATH_LITERAL("wallpapers"));
406 break;
407 case chrome::DIR_CHROMEOS_WALLPAPER_THUMBNAILS:
408 if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
409 return false;
410 cur = cur.Append(FILE_PATH_LITERAL("wallpaper_thumbnails"));
411 break;
412 case chrome::DIR_CHROMEOS_CUSTOM_WALLPAPERS:
413 if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
414 return false;
415 cur = cur.Append(FILE_PATH_LITERAL("custom_wallpapers"));
416 break;
417 #endif
418 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
419 case chrome::DIR_SUPERVISED_USER_INSTALLED_WHITELISTS:
420 if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
421 return false;
422 cur = cur.Append(FILE_PATH_LITERAL("SupervisedUserInstalledWhitelists"));
423 break;
424 #endif
425 // The following are only valid in the development environment, and
426 // will fail if executed from an installed executable (because the
427 // generated path won't exist).
428 case chrome::DIR_GEN_TEST_DATA:
429 #if defined(OS_ANDROID)
430 // On Android, our tests don't have permission to write to DIR_MODULE.
431 // gtest/test_runner.py pushes data to external storage.
432 if (!base::PathService::Get(base::DIR_SOURCE_ROOT, &cur))
433 return false;
434 #else
435 if (!base::PathService::Get(base::DIR_MODULE, &cur))
436 return false;
437 #endif
438 cur = cur.Append(FILE_PATH_LITERAL("test_data"));
439 if (!base::PathExists(cur)) // We don't want to create this.
440 return false;
441 break;
442 case chrome::DIR_TEST_DATA:
443 if (!base::PathService::Get(base::DIR_SOURCE_ROOT, &cur))
444 return false;
445 cur = cur.Append(FILE_PATH_LITERAL("chrome"));
446 cur = cur.Append(FILE_PATH_LITERAL("test"));
447 cur = cur.Append(FILE_PATH_LITERAL("data"));
448 if (!base::PathExists(cur)) // We don't want to create this.
449 return false;
450 break;
451 case chrome::DIR_TEST_TOOLS:
452 if (!base::PathService::Get(base::DIR_SOURCE_ROOT, &cur))
453 return false;
454 cur = cur.Append(FILE_PATH_LITERAL("chrome"));
455 cur = cur.Append(FILE_PATH_LITERAL("tools"));
456 cur = cur.Append(FILE_PATH_LITERAL("test"));
457 if (!base::PathExists(cur)) // We don't want to create this
458 return false;
459 break;
460 #if defined(OS_POSIX) && !defined(OS_MAC) && !defined(OS_OPENBSD)
461 case chrome::DIR_POLICY_FILES: {
462 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
463 cur = base::FilePath(FILE_PATH_LITERAL("/etc/opt/chrome/policies"));
464 #elif defined(OS_BSD)
465 cur = base::FilePath(FILE_PATH_LITERAL(
466 "/usr/local/etc/chrome/policies"));
467 #else
468 cur = base::FilePath(FILE_PATH_LITERAL("/etc/chromium/policies"));
469 #endif
470 break;
471 }
472 #endif
473 #if defined(OS_CHROMEOS) || \
474 (defined(OS_LINUX) && BUILDFLAG(CHROMIUM_BRANDING)) || defined(OS_MAC) || defined(OS_BSD)
475 case chrome::DIR_USER_EXTERNAL_EXTENSIONS: {
476 if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
477 return false;
478 cur = cur.Append(FILE_PATH_LITERAL("External Extensions"));
479 break;
480 }
481 #endif
482 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
483 case chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS: {
484 cur = base::FilePath(kFilepathSinglePrefExtensions);
485 break;
486 }
487 #endif
488 case chrome::DIR_EXTERNAL_EXTENSIONS:
489 #if defined(OS_MAC)
490 if (!chrome::GetGlobalApplicationSupportDirectory(&cur))
491 return false;
492
493 cur = cur.Append(FILE_PATH_LITERAL("Google"))
494 .Append(FILE_PATH_LITERAL("Chrome"))
495 .Append(FILE_PATH_LITERAL("External Extensions"));
496 create_dir = false;
497 #else
498 if (!base::PathService::Get(base::DIR_MODULE, &cur))
499 return false;
500
501 cur = cur.Append(FILE_PATH_LITERAL("extensions"));
502 create_dir = true;
503 #endif
504 break;
505
506 case chrome::DIR_DEFAULT_APPS:
507 #if defined(OS_MAC)
508 cur = base::mac::FrameworkBundlePath();
509 cur = cur.Append(FILE_PATH_LITERAL("Default Apps"));
510 #else
511 if (!base::PathService::Get(chrome::DIR_APP, &cur))
512 return false;
513 cur = cur.Append(FILE_PATH_LITERAL("default_apps"));
514 #endif
515 break;
516
517 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_BSD)
518 case chrome::DIR_NATIVE_MESSAGING:
519 #if defined(OS_MAC)
520 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
521 cur = base::FilePath(FILE_PATH_LITERAL(
522 "/Library/Google/Chrome/NativeMessagingHosts"));
523 #else
524 cur = base::FilePath(FILE_PATH_LITERAL(
525 "/Library/Application Support/Chromium/NativeMessagingHosts"));
526 #endif
527 #else // defined(OS_MAC)
528 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
529 cur = base::FilePath(FILE_PATH_LITERAL(
530 "/etc/opt/chrome/native-messaging-hosts"));
531 #elif defined(OS_BSD)
532 cur = base::FilePath(FILE_PATH_LITERAL(
533 "/usr/local/etc/chrome/native-messaging-hosts"));
534 #else
535 cur = base::FilePath(FILE_PATH_LITERAL(
536 "/etc/chromium/native-messaging-hosts"));
537 #endif
538 #endif // !defined(OS_MAC)
539 break;
540
541 case chrome::DIR_USER_NATIVE_MESSAGING:
542 if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
543 return false;
544 cur = cur.Append(FILE_PATH_LITERAL("NativeMessagingHosts"));
545 break;
546 #endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_BSD)
547 #if !defined(OS_ANDROID)
548 case chrome::DIR_GLOBAL_GCM_STORE:
549 if (!base::PathService::Get(chrome::DIR_USER_DATA, &cur))
550 return false;
551 cur = cur.Append(kGCMStoreDirname);
552 break;
553 #endif // !defined(OS_ANDROID)
554 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
555 case chrome::FILE_COMPONENT_FLASH_HINT:
556 if (!base::PathService::Get(
557 chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, &cur)) {
558 return false;
559 }
560 cur = cur.Append(kComponentUpdatedFlashHint);
561 break;
562 #endif // defined(OS_LINUX) || defined(OS_CHROMEOS)
563 #if defined(OS_CHROMEOS)
564 case chrome::FILE_CHROME_OS_TPM_FIRMWARE_UPDATE_LOCATION:
565 cur = base::FilePath(kChromeOSTPMFirmwareUpdateLocation);
566 create_dir = false;
567 break;
568 case chrome::FILE_CHROME_OS_TPM_FIRMWARE_UPDATE_SRK_VULNERABLE_ROCA:
569 cur = base::FilePath(kChromeOSTPMFirmwareUpdateSRKVulnerableROCA);
570 create_dir = false;
571 break;
572 #endif // defined(OS_CHROMEOS)
573
574 default:
575 return false;
576 }
577
578 // TODO(bauerb): http://crbug.com/259796
579 base::ThreadRestrictions::ScopedAllowIO allow_io;
580 if (create_dir && !base::PathExists(cur) &&
581 !base::CreateDirectory(cur))
582 return false;
583
584 *result = cur;
585 return true;
586 }
587
588 // This cannot be done as a static initializer sadly since Visual Studio will
589 // eliminate this object file if there is no direct entry point into it.
RegisterPathProvider()590 void RegisterPathProvider() {
591 base::PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);
592 }
593
SetInvalidSpecifiedUserDataDir(const base::FilePath & user_data_dir)594 void SetInvalidSpecifiedUserDataDir(const base::FilePath& user_data_dir) {
595 GetInvalidSpecifiedUserDataDirInternal() = user_data_dir;
596 }
597
GetInvalidSpecifiedUserDataDir()598 const base::FilePath& GetInvalidSpecifiedUserDataDir() {
599 return GetInvalidSpecifiedUserDataDirInternal();
600 }
601
602 } // namespace chrome
603