Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / child / fileapi / file_system_dispatcher.cc
blob8d5a42c0461d6156586ff0f20180346f6a19dc5d
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.
5 #include "content/child/fileapi/file_system_dispatcher.h"
7 #include "base/callback.h"
8 #include "base/files/file_util.h"
9 #include "base/process/process.h"
10 #include "content/child/child_thread_impl.h"
11 #include "content/common/fileapi/file_system_messages.h"
12 #include "storage/common/fileapi/file_system_info.h"
14 namespace content {
16 class FileSystemDispatcher::CallbackDispatcher {
17 public:
18 typedef CallbackDispatcher self;
19 typedef FileSystemDispatcher::StatusCallback StatusCallback;
20 typedef FileSystemDispatcher::MetadataCallback MetadataCallback;
21 typedef FileSystemDispatcher::ReadDirectoryCallback ReadDirectoryCallback;
22 typedef FileSystemDispatcher::OpenFileSystemCallback OpenFileSystemCallback;
23 typedef FileSystemDispatcher::ResolveURLCallback ResolveURLCallback;
24 typedef FileSystemDispatcher::WriteCallback WriteCallback;
25 typedef FileSystemDispatcher::OpenFileCallback OpenFileCallback;
27 static CallbackDispatcher* Create(const StatusCallback& callback) {
28 CallbackDispatcher* dispatcher = new CallbackDispatcher;
29 dispatcher->status_callback_ = callback;
30 dispatcher->error_callback_ = callback;
31 return dispatcher;
33 static CallbackDispatcher* Create(const MetadataCallback& callback,
34 const StatusCallback& error_callback) {
35 CallbackDispatcher* dispatcher = new CallbackDispatcher;
36 dispatcher->metadata_callback_ = callback;
37 dispatcher->error_callback_ = error_callback;
38 return dispatcher;
40 static CallbackDispatcher* Create(const CreateSnapshotFileCallback& callback,
41 const StatusCallback& error_callback) {
42 CallbackDispatcher* dispatcher = new CallbackDispatcher;
43 dispatcher->snapshot_callback_ = callback;
44 dispatcher->error_callback_ = error_callback;
45 return dispatcher;
47 static CallbackDispatcher* Create(const ReadDirectoryCallback& callback,
48 const StatusCallback& error_callback) {
49 CallbackDispatcher* dispatcher = new CallbackDispatcher;
50 dispatcher->directory_callback_ = callback;
51 dispatcher->error_callback_ = error_callback;
52 return dispatcher;
54 static CallbackDispatcher* Create(const OpenFileSystemCallback& callback,
55 const StatusCallback& error_callback) {
56 CallbackDispatcher* dispatcher = new CallbackDispatcher;
57 dispatcher->filesystem_callback_ = callback;
58 dispatcher->error_callback_ = error_callback;
59 return dispatcher;
61 static CallbackDispatcher* Create(const ResolveURLCallback& callback,
62 const StatusCallback& error_callback) {
63 CallbackDispatcher* dispatcher = new CallbackDispatcher;
64 dispatcher->resolve_callback_ = callback;
65 dispatcher->error_callback_ = error_callback;
66 return dispatcher;
68 static CallbackDispatcher* Create(const WriteCallback& callback,
69 const StatusCallback& error_callback) {
70 CallbackDispatcher* dispatcher = new CallbackDispatcher;
71 dispatcher->write_callback_ = callback;
72 dispatcher->error_callback_ = error_callback;
73 return dispatcher;
76 ~CallbackDispatcher() {}
78 void DidSucceed() {
79 status_callback_.Run(base::File::FILE_OK);
82 void DidFail(base::File::Error error_code) {
83 error_callback_.Run(error_code);
86 void DidReadMetadata(
87 const base::File::Info& file_info) {
88 metadata_callback_.Run(file_info);
91 void DidCreateSnapshotFile(
92 const base::File::Info& file_info,
93 const base::FilePath& platform_path,
94 int request_id) {
95 snapshot_callback_.Run(file_info, platform_path, request_id);
98 void DidReadDirectory(const std::vector<storage::DirectoryEntry>& entries,
99 bool has_more) {
100 directory_callback_.Run(entries, has_more);
103 void DidOpenFileSystem(const std::string& name,
104 const GURL& root) {
105 filesystem_callback_.Run(name, root);
108 void DidResolveURL(const storage::FileSystemInfo& info,
109 const base::FilePath& file_path,
110 bool is_directory) {
111 resolve_callback_.Run(info, file_path, is_directory);
114 void DidWrite(int64 bytes, bool complete) {
115 write_callback_.Run(bytes, complete);
118 private:
119 CallbackDispatcher() {}
121 StatusCallback status_callback_;
122 MetadataCallback metadata_callback_;
123 CreateSnapshotFileCallback snapshot_callback_;
124 ReadDirectoryCallback directory_callback_;
125 OpenFileSystemCallback filesystem_callback_;
126 ResolveURLCallback resolve_callback_;
127 WriteCallback write_callback_;
129 StatusCallback error_callback_;
131 DISALLOW_COPY_AND_ASSIGN(CallbackDispatcher);
134 FileSystemDispatcher::FileSystemDispatcher() {
137 FileSystemDispatcher::~FileSystemDispatcher() {
138 // Make sure we fire all the remaining callbacks.
139 for (IDMap<CallbackDispatcher, IDMapOwnPointer>::iterator
140 iter(&dispatchers_); !iter.IsAtEnd(); iter.Advance()) {
141 int request_id = iter.GetCurrentKey();
142 CallbackDispatcher* dispatcher = iter.GetCurrentValue();
143 DCHECK(dispatcher);
144 dispatcher->DidFail(base::File::FILE_ERROR_ABORT);
145 dispatchers_.Remove(request_id);
149 bool FileSystemDispatcher::OnMessageReceived(const IPC::Message& msg) {
150 bool handled = true;
151 IPC_BEGIN_MESSAGE_MAP(FileSystemDispatcher, msg)
152 IPC_MESSAGE_HANDLER(FileSystemMsg_DidOpenFileSystem, OnDidOpenFileSystem)
153 IPC_MESSAGE_HANDLER(FileSystemMsg_DidResolveURL, OnDidResolveURL)
154 IPC_MESSAGE_HANDLER(FileSystemMsg_DidSucceed, OnDidSucceed)
155 IPC_MESSAGE_HANDLER(FileSystemMsg_DidReadDirectory, OnDidReadDirectory)
156 IPC_MESSAGE_HANDLER(FileSystemMsg_DidReadMetadata, OnDidReadMetadata)
157 IPC_MESSAGE_HANDLER(FileSystemMsg_DidCreateSnapshotFile,
158 OnDidCreateSnapshotFile)
159 IPC_MESSAGE_HANDLER(FileSystemMsg_DidFail, OnDidFail)
160 IPC_MESSAGE_HANDLER(FileSystemMsg_DidWrite, OnDidWrite)
161 IPC_MESSAGE_UNHANDLED(handled = false)
162 IPC_END_MESSAGE_MAP()
163 return handled;
166 void FileSystemDispatcher::OpenFileSystem(
167 const GURL& origin_url,
168 storage::FileSystemType type,
169 const OpenFileSystemCallback& success_callback,
170 const StatusCallback& error_callback) {
171 int request_id = dispatchers_.Add(
172 CallbackDispatcher::Create(success_callback, error_callback));
173 ChildThreadImpl::current()->Send(new FileSystemHostMsg_OpenFileSystem(
174 request_id, origin_url, type));
177 void FileSystemDispatcher::ResolveURL(
178 const GURL& filesystem_url,
179 const ResolveURLCallback& success_callback,
180 const StatusCallback& error_callback) {
181 int request_id = dispatchers_.Add(
182 CallbackDispatcher::Create(success_callback, error_callback));
183 ChildThreadImpl::current()->Send(new FileSystemHostMsg_ResolveURL(
184 request_id, filesystem_url));
187 void FileSystemDispatcher::DeleteFileSystem(const GURL& origin_url,
188 storage::FileSystemType type,
189 const StatusCallback& callback) {
190 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
191 ChildThreadImpl::current()->Send(new FileSystemHostMsg_DeleteFileSystem(
192 request_id, origin_url, type));
195 void FileSystemDispatcher::Move(
196 const GURL& src_path,
197 const GURL& dest_path,
198 const StatusCallback& callback) {
199 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
200 ChildThreadImpl::current()->Send(new FileSystemHostMsg_Move(
201 request_id, src_path, dest_path));
204 void FileSystemDispatcher::Copy(
205 const GURL& src_path,
206 const GURL& dest_path,
207 const StatusCallback& callback) {
208 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
209 ChildThreadImpl::current()->Send(new FileSystemHostMsg_Copy(
210 request_id, src_path, dest_path));
213 void FileSystemDispatcher::Remove(
214 const GURL& path,
215 bool recursive,
216 const StatusCallback& callback) {
217 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
218 ChildThreadImpl::current()->Send(
219 new FileSystemHostMsg_Remove(request_id, path, recursive));
222 void FileSystemDispatcher::ReadMetadata(
223 const GURL& path,
224 const MetadataCallback& success_callback,
225 const StatusCallback& error_callback) {
226 int request_id = dispatchers_.Add(
227 CallbackDispatcher::Create(success_callback, error_callback));
228 ChildThreadImpl::current()->Send(
229 new FileSystemHostMsg_ReadMetadata(request_id, path));
232 void FileSystemDispatcher::CreateFile(
233 const GURL& path,
234 bool exclusive,
235 const StatusCallback& callback) {
236 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
237 ChildThreadImpl::current()->Send(new FileSystemHostMsg_Create(
238 request_id, path, exclusive,
239 false /* is_directory */, false /* recursive */));
242 void FileSystemDispatcher::CreateDirectory(
243 const GURL& path,
244 bool exclusive,
245 bool recursive,
246 const StatusCallback& callback) {
247 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
248 ChildThreadImpl::current()->Send(new FileSystemHostMsg_Create(
249 request_id, path, exclusive, true /* is_directory */, recursive));
252 void FileSystemDispatcher::Exists(
253 const GURL& path,
254 bool is_directory,
255 const StatusCallback& callback) {
256 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
257 ChildThreadImpl::current()->Send(
258 new FileSystemHostMsg_Exists(request_id, path, is_directory));
261 void FileSystemDispatcher::ReadDirectory(
262 const GURL& path,
263 const ReadDirectoryCallback& success_callback,
264 const StatusCallback& error_callback) {
265 int request_id = dispatchers_.Add(
266 CallbackDispatcher::Create(success_callback, error_callback));
267 ChildThreadImpl::current()->Send(
268 new FileSystemHostMsg_ReadDirectory(request_id, path));
271 void FileSystemDispatcher::Truncate(
272 const GURL& path,
273 int64 offset,
274 int* request_id_out,
275 const StatusCallback& callback) {
276 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
277 ChildThreadImpl::current()->Send(
278 new FileSystemHostMsg_Truncate(request_id, path, offset));
280 if (request_id_out)
281 *request_id_out = request_id;
284 void FileSystemDispatcher::Write(
285 const GURL& path,
286 const std::string& blob_id,
287 int64 offset,
288 int* request_id_out,
289 const WriteCallback& success_callback,
290 const StatusCallback& error_callback) {
291 int request_id = dispatchers_.Add(
292 CallbackDispatcher::Create(success_callback, error_callback));
293 ChildThreadImpl::current()->Send(
294 new FileSystemHostMsg_Write(request_id, path, blob_id, offset));
296 if (request_id_out)
297 *request_id_out = request_id;
300 void FileSystemDispatcher::Cancel(
301 int request_id_to_cancel,
302 const StatusCallback& callback) {
303 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
304 ChildThreadImpl::current()->Send(new FileSystemHostMsg_CancelWrite(
305 request_id, request_id_to_cancel));
308 void FileSystemDispatcher::TouchFile(
309 const GURL& path,
310 const base::Time& last_access_time,
311 const base::Time& last_modified_time,
312 const StatusCallback& callback) {
313 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
314 ChildThreadImpl::current()->Send(
315 new FileSystemHostMsg_TouchFile(
316 request_id, path, last_access_time, last_modified_time));
319 void FileSystemDispatcher::CreateSnapshotFile(
320 const GURL& file_path,
321 const CreateSnapshotFileCallback& success_callback,
322 const StatusCallback& error_callback) {
323 int request_id = dispatchers_.Add(
324 CallbackDispatcher::Create(success_callback, error_callback));
325 ChildThreadImpl::current()->Send(
326 new FileSystemHostMsg_CreateSnapshotFile(
327 request_id, file_path));
330 void FileSystemDispatcher::OnDidOpenFileSystem(int request_id,
331 const std::string& name,
332 const GURL& root) {
333 DCHECK(root.is_valid());
334 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
335 DCHECK(dispatcher);
336 dispatcher->DidOpenFileSystem(name, root);
337 dispatchers_.Remove(request_id);
340 void FileSystemDispatcher::OnDidResolveURL(int request_id,
341 const storage::FileSystemInfo& info,
342 const base::FilePath& file_path,
343 bool is_directory) {
344 DCHECK(info.root_url.is_valid());
345 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
346 DCHECK(dispatcher);
347 dispatcher->DidResolveURL(info, file_path, is_directory);
348 dispatchers_.Remove(request_id);
351 void FileSystemDispatcher::OnDidSucceed(int request_id) {
352 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
353 DCHECK(dispatcher);
354 dispatcher->DidSucceed();
355 dispatchers_.Remove(request_id);
358 void FileSystemDispatcher::OnDidReadMetadata(
359 int request_id, const base::File::Info& file_info) {
360 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
361 DCHECK(dispatcher);
362 dispatcher->DidReadMetadata(file_info);
363 dispatchers_.Remove(request_id);
366 void FileSystemDispatcher::OnDidCreateSnapshotFile(
367 int request_id, const base::File::Info& file_info,
368 const base::FilePath& platform_path) {
369 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
370 DCHECK(dispatcher);
371 dispatcher->DidCreateSnapshotFile(file_info, platform_path, request_id);
372 dispatchers_.Remove(request_id);
375 void FileSystemDispatcher::OnDidReadDirectory(
376 int request_id,
377 const std::vector<storage::DirectoryEntry>& entries,
378 bool has_more) {
379 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
380 DCHECK(dispatcher);
381 dispatcher->DidReadDirectory(entries, has_more);
382 if (!has_more)
383 dispatchers_.Remove(request_id);
386 void FileSystemDispatcher::OnDidFail(
387 int request_id, base::File::Error error_code) {
388 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
389 DCHECK(dispatcher);
390 dispatcher->DidFail(error_code);
391 dispatchers_.Remove(request_id);
394 void FileSystemDispatcher::OnDidWrite(
395 int request_id, int64 bytes, bool complete) {
396 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
397 DCHECK(dispatcher);
398 dispatcher->DidWrite(bytes, complete);
399 if (complete)
400 dispatchers_.Remove(request_id);
403 } // namespace content