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