Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / webkit / chromeos / fileapi / cros_mount_point_provider.cc
blob11cf6f778b76a6bc035035db8d0f13bb254dd68a
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 "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.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/copy_or_move_file_validator.h"
24 #include "webkit/fileapi/external_mount_points.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_url.h"
28 #include "webkit/fileapi/file_system_util.h"
29 #include "webkit/fileapi/isolated_context.h"
30 #include "webkit/fileapi/isolated_file_util.h"
31 #include "webkit/fileapi/local_file_stream_writer.h"
32 #include "webkit/fileapi/local_file_system_operation.h"
33 #include "webkit/glue/webkit_glue.h"
35 namespace {
37 const char kChromeUIScheme[] = "chrome";
39 } // namespace
41 namespace chromeos {
43 // static
44 bool CrosMountPointProvider::CanHandleURL(const fileapi::FileSystemURL& url) {
45 if (!url.is_valid())
46 return false;
47 return url.type() == fileapi::kFileSystemTypeNativeLocal ||
48 url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal ||
49 url.type() == fileapi::kFileSystemTypeDrive;
52 CrosMountPointProvider::CrosMountPointProvider(
53 scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy,
54 scoped_refptr<fileapi::ExternalMountPoints> mount_points,
55 fileapi::ExternalMountPoints* system_mount_points)
56 : special_storage_policy_(special_storage_policy),
57 file_access_permissions_(new FileAccessPermissions()),
58 local_file_util_(new fileapi::AsyncFileUtilAdapter(
59 new fileapi::IsolatedFileUtil())),
60 mount_points_(mount_points),
61 system_mount_points_(system_mount_points) {
62 // Add default system mount points.
63 system_mount_points_->RegisterFileSystem(
64 "archive",
65 fileapi::kFileSystemTypeNativeLocal,
66 chromeos::CrosDisksClient::GetArchiveMountPoint());
67 system_mount_points_->RegisterFileSystem(
68 "removable",
69 fileapi::kFileSystemTypeNativeLocal,
70 chromeos::CrosDisksClient::GetRemovableDiskMountPoint());
71 system_mount_points_->RegisterFileSystem(
72 "oem",
73 fileapi::kFileSystemTypeRestrictedNativeLocal,
74 base::FilePath(FILE_PATH_LITERAL("/usr/share/oem")));
77 CrosMountPointProvider::~CrosMountPointProvider() {
80 void CrosMountPointProvider::ValidateFileSystemRoot(
81 const GURL& origin_url,
82 fileapi::FileSystemType type,
83 bool create,
84 const ValidateFileSystemCallback& callback) {
85 DCHECK(fileapi::IsolatedContext::IsIsolatedType(type));
86 // Nothing to validate for external filesystem.
87 callback.Run(base::PLATFORM_FILE_OK);
90 base::FilePath CrosMountPointProvider::GetFileSystemRootPathOnFileThread(
91 const fileapi::FileSystemURL& url,
92 bool create) {
93 DCHECK(fileapi::IsolatedContext::IsIsolatedType(url.mount_type()));
94 if (!url.is_valid())
95 return base::FilePath();
97 base::FilePath root_path;
98 std::string mount_name = url.filesystem_id();
99 if (!mount_points_->GetRegisteredPath(mount_name, &root_path) &&
100 !system_mount_points_->GetRegisteredPath(mount_name, &root_path)) {
101 return base::FilePath();
104 return root_path.DirName();
107 fileapi::FileSystemQuotaUtil* CrosMountPointProvider::GetQuotaUtil() {
108 // No quota support.
109 return NULL;
112 void CrosMountPointProvider::DeleteFileSystem(
113 const GURL& origin_url,
114 fileapi::FileSystemType type,
115 fileapi::FileSystemContext* context,
116 const DeleteFileSystemCallback& callback) {
117 NOTREACHED();
118 callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
121 bool CrosMountPointProvider::IsAccessAllowed(
122 const fileapi::FileSystemURL& url) const {
123 if (!url.is_valid())
124 return false;
126 // Permit access to mount points from internal WebUI.
127 const GURL& origin_url = url.origin();
128 if (origin_url.SchemeIs(kChromeUIScheme))
129 return true;
131 // No extra check is needed for isolated file systems.
132 if (url.mount_type() == fileapi::kFileSystemTypeIsolated)
133 return true;
135 if (!CanHandleURL(url))
136 return false;
138 std::string extension_id = origin_url.host();
139 // Check first to make sure this extension has fileBrowserHander permissions.
140 if (!special_storage_policy_->IsFileHandler(extension_id))
141 return false;
143 return file_access_permissions_->HasAccessPermission(extension_id,
144 url.virtual_path());
147 void CrosMountPointProvider::GrantFullAccessToExtension(
148 const std::string& extension_id) {
149 DCHECK(special_storage_policy_->IsFileHandler(extension_id));
150 if (!special_storage_policy_->IsFileHandler(extension_id))
151 return;
153 std::vector<fileapi::MountPoints::MountPointInfo> files;
154 mount_points_->AddMountPointInfosTo(&files);
155 system_mount_points_->AddMountPointInfosTo(&files);
157 for (size_t i = 0; i < files.size(); ++i) {
158 file_access_permissions_->GrantAccessPermission(
159 extension_id,
160 base::FilePath::FromUTF8Unsafe(files[i].name));
164 void CrosMountPointProvider::GrantFileAccessToExtension(
165 const std::string& extension_id, const base::FilePath& virtual_path) {
166 // All we care about here is access from extensions for now.
167 DCHECK(special_storage_policy_->IsFileHandler(extension_id));
168 if (!special_storage_policy_->IsFileHandler(extension_id))
169 return;
171 std::string id;
172 fileapi::FileSystemType type;
173 base::FilePath path;
174 if (!mount_points_->CrackVirtualPath(virtual_path, &id, &type, &path) &&
175 !system_mount_points_->CrackVirtualPath(virtual_path,
176 &id, &type, &path)) {
177 return;
180 if (type == fileapi::kFileSystemTypeRestrictedNativeLocal) {
181 LOG(ERROR) << "Can't grant access for restricted mount point";
182 return;
185 file_access_permissions_->GrantAccessPermission(extension_id, virtual_path);
188 void CrosMountPointProvider::RevokeAccessForExtension(
189 const std::string& extension_id) {
190 file_access_permissions_->RevokePermissions(extension_id);
193 std::vector<base::FilePath> CrosMountPointProvider::GetRootDirectories() const {
194 std::vector<fileapi::MountPoints::MountPointInfo> mount_points;
195 mount_points_->AddMountPointInfosTo(&mount_points);
196 system_mount_points_->AddMountPointInfosTo(&mount_points);
198 std::vector<base::FilePath> root_dirs;
199 for (size_t i = 0; i < mount_points.size(); ++i)
200 root_dirs.push_back(mount_points[i].path);
201 return root_dirs;
204 fileapi::FileSystemFileUtil* CrosMountPointProvider::GetFileUtil(
205 fileapi::FileSystemType type) {
206 DCHECK(type == fileapi::kFileSystemTypeNativeLocal ||
207 type == fileapi::kFileSystemTypeRestrictedNativeLocal);
208 return local_file_util_->sync_file_util();
211 fileapi::AsyncFileUtil* CrosMountPointProvider::GetAsyncFileUtil(
212 fileapi::FileSystemType type) {
213 DCHECK(type == fileapi::kFileSystemTypeNativeLocal ||
214 type == fileapi::kFileSystemTypeRestrictedNativeLocal);
215 return local_file_util_.get();
218 fileapi::CopyOrMoveFileValidatorFactory*
219 CrosMountPointProvider::GetCopyOrMoveFileValidatorFactory(
220 fileapi::FileSystemType type, base::PlatformFileError* error_code) {
221 DCHECK(error_code);
222 *error_code = base::PLATFORM_FILE_OK;
223 return NULL;
226 void CrosMountPointProvider::InitializeCopyOrMoveFileValidatorFactory(
227 fileapi::FileSystemType type,
228 scoped_ptr<fileapi::CopyOrMoveFileValidatorFactory> factory) {
229 DCHECK(!factory);
232 fileapi::FilePermissionPolicy CrosMountPointProvider::GetPermissionPolicy(
233 const fileapi::FileSystemURL& url, int permissions) const {
234 if (url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal &&
235 (permissions & ~fileapi::kReadFilePermissions)) {
236 // Restricted file system is read-only.
237 return fileapi::FILE_PERMISSION_ALWAYS_DENY;
240 if (!IsAccessAllowed(url))
241 return fileapi::FILE_PERMISSION_ALWAYS_DENY;
243 // Permit access to mount points from internal WebUI.
244 const GURL& origin_url = url.origin();
245 if (origin_url.SchemeIs(kChromeUIScheme))
246 return fileapi::FILE_PERMISSION_ALWAYS_ALLOW;
248 if (url.mount_type() == fileapi::kFileSystemTypeIsolated) {
249 // Permissions in isolated filesystems should be examined with
250 // FileSystem permission.
251 return fileapi::FILE_PERMISSION_USE_FILESYSTEM_PERMISSION;
254 // Also apply system's file permission by default.
255 return fileapi::FILE_PERMISSION_USE_FILE_PERMISSION;
258 fileapi::FileSystemOperation* CrosMountPointProvider::CreateFileSystemOperation(
259 const fileapi::FileSystemURL& url,
260 fileapi::FileSystemContext* context,
261 base::PlatformFileError* error_code) const {
262 DCHECK(url.is_valid());
264 if (url.type() == fileapi::kFileSystemTypeDrive) {
265 fileapi::RemoteFileSystemProxyInterface* remote_proxy =
266 GetRemoteProxy(url.filesystem_id());
267 if (!remote_proxy) {
268 *error_code = base::PLATFORM_FILE_ERROR_NOT_FOUND;
269 return NULL;
271 return new chromeos::RemoteFileSystemOperation(remote_proxy);
274 DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal ||
275 url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal);
276 scoped_ptr<fileapi::FileSystemOperationContext> operation_context(
277 new fileapi::FileSystemOperationContext(context));
278 return new fileapi::LocalFileSystemOperation(context,
279 operation_context.Pass());
282 scoped_ptr<webkit_blob::FileStreamReader>
283 CrosMountPointProvider::CreateFileStreamReader(
284 const fileapi::FileSystemURL& url,
285 int64 offset,
286 const base::Time& expected_modification_time,
287 fileapi::FileSystemContext* context) const {
288 // For now we return a generic Reader implementation which utilizes
289 // CreateSnapshotFile internally (i.e. will download everything first).
290 // TODO(satorux,zel): implement more efficient reader for remote cases.
291 return scoped_ptr<webkit_blob::FileStreamReader>(
292 new fileapi::FileSystemFileStreamReader(
293 context, url, offset, expected_modification_time));
296 scoped_ptr<fileapi::FileStreamWriter>
297 CrosMountPointProvider::CreateFileStreamWriter(
298 const fileapi::FileSystemURL& url,
299 int64 offset,
300 fileapi::FileSystemContext* context) const {
301 DCHECK(url.is_valid());
303 if (url.type() == fileapi::kFileSystemTypeDrive) {
304 fileapi::RemoteFileSystemProxyInterface* remote_proxy =
305 GetRemoteProxy(url.filesystem_id());
306 if (!remote_proxy)
307 return scoped_ptr<fileapi::FileStreamWriter>();
308 return scoped_ptr<fileapi::FileStreamWriter>(
309 new fileapi::RemoteFileStreamWriter(remote_proxy, url, offset));
312 if (url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal)
313 return scoped_ptr<fileapi::FileStreamWriter>();
315 DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal);
316 return scoped_ptr<fileapi::FileStreamWriter>(
317 new fileapi::LocalFileStreamWriter(url.path(), offset));
320 bool CrosMountPointProvider::GetVirtualPath(
321 const base::FilePath& filesystem_path,
322 base::FilePath* virtual_path) {
323 return mount_points_->GetVirtualPath(filesystem_path, virtual_path) ||
324 system_mount_points_->GetVirtualPath(filesystem_path, virtual_path);
327 fileapi::RemoteFileSystemProxyInterface* CrosMountPointProvider::GetRemoteProxy(
328 const std::string& mount_name) const {
329 fileapi::RemoteFileSystemProxyInterface* proxy =
330 mount_points_->GetRemoteFileSystemProxy(mount_name);
331 if (proxy)
332 return proxy;
333 return system_mount_points_->GetRemoteFileSystemProxy(mount_name);
336 } // namespace chromeos