When enabling new profile management programmatically, make sure to set the
[chromium-blink-merge.git] / webkit / browser / fileapi / plugin_private_file_system_backend.cc
blob2c8ed3bac8fe8b7c97f5e7f3c60d685c087dff56
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 "webkit/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 "net/base/net_util.h"
13 #include "webkit/browser/blob/file_stream_reader.h"
14 #include "webkit/browser/fileapi/async_file_util_adapter.h"
15 #include "webkit/browser/fileapi/file_stream_writer.h"
16 #include "webkit/browser/fileapi/file_system_context.h"
17 #include "webkit/browser/fileapi/file_system_operation.h"
18 #include "webkit/browser/fileapi/file_system_operation_context.h"
19 #include "webkit/browser/fileapi/file_system_options.h"
20 #include "webkit/browser/fileapi/isolated_context.h"
21 #include "webkit/browser/fileapi/obfuscated_file_util.h"
22 #include "webkit/browser/fileapi/quota/quota_reservation.h"
23 #include "webkit/common/fileapi/file_system_util.h"
25 namespace fileapi {
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 quota::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(
95 kFileSystemDirectory).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::MessageLoopProxy::current()->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::MessageLoopProxy::current()->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 CopyOrMoveFileValidatorFactory*
164 PluginPrivateFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
165 FileSystemType type,
166 base::File::Error* error_code) {
167 DCHECK(error_code);
168 *error_code = base::File::FILE_OK;
169 return NULL;
172 FileSystemOperation* PluginPrivateFileSystemBackend::CreateFileSystemOperation(
173 const FileSystemURL& url,
174 FileSystemContext* context,
175 base::File::Error* error_code) const {
176 scoped_ptr<FileSystemOperationContext> operation_context(
177 new FileSystemOperationContext(context));
178 return FileSystemOperation::Create(url, context, operation_context.Pass());
181 bool PluginPrivateFileSystemBackend::SupportsStreaming(
182 const fileapi::FileSystemURL& url) const {
183 return false;
186 scoped_ptr<webkit_blob::FileStreamReader>
187 PluginPrivateFileSystemBackend::CreateFileStreamReader(
188 const FileSystemURL& url,
189 int64 offset,
190 const base::Time& expected_modification_time,
191 FileSystemContext* context) const {
192 return scoped_ptr<webkit_blob::FileStreamReader>();
195 scoped_ptr<FileStreamWriter>
196 PluginPrivateFileSystemBackend::CreateFileStreamWriter(
197 const FileSystemURL& url,
198 int64 offset,
199 FileSystemContext* context) const {
200 return scoped_ptr<FileStreamWriter>();
203 FileSystemQuotaUtil* PluginPrivateFileSystemBackend::GetQuotaUtil() {
204 return this;
207 base::File::Error
208 PluginPrivateFileSystemBackend::DeleteOriginDataOnFileTaskRunner(
209 FileSystemContext* context,
210 quota::QuotaManagerProxy* proxy,
211 const GURL& origin_url,
212 FileSystemType type) {
213 if (!CanHandleType(type))
214 return base::File::FILE_ERROR_SECURITY;
215 bool result = obfuscated_file_util()->DeleteDirectoryForOriginAndType(
216 origin_url, std::string());
217 if (result)
218 return base::File::FILE_OK;
219 return base::File::FILE_ERROR_FAILED;
222 void PluginPrivateFileSystemBackend::GetOriginsForTypeOnFileTaskRunner(
223 FileSystemType type,
224 std::set<GURL>* origins) {
225 if (!CanHandleType(type))
226 return;
227 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator(
228 obfuscated_file_util()->CreateOriginEnumerator());
229 GURL origin;
230 while (!(origin = enumerator->Next()).is_empty())
231 origins->insert(origin);
234 void PluginPrivateFileSystemBackend::GetOriginsForHostOnFileTaskRunner(
235 FileSystemType type,
236 const std::string& host,
237 std::set<GURL>* origins) {
238 if (!CanHandleType(type))
239 return;
240 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator(
241 obfuscated_file_util()->CreateOriginEnumerator());
242 GURL origin;
243 while (!(origin = enumerator->Next()).is_empty()) {
244 if (host == net::GetHostOrSpecFromURL(origin))
245 origins->insert(origin);
249 int64 PluginPrivateFileSystemBackend::GetOriginUsageOnFileTaskRunner(
250 FileSystemContext* context,
251 const GURL& origin_url,
252 FileSystemType type) {
253 // We don't track usage on this filesystem.
254 return 0;
257 scoped_refptr<QuotaReservation>
258 PluginPrivateFileSystemBackend::CreateQuotaReservationOnFileTaskRunner(
259 const GURL& origin_url,
260 FileSystemType type) {
261 // We don't track usage on this filesystem.
262 NOTREACHED();
263 return scoped_refptr<QuotaReservation>();
266 void PluginPrivateFileSystemBackend::AddFileUpdateObserver(
267 FileSystemType type,
268 FileUpdateObserver* observer,
269 base::SequencedTaskRunner* task_runner) {}
271 void PluginPrivateFileSystemBackend::AddFileChangeObserver(
272 FileSystemType type,
273 FileChangeObserver* observer,
274 base::SequencedTaskRunner* task_runner) {}
276 void PluginPrivateFileSystemBackend::AddFileAccessObserver(
277 FileSystemType type,
278 FileAccessObserver* observer,
279 base::SequencedTaskRunner* task_runner) {}
281 const UpdateObserverList* PluginPrivateFileSystemBackend::GetUpdateObservers(
282 FileSystemType type) const {
283 return NULL;
286 const ChangeObserverList* PluginPrivateFileSystemBackend::GetChangeObservers(
287 FileSystemType type) const {
288 return NULL;
291 const AccessObserverList* PluginPrivateFileSystemBackend::GetAccessObservers(
292 FileSystemType type) const {
293 return NULL;
296 ObfuscatedFileUtil* PluginPrivateFileSystemBackend::obfuscated_file_util() {
297 return static_cast<ObfuscatedFileUtil*>(
298 static_cast<AsyncFileUtilAdapter*>(file_util_.get())->sync_file_util());
301 } // namespace fileapi