Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / chromeos / file_system_provider / mount_path_util.cc
blob22a1aa107e9dc106a50e6e9571ecbb1dd3ff60d8
1 // Copyright 2014 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_system_provider/mount_path_util.h"
7 #include <vector>
9 #include "base/stl_util.h"
10 #include "base/strings/stringprintf.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/chromeos/file_system_provider/provided_file_system.h"
13 #include "chrome/browser/chromeos/file_system_provider/service.h"
14 #include "chrome/browser/chromeos/profiles/profile_helper.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/profiles/profile_manager.h"
17 #include "components/user_manager/user.h"
18 #include "components/user_manager/user_manager.h"
19 #include "content/public/browser/browser_thread.h"
21 using content::BrowserThread;
23 namespace chromeos {
24 namespace file_system_provider {
25 namespace util {
27 namespace {
29 // Root mount path for all of the provided file systems.
30 const base::FilePath::CharType kProvidedMountPointRoot[] =
31 FILE_PATH_LITERAL("/provided");
33 } // namespace
35 // Escapes the file system id so it can be used as a file/directory name.
36 // This is based on net/base/escape.cc: net::(anonymous namespace)::Escape
37 std::string EscapeFileSystemId(const std::string& file_system_id) {
38 std::string escaped;
39 for (size_t i = 0; i < file_system_id.size(); ++i) {
40 const char c = file_system_id[i];
41 if (c == '%' || c == '.' || c == '/') {
42 base::StringAppendF(&escaped, "%%%02X", c);
43 } else {
44 escaped.push_back(c);
47 return escaped;
50 base::FilePath GetMountPath(Profile* profile,
51 const std::string& extension_id,
52 const std::string& file_system_id) {
53 const user_manager::User* const user =
54 user_manager::UserManager::IsInitialized()
55 ? chromeos::ProfileHelper::Get()->GetUserByProfile(
56 profile->GetOriginalProfile())
57 : NULL;
58 const std::string safe_file_system_id = EscapeFileSystemId(file_system_id);
59 const std::string username_suffix = user ? user->username_hash() : "";
60 return base::FilePath(kProvidedMountPointRoot).AppendASCII(
61 extension_id + ":" + safe_file_system_id + ":" + username_suffix);
64 bool IsFileSystemProviderLocalPath(const base::FilePath& local_path) {
65 std::vector<base::FilePath::StringType> components;
66 local_path.GetComponents(&components);
68 if (components.size() < 3)
69 return false;
71 if (components[0] != FILE_PATH_LITERAL("/"))
72 return false;
74 if (components[1] != kProvidedMountPointRoot + 1 /* no leading slash */)
75 return false;
77 return true;
80 FileSystemURLParser::FileSystemURLParser(const storage::FileSystemURL& url)
81 : url_(url), file_system_(NULL) {
84 FileSystemURLParser::~FileSystemURLParser() {
87 bool FileSystemURLParser::Parse() {
88 DCHECK_CURRENTLY_ON(BrowserThread::UI);
90 if (url_.type() != storage::kFileSystemTypeProvided)
91 return false;
93 // First, find the service handling the mount point of the URL.
94 const std::vector<Profile*>& profiles =
95 g_browser_process->profile_manager()->GetLoadedProfiles();
97 for (size_t i = 0; i < profiles.size(); ++i) {
98 Profile* original_profile = profiles[i]->GetOriginalProfile();
100 if (original_profile != profiles[i] ||
101 chromeos::ProfileHelper::IsSigninProfile(original_profile)) {
102 continue;
105 Service* const service = Service::Get(original_profile);
106 if (!service)
107 continue;
109 ProvidedFileSystemInterface* const file_system =
110 service->GetProvidedFileSystem(url_.filesystem_id());
111 if (!file_system)
112 continue;
114 // Strip the mount path name from the local path, to extract the file path
115 // within the provided file system.
116 file_system_ = file_system;
117 std::vector<base::FilePath::StringType> components;
118 url_.path().GetComponents(&components);
119 if (components.size() < 3)
120 return false;
122 file_path_ = base::FilePath(FILE_PATH_LITERAL("/"));
123 for (size_t i = 3; i < components.size(); ++i) {
124 // TODO(mtomasz): This could be optimized, to avoid unnecessary copies.
125 file_path_ = file_path_.Append(components[i]);
128 return true;
131 // Nothing has been found.
132 return false;
135 LocalPathParser::LocalPathParser(Profile* profile,
136 const base::FilePath& local_path)
137 : profile_(profile), local_path_(local_path), file_system_(NULL) {
140 LocalPathParser::~LocalPathParser() {
143 bool LocalPathParser::Parse() {
144 DCHECK_CURRENTLY_ON(BrowserThread::UI);
146 if (!IsFileSystemProviderLocalPath(local_path_))
147 return false;
149 std::vector<base::FilePath::StringType> components;
150 local_path_.GetComponents(&components);
152 if (components.size() < 3)
153 return false;
155 const std::string mount_point_name = components[2];
157 Service* const service = Service::Get(profile_);
158 if (!service)
159 return false;
161 ProvidedFileSystemInterface* const file_system =
162 service->GetProvidedFileSystem(mount_point_name);
163 if (!file_system)
164 return false;
166 // Strip the mount point path from the virtual path, to extract the file
167 // path within the provided file system.
168 file_system_ = file_system;
169 file_path_ = base::FilePath(FILE_PATH_LITERAL("/"));
170 for (size_t i = 3; i < components.size(); ++i) {
171 file_path_ = file_path_.Append(components[i]);
174 return true;
177 } // namespace util
178 } // namespace file_system_provider
179 } // namespace chromeos