Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Side by Side Diff: webkit/browser/fileapi/file_system_context.cc

Issue 442383002: Move storage-related files from webkit/ to new top-level directory storage/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "webkit/browser/fileapi/file_system_context.h"
6
7 #include "base/bind.h"
8 #include "base/single_thread_task_runner.h"
9 #include "base/stl_util.h"
10 #include "base/task_runner_util.h"
11 #include "net/url_request/url_request.h"
12 #include "url/gurl.h"
13 #include "webkit/browser/blob/file_stream_reader.h"
14 #include "webkit/browser/fileapi/copy_or_move_file_validator.h"
15 #include "webkit/browser/fileapi/external_mount_points.h"
16 #include "webkit/browser/fileapi/file_permission_policy.h"
17 #include "webkit/browser/fileapi/file_stream_writer.h"
18 #include "webkit/browser/fileapi/file_system_file_util.h"
19 #include "webkit/browser/fileapi/file_system_operation.h"
20 #include "webkit/browser/fileapi/file_system_operation_runner.h"
21 #include "webkit/browser/fileapi/file_system_options.h"
22 #include "webkit/browser/fileapi/file_system_quota_client.h"
23 #include "webkit/browser/fileapi/file_system_url.h"
24 #include "webkit/browser/fileapi/isolated_context.h"
25 #include "webkit/browser/fileapi/isolated_file_system_backend.h"
26 #include "webkit/browser/fileapi/mount_points.h"
27 #include "webkit/browser/fileapi/quota/quota_reservation.h"
28 #include "webkit/browser/fileapi/sandbox_file_system_backend.h"
29 #include "webkit/browser/quota/quota_manager_proxy.h"
30 #include "webkit/browser/quota/special_storage_policy.h"
31 #include "webkit/common/fileapi/file_system_info.h"
32 #include "webkit/common/fileapi/file_system_util.h"
33
34 using quota::QuotaClient;
35
36 namespace fileapi {
37
38 namespace {
39
40 QuotaClient* CreateQuotaClient(
41 FileSystemContext* context,
42 bool is_incognito) {
43 return new FileSystemQuotaClient(context, is_incognito);
44 }
45
46
47 void DidGetMetadataForResolveURL(
48 const base::FilePath& path,
49 const FileSystemContext::ResolveURLCallback& callback,
50 const FileSystemInfo& info,
51 base::File::Error error,
52 const base::File::Info& file_info) {
53 if (error != base::File::FILE_OK) {
54 if (error == base::File::FILE_ERROR_NOT_FOUND) {
55 callback.Run(base::File::FILE_OK, info, path,
56 FileSystemContext::RESOLVED_ENTRY_NOT_FOUND);
57 } else {
58 callback.Run(error, FileSystemInfo(), base::FilePath(),
59 FileSystemContext::RESOLVED_ENTRY_NOT_FOUND);
60 }
61 return;
62 }
63 callback.Run(error, info, path, file_info.is_directory ?
64 FileSystemContext::RESOLVED_ENTRY_DIRECTORY :
65 FileSystemContext::RESOLVED_ENTRY_FILE);
66 }
67
68 void RelayResolveURLCallback(
69 scoped_refptr<base::MessageLoopProxy> message_loop,
70 const FileSystemContext::ResolveURLCallback& callback,
71 base::File::Error result,
72 const FileSystemInfo& info,
73 const base::FilePath& file_path,
74 FileSystemContext::ResolvedEntryType type) {
75 message_loop->PostTask(
76 FROM_HERE, base::Bind(callback, result, info, file_path, type));
77 }
78
79 } // namespace
80
81 // static
82 int FileSystemContext::GetPermissionPolicy(FileSystemType type) {
83 switch (type) {
84 case kFileSystemTypeTemporary:
85 case kFileSystemTypePersistent:
86 case kFileSystemTypeSyncable:
87 return FILE_PERMISSION_SANDBOX;
88
89 case kFileSystemTypeDrive:
90 case kFileSystemTypeNativeForPlatformApp:
91 case kFileSystemTypeNativeLocal:
92 case kFileSystemTypeCloudDevice:
93 case kFileSystemTypeProvided:
94 case kFileSystemTypeDeviceMediaAsFileStorage:
95 return FILE_PERMISSION_USE_FILE_PERMISSION;
96
97 case kFileSystemTypeRestrictedNativeLocal:
98 return FILE_PERMISSION_READ_ONLY |
99 FILE_PERMISSION_USE_FILE_PERMISSION;
100
101 case kFileSystemTypeDeviceMedia:
102 case kFileSystemTypeIphoto:
103 case kFileSystemTypeItunes:
104 case kFileSystemTypeNativeMedia:
105 case kFileSystemTypePicasa:
106 return FILE_PERMISSION_USE_FILE_PERMISSION;
107
108 // Following types are only accessed via IsolatedFileSystem, and
109 // don't have their own permission policies.
110 case kFileSystemTypeDragged:
111 case kFileSystemTypeForTransientFile:
112 case kFileSystemTypePluginPrivate:
113 return FILE_PERMISSION_ALWAYS_DENY;
114
115 // Following types only appear as mount_type, and will not be
116 // queried for their permission policies.
117 case kFileSystemTypeIsolated:
118 case kFileSystemTypeExternal:
119 return FILE_PERMISSION_ALWAYS_DENY;
120
121 // Following types should not be used to access files by FileAPI clients.
122 case kFileSystemTypeTest:
123 case kFileSystemTypeSyncableForInternalSync:
124 case kFileSystemInternalTypeEnumEnd:
125 case kFileSystemInternalTypeEnumStart:
126 case kFileSystemTypeUnknown:
127 return FILE_PERMISSION_ALWAYS_DENY;
128 }
129 NOTREACHED();
130 return FILE_PERMISSION_ALWAYS_DENY;
131 }
132
133 FileSystemContext::FileSystemContext(
134 base::SingleThreadTaskRunner* io_task_runner,
135 base::SequencedTaskRunner* file_task_runner,
136 ExternalMountPoints* external_mount_points,
137 quota::SpecialStoragePolicy* special_storage_policy,
138 quota::QuotaManagerProxy* quota_manager_proxy,
139 ScopedVector<FileSystemBackend> additional_backends,
140 const std::vector<URLRequestAutoMountHandler>& auto_mount_handlers,
141 const base::FilePath& partition_path,
142 const FileSystemOptions& options)
143 : io_task_runner_(io_task_runner),
144 default_file_task_runner_(file_task_runner),
145 quota_manager_proxy_(quota_manager_proxy),
146 sandbox_delegate_(new SandboxFileSystemBackendDelegate(
147 quota_manager_proxy,
148 file_task_runner,
149 partition_path,
150 special_storage_policy,
151 options)),
152 sandbox_backend_(new SandboxFileSystemBackend(
153 sandbox_delegate_.get())),
154 isolated_backend_(new IsolatedFileSystemBackend()),
155 plugin_private_backend_(new PluginPrivateFileSystemBackend(
156 file_task_runner,
157 partition_path,
158 special_storage_policy,
159 options)),
160 additional_backends_(additional_backends.Pass()),
161 auto_mount_handlers_(auto_mount_handlers),
162 external_mount_points_(external_mount_points),
163 partition_path_(partition_path),
164 is_incognito_(options.is_incognito()),
165 operation_runner_(new FileSystemOperationRunner(this)) {
166 RegisterBackend(sandbox_backend_.get());
167 RegisterBackend(isolated_backend_.get());
168 RegisterBackend(plugin_private_backend_.get());
169
170 for (ScopedVector<FileSystemBackend>::const_iterator iter =
171 additional_backends_.begin();
172 iter != additional_backends_.end(); ++iter) {
173 RegisterBackend(*iter);
174 }
175
176 if (quota_manager_proxy) {
177 // Quota client assumes all backends have registered.
178 quota_manager_proxy->RegisterClient(CreateQuotaClient(
179 this, options.is_incognito()));
180 }
181
182 sandbox_backend_->Initialize(this);
183 isolated_backend_->Initialize(this);
184 plugin_private_backend_->Initialize(this);
185 for (ScopedVector<FileSystemBackend>::const_iterator iter =
186 additional_backends_.begin();
187 iter != additional_backends_.end(); ++iter) {
188 (*iter)->Initialize(this);
189 }
190
191 // Additional mount points must be added before regular system-wide
192 // mount points.
193 if (external_mount_points)
194 url_crackers_.push_back(external_mount_points);
195 url_crackers_.push_back(ExternalMountPoints::GetSystemInstance());
196 url_crackers_.push_back(IsolatedContext::GetInstance());
197 }
198
199 bool FileSystemContext::DeleteDataForOriginOnFileTaskRunner(
200 const GURL& origin_url) {
201 DCHECK(default_file_task_runner()->RunsTasksOnCurrentThread());
202 DCHECK(origin_url == origin_url.GetOrigin());
203
204 bool success = true;
205 for (FileSystemBackendMap::iterator iter = backend_map_.begin();
206 iter != backend_map_.end();
207 ++iter) {
208 FileSystemBackend* backend = iter->second;
209 if (!backend->GetQuotaUtil())
210 continue;
211 if (backend->GetQuotaUtil()->DeleteOriginDataOnFileTaskRunner(
212 this, quota_manager_proxy(), origin_url, iter->first)
213 != base::File::FILE_OK) {
214 // Continue the loop, but record the failure.
215 success = false;
216 }
217 }
218
219 return success;
220 }
221
222 scoped_refptr<QuotaReservation>
223 FileSystemContext::CreateQuotaReservationOnFileTaskRunner(
224 const GURL& origin_url,
225 FileSystemType type) {
226 DCHECK(default_file_task_runner()->RunsTasksOnCurrentThread());
227 FileSystemBackend* backend = GetFileSystemBackend(type);
228 if (!backend || !backend->GetQuotaUtil())
229 return scoped_refptr<QuotaReservation>();
230 return backend->GetQuotaUtil()->CreateQuotaReservationOnFileTaskRunner(
231 origin_url, type);
232 }
233
234 void FileSystemContext::Shutdown() {
235 if (!io_task_runner_->RunsTasksOnCurrentThread()) {
236 io_task_runner_->PostTask(
237 FROM_HERE, base::Bind(&FileSystemContext::Shutdown,
238 make_scoped_refptr(this)));
239 return;
240 }
241 operation_runner_->Shutdown();
242 }
243
244 FileSystemQuotaUtil*
245 FileSystemContext::GetQuotaUtil(FileSystemType type) const {
246 FileSystemBackend* backend = GetFileSystemBackend(type);
247 if (!backend)
248 return NULL;
249 return backend->GetQuotaUtil();
250 }
251
252 AsyncFileUtil* FileSystemContext::GetAsyncFileUtil(
253 FileSystemType type) const {
254 FileSystemBackend* backend = GetFileSystemBackend(type);
255 if (!backend)
256 return NULL;
257 return backend->GetAsyncFileUtil(type);
258 }
259
260 CopyOrMoveFileValidatorFactory*
261 FileSystemContext::GetCopyOrMoveFileValidatorFactory(
262 FileSystemType type, base::File::Error* error_code) const {
263 DCHECK(error_code);
264 *error_code = base::File::FILE_OK;
265 FileSystemBackend* backend = GetFileSystemBackend(type);
266 if (!backend)
267 return NULL;
268 return backend->GetCopyOrMoveFileValidatorFactory(
269 type, error_code);
270 }
271
272 FileSystemBackend* FileSystemContext::GetFileSystemBackend(
273 FileSystemType type) const {
274 FileSystemBackendMap::const_iterator found = backend_map_.find(type);
275 if (found != backend_map_.end())
276 return found->second;
277 NOTREACHED() << "Unknown filesystem type: " << type;
278 return NULL;
279 }
280
281 bool FileSystemContext::IsSandboxFileSystem(FileSystemType type) const {
282 FileSystemBackendMap::const_iterator found = backend_map_.find(type);
283 return found != backend_map_.end() && found->second->GetQuotaUtil();
284 }
285
286 const UpdateObserverList* FileSystemContext::GetUpdateObservers(
287 FileSystemType type) const {
288 FileSystemBackend* backend = GetFileSystemBackend(type);
289 if (backend->GetQuotaUtil())
290 return backend->GetQuotaUtil()->GetUpdateObservers(type);
291 return NULL;
292 }
293
294 const AccessObserverList* FileSystemContext::GetAccessObservers(
295 FileSystemType type) const {
296 FileSystemBackend* backend = GetFileSystemBackend(type);
297 if (backend->GetQuotaUtil())
298 return backend->GetQuotaUtil()->GetAccessObservers(type);
299 return NULL;
300 }
301
302 void FileSystemContext::GetFileSystemTypes(
303 std::vector<FileSystemType>* types) const {
304 types->clear();
305 for (FileSystemBackendMap::const_iterator iter = backend_map_.begin();
306 iter != backend_map_.end(); ++iter)
307 types->push_back(iter->first);
308 }
309
310 ExternalFileSystemBackend*
311 FileSystemContext::external_backend() const {
312 return static_cast<ExternalFileSystemBackend*>(
313 GetFileSystemBackend(kFileSystemTypeExternal));
314 }
315
316 void FileSystemContext::OpenFileSystem(
317 const GURL& origin_url,
318 FileSystemType type,
319 OpenFileSystemMode mode,
320 const OpenFileSystemCallback& callback) {
321 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
322 DCHECK(!callback.is_null());
323
324 if (!FileSystemContext::IsSandboxFileSystem(type)) {
325 // Disallow opening a non-sandboxed filesystem.
326 callback.Run(GURL(), std::string(), base::File::FILE_ERROR_SECURITY);
327 return;
328 }
329
330 FileSystemBackend* backend = GetFileSystemBackend(type);
331 if (!backend) {
332 callback.Run(GURL(), std::string(), base::File::FILE_ERROR_SECURITY);
333 return;
334 }
335
336 backend->ResolveURL(
337 CreateCrackedFileSystemURL(origin_url, type, base::FilePath()),
338 mode,
339 callback);
340 }
341
342 void FileSystemContext::ResolveURL(
343 const FileSystemURL& url,
344 const ResolveURLCallback& callback) {
345 DCHECK(!callback.is_null());
346
347 // If not on IO thread, forward before passing the task to the backend.
348 if (!io_task_runner_->RunsTasksOnCurrentThread()) {
349 ResolveURLCallback relay_callback =
350 base::Bind(&RelayResolveURLCallback,
351 base::MessageLoopProxy::current(), callback);
352 io_task_runner_->PostTask(
353 FROM_HERE,
354 base::Bind(&FileSystemContext::ResolveURL, this, url, relay_callback));
355 return;
356 }
357
358 FileSystemBackend* backend = GetFileSystemBackend(url.type());
359 if (!backend) {
360 callback.Run(base::File::FILE_ERROR_SECURITY,
361 FileSystemInfo(), base::FilePath(),
362 FileSystemContext::RESOLVED_ENTRY_NOT_FOUND);
363 return;
364 }
365
366 backend->ResolveURL(
367 url,
368 OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT,
369 base::Bind(&FileSystemContext::DidOpenFileSystemForResolveURL,
370 this,
371 url,
372 callback));
373 }
374
375 void FileSystemContext::AttemptAutoMountForURLRequest(
376 const net::URLRequest* url_request,
377 const std::string& storage_domain,
378 const StatusCallback& callback) {
379 FileSystemURL filesystem_url(url_request->url());
380 if (filesystem_url.type() == kFileSystemTypeExternal) {
381 for (size_t i = 0; i < auto_mount_handlers_.size(); i++) {
382 if (auto_mount_handlers_[i].Run(url_request, filesystem_url,
383 storage_domain, callback)) {
384 return;
385 }
386 }
387 }
388 callback.Run(base::File::FILE_ERROR_NOT_FOUND);
389 }
390
391 void FileSystemContext::DeleteFileSystem(
392 const GURL& origin_url,
393 FileSystemType type,
394 const StatusCallback& callback) {
395 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
396 DCHECK(origin_url == origin_url.GetOrigin());
397 DCHECK(!callback.is_null());
398
399 FileSystemBackend* backend = GetFileSystemBackend(type);
400 if (!backend) {
401 callback.Run(base::File::FILE_ERROR_SECURITY);
402 return;
403 }
404 if (!backend->GetQuotaUtil()) {
405 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
406 return;
407 }
408
409 base::PostTaskAndReplyWithResult(
410 default_file_task_runner(),
411 FROM_HERE,
412 // It is safe to pass Unretained(quota_util) since context owns it.
413 base::Bind(&FileSystemQuotaUtil::DeleteOriginDataOnFileTaskRunner,
414 base::Unretained(backend->GetQuotaUtil()),
415 make_scoped_refptr(this),
416 base::Unretained(quota_manager_proxy()),
417 origin_url,
418 type),
419 callback);
420 }
421
422 scoped_ptr<webkit_blob::FileStreamReader>
423 FileSystemContext::CreateFileStreamReader(
424 const FileSystemURL& url,
425 int64 offset,
426 const base::Time& expected_modification_time) {
427 if (!url.is_valid())
428 return scoped_ptr<webkit_blob::FileStreamReader>();
429 FileSystemBackend* backend = GetFileSystemBackend(url.type());
430 if (!backend)
431 return scoped_ptr<webkit_blob::FileStreamReader>();
432 return backend->CreateFileStreamReader(
433 url, offset, expected_modification_time, this);
434 }
435
436 scoped_ptr<FileStreamWriter> FileSystemContext::CreateFileStreamWriter(
437 const FileSystemURL& url,
438 int64 offset) {
439 if (!url.is_valid())
440 return scoped_ptr<FileStreamWriter>();
441 FileSystemBackend* backend = GetFileSystemBackend(url.type());
442 if (!backend)
443 return scoped_ptr<FileStreamWriter>();
444 return backend->CreateFileStreamWriter(url, offset, this);
445 }
446
447 scoped_ptr<FileSystemOperationRunner>
448 FileSystemContext::CreateFileSystemOperationRunner() {
449 return make_scoped_ptr(new FileSystemOperationRunner(this));
450 }
451
452 FileSystemURL FileSystemContext::CrackURL(const GURL& url) const {
453 return CrackFileSystemURL(FileSystemURL(url));
454 }
455
456 FileSystemURL FileSystemContext::CreateCrackedFileSystemURL(
457 const GURL& origin,
458 FileSystemType type,
459 const base::FilePath& path) const {
460 return CrackFileSystemURL(FileSystemURL(origin, type, path));
461 }
462
463 #if defined(OS_CHROMEOS)
464 void FileSystemContext::EnableTemporaryFileSystemInIncognito() {
465 sandbox_backend_->set_enable_temporary_file_system_in_incognito(true);
466 }
467 #endif
468
469 bool FileSystemContext::CanServeURLRequest(const FileSystemURL& url) const {
470 // We never support accessing files in isolated filesystems via an URL.
471 if (url.mount_type() == kFileSystemTypeIsolated)
472 return false;
473 #if defined(OS_CHROMEOS)
474 if (url.type() == kFileSystemTypeTemporary &&
475 sandbox_backend_->enable_temporary_file_system_in_incognito()) {
476 return true;
477 }
478 #endif
479 return !is_incognito_ || !FileSystemContext::IsSandboxFileSystem(url.type());
480 }
481
482 bool FileSystemContext::ShouldFlushOnWriteCompletion(
483 FileSystemType type) const {
484 if (IsSandboxFileSystem(type)) {
485 // Disable Flush() for each write operation on SandboxFileSystems since it
486 // hurts the performance, assuming the FileSystems are stored in a local
487 // disk, we don't need to keep calling fsync() for it.
488 // On the other hand, other FileSystems that may stored on a removable media
489 // should be Flush()ed as soon as a write operation is completed, so that
490 // written data is saved over sudden media removal.
491 return false;
492 }
493 return true;
494 }
495
496 void FileSystemContext::OpenPluginPrivateFileSystem(
497 const GURL& origin_url,
498 FileSystemType type,
499 const std::string& filesystem_id,
500 const std::string& plugin_id,
501 OpenFileSystemMode mode,
502 const StatusCallback& callback) {
503 DCHECK(plugin_private_backend_);
504 plugin_private_backend_->OpenPrivateFileSystem(
505 origin_url, type, filesystem_id, plugin_id, mode, callback);
506 }
507
508 FileSystemContext::~FileSystemContext() {
509 }
510
511 void FileSystemContext::DeleteOnCorrectThread() const {
512 if (!io_task_runner_->RunsTasksOnCurrentThread() &&
513 io_task_runner_->DeleteSoon(FROM_HERE, this)) {
514 return;
515 }
516 delete this;
517 }
518
519 FileSystemOperation* FileSystemContext::CreateFileSystemOperation(
520 const FileSystemURL& url, base::File::Error* error_code) {
521 if (!url.is_valid()) {
522 if (error_code)
523 *error_code = base::File::FILE_ERROR_INVALID_URL;
524 return NULL;
525 }
526
527 FileSystemBackend* backend = GetFileSystemBackend(url.type());
528 if (!backend) {
529 if (error_code)
530 *error_code = base::File::FILE_ERROR_FAILED;
531 return NULL;
532 }
533
534 base::File::Error fs_error = base::File::FILE_OK;
535 FileSystemOperation* operation =
536 backend->CreateFileSystemOperation(url, this, &fs_error);
537
538 if (error_code)
539 *error_code = fs_error;
540 return operation;
541 }
542
543 FileSystemURL FileSystemContext::CrackFileSystemURL(
544 const FileSystemURL& url) const {
545 if (!url.is_valid())
546 return FileSystemURL();
547
548 // The returned value in case there is no crackers which can crack the url.
549 // This is valid situation for non isolated/external file systems.
550 FileSystemURL current = url;
551
552 // File system may be mounted multiple times (e.g., an isolated filesystem on
553 // top of an external filesystem). Hence cracking needs to be iterated.
554 for (;;) {
555 FileSystemURL cracked = current;
556 for (size_t i = 0; i < url_crackers_.size(); ++i) {
557 if (!url_crackers_[i]->HandlesFileSystemMountType(current.type()))
558 continue;
559 cracked = url_crackers_[i]->CrackFileSystemURL(current);
560 if (cracked.is_valid())
561 break;
562 }
563 if (cracked == current)
564 break;
565 current = cracked;
566 }
567 return current;
568 }
569
570 void FileSystemContext::RegisterBackend(FileSystemBackend* backend) {
571 const FileSystemType mount_types[] = {
572 kFileSystemTypeTemporary,
573 kFileSystemTypePersistent,
574 kFileSystemTypeIsolated,
575 kFileSystemTypeExternal,
576 };
577 // Register file system backends for public mount types.
578 for (size_t j = 0; j < ARRAYSIZE_UNSAFE(mount_types); ++j) {
579 if (backend->CanHandleType(mount_types[j])) {
580 const bool inserted = backend_map_.insert(
581 std::make_pair(mount_types[j], backend)).second;
582 DCHECK(inserted);
583 }
584 }
585 // Register file system backends for internal types.
586 for (int t = kFileSystemInternalTypeEnumStart + 1;
587 t < kFileSystemInternalTypeEnumEnd; ++t) {
588 FileSystemType type = static_cast<FileSystemType>(t);
589 if (backend->CanHandleType(type)) {
590 const bool inserted = backend_map_.insert(
591 std::make_pair(type, backend)).second;
592 DCHECK(inserted);
593 }
594 }
595 }
596
597 void FileSystemContext::DidOpenFileSystemForResolveURL(
598 const FileSystemURL& url,
599 const FileSystemContext::ResolveURLCallback& callback,
600 const GURL& filesystem_root,
601 const std::string& filesystem_name,
602 base::File::Error error) {
603 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
604
605 if (error != base::File::FILE_OK) {
606 callback.Run(error, FileSystemInfo(), base::FilePath(),
607 FileSystemContext::RESOLVED_ENTRY_NOT_FOUND);
608 return;
609 }
610
611 fileapi::FileSystemInfo info(
612 filesystem_name, filesystem_root, url.mount_type());
613
614 // Extract the virtual path not containing a filesystem type part from |url|.
615 base::FilePath parent = CrackURL(filesystem_root).virtual_path();
616 base::FilePath child = url.virtual_path();
617 base::FilePath path;
618
619 if (parent.empty()) {
620 path = child;
621 } else if (parent != child) {
622 bool result = parent.AppendRelativePath(child, &path);
623 DCHECK(result);
624 }
625
626 operation_runner()->GetMetadata(
627 url, base::Bind(&DidGetMetadataForResolveURL, path, callback, info));
628 }
629
630 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/browser/fileapi/file_system_context.h ('k') | webkit/browser/fileapi/file_system_dir_url_request_job.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698