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"
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
;
24 namespace file_system_provider
{
29 // Root mount path for all of the provided file systems.
30 const base::FilePath::CharType kProvidedMountPointRoot
[] =
31 FILE_PATH_LITERAL("/provided");
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
) {
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
);
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())
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)
71 if (components
[0] != FILE_PATH_LITERAL("/"))
74 if (components
[1] != kProvidedMountPointRoot
+ 1 /* no leading slash */)
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
)
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
)) {
105 Service
* const service
= Service::Get(original_profile
);
109 ProvidedFileSystemInterface
* const file_system
=
110 service
->GetProvidedFileSystem(url_
.filesystem_id());
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)
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
]);
131 // Nothing has been found.
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_
))
149 std::vector
<base::FilePath::StringType
> components
;
150 local_path_
.GetComponents(&components
);
152 if (components
.size() < 3)
155 const std::string mount_point_name
= components
[2];
157 Service
* const service
= Service::Get(profile_
);
161 ProvidedFileSystemInterface
* const file_system
=
162 service
->GetProvidedFileSystem(mount_point_name
);
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
]);
178 } // namespace file_system_provider
179 } // namespace chromeos