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.
5 #include "chrome/browser/chromeos/file_manager/path_util.h"
7 #include "base/files/file_path.h"
8 #include "base/logging.h"
9 #include "base/path_service.h"
10 #include "base/sys_info.h"
11 #include "chrome/browser/chromeos/drive/file_system_util.h"
12 #include "chrome/browser/chromeos/login/user.h"
13 #include "chrome/browser/chromeos/login/user_manager.h"
14 #include "chrome/browser/chromeos/profiles/profile_helper.h"
15 #include "chrome/browser/download/download_prefs.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "net/base/escape.h"
19 namespace file_manager
{
24 const char kDownloadsFolderName
[] = "Downloads";
25 const base::FilePath::CharType kOldDownloadsFolderPath
[] =
26 FILE_PATH_LITERAL("/home/chronos/user/Downloads");
27 const base::FilePath::CharType kOldDriveFolderPath
[] =
28 FILE_PATH_LITERAL("/special/drive");
29 // Unintended path introduced in crbug.com/363026.
30 const base::FilePath::CharType kBuggyDriveFolderPath
[] =
31 FILE_PATH_LITERAL("/special/drive-user");
35 base::FilePath
GetDownloadsFolderForProfile(Profile
* profile
) {
36 if (!base::SysInfo::IsRunningOnChromeOS() &&
37 !chromeos::UserManager::IsMultipleProfilesAllowed()) {
38 // On the developer run on Linux desktop build, if multiple profiles are
39 // not enabled, use $HOME/Downloads for ease for accessing local files for
42 CHECK(PathService::Get(base::DIR_HOME
, &path
));
43 return path
.AppendASCII(kDownloadsFolderName
);
46 return profile
->GetPath().AppendASCII(kDownloadsFolderName
);
49 bool MigratePathFromOldFormat(Profile
* profile
,
50 const base::FilePath
& old_path
,
51 base::FilePath
* new_path
) {
53 // /home/chronos/user/Downloads/xxx => /home/chronos/u-hash/Downloads/xxx
54 // /special/drive => /special/drive-xxx
56 // Old path format comes either from stored old settings or from the initial
57 // default value set in DownloadPrefs::RegisterProfilePrefs in profile-unaware
58 // code location. In the former case it is "/home/chronos/user/Downloads",
59 // and in the latter case it is DownloadPrefs::GetDefaultDownloadDirectory().
60 // Those two paths coincides as long as $HOME=/home/chronos/user, but the
61 // environment variable is phasing out (crbug.com/333031) so we care both.
63 const base::FilePath downloads
= GetDownloadsFolderForProfile(profile
);
64 const base::FilePath drive
= drive::util::GetDriveMountPointPath(profile
);
66 std::vector
<std::pair
<base::FilePath
, base::FilePath
> > bases
;
67 bases
.push_back(std::make_pair(base::FilePath(kOldDownloadsFolderPath
),
69 bases
.push_back(std::make_pair(DownloadPrefs::GetDefaultDownloadDirectory(),
71 bases
.push_back(std::make_pair(base::FilePath(kOldDriveFolderPath
), drive
));
72 bases
.push_back(std::make_pair(base::FilePath(kBuggyDriveFolderPath
), drive
));
74 // Trying migrating u-<hash>/Downloads to the current download path. This is
75 // no-op when multi-profile is enabled. This is necessary for (1) back
76 // migration when multi-profile flag is enabled and then disabled, or (2) in
77 // some edge cases (crbug.com/356322) that u-<hash> path is temporarily used.
78 if (chromeos::UserManager::IsInitialized()) {
79 const chromeos::User
* const user
=
80 chromeos::UserManager::Get()->GetUserByProfile(profile
);
82 const base::FilePath hashed_downloads
=
83 chromeos::ProfileHelper::GetProfilePathByUserIdHash(
84 user
->username_hash()).AppendASCII(kDownloadsFolderName
);
85 bases
.push_back(std::make_pair(hashed_downloads
, downloads
));
89 for (size_t i
= 0; i
< bases
.size(); ++i
) {
90 const base::FilePath
& old_base
= bases
[i
].first
;
91 const base::FilePath
& new_base
= bases
[i
].second
;
92 base::FilePath relative
;
93 if (old_path
== old_base
||
94 old_base
.AppendRelativePath(old_path
, &relative
)) {
95 *new_path
= new_base
.Append(relative
);
96 return old_path
!= *new_path
;
103 std::string
GetDownloadsMountPointName(Profile
* profile
) {
104 // To distinguish profiles in multi-profile session, we append user name hash
105 // to "Downloads". Note that some profiles (like login or test profiles)
106 // are not associated with an user account. In that case, no suffix is added
107 // because such a profile never belongs to a multi-profile session.
108 chromeos::User
* const user
=
109 chromeos::UserManager::IsInitialized() ?
110 chromeos::UserManager::Get()->GetUserByProfile(
111 profile
->GetOriginalProfile()) : NULL
;
112 const std::string id
= user
? "-" + user
->username_hash() : "";
113 return net::EscapePath(kDownloadsFolderName
+ id
);
117 } // namespace file_manager