Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / storage / 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 "storage/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 "storage/browser/blob/file_stream_reader.h"
14 #include "storage/browser/fileapi/async_file_util_adapter.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/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"
24
25 namespace storage {
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     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)));
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::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));
156 }
157
158 AsyncFileUtil*
159 PluginPrivateFileSystemBackend::GetAsyncFileUtil(FileSystemType type) {
160   return file_util_.get();
161 }
162
163 WatcherManager* PluginPrivateFileSystemBackend::GetWatcherManager(
164     FileSystemType type) {
165   return NULL;
166 }
167
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;
175 }
176
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());
184 }
185
186 bool PluginPrivateFileSystemBackend::SupportsStreaming(
187     const storage::FileSystemURL& url) const {
188   return false;
189 }
190
191 bool PluginPrivateFileSystemBackend::HasInplaceCopyImplementation(
192     storage::FileSystemType type) const {
193   return false;
194 }
195
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>();
204 }
205
206 scoped_ptr<FileStreamWriter>
207 PluginPrivateFileSystemBackend::CreateFileStreamWriter(
208     const FileSystemURL& url,
209     int64 offset,
210     FileSystemContext* context) const {
211   return scoped_ptr<FileStreamWriter>();
212 }
213
214 FileSystemQuotaUtil* PluginPrivateFileSystemBackend::GetQuotaUtil() {
215   return this;
216 }
217
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;
231 }
232
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);
243 }
244
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);
257   }
258 }
259
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;
266 }
267
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>();
275 }
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 storage