• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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/browser/chromeos/file_manager/path_util.h"
6 
7 #include "base/files/file_path.h"
8 #include "base/logging.h"
9 #include "base/sys_info.h"
10 #include "chrome/browser/chromeos/drive/file_system_util.h"
11 #include "chrome/browser/chromeos/profiles/profile_helper.h"
12 #include "chrome/browser/download/download_prefs.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "components/user_manager/user.h"
15 #include "components/user_manager/user_manager.h"
16 #include "net/base/escape.h"
17 
18 namespace file_manager {
19 namespace util {
20 
21 namespace {
22 
23 const char kDownloadsFolderName[] = "Downloads";
24 const base::FilePath::CharType kOldDownloadsFolderPath[] =
25     FILE_PATH_LITERAL("/home/chronos/user/Downloads");
26 const base::FilePath::CharType kOldDriveFolderPath[] =
27     FILE_PATH_LITERAL("/special/drive");
28 // Unintended path introduced in crbug.com/363026.
29 const base::FilePath::CharType kBuggyDriveFolderPath[] =
30     FILE_PATH_LITERAL("/special/drive-user");
31 
32 }  // namespace
33 
GetDownloadsFolderForProfile(Profile * profile)34 base::FilePath GetDownloadsFolderForProfile(Profile* profile) {
35   // On non-ChromeOS system (test+development), the primary profile uses
36   // $HOME/Downloads for ease for accessing local files for debugging.
37   if (!base::SysInfo::IsRunningOnChromeOS() &&
38       user_manager::UserManager::IsInitialized()) {
39     const user_manager::User* const user =
40         chromeos::ProfileHelper::Get()->GetUserByProfile(
41             profile->GetOriginalProfile());
42     const user_manager::User* const primary_user =
43         user_manager::UserManager::Get()->GetPrimaryUser();
44     if (user == primary_user)
45       return DownloadPrefs::GetDefaultDownloadDirectory();
46   }
47   return profile->GetPath().AppendASCII(kDownloadsFolderName);
48 }
49 
MigratePathFromOldFormat(Profile * profile,const base::FilePath & old_path,base::FilePath * new_path)50 bool MigratePathFromOldFormat(Profile* profile,
51                               const base::FilePath& old_path,
52                               base::FilePath* new_path) {
53   // M34:
54   // /home/chronos/user/Downloads/xxx => /home/chronos/u-hash/Downloads/xxx
55   // /special/drive => /special/drive-xxx
56   //
57   // Old path format comes either from stored old settings or from the initial
58   // default value set in DownloadPrefs::RegisterProfilePrefs in profile-unaware
59   // code location. In the former case it is "/home/chronos/user/Downloads",
60   // and in the latter case it is DownloadPrefs::GetDefaultDownloadDirectory().
61   // Those two paths coincides as long as $HOME=/home/chronos/user, but the
62   // environment variable is phasing out (crbug.com/333031) so we care both.
63 
64   const base::FilePath downloads = GetDownloadsFolderForProfile(profile);
65   const base::FilePath drive = drive::util::GetDriveMountPointPath(profile);
66 
67   std::vector<std::pair<base::FilePath, base::FilePath> > bases;
68   bases.push_back(std::make_pair(base::FilePath(kOldDownloadsFolderPath),
69                                  downloads));
70   bases.push_back(std::make_pair(DownloadPrefs::GetDefaultDownloadDirectory(),
71                                  downloads));
72   bases.push_back(std::make_pair(base::FilePath(kOldDriveFolderPath), drive));
73   bases.push_back(std::make_pair(base::FilePath(kBuggyDriveFolderPath), drive));
74 
75   // Trying migrating u-<hash>/Downloads to the current download path. This is
76   // no-op when multi-profile is enabled. This is necessary for (1) back
77   // migration when multi-profile flag is enabled and then disabled, or (2) in
78   // some edge cases (crbug.com/356322) that u-<hash> path is temporarily used.
79   if (user_manager::UserManager::IsInitialized()) {
80     const user_manager::User* const user =
81         chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
82     if (user) {
83       const base::FilePath hashed_downloads =
84           chromeos::ProfileHelper::GetProfilePathByUserIdHash(
85               user->username_hash()).AppendASCII(kDownloadsFolderName);
86       bases.push_back(std::make_pair(hashed_downloads, downloads));
87     }
88   }
89 
90   for (size_t i = 0; i < bases.size(); ++i) {
91     const base::FilePath& old_base = bases[i].first;
92     const base::FilePath& new_base = bases[i].second;
93     base::FilePath relative;
94     if (old_path == old_base ||
95         old_base.AppendRelativePath(old_path, &relative)) {
96       *new_path = new_base.Append(relative);
97       return old_path != *new_path;
98     }
99   }
100 
101   return false;
102 }
103 
GetDownloadsMountPointName(Profile * profile)104 std::string GetDownloadsMountPointName(Profile* profile) {
105   // To distinguish profiles in multi-profile session, we append user name hash
106   // to "Downloads". Note that some profiles (like login or test profiles)
107   // are not associated with an user account. In that case, no suffix is added
108   // because such a profile never belongs to a multi-profile session.
109   user_manager::User* const user =
110       user_manager::UserManager::IsInitialized()
111           ? chromeos::ProfileHelper::Get()->GetUserByProfile(
112                 profile->GetOriginalProfile())
113           : NULL;
114   const std::string id = user ? "-" + user->username_hash() : "";
115   return net::EscapeQueryParamValue(kDownloadsFolderName + id, false);
116 }
117 
118 }  // namespace util
119 }  // namespace file_manager
120