1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "storage/browser/fileapi/sandbox_file_system_backend.h"
6
7#include "base/bind.h"
8#include "base/files/file_util.h"
9#include "base/logging.h"
10#include "base/metrics/histogram.h"
11#include "base/task_runner_util.h"
12#include "storage/browser/blob/file_stream_reader.h"
13#include "storage/browser/fileapi/async_file_util_adapter.h"
14#include "storage/browser/fileapi/copy_or_move_file_validator.h"
15#include "storage/browser/fileapi/file_stream_writer.h"
16#include "storage/browser/fileapi/file_system_context.h"
17#include "storage/browser/fileapi/file_system_operation.h"
18#include "storage/browser/fileapi/file_system_operation_context.h"
19#include "storage/browser/fileapi/file_system_options.h"
20#include "storage/browser/fileapi/file_system_usage_cache.h"
21#include "storage/browser/fileapi/obfuscated_file_util.h"
22#include "storage/browser/fileapi/sandbox_file_system_backend_delegate.h"
23#include "storage/browser/fileapi/sandbox_quota_observer.h"
24#include "storage/browser/quota/quota_manager.h"
25#include "storage/common/fileapi/file_system_types.h"
26#include "storage/common/fileapi/file_system_util.h"
27#include "url/gurl.h"
28
29using storage::QuotaManagerProxy;
30using storage::SpecialStoragePolicy;
31
32namespace storage {
33
34SandboxFileSystemBackend::SandboxFileSystemBackend(
35    SandboxFileSystemBackendDelegate* delegate)
36    : delegate_(delegate),
37      enable_temporary_file_system_in_incognito_(false) {
38}
39
40SandboxFileSystemBackend::~SandboxFileSystemBackend() {
41}
42
43bool SandboxFileSystemBackend::CanHandleType(FileSystemType type) const {
44  return type == kFileSystemTypeTemporary ||
45         type == kFileSystemTypePersistent;
46}
47
48void SandboxFileSystemBackend::Initialize(FileSystemContext* context) {
49  DCHECK(delegate_);
50
51  // Set quota observers.
52  delegate_->RegisterQuotaUpdateObserver(storage::kFileSystemTypeTemporary);
53  delegate_->AddFileAccessObserver(
54      storage::kFileSystemTypeTemporary, delegate_->quota_observer(), NULL);
55
56  delegate_->RegisterQuotaUpdateObserver(storage::kFileSystemTypePersistent);
57  delegate_->AddFileAccessObserver(
58      storage::kFileSystemTypePersistent, delegate_->quota_observer(), NULL);
59}
60
61void SandboxFileSystemBackend::ResolveURL(
62    const FileSystemURL& url,
63    OpenFileSystemMode mode,
64    const OpenFileSystemCallback& callback) {
65  DCHECK(CanHandleType(url.type()));
66  DCHECK(delegate_);
67  if (delegate_->file_system_options().is_incognito() &&
68      !(url.type() == kFileSystemTypeTemporary &&
69        enable_temporary_file_system_in_incognito_)) {
70    // TODO(kinuko): return an isolated temporary directory.
71    callback.Run(GURL(), std::string(), base::File::FILE_ERROR_SECURITY);
72    return;
73  }
74
75  delegate_->OpenFileSystem(url.origin(),
76                            url.type(),
77                            mode,
78                            callback,
79                            GetFileSystemRootURI(url.origin(), url.type()));
80}
81
82AsyncFileUtil* SandboxFileSystemBackend::GetAsyncFileUtil(
83    FileSystemType type) {
84  DCHECK(delegate_);
85  return delegate_->file_util();
86}
87
88WatcherManager* SandboxFileSystemBackend::GetWatcherManager(
89    FileSystemType type) {
90  return NULL;
91}
92
93CopyOrMoveFileValidatorFactory*
94SandboxFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
95    FileSystemType type,
96    base::File::Error* error_code) {
97  DCHECK(error_code);
98  *error_code = base::File::FILE_OK;
99  return NULL;
100}
101
102FileSystemOperation* SandboxFileSystemBackend::CreateFileSystemOperation(
103    const FileSystemURL& url,
104    FileSystemContext* context,
105    base::File::Error* error_code) const {
106  DCHECK(CanHandleType(url.type()));
107  DCHECK(error_code);
108
109  DCHECK(delegate_);
110  scoped_ptr<FileSystemOperationContext> operation_context =
111      delegate_->CreateFileSystemOperationContext(url, context, error_code);
112  if (!operation_context)
113    return NULL;
114
115  SpecialStoragePolicy* policy = delegate_->special_storage_policy();
116  if (policy && policy->IsStorageUnlimited(url.origin()))
117    operation_context->set_quota_limit_type(storage::kQuotaLimitTypeUnlimited);
118  else
119    operation_context->set_quota_limit_type(storage::kQuotaLimitTypeLimited);
120
121  return FileSystemOperation::Create(url, context, operation_context.Pass());
122}
123
124bool SandboxFileSystemBackend::SupportsStreaming(
125    const storage::FileSystemURL& url) const {
126  return false;
127}
128
129bool SandboxFileSystemBackend::HasInplaceCopyImplementation(
130    storage::FileSystemType type) const {
131  return false;
132}
133
134scoped_ptr<storage::FileStreamReader>
135SandboxFileSystemBackend::CreateFileStreamReader(
136    const FileSystemURL& url,
137    int64 offset,
138    int64 max_bytes_to_read,
139    const base::Time& expected_modification_time,
140    FileSystemContext* context) const {
141  DCHECK(CanHandleType(url.type()));
142  DCHECK(delegate_);
143  return delegate_->CreateFileStreamReader(
144      url, offset, expected_modification_time, context);
145}
146
147scoped_ptr<storage::FileStreamWriter>
148SandboxFileSystemBackend::CreateFileStreamWriter(
149    const FileSystemURL& url,
150    int64 offset,
151    FileSystemContext* context) const {
152  DCHECK(CanHandleType(url.type()));
153  DCHECK(delegate_);
154  return delegate_->CreateFileStreamWriter(url, offset, context, url.type());
155}
156
157FileSystemQuotaUtil* SandboxFileSystemBackend::GetQuotaUtil() {
158  return delegate_;
159}
160
161const UpdateObserverList* SandboxFileSystemBackend::GetUpdateObservers(
162    FileSystemType type) const {
163  return delegate_->GetUpdateObservers(type);
164}
165
166const ChangeObserverList* SandboxFileSystemBackend::GetChangeObservers(
167    FileSystemType type) const {
168  return delegate_->GetChangeObservers(type);
169}
170
171const AccessObserverList* SandboxFileSystemBackend::GetAccessObservers(
172    FileSystemType type) const {
173  return delegate_->GetAccessObservers(type);
174}
175
176SandboxFileSystemBackendDelegate::OriginEnumerator*
177SandboxFileSystemBackend::CreateOriginEnumerator() {
178  DCHECK(delegate_);
179  return delegate_->CreateOriginEnumerator();
180}
181
182}  // namespace storage
183