Home | History | Annotate | Download | only in file_manager
      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/login/users/user.h"
     12 #include "chrome/browser/chromeos/login/users/user_manager.h"
     13 #include "chrome/browser/chromeos/profiles/profile_helper.h"
     14 #include "chrome/browser/download/download_prefs.h"
     15 #include "chrome/browser/profiles/profile.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 
     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       chromeos::UserManager::IsInitialized()) {
     39     const chromeos::User* const user =
     40         chromeos::UserManager::Get()->GetUserByProfile(
     41             profile->GetOriginalProfile());
     42     const chromeos::User* const primary_user =
     43         chromeos::UserManager::Get()->GetPrimaryUser();
     44     if (user == primary_user)
     45       return DownloadPrefs::GetDefaultDownloadDirectory();
     46   }
     47   return profile->GetPath().AppendASCII(kDownloadsFolderName);
     48 }
     49 
     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 (chromeos::UserManager::IsInitialized()) {
     80     const chromeos::User* const user =
     81         chromeos::UserManager::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 
    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   chromeos::User* const user =
    110       chromeos::UserManager::IsInitialized() ?
    111           chromeos::UserManager::Get()->GetUserByProfile(
    112               profile->GetOriginalProfile()) : NULL;
    113   const std::string id = user ? "-" + user->username_hash() : "";
    114   return net::EscapePath(kDownloadsFolderName + id);
    115 }
    116 
    117 }  // namespace util
    118 }  // namespace file_manager
    119