Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / webkit / browser / fileapi / plugin_private_file_system_backend.cc
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.
4
5 #include "webkit/browser/fileapi/plugin_private_file_system_backend.h"
6
7 #include <map>
8
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"
24
25 namespace fileapi {
26
27 class PluginPrivateFileSystemBackend::FileSystemIDToPluginMap {
28  public:
29   explicit FileSystemIDToPluginMap(base::SequencedTaskRunner* task_runner)
30       : task_runner_(task_runner) {}
31   ~FileSystemIDToPluginMap() {}
32
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();
39     }
40     return found->second;
41   }
42
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;
49   }
50
51   void RemoveFileSystem(const std::string& filesystem_id) {
52     DCHECK(task_runner_->RunsTasksOnCurrentThread());
53     map_.erase(filesystem_id);
54   }
55
56  private:
57   typedef std::map<std::string, std::string> Map;
58   scoped_refptr<base::SequencedTaskRunner> task_runner_;
59   Map map_;
60 };
61
62 namespace {
63
64 const base::FilePath::CharType* kFileSystemDirectory =
65     SandboxFileSystemBackendDelegate::kFileSystemDirectory;
66 const base::FilePath::CharType* kPluginPrivateDirectory =
67     FILE_PATH_LITERAL("Plugins");
68
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;
83 }
84
85 }  // namespace
86
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)));
107 }
108
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;
114   }
115 }
116
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;
128   }
129
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);
137 }
138
139 bool PluginPrivateFileSystemBackend::CanHandleType(FileSystemType type) const {
140   return type == kFileSystemTypePluginPrivate;
141 }
142
143 void PluginPrivateFileSystemBackend::Initialize(FileSystemContext* context) {
144 }
145
146 void PluginPrivateFileSystemBackend::OpenFileSystem(
147     const GURL& origin_url,
148     FileSystemType type,
149     OpenFileSystemMode mode,
150     const OpenFileSystemCallback& callback) {
151   // We never allow opening a new plugin-private filesystem via usual
152   // OpenFileSystem.
153   base::MessageLoopProxy::current()->PostTask(
154       FROM_HERE,
155       base::Bind(callback, GURL(), std::string(),
156                  base::File::FILE_ERROR_SECURITY));
157 }
158
159 AsyncFileUtil*
160 PluginPrivateFileSystemBackend::GetAsyncFileUtil(FileSystemType type) {
161   return file_util_.get();
162 }
163
164 CopyOrMoveFileValidatorFactory*
165 PluginPrivateFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
166     FileSystemType type,
167     base::File::Error* error_code) {
168   DCHECK(error_code);
169   *error_code = base::File::FILE_OK;
170   return NULL;
171 }
172
173 FileSystemOperation* PluginPrivateFileSystemBackend::CreateFileSystemOperation(
174     const FileSystemURL& url,
175     FileSystemContext* context,
176     base::File::Error* error_code) const {
177   scoped_ptr<FileSystemOperationContext> operation_context(
178       new FileSystemOperationContext(context));
179   return FileSystemOperation::Create(url, context, operation_context.Pass());
180 }
181
182 scoped_ptr<webkit_blob::FileStreamReader>
183 PluginPrivateFileSystemBackend::CreateFileStreamReader(
184     const FileSystemURL& url,
185     int64 offset,
186     const base::Time& expected_modification_time,
187     FileSystemContext* context) const {
188   return scoped_ptr<webkit_blob::FileStreamReader>();
189 }
190
191 scoped_ptr<FileStreamWriter>
192 PluginPrivateFileSystemBackend::CreateFileStreamWriter(
193     const FileSystemURL& url,
194     int64 offset,
195     FileSystemContext* context) const {
196   return scoped_ptr<FileStreamWriter>();
197 }
198
199 FileSystemQuotaUtil* PluginPrivateFileSystemBackend::GetQuotaUtil() {
200   return this;
201 }
202
203 base::File::Error
204 PluginPrivateFileSystemBackend::DeleteOriginDataOnFileTaskRunner(
205     FileSystemContext* context,
206     quota::QuotaManagerProxy* proxy,
207     const GURL& origin_url,
208     FileSystemType type) {
209   if (!CanHandleType(type))
210     return base::File::FILE_ERROR_SECURITY;
211   bool result = obfuscated_file_util()->DeleteDirectoryForOriginAndType(
212       origin_url, std::string());
213   if (result)
214     return base::File::FILE_OK;
215   return base::File::FILE_ERROR_FAILED;
216 }
217
218 void PluginPrivateFileSystemBackend::GetOriginsForTypeOnFileTaskRunner(
219     FileSystemType type,
220     std::set<GURL>* origins) {
221   if (!CanHandleType(type))
222     return;
223   scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator(
224       obfuscated_file_util()->CreateOriginEnumerator());
225   GURL origin;
226   while (!(origin = enumerator->Next()).is_empty())
227     origins->insert(origin);
228 }
229
230 void PluginPrivateFileSystemBackend::GetOriginsForHostOnFileTaskRunner(
231     FileSystemType type,
232     const std::string& host,
233     std::set<GURL>* origins) {
234   if (!CanHandleType(type))
235     return;
236   scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator(
237       obfuscated_file_util()->CreateOriginEnumerator());
238   GURL origin;
239   while (!(origin = enumerator->Next()).is_empty()) {
240     if (host == net::GetHostOrSpecFromURL(origin))
241       origins->insert(origin);
242   }
243 }
244
245 int64 PluginPrivateFileSystemBackend::GetOriginUsageOnFileTaskRunner(
246     FileSystemContext* context,
247     const GURL& origin_url,
248     FileSystemType type) {
249   // We don't track usage on this filesystem.
250   return 0;
251 }
252
253 scoped_refptr<QuotaReservation>
254 PluginPrivateFileSystemBackend::CreateQuotaReservationOnFileTaskRunner(
255     const GURL& origin_url,
256     FileSystemType type) {
257   // We don't track usage on this filesystem.
258   NOTREACHED();
259   return scoped_refptr<QuotaReservation>();
260 }
261
262 void PluginPrivateFileSystemBackend::AddFileUpdateObserver(
263     FileSystemType type,
264     FileUpdateObserver* observer,
265     base::SequencedTaskRunner* task_runner) {}
266
267 void PluginPrivateFileSystemBackend::AddFileChangeObserver(
268     FileSystemType type,
269     FileChangeObserver* observer,
270     base::SequencedTaskRunner* task_runner) {}
271
272 void PluginPrivateFileSystemBackend::AddFileAccessObserver(
273     FileSystemType type,
274     FileAccessObserver* observer,
275     base::SequencedTaskRunner* task_runner) {}
276
277 const UpdateObserverList* PluginPrivateFileSystemBackend::GetUpdateObservers(
278     FileSystemType type) const {
279   return NULL;
280 }
281
282 const ChangeObserverList* PluginPrivateFileSystemBackend::GetChangeObservers(
283     FileSystemType type) const {
284   return NULL;
285 }
286
287 const AccessObserverList* PluginPrivateFileSystemBackend::GetAccessObservers(
288     FileSystemType type) const {
289   return NULL;
290 }
291
292 ObfuscatedFileUtil* PluginPrivateFileSystemBackend::obfuscated_file_util() {
293   return static_cast<ObfuscatedFileUtil*>(
294       static_cast<AsyncFileUtilAdapter*>(file_util_.get())->sync_file_util());
295 }
296
297 }  // namespace fileapi