When Retrier succeeds, record errors it encountered.
[chromium-blink-merge.git] / webkit / chromeos / fileapi / cros_mount_point_provider.cc
blobe415943f0e6462e4a3ed8f1448572fc29780cded
1 // Copyright (c) 2012 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 "webkit/chromeos/fileapi/cros_mount_point_provider.h"
7 #include "base/chromeos/chromeos_version.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop.h"
11 #include "base/stringprintf.h"
12 #include "base/synchronization/lock.h"
13 #include "base/utf_string_conversions.h"
14 #include "chromeos/dbus/cros_disks_client.h"
15 #include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h"
16 #include "third_party/WebKit/Source/Platform/chromium/public/WebFileSystem.h"
17 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
18 #include "webkit/browser/fileapi/copy_or_move_file_validator.h"
19 #include "webkit/chromeos/fileapi/file_access_permissions.h"
20 #include "webkit/chromeos/fileapi/remote_file_stream_writer.h"
21 #include "webkit/chromeos/fileapi/remote_file_system_operation.h"
22 #include "webkit/fileapi/async_file_util_adapter.h"
23 #include "webkit/fileapi/external_mount_points.h"
24 #include "webkit/fileapi/file_system_context.h"
25 #include "webkit/fileapi/file_system_file_stream_reader.h"
26 #include "webkit/fileapi/file_system_operation_context.h"
27 #include "webkit/fileapi/file_system_task_runners.h"
28 #include "webkit/fileapi/file_system_url.h"
29 #include "webkit/fileapi/file_system_util.h"
30 #include "webkit/fileapi/isolated_context.h"
31 #include "webkit/fileapi/isolated_file_util.h"
32 #include "webkit/fileapi/local_file_stream_writer.h"
33 #include "webkit/fileapi/local_file_system_operation.h"
34 #include "webkit/glue/webkit_glue.h"
36 namespace {
38 const char kChromeUIScheme[] = "chrome";
40 } // namespace
42 namespace chromeos {
44 // static
45 bool CrosMountPointProvider::CanHandleURL(const fileapi::FileSystemURL& url) {
46 if (!url.is_valid())
47 return false;
48 return url.type() == fileapi::kFileSystemTypeNativeLocal ||
49 url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal ||
50 url.type() == fileapi::kFileSystemTypeDrive;
53 CrosMountPointProvider::CrosMountPointProvider(
54 scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy,
55 scoped_refptr<fileapi::ExternalMountPoints> mount_points,
56 fileapi::ExternalMountPoints* system_mount_points)
57 : special_storage_policy_(special_storage_policy),
58 file_access_permissions_(new FileAccessPermissions()),
59 local_file_util_(new fileapi::AsyncFileUtilAdapter(
60 new fileapi::IsolatedFileUtil())),
61 mount_points_(mount_points),
62 system_mount_points_(system_mount_points) {
63 // Add default system mount points.
64 system_mount_points_->RegisterFileSystem(
65 "archive",
66 fileapi::kFileSystemTypeNativeLocal,
67 chromeos::CrosDisksClient::GetArchiveMountPoint());
68 system_mount_points_->RegisterFileSystem(
69 "removable",
70 fileapi::kFileSystemTypeNativeLocal,
71 chromeos::CrosDisksClient::GetRemovableDiskMountPoint());
72 system_mount_points_->RegisterFileSystem(
73 "oem",
74 fileapi::kFileSystemTypeRestrictedNativeLocal,
75 base::FilePath(FILE_PATH_LITERAL("/usr/share/oem")));
78 CrosMountPointProvider::~CrosMountPointProvider() {
81 bool CrosMountPointProvider::CanHandleType(fileapi::FileSystemType type) const {
82 switch (type) {
83 case fileapi::kFileSystemTypeExternal:
84 case fileapi::kFileSystemTypeDrive:
85 case fileapi::kFileSystemTypeRestrictedNativeLocal:
86 case fileapi::kFileSystemTypeNativeLocal:
87 case fileapi::kFileSystemTypeNativeForPlatformApp:
88 return true;
89 default:
90 return false;
94 void CrosMountPointProvider::ValidateFileSystemRoot(
95 const GURL& origin_url,
96 fileapi::FileSystemType type,
97 bool create,
98 const ValidateFileSystemCallback& callback) {
99 DCHECK(fileapi::IsolatedContext::IsIsolatedType(type));
100 // Nothing to validate for external filesystem.
101 callback.Run(base::PLATFORM_FILE_OK);
104 base::FilePath CrosMountPointProvider::GetFileSystemRootPathOnFileThread(
105 const fileapi::FileSystemURL& url,
106 bool create) {
107 DCHECK(fileapi::IsolatedContext::IsIsolatedType(url.mount_type()));
108 if (!url.is_valid())
109 return base::FilePath();
111 base::FilePath root_path;
112 std::string mount_name = url.filesystem_id();
113 if (!mount_points_->GetRegisteredPath(mount_name, &root_path) &&
114 !system_mount_points_->GetRegisteredPath(mount_name, &root_path)) {
115 return base::FilePath();
118 return root_path.DirName();
121 fileapi::FileSystemQuotaUtil* CrosMountPointProvider::GetQuotaUtil() {
122 // No quota support.
123 return NULL;
126 void CrosMountPointProvider::DeleteFileSystem(
127 const GURL& origin_url,
128 fileapi::FileSystemType type,
129 fileapi::FileSystemContext* context,
130 const DeleteFileSystemCallback& callback) {
131 NOTREACHED();
132 callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
135 bool CrosMountPointProvider::IsAccessAllowed(
136 const fileapi::FileSystemURL& url) const {
137 if (!url.is_valid())
138 return false;
140 // Permit access to mount points from internal WebUI.
141 const GURL& origin_url = url.origin();
142 if (origin_url.SchemeIs(kChromeUIScheme))
143 return true;
145 // No extra check is needed for isolated file systems.
146 if (url.mount_type() == fileapi::kFileSystemTypeIsolated)
147 return true;
149 if (!CanHandleURL(url))
150 return false;
152 std::string extension_id = origin_url.host();
153 // Check first to make sure this extension has fileBrowserHander permissions.
154 if (!special_storage_policy_->IsFileHandler(extension_id))
155 return false;
157 return file_access_permissions_->HasAccessPermission(extension_id,
158 url.virtual_path());
161 void CrosMountPointProvider::GrantFullAccessToExtension(
162 const std::string& extension_id) {
163 DCHECK(special_storage_policy_->IsFileHandler(extension_id));
164 if (!special_storage_policy_->IsFileHandler(extension_id))
165 return;
167 std::vector<fileapi::MountPoints::MountPointInfo> files;
168 mount_points_->AddMountPointInfosTo(&files);
169 system_mount_points_->AddMountPointInfosTo(&files);
171 for (size_t i = 0; i < files.size(); ++i) {
172 file_access_permissions_->GrantAccessPermission(
173 extension_id,
174 base::FilePath::FromUTF8Unsafe(files[i].name));
178 void CrosMountPointProvider::GrantFileAccessToExtension(
179 const std::string& extension_id, const base::FilePath& virtual_path) {
180 // All we care about here is access from extensions for now.
181 DCHECK(special_storage_policy_->IsFileHandler(extension_id));
182 if (!special_storage_policy_->IsFileHandler(extension_id))
183 return;
185 std::string id;
186 fileapi::FileSystemType type;
187 base::FilePath path;
188 if (!mount_points_->CrackVirtualPath(virtual_path, &id, &type, &path) &&
189 !system_mount_points_->CrackVirtualPath(virtual_path,
190 &id, &type, &path)) {
191 return;
194 if (type == fileapi::kFileSystemTypeRestrictedNativeLocal) {
195 LOG(ERROR) << "Can't grant access for restricted mount point";
196 return;
199 file_access_permissions_->GrantAccessPermission(extension_id, virtual_path);
202 void CrosMountPointProvider::RevokeAccessForExtension(
203 const std::string& extension_id) {
204 file_access_permissions_->RevokePermissions(extension_id);
207 std::vector<base::FilePath> CrosMountPointProvider::GetRootDirectories() const {
208 std::vector<fileapi::MountPoints::MountPointInfo> mount_points;
209 mount_points_->AddMountPointInfosTo(&mount_points);
210 system_mount_points_->AddMountPointInfosTo(&mount_points);
212 std::vector<base::FilePath> root_dirs;
213 for (size_t i = 0; i < mount_points.size(); ++i)
214 root_dirs.push_back(mount_points[i].path);
215 return root_dirs;
218 fileapi::FileSystemFileUtil* CrosMountPointProvider::GetFileUtil(
219 fileapi::FileSystemType type) {
220 DCHECK(type == fileapi::kFileSystemTypeNativeLocal ||
221 type == fileapi::kFileSystemTypeRestrictedNativeLocal);
222 return local_file_util_->sync_file_util();
225 fileapi::AsyncFileUtil* CrosMountPointProvider::GetAsyncFileUtil(
226 fileapi::FileSystemType type) {
227 DCHECK(type == fileapi::kFileSystemTypeNativeLocal ||
228 type == fileapi::kFileSystemTypeRestrictedNativeLocal);
229 return local_file_util_.get();
232 fileapi::CopyOrMoveFileValidatorFactory*
233 CrosMountPointProvider::GetCopyOrMoveFileValidatorFactory(
234 fileapi::FileSystemType type, base::PlatformFileError* error_code) {
235 DCHECK(error_code);
236 *error_code = base::PLATFORM_FILE_OK;
237 return NULL;
240 void CrosMountPointProvider::InitializeCopyOrMoveFileValidatorFactory(
241 fileapi::FileSystemType type,
242 scoped_ptr<fileapi::CopyOrMoveFileValidatorFactory> factory) {
243 DCHECK(!factory);
246 fileapi::FilePermissionPolicy CrosMountPointProvider::GetPermissionPolicy(
247 const fileapi::FileSystemURL& url, int permissions) const {
248 if (url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal &&
249 (permissions & ~fileapi::kReadFilePermissions)) {
250 // Restricted file system is read-only.
251 return fileapi::FILE_PERMISSION_ALWAYS_DENY;
254 if (!IsAccessAllowed(url))
255 return fileapi::FILE_PERMISSION_ALWAYS_DENY;
257 // Permit access to mount points from internal WebUI.
258 const GURL& origin_url = url.origin();
259 if (origin_url.SchemeIs(kChromeUIScheme))
260 return fileapi::FILE_PERMISSION_ALWAYS_ALLOW;
262 if (url.mount_type() == fileapi::kFileSystemTypeIsolated) {
263 // Permissions in isolated filesystems should be examined with
264 // FileSystem permission.
265 return fileapi::FILE_PERMISSION_USE_FILESYSTEM_PERMISSION;
268 // Also apply system's file permission by default.
269 return fileapi::FILE_PERMISSION_USE_FILE_PERMISSION;
272 fileapi::FileSystemOperation* CrosMountPointProvider::CreateFileSystemOperation(
273 const fileapi::FileSystemURL& url,
274 fileapi::FileSystemContext* context,
275 base::PlatformFileError* error_code) const {
276 DCHECK(url.is_valid());
278 if (url.type() == fileapi::kFileSystemTypeDrive) {
279 fileapi::RemoteFileSystemProxyInterface* remote_proxy =
280 GetRemoteProxy(url.filesystem_id());
281 if (!remote_proxy) {
282 *error_code = base::PLATFORM_FILE_ERROR_NOT_FOUND;
283 return NULL;
285 return new chromeos::RemoteFileSystemOperation(remote_proxy);
288 DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal ||
289 url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal);
290 scoped_ptr<fileapi::FileSystemOperationContext> operation_context(
291 new fileapi::FileSystemOperationContext(context));
292 return new fileapi::LocalFileSystemOperation(context,
293 operation_context.Pass());
296 scoped_ptr<webkit_blob::FileStreamReader>
297 CrosMountPointProvider::CreateFileStreamReader(
298 const fileapi::FileSystemURL& url,
299 int64 offset,
300 const base::Time& expected_modification_time,
301 fileapi::FileSystemContext* context) const {
302 DCHECK(url.is_valid());
304 if (url.type() == fileapi::kFileSystemTypeDrive) {
305 fileapi::RemoteFileSystemProxyInterface* remote_proxy =
306 GetRemoteProxy(url.filesystem_id());
307 if (!remote_proxy)
308 return scoped_ptr<webkit_blob::FileStreamReader>();
309 return remote_proxy->CreateFileStreamReader(
310 context->task_runners()->file_task_runner(),
311 url, offset, expected_modification_time);
314 return scoped_ptr<webkit_blob::FileStreamReader>(
315 new fileapi::FileSystemFileStreamReader(
316 context, url, offset, expected_modification_time));
319 scoped_ptr<fileapi::FileStreamWriter>
320 CrosMountPointProvider::CreateFileStreamWriter(
321 const fileapi::FileSystemURL& url,
322 int64 offset,
323 fileapi::FileSystemContext* context) const {
324 DCHECK(url.is_valid());
326 if (url.type() == fileapi::kFileSystemTypeDrive) {
327 fileapi::RemoteFileSystemProxyInterface* remote_proxy =
328 GetRemoteProxy(url.filesystem_id());
329 if (!remote_proxy)
330 return scoped_ptr<fileapi::FileStreamWriter>();
331 return scoped_ptr<fileapi::FileStreamWriter>(
332 new fileapi::RemoteFileStreamWriter(remote_proxy, url, offset));
335 if (url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal)
336 return scoped_ptr<fileapi::FileStreamWriter>();
338 DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal);
339 return scoped_ptr<fileapi::FileStreamWriter>(
340 new fileapi::LocalFileStreamWriter(url.path(), offset));
343 bool CrosMountPointProvider::GetVirtualPath(
344 const base::FilePath& filesystem_path,
345 base::FilePath* virtual_path) {
346 return mount_points_->GetVirtualPath(filesystem_path, virtual_path) ||
347 system_mount_points_->GetVirtualPath(filesystem_path, virtual_path);
350 fileapi::RemoteFileSystemProxyInterface* CrosMountPointProvider::GetRemoteProxy(
351 const std::string& mount_name) const {
352 fileapi::RemoteFileSystemProxyInterface* proxy =
353 mount_points_->GetRemoteFileSystemProxy(mount_name);
354 if (proxy)
355 return proxy;
356 return system_mount_points_->GetRemoteFileSystemProxy(mount_name);
359 } // namespace chromeos