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 <memory>
8
9 #include "base/base_paths.h"
10 #include "base/environment.h"
11 #include "base/files/file_util.h"
12 #include "base/nix/xdg_util.h"
13 #include "base/path_service.h"
14 #include "base/strings/string_util.h"
15 #include "build/branding_buildflags.h"
16 #include "build/build_config.h"
17 #include "chrome/common/channel_info.h"
18 #include "chrome/common/chrome_paths_internal.h"
19
20 namespace chrome {
21
22 using base::nix::GetXDGDirectory;
23 using base::nix::GetXDGUserDirectory;
24 using base::nix::kDotConfigDir;
25 using base::nix::kXdgConfigHomeEnvVar;
26
27 namespace {
28
29 const char kDownloadsDir[] = "Downloads";
30 const char kMusicDir[] = "Music";
31 const char kPicturesDir[] = "Pictures";
32 const char kVideosDir[] = "Videos";
33
34 // Generic function for GetUser{Music,Pictures,Video}Directory.
GetUserMediaDirectory(const std::string & xdg_name,const std::string & fallback_name,base::FilePath * result)35 bool GetUserMediaDirectory(const std::string& xdg_name,
36 const std::string& fallback_name,
37 base::FilePath* result) {
38 #if defined(OS_CHROMEOS)
39 // No local media directories on CrOS.
40 return false;
41 #else
42 *result = GetXDGUserDirectory(xdg_name.c_str(), fallback_name.c_str());
43
44 base::FilePath home;
45 base::PathService::Get(base::DIR_HOME, &home);
46 if (*result != home) {
47 base::FilePath desktop;
48 if (!base::PathService::Get(base::DIR_USER_DESKTOP, &desktop))
49 return false;
50 if (*result != desktop) {
51 return true;
52 }
53 }
54
55 *result = home.Append(fallback_name);
56 return true;
57 #endif
58 }
59
60 } // namespace
61
62 // This returns <config-home>/<product>, where
63 // <config-home> is:
64 // $CHROME_CONFIG_HOME if set
65 // otherwise $XDG_CONFIG_HOME if set
66 // otherwise ~/.config
67 // and <product> is:
68 // "chromium" for Chromium
69 // "google-chrome" for stable channel official build
70 // "google-chrome-beta" for beta channel official build
71 // "google-chrome-unstable" for dev channel official build
72 //
73 // (Note that ChromeMainDelegate will override the value returned by this
74 // function if $CHROME_USER_DATA_DIR or --user-data-dir is set.)
75 //
76 // See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
77 // for a spec on where config files go. Using ~/.config also helps us sidestep
78 // issues with other apps grabbing ~/.chromium .
GetDefaultUserDataDirectory(base::FilePath * result)79 bool GetDefaultUserDataDirectory(base::FilePath* result) {
80 std::unique_ptr<base::Environment> env(base::Environment::Create());
81 base::FilePath config_dir;
82 std::string chrome_config_home_str;
83 if (env->GetVar("CHROME_CONFIG_HOME", &chrome_config_home_str) &&
84 base::IsStringUTF8(chrome_config_home_str)) {
85 config_dir = base::FilePath::FromUTF8Unsafe(chrome_config_home_str);
86 } else {
87 config_dir =
88 GetXDGDirectory(env.get(), kXdgConfigHomeEnvVar, kDotConfigDir);
89 }
90
91 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
92 std::string data_dir_basename = "google-chrome";
93 #else
94 std::string data_dir_basename = "chromium";
95 #endif
96 *result = config_dir.Append(data_dir_basename + GetChannelSuffixForDataDir());
97 return true;
98 }
99
GetUserCacheDirectory(const base::FilePath & profile_dir,base::FilePath * result)100 void GetUserCacheDirectory(const base::FilePath& profile_dir,
101 base::FilePath* result) {
102 // See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
103 // for a spec on where cache files go. Our rule is:
104 // - if the user-data-dir in the standard place,
105 // use same subdirectory of the cache directory.
106 // (this maps ~/.config/google-chrome to ~/.cache/google-chrome as well
107 // as the same thing for ~/.config/chromium)
108 // - otherwise, use the profile dir directly.
109
110 // Default value in cases where any of the following fails.
111 *result = profile_dir;
112
113 std::unique_ptr<base::Environment> env(base::Environment::Create());
114
115 base::FilePath cache_dir;
116 if (!base::PathService::Get(base::DIR_CACHE, &cache_dir))
117 return;
118 base::FilePath config_dir(GetXDGDirectory(env.get(),
119 kXdgConfigHomeEnvVar,
120 kDotConfigDir));
121
122 if (!config_dir.AppendRelativePath(profile_dir, &cache_dir))
123 return;
124
125 *result = cache_dir;
126 }
127
GetUserDocumentsDirectory(base::FilePath * result)128 bool GetUserDocumentsDirectory(base::FilePath* result) {
129 *result = GetXDGUserDirectory("DOCUMENTS", "Documents");
130 return true;
131 }
132
GetUserDownloadsDirectorySafe(base::FilePath * result)133 bool GetUserDownloadsDirectorySafe(base::FilePath* result) {
134 base::FilePath home;
135 base::PathService::Get(base::DIR_HOME, &home);
136 *result = home.Append(kDownloadsDir);
137 return true;
138 }
139
GetUserDownloadsDirectory(base::FilePath * result)140 bool GetUserDownloadsDirectory(base::FilePath* result) {
141 *result = GetXDGUserDirectory("DOWNLOAD", kDownloadsDir);
142 return true;
143 }
144
145 // We respect the user's preferred pictures location, unless it is
146 // ~ or their desktop directory, in which case we default to ~/Music.
GetUserMusicDirectory(base::FilePath * result)147 bool GetUserMusicDirectory(base::FilePath* result) {
148 return GetUserMediaDirectory("MUSIC", kMusicDir, result);
149 }
150
151 // We respect the user's preferred pictures location, unless it is
152 // ~ or their desktop directory, in which case we default to ~/Pictures.
GetUserPicturesDirectory(base::FilePath * result)153 bool GetUserPicturesDirectory(base::FilePath* result) {
154 return GetUserMediaDirectory("PICTURES", kPicturesDir, result);
155 }
156
157 // We respect the user's preferred pictures location, unless it is
158 // ~ or their desktop directory, in which case we default to ~/Videos.
GetUserVideosDirectory(base::FilePath * result)159 bool GetUserVideosDirectory(base::FilePath* result) {
160 return GetUserMediaDirectory("VIDEOS", kVideosDir, result);
161 }
162
ProcessNeedsProfileDir(const std::string & process_type)163 bool ProcessNeedsProfileDir(const std::string& process_type) {
164 // For now we have no reason to forbid this on Linux as we don't
165 // have the roaming profile troubles there. Moreover the Linux breakpad needs
166 // profile dir access in all process if enabled on Linux.
167 return true;
168 }
169
170 } // namespace chrome
171