Include all dupe types (event when value is zero) in scan stats.
[chromium-blink-merge.git] / storage / browser / fileapi / plugin_private_file_system_backend.cc
blobd298f04fe82096064e59f4c4e5d6495c6932ecfc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "storage/browser/fileapi/plugin_private_file_system_backend.h"
7 #include <map>
9 #include "base/stl_util.h"
10 #include "base/synchronization/lock.h"
11 #include "base/task_runner_util.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "net/base/net_util.h"
14 #include "storage/browser/fileapi/async_file_util_adapter.h"
15 #include "storage/browser/fileapi/file_stream_reader.h"
16 #include "storage/browser/fileapi/file_stream_writer.h"
17 #include "storage/browser/fileapi/file_system_context.h"
18 #include "storage/browser/fileapi/file_system_operation.h"
19 #include "storage/browser/fileapi/file_system_operation_context.h"
20 #include "storage/browser/fileapi/isolated_context.h"
21 #include "storage/browser/fileapi/obfuscated_file_util.h"
22 #include "storage/browser/fileapi/quota/quota_reservation.h"
23 #include "storage/common/fileapi/file_system_util.h"
25 namespace storage {
27 class PluginPrivateFileSystemBackend::FileSystemIDToPluginMap {
28 public:
29 explicit FileSystemIDToPluginMap(base::SequencedTaskRunner* task_runner)
30 : task_runner_(task_runner) {}
31 ~FileSystemIDToPluginMap() {}
33 std::string GetPluginIDForURL(const FileSystemURL& url) {
34 DCHECK(task_runner_->RunsTasksOnCurrentThread());
35 Map::iterator found = map_.find(url.filesystem_id());
36 if (url.type() != kFileSystemTypePluginPrivate || found == map_.end()) {
37 NOTREACHED() << "Unsupported url is given: " << url.DebugString();
38 return std::string();
40 return found->second;
43 void RegisterFileSystem(const std::string& filesystem_id,
44 const std::string& plugin_id) {
45 DCHECK(task_runner_->RunsTasksOnCurrentThread());
46 DCHECK(!filesystem_id.empty());
47 DCHECK(!ContainsKey(map_, filesystem_id)) << filesystem_id;
48 map_[filesystem_id] = plugin_id;
51 void RemoveFileSystem(const std::string& filesystem_id) {
52 DCHECK(task_runner_->RunsTasksOnCurrentThread());
53 map_.erase(filesystem_id);
56 private:
57 typedef std::map<std::string, std::string> Map;
58 scoped_refptr<base::SequencedTaskRunner> task_runner_;
59 Map map_;
62 namespace {
64 const base::FilePath::CharType* kFileSystemDirectory =
65 SandboxFileSystemBackendDelegate::kFileSystemDirectory;
66 const base::FilePath::CharType* kPluginPrivateDirectory =
67 FILE_PATH_LITERAL("Plugins");
69 base::File::Error OpenFileSystemOnFileTaskRunner(
70 ObfuscatedFileUtil* file_util,
71 PluginPrivateFileSystemBackend::FileSystemIDToPluginMap* plugin_map,
72 const GURL& origin_url,
73 const std::string& filesystem_id,
74 const std::string& plugin_id,
75 OpenFileSystemMode mode) {
76 base::File::Error error = base::File::FILE_ERROR_FAILED;
77 const bool create = (mode == OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT);
78 file_util->GetDirectoryForOriginAndType(
79 origin_url, plugin_id, create, &error);
80 if (error == base::File::FILE_OK)
81 plugin_map->RegisterFileSystem(filesystem_id, plugin_id);
82 return error;
85 } // namespace
87 PluginPrivateFileSystemBackend::PluginPrivateFileSystemBackend(
88 base::SequencedTaskRunner* file_task_runner,
89 const base::FilePath& profile_path,
90 storage::SpecialStoragePolicy* special_storage_policy,
91 const FileSystemOptions& file_system_options)
92 : file_task_runner_(file_task_runner),
93 file_system_options_(file_system_options),
94 base_path_(profile_path.Append(kFileSystemDirectory)
95 .Append(kPluginPrivateDirectory)),
96 plugin_map_(new FileSystemIDToPluginMap(file_task_runner)),
97 weak_factory_(this) {
98 file_util_.reset(
99 new AsyncFileUtilAdapter(new ObfuscatedFileUtil(
100 special_storage_policy,
101 base_path_, file_system_options.env_override(),
102 file_task_runner,
103 base::Bind(&FileSystemIDToPluginMap::GetPluginIDForURL,
104 base::Owned(plugin_map_)),
105 std::set<std::string>(),
106 NULL)));
109 PluginPrivateFileSystemBackend::~PluginPrivateFileSystemBackend() {
110 if (!file_task_runner_->RunsTasksOnCurrentThread()) {
111 AsyncFileUtil* file_util = file_util_.release();
112 if (!file_task_runner_->DeleteSoon(FROM_HERE, file_util))
113 delete file_util;
117 void PluginPrivateFileSystemBackend::OpenPrivateFileSystem(
118 const GURL& origin_url,
119 FileSystemType type,
120 const std::string& filesystem_id,
121 const std::string& plugin_id,
122 OpenFileSystemMode mode,
123 const StatusCallback& callback) {
124 if (!CanHandleType(type) || file_system_options_.is_incognito()) {
125 base::ThreadTaskRunnerHandle::Get()->PostTask(
126 FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_SECURITY));
127 return;
130 PostTaskAndReplyWithResult(
131 file_task_runner_.get(),
132 FROM_HERE,
133 base::Bind(&OpenFileSystemOnFileTaskRunner,
134 obfuscated_file_util(), plugin_map_,
135 origin_url, filesystem_id, plugin_id, mode),
136 callback);
139 bool PluginPrivateFileSystemBackend::CanHandleType(FileSystemType type) const {
140 return type == kFileSystemTypePluginPrivate;
143 void PluginPrivateFileSystemBackend::Initialize(FileSystemContext* context) {
146 void PluginPrivateFileSystemBackend::ResolveURL(
147 const FileSystemURL& url,
148 OpenFileSystemMode mode,
149 const OpenFileSystemCallback& callback) {
150 // We never allow opening a new plugin-private filesystem via usual
151 // ResolveURL.
152 base::ThreadTaskRunnerHandle::Get()->PostTask(
153 FROM_HERE,
154 base::Bind(callback, GURL(), std::string(),
155 base::File::FILE_ERROR_SECURITY));
158 AsyncFileUtil*
159 PluginPrivateFileSystemBackend::GetAsyncFileUtil(FileSystemType type) {
160 return file_util_.get();
163 WatcherManager* PluginPrivateFileSystemBackend::GetWatcherManager(
164 FileSystemType type) {
165 return NULL;
168 CopyOrMoveFileValidatorFactory*
169 PluginPrivateFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
170 FileSystemType type,
171 base::File::Error* error_code) {
172 DCHECK(error_code);
173 *error_code = base::File::FILE_OK;
174 return NULL;
177 FileSystemOperation* PluginPrivateFileSystemBackend::CreateFileSystemOperation(
178 const FileSystemURL& url,
179 FileSystemContext* context,
180 base::File::Error* error_code) const {
181 scoped_ptr<FileSystemOperationContext> operation_context(
182 new FileSystemOperationContext(context));
183 return FileSystemOperation::Create(url, context, operation_context.Pass());
186 bool PluginPrivateFileSystemBackend::SupportsStreaming(
187 const storage::FileSystemURL& url) const {
188 return false;
191 bool PluginPrivateFileSystemBackend::HasInplaceCopyImplementation(
192 storage::FileSystemType type) const {
193 return false;
196 scoped_ptr<storage::FileStreamReader>
197 PluginPrivateFileSystemBackend::CreateFileStreamReader(
198 const FileSystemURL& url,
199 int64 offset,
200 int64 max_bytes_to_read,
201 const base::Time& expected_modification_time,
202 FileSystemContext* context) const {
203 return scoped_ptr<storage::FileStreamReader>();
206 scoped_ptr<FileStreamWriter>
207 PluginPrivateFileSystemBackend::CreateFileStreamWriter(
208 const FileSystemURL& url,
209 int64 offset,
210 FileSystemContext* context) const {
211 return scoped_ptr<FileStreamWriter>();
214 FileSystemQuotaUtil* PluginPrivateFileSystemBackend::GetQuotaUtil() {
215 return this;
218 base::File::Error
219 PluginPrivateFileSystemBackend::DeleteOriginDataOnFileTaskRunner(
220 FileSystemContext* context,
221 storage::QuotaManagerProxy* proxy,
222 const GURL& origin_url,
223 FileSystemType type) {
224 if (!CanHandleType(type))
225 return base::File::FILE_ERROR_SECURITY;
226 bool result = obfuscated_file_util()->DeleteDirectoryForOriginAndType(
227 origin_url, std::string());
228 if (result)
229 return base::File::FILE_OK;
230 return base::File::FILE_ERROR_FAILED;
233 void PluginPrivateFileSystemBackend::GetOriginsForTypeOnFileTaskRunner(
234 FileSystemType type,
235 std::set<GURL>* origins) {
236 if (!CanHandleType(type))
237 return;
238 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator(
239 obfuscated_file_util()->CreateOriginEnumerator());
240 GURL origin;
241 while (!(origin = enumerator->Next()).is_empty())
242 origins->insert(origin);
245 void PluginPrivateFileSystemBackend::GetOriginsForHostOnFileTaskRunner(
246 FileSystemType type,
247 const std::string& host,
248 std::set<GURL>* origins) {
249 if (!CanHandleType(type))
250 return;
251 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator(
252 obfuscated_file_util()->CreateOriginEnumerator());
253 GURL origin;
254 while (!(origin = enumerator->Next()).is_empty()) {
255 if (host == net::GetHostOrSpecFromURL(origin))
256 origins->insert(origin);
260 int64 PluginPrivateFileSystemBackend::GetOriginUsageOnFileTaskRunner(
261 FileSystemContext* context,
262 const GURL& origin_url,
263 FileSystemType type) {
264 // We don't track usage on this filesystem.
265 return 0;
268 scoped_refptr<QuotaReservation>
269 PluginPrivateFileSystemBackend::CreateQuotaReservationOnFileTaskRunner(
270 const GURL& origin_url,
271 FileSystemType type) {
272 // We don't track usage on this filesystem.
273 NOTREACHED();
274 return scoped_refptr<QuotaReservation>();
277 const UpdateObserverList* PluginPrivateFileSystemBackend::GetUpdateObservers(
278 FileSystemType type) const {
279 return NULL;
282 const ChangeObserverList* PluginPrivateFileSystemBackend::GetChangeObservers(
283 FileSystemType type) const {
284 return NULL;
287 const AccessObserverList* PluginPrivateFileSystemBackend::GetAccessObservers(
288 FileSystemType type) const {
289 return NULL;
292 ObfuscatedFileUtil* PluginPrivateFileSystemBackend::obfuscated_file_util() {
293 return static_cast<ObfuscatedFileUtil*>(
294 static_cast<AsyncFileUtilAdapter*>(file_util_.get())->sync_file_util());
297 } // namespace storage