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)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/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"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/file_stream_reader.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/copy_or_move_file_validator.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/external_mount_points.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_permission_policy.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_stream_writer.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_file_util.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_options.h"
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_quota_client.h"
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h"
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/isolated_context.h"
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/isolated_file_system_backend.h"
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/mount_points.h"
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/quota/quota_reservation.h"
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/sandbox_file_system_backend.h"
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager_proxy.h"
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/special_storage_policy.h"
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_info.h"
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h"
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::QuotaClient;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
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,
13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::SpecialStoragePolicy* special_storage_policy,
13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::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),
14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      sandbox_delegate_(
14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          new SandboxFileSystemBackendDelegate(quota_manager_proxy,
14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                               file_task_runner,
14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                               partition_path,
15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                               special_storage_policy,
15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                               options)),
15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      sandbox_backend_(new SandboxFileSystemBackend(sandbox_delegate_.get())),
1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      isolated_backend_(new IsolatedFileSystemBackend()),
15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      plugin_private_backend_(
15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          new PluginPrivateFileSystemBackend(file_task_runner,
15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                             partition_path,
15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                             special_storage_policy,
15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                             options)),
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      additional_backends_(additional_backends.Pass()),
16023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      auto_mount_handlers_(auto_mount_handlers),
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      external_mount_points_(external_mount_points),
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      partition_path_(partition_path),
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      is_incognito_(options.is_incognito()),
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      operation_runner_(new FileSystemOperationRunner(this)) {
1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  RegisterBackend(sandbox_backend_.get());
1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  RegisterBackend(isolated_backend_.get());
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  RegisterBackend(plugin_private_backend_.get());
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (ScopedVector<FileSystemBackend>::const_iterator iter =
1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          additional_backends_.begin();
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       iter != additional_backends_.end(); ++iter) {
1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    RegisterBackend(*iter);
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (quota_manager_proxy) {
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Quota client assumes all backends have registered.
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    quota_manager_proxy->RegisterClient(CreateQuotaClient(
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            this, options.is_incognito()));
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
181bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  sandbox_backend_->Initialize(this);
182bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  isolated_backend_->Initialize(this);
1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  plugin_private_backend_->Initialize(this);
184bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  for (ScopedVector<FileSystemBackend>::const_iterator iter =
185bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch          additional_backends_.begin();
186bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch       iter != additional_backends_.end(); ++iter) {
187bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    (*iter)->Initialize(this);
188bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  }
189bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Additional mount points must be added before regular system-wide
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // mount points.
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (external_mount_points)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    url_crackers_.push_back(external_mount_points);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_crackers_.push_back(ExternalMountPoints::GetSystemInstance());
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_crackers_.push_back(IsolatedContext::GetInstance());
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool FileSystemContext::DeleteDataForOriginOnFileTaskRunner(
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin_url) {
200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(default_file_task_runner()->RunsTasksOnCurrentThread());
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(origin_url == origin_url.GetOrigin());
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool success = true;
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (FileSystemBackendMap::iterator iter = backend_map_.begin();
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       iter != backend_map_.end();
2067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)       ++iter) {
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    FileSystemBackend* backend = iter->second;
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!backend->GetQuotaUtil())
2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (backend->GetQuotaUtil()->DeleteOriginDataOnFileTaskRunner(
2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            this, quota_manager_proxy(), origin_url, iter->first)
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            != base::File::FILE_OK) {
2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Continue the loop, but record the failure.
2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      success = false;
2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return success;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_refptr<QuotaReservation>
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)FileSystemContext::CreateQuotaReservationOnFileTaskRunner(
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const GURL& origin_url,
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FileSystemType type) {
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(default_file_task_runner()->RunsTasksOnCurrentThread());
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FileSystemBackend* backend = GetFileSystemBackend(type);
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!backend || !backend->GetQuotaUtil())
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return scoped_refptr<QuotaReservation>();
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return backend->GetQuotaUtil()->CreateQuotaReservationOnFileTaskRunner(
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      origin_url, type);
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void FileSystemContext::Shutdown() {
2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!io_task_runner_->RunsTasksOnCurrentThread()) {
2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    io_task_runner_->PostTask(
2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        FROM_HERE, base::Bind(&FileSystemContext::Shutdown,
2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              make_scoped_refptr(this)));
2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  operation_runner_->Shutdown();
2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemQuotaUtil*
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemContext::GetQuotaUtil(FileSystemType type) const {
2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(type);
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return backend->GetQuotaUtil();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AsyncFileUtil* FileSystemContext::GetAsyncFileUtil(
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemType type) const {
2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(type);
2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return backend->GetAsyncFileUtil(type);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CopyOrMoveFileValidatorFactory*
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)FileSystemContext::GetCopyOrMoveFileValidatorFactory(
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FileSystemType type, base::File::Error* error_code) const {
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(error_code);
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *error_code = base::File::FILE_OK;
2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(type);
2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend)
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return backend->GetCopyOrMoveFileValidatorFactory(
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      type, error_code);
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochFileSystemBackend* FileSystemContext::GetFileSystemBackend(
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemType type) const {
2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackendMap::const_iterator found = backend_map_.find(type);
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (found != backend_map_.end())
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return found->second;
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NOTREACHED() << "Unknown filesystem type: " << type;
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return NULL;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciWatcherManager* FileSystemContext::GetWatcherManager(
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FileSystemType type) const {
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FileSystemBackend* backend = GetFileSystemBackend(type);
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!backend)
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return NULL;
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return backend->GetWatcherManager(type);
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool FileSystemContext::IsSandboxFileSystem(FileSystemType type) const {
28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FileSystemBackendMap::const_iterator found = backend_map_.find(type);
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return found != backend_map_.end() && found->second->GetQuotaUtil();
291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const UpdateObserverList* FileSystemContext::GetUpdateObservers(
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemType type) const {
2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(type);
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return backend->GetUpdateObservers(type);
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst ChangeObserverList* FileSystemContext::GetChangeObservers(
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FileSystemType type) const {
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FileSystemBackend* backend = GetFileSystemBackend(type);
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return backend->GetChangeObservers(type);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const AccessObserverList* FileSystemContext::GetAccessObservers(
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    FileSystemType type) const {
307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FileSystemBackend* backend = GetFileSystemBackend(type);
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return backend->GetAccessObservers(type);
309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid FileSystemContext::GetFileSystemTypes(
312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::vector<FileSystemType>* types) const {
313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  types->clear();
3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (FileSystemBackendMap::const_iterator iter = backend_map_.begin();
3157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       iter != backend_map_.end(); ++iter)
316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    types->push_back(iter->first);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3197dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochExternalFileSystemBackend*
3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochFileSystemContext::external_backend() const {
3217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return static_cast<ExternalFileSystemBackend*>(
3227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      GetFileSystemBackend(kFileSystemTypeExternal));
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemContext::OpenFileSystem(
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin_url,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemType type,
32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    OpenFileSystemMode mode,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const OpenFileSystemCallback& callback) {
3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!callback.is_null());
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!FileSystemContext::IsSandboxFileSystem(type)) {
3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Disallow opening a non-sandboxed filesystem.
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(GURL(), std::string(), base::File::FILE_ERROR_SECURITY);
3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(type);
3407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend) {
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(GURL(), std::string(), base::File::FILE_ERROR_SECURITY);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  backend->ResolveURL(
346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      CreateCrackedFileSystemURL(origin_url, type, base::FilePath()),
347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      mode,
348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      callback);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void FileSystemContext::ResolveURL(
35268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& url,
35368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const ResolveURLCallback& callback) {
35468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(!callback.is_null());
35568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // If not on IO thread, forward before passing the task to the backend.
3570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!io_task_runner_->RunsTasksOnCurrentThread()) {
3580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ResolveURLCallback relay_callback =
3590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        base::Bind(&RelayResolveURLCallback,
3600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   base::MessageLoopProxy::current(), callback);
3610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    io_task_runner_->PostTask(
3620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        FROM_HERE,
3630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        base::Bind(&FileSystemContext::ResolveURL, this, url, relay_callback));
3640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
3650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
36768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  FileSystemBackend* backend = GetFileSystemBackend(url.type());
36868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!backend) {
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_SECURITY,
3700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 FileSystemInfo(), base::FilePath(),
3710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 FileSystemContext::RESOLVED_ENTRY_NOT_FOUND);
37268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
37368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
37468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  backend->ResolveURL(
376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      url,
37768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT,
37868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::Bind(&FileSystemContext::DidOpenFileSystemForResolveURL,
379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 this,
380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 url,
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 callback));
38268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
38368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
38423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void FileSystemContext::AttemptAutoMountForURLRequest(
38523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const net::URLRequest* url_request,
38623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& storage_domain,
38723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const StatusCallback& callback) {
38823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  FileSystemURL filesystem_url(url_request->url());
38923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (filesystem_url.type() == kFileSystemTypeExternal) {
39023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    for (size_t i = 0; i < auto_mount_handlers_.size(); i++) {
39123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      if (auto_mount_handlers_[i].Run(url_request, filesystem_url,
39223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                      storage_domain, callback)) {
39323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        return;
39423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      }
39523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
39623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
39723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  callback.Run(base::File::FILE_ERROR_NOT_FOUND);
39823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
39923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemContext::DeleteFileSystem(
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin_url,
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemType type,
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const StatusCallback& callback) {
4044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(origin_url == origin_url.GetOrigin());
4064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!callback.is_null());
4074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(type);
4097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend) {
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_SECURITY);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend->GetQuotaUtil()) {
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
4157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
4167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::PostTaskAndReplyWithResult(
419a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      default_file_task_runner(),
4207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      FROM_HERE,
4217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // It is safe to pass Unretained(quota_util) since context owns it.
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&FileSystemQuotaUtil::DeleteOriginDataOnFileTaskRunner,
4237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::Unretained(backend->GetQuotaUtil()),
4247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 make_scoped_refptr(this),
4257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::Unretained(quota_manager_proxy()),
4267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 origin_url,
4277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 type),
4287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      callback);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_ptr<storage::FileStreamReader> FileSystemContext::CreateFileStreamReader(
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FileSystemURL& url,
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 offset,
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int64 max_bytes_to_read,
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Time& expected_modification_time) {
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url.is_valid())
43703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return scoped_ptr<storage::FileStreamReader>();
4387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(url.type());
4397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend)
44003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return scoped_ptr<storage::FileStreamReader>();
4417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return backend->CreateFileStreamReader(
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url, offset, max_bytes_to_read, expected_modification_time, this);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<FileStreamWriter> FileSystemContext::CreateFileStreamWriter(
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const FileSystemURL& url,
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int64 offset) {
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!url.is_valid())
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return scoped_ptr<FileStreamWriter>();
4507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(url.type());
4517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend)
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return scoped_ptr<FileStreamWriter>();
4537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return backend->CreateFileStreamWriter(url, offset, this);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
456bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochscoped_ptr<FileSystemOperationRunner>
457bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochFileSystemContext::CreateFileSystemOperationRunner() {
458bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  return make_scoped_ptr(new FileSystemOperationRunner(this));
459bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
460bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL FileSystemContext::CrackURL(const GURL& url) const {
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CrackFileSystemURL(FileSystemURL(url));
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL FileSystemContext::CreateCrackedFileSystemURL(
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& origin,
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FileSystemType type,
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path) const {
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CrackFileSystemURL(FileSystemURL(origin, type, path));
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid FileSystemContext::EnableTemporaryFileSystemInIncognito() {
4747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  sandbox_backend_->set_enable_temporary_file_system_in_incognito(true);
475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
477eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
47858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool FileSystemContext::CanServeURLRequest(const FileSystemURL& url) const {
4791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // We never support accessing files in isolated filesystems via an URL.
4801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (url.mount_type() == kFileSystemTypeIsolated)
4811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return false;
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
48358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (url.type() == kFileSystemTypeTemporary &&
48458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      sandbox_backend_->enable_temporary_file_system_in_incognito()) {
48558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return true;
48658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
48758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif
48868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return !is_incognito_ || !FileSystemContext::IsSandboxFileSystem(url.type());
48958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
49058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
491010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool FileSystemContext::ShouldFlushOnWriteCompletion(
492010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    FileSystemType type) const {
493010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (IsSandboxFileSystem(type)) {
494010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // Disable Flush() for each write operation on SandboxFileSystems since it
495010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // hurts the performance, assuming the FileSystems are stored in a local
496010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // disk, we don't need to keep calling fsync() for it.
497010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // On the other hand, other FileSystems that may stored on a removable media
498010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // should be Flush()ed as soon as a write operation is completed, so that
499010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // written data is saved over sudden media removal.
500010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
501010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
502010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return true;
503010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
504010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
5051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void FileSystemContext::OpenPluginPrivateFileSystem(
5061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const GURL& origin_url,
5071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    FileSystemType type,
508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& filesystem_id,
5091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const std::string& plugin_id,
5101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    OpenFileSystemMode mode,
511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const StatusCallback& callback) {
5121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(plugin_private_backend_);
5131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  plugin_private_backend_->OpenPrivateFileSystem(
514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      origin_url, type, filesystem_id, plugin_id, mode, callback);
5151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
5161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemContext::~FileSystemContext() {
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemContext::DeleteOnCorrectThread() const {
521a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!io_task_runner_->RunsTasksOnCurrentThread() &&
522a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      io_task_runner_->DeleteSoon(FROM_HERE, this)) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)FileSystemOperation* FileSystemContext::CreateFileSystemOperation(
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const FileSystemURL& url, base::File::Error* error_code) {
530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!url.is_valid()) {
531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (error_code)
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *error_code = base::File::FILE_ERROR_INVALID_URL;
533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return NULL;
534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  FileSystemBackend* backend = GetFileSystemBackend(url.type());
5377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!backend) {
538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (error_code)
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *error_code = base::File::FILE_ERROR_FAILED;
540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return NULL;
541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error fs_error = base::File::FILE_OK;
544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
5457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      backend->CreateFileSystemOperation(url, this, &fs_error);
546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (error_code)
548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *error_code = fs_error;
549868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return operation;
550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL FileSystemContext::CrackFileSystemURL(
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FileSystemURL& url) const {
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!url.is_valid())
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return FileSystemURL();
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The returned value in case there is no crackers which can crack the url.
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This is valid situation for non isolated/external file systems.
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL current = url;
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // File system may be mounted multiple times (e.g., an isolated filesystem on
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // top of an external filesystem). Hence cracking needs to be iterated.
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (;;) {
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FileSystemURL cracked = current;
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < url_crackers_.size(); ++i) {
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!url_crackers_[i]->HandlesFileSystemMountType(current.type()))
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cracked = url_crackers_[i]->CrackFileSystemURL(current);
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (cracked.is_valid())
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (cracked == current)
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current = cracked;
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return current;
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
57968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void FileSystemContext::RegisterBackend(FileSystemBackend* backend) {
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const FileSystemType mount_types[] = {
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    kFileSystemTypeTemporary,
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    kFileSystemTypePersistent,
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    kFileSystemTypeIsolated,
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    kFileSystemTypeExternal,
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
5867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Register file system backends for public mount types.
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t j = 0; j < ARRAYSIZE_UNSAFE(mount_types); ++j) {
5887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (backend->CanHandleType(mount_types[j])) {
5897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const bool inserted = backend_map_.insert(
5907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          std::make_pair(mount_types[j], backend)).second;
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DCHECK(inserted);
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
5947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Register file system backends for internal types.
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int t = kFileSystemInternalTypeEnumStart + 1;
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       t < kFileSystemInternalTypeEnumEnd; ++t) {
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FileSystemType type = static_cast<FileSystemType>(t);
5987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (backend->CanHandleType(type)) {
5997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const bool inserted = backend_map_.insert(
6007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          std::make_pair(type, backend)).second;
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DCHECK(inserted);
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
60668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void FileSystemContext::DidOpenFileSystemForResolveURL(
60768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& url,
60868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemContext::ResolveURLCallback& callback,
60968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const GURL& filesystem_root,
61068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& filesystem_name,
6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error) {
61268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
61368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (error != base::File::FILE_OK) {
6150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    callback.Run(error, FileSystemInfo(), base::FilePath(),
6160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 FileSystemContext::RESOLVED_ENTRY_NOT_FOUND);
61768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
61868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
61968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
62003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemInfo info(
62168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      filesystem_name, filesystem_root, url.mount_type());
62268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
62368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Extract the virtual path not containing a filesystem type part from |url|.
6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::FilePath parent = CrackURL(filesystem_root).virtual_path();
6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::FilePath child = url.virtual_path();
62668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::FilePath path;
62768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (parent.empty()) {
6294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    path = child;
6304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else if (parent != child) {
63168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    bool result = parent.AppendRelativePath(child, &path);
63268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK(result);
63368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
63468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
63568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  operation_runner()->GetMetadata(
63668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      url, base::Bind(&DidGetMetadataForResolveURL, path, callback, info));
63768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
63868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
63903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace storage
640