15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_context.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/single_thread_task_runner.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/stl_util.h"
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/task_runner_util.h"
1123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "net/url_request/url_request.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/blob/file_stream_reader.h"
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/copy_or_move_file_validator.h"
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/external_mount_points.h"
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "webkit/browser/fileapi/file_permission_policy.h"
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_stream_writer.h"
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_file_util.h"
1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_operation.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/fileapi/file_system_operation_runner.h"
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_options.h"
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_quota_client.h"
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_url.h"
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/isolated_context.h"
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "webkit/browser/fileapi/isolated_file_system_backend.h"
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/mount_points.h"
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "webkit/browser/fileapi/quota/quota_reservation.h"
287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "webkit/browser/fileapi/sandbox_file_system_backend.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "webkit/browser/quota/quota_manager_proxy.h"
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/quota/special_storage_policy.h"
3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "webkit/common/fileapi/file_system_info.h"
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/fileapi/file_system_util.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using quota::QuotaClient;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace fileapi {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuotaClient* CreateQuotaClient(
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemContext* context,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_incognito) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new FileSystemQuotaClient(context, is_incognito);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DidGetMetadataForResolveURL(
4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const base::FilePath& path,
4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemContext::ResolveURLCallback& callback,
5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemInfo& info,
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error,
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::File::Info& file_info) {
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (error != base::File::FILE_OK) {
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (error == base::File::FILE_ERROR_NOT_FOUND) {
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      callback.Run(base::File::FILE_OK, info, path,
560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   FileSystemContext::RESOLVED_ENTRY_NOT_FOUND);
570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    } else {
580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      callback.Run(error, FileSystemInfo(), base::FilePath(),
590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   FileSystemContext::RESOLVED_ENTRY_NOT_FOUND);
600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  callback.Run(error, info, path, file_info.is_directory ?
640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      FileSystemContext::RESOLVED_ENTRY_DIRECTORY :
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      FileSystemContext::RESOLVED_ENTRY_FILE);
660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid RelayResolveURLCallback(
690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_refptr<base::MessageLoopProxy> message_loop,
700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const FileSystemContext::ResolveURLCallback& callback,
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::File::Error result,
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const FileSystemInfo& info,
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const base::FilePath& file_path,
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    FileSystemContext::ResolvedEntryType type) {
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  message_loop->PostTask(
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      FROM_HERE, base::Bind(callback, result, info, file_path, type));
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// static
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint FileSystemContext::GetPermissionPolicy(FileSystemType type) {
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  switch (type) {
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypeTemporary:
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypePersistent:
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypeSyncable:
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return FILE_PERMISSION_SANDBOX;
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypeDrive:
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypeNativeForPlatformApp:
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypeNativeLocal:
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case kFileSystemTypeCloudDevice:
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case kFileSystemTypeProvided:
945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    case kFileSystemTypeDeviceMediaAsFileStorage:
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return FILE_PERMISSION_USE_FILE_PERMISSION;
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypeRestrictedNativeLocal:
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return FILE_PERMISSION_READ_ONLY |
99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             FILE_PERMISSION_USE_FILE_PERMISSION;
100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypeDeviceMedia:
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case kFileSystemTypeIphoto:
103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypeItunes:
104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypeNativeMedia:
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypePicasa:
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return FILE_PERMISSION_USE_FILE_PERMISSION;
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Following types are only accessed via IsolatedFileSystem, and
109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // don't have their own permission policies.
110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case kFileSystemTypeDragged:
111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case kFileSystemTypeForTransientFile:
1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    case kFileSystemTypePluginPrivate:
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return FILE_PERMISSION_ALWAYS_DENY;
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Following types only appear as mount_type, and will not be
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // queried for their permission policies.
117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypeIsolated:
118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypeExternal:
119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return FILE_PERMISSION_ALWAYS_DENY;
120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Following types should not be used to access files by FileAPI clients.
122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypeTest:
123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypeSyncableForInternalSync:
124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemInternalTypeEnumEnd:
125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemInternalTypeEnumStart:
126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case kFileSystemTypeUnknown:
127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return FILE_PERMISSION_ALWAYS_DENY;
128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  NOTREACHED();
130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return FILE_PERMISSION_ALWAYS_DENY;
131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemContext::FileSystemContext(
134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    base::SingleThreadTaskRunner* io_task_runner,
135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    base::SequencedTaskRunner* file_task_runner,
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ExternalMountPoints* external_mount_points,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    quota::SpecialStoragePolicy* special_storage_policy,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    quota::QuotaManagerProxy* quota_manager_proxy,
1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    ScopedVector<FileSystemBackend> additional_backends,
14023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::vector<URLRequestAutoMountHandler>& auto_mount_handlers,
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& partition_path,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FileSystemOptions& options)
143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : io_task_runner_(io_task_runner),
144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      default_file_task_runner_(file_task_runner),
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      quota_manager_proxy_(quota_manager_proxy),
1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      sandbox_delegate_(new SandboxFileSystemBackendDelegate(
1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          quota_manager_proxy,
148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          file_task_runner,
1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          partition_path,
150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          special_storage_policy,
1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          options)),
152a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      sandbox_backend_(new SandboxFileSystemBackend(
1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          sandbox_delegate_.get())),
1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      isolated_backend_(new IsolatedFileSystemBackend()),
1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      plugin_private_backend_(new PluginPrivateFileSystemBackend(
1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          file_task_runner,
1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          partition_path,
1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          special_storage_policy,
1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          options)),
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      additional_backends_(additional_backends.Pass()),
16123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      auto_mount_handlers_(auto_mount_handlers),
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      external_mount_points_(external_mount_points),
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      partition_path_(partition_path),
16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      is_incognito_(options.is_incognito()),
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      operation_runner_(new FileSystemOperationRunner(this)) {
1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  RegisterBackend(sandbox_backend_.get());
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  RegisterBackend(isolated_backend_.get());
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  RegisterBackend(plugin_private_backend_.get());
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (ScopedVector<FileSystemBackend>::const_iterator iter =
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          additional_backends_.begin();
1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       iter != additional_backends_.end(); ++iter) {
1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    RegisterBackend(*iter);
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (quota_manager_proxy) {
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Quota client assumes all backends have registered.
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    quota_manager_proxy->RegisterClient(CreateQuotaClient(
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            this, options.is_incognito()));
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
182bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  sandbox_backend_->Initialize(this);
183bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  isolated_backend_->Initialize(this);
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  plugin_private_backend_->Initialize(this);
185bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  for (ScopedVector<FileSystemBackend>::const_iterator iter =
186bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch          additional_backends_.begin();
187bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch       iter != additional_backends_.end(); ++iter) {
188bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    (*iter)->Initialize(this);
189bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  }
190bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Additional mount points must be added before regular system-wide
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // mount points.
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (external_mount_points)
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    url_crackers_.push_back(external_mount_points);
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_crackers_.push_back(ExternalMountPoints::GetSystemInstance());
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_crackers_.push_back(IsolatedContext::GetInstance());
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool FileSystemContext::DeleteDataForOriginOnFileTaskRunner(
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin_url) {
201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(default_file_task_runner()->RunsTasksOnCurrentThread());
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(origin_url == origin_url.GetOrigin());
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool success = true;
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (FileSystemBackendMap::iterator iter = backend_map_.begin();
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       iter != backend_map_.end();
2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)       ++iter) {
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    FileSystemBackend* backend = iter->second;
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!backend->GetQuotaUtil())
2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (backend->GetQuotaUtil()->DeleteOriginDataOnFileTaskRunner(
2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            this, quota_manager_proxy(), origin_url, iter->first)
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            != base::File::FILE_OK) {
2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Continue the loop, but record the failure.
2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      success = false;
2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return success;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_refptr<QuotaReservation>
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)FileSystemContext::CreateQuotaReservationOnFileTaskRunner(
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const GURL& origin_url,
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FileSystemType type) {
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(default_file_task_runner()->RunsTasksOnCurrentThread());
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FileSystemBackend* backend = GetFileSystemBackend(type);
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!backend || !backend->GetQuotaUtil())
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return scoped_refptr<QuotaReservation>();
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return backend->GetQuotaUtil()->CreateQuotaReservationOnFileTaskRunner(
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      origin_url, type);
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void FileSystemContext::Shutdown() {
2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!io_task_runner_->RunsTasksOnCurrentThread()) {
2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    io_task_runner_->PostTask(
2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        FROM_HERE, base::Bind(&FileSystemContext::Shutdown,
2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              make_scoped_refptr(this)));
2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  operation_runner_->Shutdown();
2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemQuotaUtil*
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemContext::GetQuotaUtil(FileSystemType type) const {
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(type);
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return backend->GetQuotaUtil();
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AsyncFileUtil* FileSystemContext::GetAsyncFileUtil(
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemType type) const {
2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(type);
2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return backend->GetAsyncFileUtil(type);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CopyOrMoveFileValidatorFactory*
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)FileSystemContext::GetCopyOrMoveFileValidatorFactory(
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FileSystemType type, base::File::Error* error_code) const {
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(error_code);
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *error_code = base::File::FILE_OK;
2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(type);
2667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend)
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return backend->GetCopyOrMoveFileValidatorFactory(
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      type, error_code);
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochFileSystemBackend* FileSystemContext::GetFileSystemBackend(
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemType type) const {
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackendMap::const_iterator found = backend_map_.find(type);
2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (found != backend_map_.end())
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return found->second;
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NOTREACHED() << "Unknown filesystem type: " << type;
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return NULL;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool FileSystemContext::IsSandboxFileSystem(FileSystemType type) const {
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FileSystemBackendMap::const_iterator found = backend_map_.find(type);
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return found != backend_map_.end() && found->second->GetQuotaUtil();
284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const UpdateObserverList* FileSystemContext::GetUpdateObservers(
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemType type) const {
2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(type);
289a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (backend->GetQuotaUtil())
290a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return backend->GetQuotaUtil()->GetUpdateObservers(type);
291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return NULL;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const AccessObserverList* FileSystemContext::GetAccessObservers(
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    FileSystemType type) const {
296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FileSystemBackend* backend = GetFileSystemBackend(type);
297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (backend->GetQuotaUtil())
298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return backend->GetQuotaUtil()->GetAccessObservers(type);
299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return NULL;
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid FileSystemContext::GetFileSystemTypes(
303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::vector<FileSystemType>* types) const {
304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  types->clear();
3057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (FileSystemBackendMap::const_iterator iter = backend_map_.begin();
3067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       iter != backend_map_.end(); ++iter)
307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    types->push_back(iter->first);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3107dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochExternalFileSystemBackend*
3117dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochFileSystemContext::external_backend() const {
3127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return static_cast<ExternalFileSystemBackend*>(
3137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      GetFileSystemBackend(kFileSystemTypeExternal));
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemContext::OpenFileSystem(
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin_url,
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemType type,
31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    OpenFileSystemMode mode,
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const OpenFileSystemCallback& callback) {
3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback.is_null());
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!FileSystemContext::IsSandboxFileSystem(type)) {
3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Disallow opening a non-sandboxed filesystem.
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(GURL(), std::string(), base::File::FILE_ERROR_SECURITY);
3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(type);
3317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend) {
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(GURL(), std::string(), base::File::FILE_ERROR_SECURITY);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  backend->ResolveURL(
337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      CreateCrackedFileSystemURL(origin_url, type, base::FilePath()),
338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      mode,
339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      callback);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void FileSystemContext::ResolveURL(
34368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& url,
34468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const ResolveURLCallback& callback) {
34568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(!callback.is_null());
34668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // If not on IO thread, forward before passing the task to the backend.
3480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!io_task_runner_->RunsTasksOnCurrentThread()) {
3490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ResolveURLCallback relay_callback =
3500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        base::Bind(&RelayResolveURLCallback,
3510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   base::MessageLoopProxy::current(), callback);
3520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    io_task_runner_->PostTask(
3530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        FROM_HERE,
3540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        base::Bind(&FileSystemContext::ResolveURL, this, url, relay_callback));
3550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
3560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
35868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  FileSystemBackend* backend = GetFileSystemBackend(url.type());
35968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!backend) {
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_SECURITY,
3610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 FileSystemInfo(), base::FilePath(),
3620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 FileSystemContext::RESOLVED_ENTRY_NOT_FOUND);
36368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
36468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
36568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  backend->ResolveURL(
367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      url,
36868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT,
36968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::Bind(&FileSystemContext::DidOpenFileSystemForResolveURL,
370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 this,
371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 url,
372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 callback));
37368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
37468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
37523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void FileSystemContext::AttemptAutoMountForURLRequest(
37623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const net::URLRequest* url_request,
37723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& storage_domain,
37823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const StatusCallback& callback) {
37923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  FileSystemURL filesystem_url(url_request->url());
38023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (filesystem_url.type() == kFileSystemTypeExternal) {
38123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    for (size_t i = 0; i < auto_mount_handlers_.size(); i++) {
38223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      if (auto_mount_handlers_[i].Run(url_request, filesystem_url,
38323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                      storage_domain, callback)) {
38423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        return;
38523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      }
38623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
38723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
38823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  callback.Run(base::File::FILE_ERROR_NOT_FOUND);
38923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
39023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemContext::DeleteFileSystem(
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin_url,
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemType type,
394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const StatusCallback& callback) {
3954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(origin_url == origin_url.GetOrigin());
3974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!callback.is_null());
3984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(type);
4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend) {
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_SECURITY);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend->GetQuotaUtil()) {
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
4077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::PostTaskAndReplyWithResult(
410a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      default_file_task_runner(),
4117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      FROM_HERE,
4127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // It is safe to pass Unretained(quota_util) since context owns it.
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&FileSystemQuotaUtil::DeleteOriginDataOnFileTaskRunner,
4147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::Unretained(backend->GetQuotaUtil()),
4157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 make_scoped_refptr(this),
4167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::Unretained(quota_manager_proxy()),
4177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 origin_url,
4187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 type),
4197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      callback);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<webkit_blob::FileStreamReader>
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)FileSystemContext::CreateFileStreamReader(
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FileSystemURL& url,
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 offset,
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Time& expected_modification_time) {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url.is_valid())
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return scoped_ptr<webkit_blob::FileStreamReader>();
4297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(url.type());
4307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend)
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return scoped_ptr<webkit_blob::FileStreamReader>();
4327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return backend->CreateFileStreamReader(
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, offset, expected_modification_time, this);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<FileStreamWriter> FileSystemContext::CreateFileStreamWriter(
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const FileSystemURL& url,
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int64 offset) {
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!url.is_valid())
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return scoped_ptr<FileStreamWriter>();
4417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(url.type());
4427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend)
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return scoped_ptr<FileStreamWriter>();
4447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return backend->CreateFileStreamWriter(url, offset, this);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
447bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochscoped_ptr<FileSystemOperationRunner>
448bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochFileSystemContext::CreateFileSystemOperationRunner() {
449bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  return make_scoped_ptr(new FileSystemOperationRunner(this));
450bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
451bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL FileSystemContext::CrackURL(const GURL& url) const {
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CrackFileSystemURL(FileSystemURL(url));
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL FileSystemContext::CreateCrackedFileSystemURL(
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& origin,
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FileSystemType type,
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path) const {
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CrackFileSystemURL(FileSystemURL(origin, type, path));
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid FileSystemContext::EnableTemporaryFileSystemInIncognito() {
4657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  sandbox_backend_->set_enable_temporary_file_system_in_incognito(true);
466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
46958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool FileSystemContext::CanServeURLRequest(const FileSystemURL& url) const {
4701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // We never support accessing files in isolated filesystems via an URL.
4711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (url.mount_type() == kFileSystemTypeIsolated)
4721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return false;
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
47458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (url.type() == kFileSystemTypeTemporary &&
47558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      sandbox_backend_->enable_temporary_file_system_in_incognito()) {
47658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return true;
47758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
47858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif
47968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return !is_incognito_ || !FileSystemContext::IsSandboxFileSystem(url.type());
48058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
48158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
482010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool FileSystemContext::ShouldFlushOnWriteCompletion(
483010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    FileSystemType type) const {
484010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (IsSandboxFileSystem(type)) {
485010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // Disable Flush() for each write operation on SandboxFileSystems since it
486010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // hurts the performance, assuming the FileSystems are stored in a local
487010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // disk, we don't need to keep calling fsync() for it.
488010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // On the other hand, other FileSystems that may stored on a removable media
489010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // should be Flush()ed as soon as a write operation is completed, so that
490010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // written data is saved over sudden media removal.
491010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
492010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
493010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return true;
494010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
495010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
4961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void FileSystemContext::OpenPluginPrivateFileSystem(
4971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const GURL& origin_url,
4981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    FileSystemType type,
499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& filesystem_id,
5001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const std::string& plugin_id,
5011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    OpenFileSystemMode mode,
502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const StatusCallback& callback) {
5031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(plugin_private_backend_);
5041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  plugin_private_backend_->OpenPrivateFileSystem(
505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      origin_url, type, filesystem_id, plugin_id, mode, callback);
5061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
5071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemContext::~FileSystemContext() {
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemContext::DeleteOnCorrectThread() const {
512a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!io_task_runner_->RunsTasksOnCurrentThread() &&
513a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      io_task_runner_->DeleteSoon(FROM_HERE, this)) {
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)FileSystemOperation* FileSystemContext::CreateFileSystemOperation(
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const FileSystemURL& url, base::File::Error* error_code) {
521868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!url.is_valid()) {
522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (error_code)
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *error_code = base::File::FILE_ERROR_INVALID_URL;
524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return NULL;
525868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(url.type());
5287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend) {
529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (error_code)
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *error_code = base::File::FILE_ERROR_FAILED;
531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return NULL;
532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error fs_error = base::File::FILE_OK;
535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
5367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      backend->CreateFileSystemOperation(url, this, &fs_error);
537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (error_code)
539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *error_code = fs_error;
540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return operation;
541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL FileSystemContext::CrackFileSystemURL(
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FileSystemURL& url) const {
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!url.is_valid())
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return FileSystemURL();
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The returned value in case there is no crackers which can crack the url.
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This is valid situation for non isolated/external file systems.
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL current = url;
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // File system may be mounted multiple times (e.g., an isolated filesystem on
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // top of an external filesystem). Hence cracking needs to be iterated.
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (;;) {
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FileSystemURL cracked = current;
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < url_crackers_.size(); ++i) {
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!url_crackers_[i]->HandlesFileSystemMountType(current.type()))
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cracked = url_crackers_[i]->CrackFileSystemURL(current);
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (cracked.is_valid())
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (cracked == current)
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current = cracked;
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return current;
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
57068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void FileSystemContext::RegisterBackend(FileSystemBackend* backend) {
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const FileSystemType mount_types[] = {
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    kFileSystemTypeTemporary,
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    kFileSystemTypePersistent,
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    kFileSystemTypeIsolated,
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    kFileSystemTypeExternal,
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
5777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Register file system backends for public mount types.
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t j = 0; j < ARRAYSIZE_UNSAFE(mount_types); ++j) {
5797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (backend->CanHandleType(mount_types[j])) {
5807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const bool inserted = backend_map_.insert(
5817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          std::make_pair(mount_types[j], backend)).second;
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DCHECK(inserted);
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
5857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Register file system backends for internal types.
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int t = kFileSystemInternalTypeEnumStart + 1;
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       t < kFileSystemInternalTypeEnumEnd; ++t) {
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FileSystemType type = static_cast<FileSystemType>(t);
5897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (backend->CanHandleType(type)) {
5907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const bool inserted = backend_map_.insert(
5917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          std::make_pair(type, backend)).second;
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DCHECK(inserted);
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
59768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void FileSystemContext::DidOpenFileSystemForResolveURL(
59868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& url,
59968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemContext::ResolveURLCallback& callback,
60068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const GURL& filesystem_root,
60168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& filesystem_name,
6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error) {
60368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
60468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (error != base::File::FILE_OK) {
6060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    callback.Run(error, FileSystemInfo(), base::FilePath(),
6070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 FileSystemContext::RESOLVED_ENTRY_NOT_FOUND);
60868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
60968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
61068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
61168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  fileapi::FileSystemInfo info(
61268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      filesystem_name, filesystem_root, url.mount_type());
61368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
61468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Extract the virtual path not containing a filesystem type part from |url|.
6154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::FilePath parent = CrackURL(filesystem_root).virtual_path();
6164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::FilePath child = url.virtual_path();
61768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::FilePath path;
61868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (parent.empty()) {
6204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    path = child;
6214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else if (parent != child) {
62268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    bool result = parent.AppendRelativePath(child, &path);
62368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK(result);
62468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
62568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
62668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  operation_runner()->GetMetadata(
62768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      url, base::Bind(&DidGetMetadataForResolveURL, path, callback, info));
62868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
62968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace fileapi
631