summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chromeos/file_manager/path_util.cc
blob: f93f97921a6e8841e8a9c25145429e5404a2bb9c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/file_manager/path_util.h"

#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/sys_info.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/login/users/user.h"
#include "chrome/browser/chromeos/login/users/user_manager.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "net/base/escape.h"

namespace file_manager {
namespace util {

namespace {

const char kDownloadsFolderName[] = "Downloads";
const base::FilePath::CharType kOldDownloadsFolderPath[] =
    FILE_PATH_LITERAL("/home/chronos/user/Downloads");
const base::FilePath::CharType kOldDriveFolderPath[] =
    FILE_PATH_LITERAL("/special/drive");
// Unintended path introduced in crbug.com/363026.
const base::FilePath::CharType kBuggyDriveFolderPath[] =
    FILE_PATH_LITERAL("/special/drive-user");

}  // namespace

base::FilePath GetDownloadsFolderForProfile(Profile* profile) {
  // On non-ChromeOS system (test+development), the primary profile uses
  // $HOME/Downloads for ease for accessing local files for debugging.
  if (!base::SysInfo::IsRunningOnChromeOS() &&
      chromeos::UserManager::IsInitialized()) {
    const chromeos::User* const user =
        chromeos::UserManager::Get()->GetUserByProfile(
            profile->GetOriginalProfile());
    const chromeos::User* const primary_user =
        chromeos::UserManager::Get()->GetPrimaryUser();
    if (user == primary_user)
      return DownloadPrefs::GetDefaultDownloadDirectory();
  }
  return profile->GetPath().AppendASCII(kDownloadsFolderName);
}

bool MigratePathFromOldFormat(Profile* profile,
                              const base::FilePath& old_path,
                              base::FilePath* new_path) {
  // M34:
  // /home/chronos/user/Downloads/xxx => /home/chronos/u-hash/Downloads/xxx
  // /special/drive => /special/drive-xxx
  //
  // Old path format comes either from stored old settings or from the initial
  // default value set in DownloadPrefs::RegisterProfilePrefs in profile-unaware
  // code location. In the former case it is "/home/chronos/user/Downloads",
  // and in the latter case it is DownloadPrefs::GetDefaultDownloadDirectory().
  // Those two paths coincides as long as $HOME=/home/chronos/user, but the
  // environment variable is phasing out (crbug.com/333031) so we care both.

  const base::FilePath downloads = GetDownloadsFolderForProfile(profile);
  const base::FilePath drive = drive::util::GetDriveMountPointPath(profile);

  std::vector<std::pair<base::FilePath, base::FilePath> > bases;
  bases.push_back(std::make_pair(base::FilePath(kOldDownloadsFolderPath),
                                 downloads));
  bases.push_back(std::make_pair(DownloadPrefs::GetDefaultDownloadDirectory(),
                                 downloads));
  bases.push_back(std::make_pair(base::FilePath(kOldDriveFolderPath), drive));
  bases.push_back(std::make_pair(base::FilePath(kBuggyDriveFolderPath), drive));

  // Trying migrating u-<hash>/Downloads to the current download path. This is
  // no-op when multi-profile is enabled. This is necessary for (1) back
  // migration when multi-profile flag is enabled and then disabled, or (2) in
  // some edge cases (crbug.com/356322) that u-<hash> path is temporarily used.
  if (chromeos::UserManager::IsInitialized()) {
    const chromeos::User* const user =
        chromeos::UserManager::Get()->GetUserByProfile(profile);
    if (user) {
      const base::FilePath hashed_downloads =
          chromeos::ProfileHelper::GetProfilePathByUserIdHash(
              user->username_hash()).AppendASCII(kDownloadsFolderName);
      bases.push_back(std::make_pair(hashed_downloads, downloads));
    }
  }

  for (size_t i = 0; i < bases.size(); ++i) {
    const base::FilePath& old_base = bases[i].first;
    const base::FilePath& new_base = bases[i].second;
    base::FilePath relative;
    if (old_path == old_base ||
        old_base.AppendRelativePath(old_path, &relative)) {
      *new_path = new_base.Append(relative);
      return old_path != *new_path;
    }
  }

  return false;
}

std::string GetDownloadsMountPointName(Profile* profile) {
  // To distinguish profiles in multi-profile session, we append user name hash
  // to "Downloads". Note that some profiles (like login or test profiles)
  // are not associated with an user account. In that case, no suffix is added
  // because such a profile never belongs to a multi-profile session.
  chromeos::User* const user =
      chromeos::UserManager::IsInitialized() ?
          chromeos::UserManager::Get()->GetUserByProfile(
              profile->GetOriginalProfile()) : NULL;
  const std::string id = user ? "-" + user->username_hash() : "";
  return net::EscapePath(kDownloadsFolderName + id);
}

}  // namespace util
}  // namespace file_manager