[SyncFS] Build indexes from FileTracker entries on disk.
[chromium-blink-merge.git] / content / child / fileapi / file_system_dispatcher.cc
blob1e69c82faeb4bf429a52b88c1c1b8255b3804b74
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/file_util.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/process/process.h"
11 #include "content/child/child_thread.h"
12 #include "content/common/fileapi/file_system_messages.h"
13 #include "webkit/common/fileapi/file_system_info.h"
15 namespace content {
17 class FileSystemDispatcher::CallbackDispatcher {
18 public:
19 typedef CallbackDispatcher self;
20 typedef FileSystemDispatcher::StatusCallback StatusCallback;
21 typedef FileSystemDispatcher::MetadataCallback MetadataCallback;
22 typedef FileSystemDispatcher::ReadDirectoryCallback ReadDirectoryCallback;
23 typedef FileSystemDispatcher::OpenFileSystemCallback OpenFileSystemCallback;
24 typedef FileSystemDispatcher::ResolveURLCallback ResolveURLCallback;
25 typedef FileSystemDispatcher::WriteCallback WriteCallback;
26 typedef FileSystemDispatcher::OpenFileCallback OpenFileCallback;
28 static CallbackDispatcher* Create(const StatusCallback& callback) {
29 CallbackDispatcher* dispatcher = new CallbackDispatcher;
30 dispatcher->status_callback_ = callback;
31 dispatcher->error_callback_ = callback;
32 return dispatcher;
34 static CallbackDispatcher* Create(const MetadataCallback& callback,
35 const StatusCallback& error_callback) {
36 CallbackDispatcher* dispatcher = new CallbackDispatcher;
37 dispatcher->metadata_callback_ = callback;
38 dispatcher->error_callback_ = error_callback;
39 return dispatcher;
41 static CallbackDispatcher* Create(const CreateSnapshotFileCallback& callback,
42 const StatusCallback& error_callback) {
43 CallbackDispatcher* dispatcher = new CallbackDispatcher;
44 dispatcher->snapshot_callback_ = callback;
45 dispatcher->error_callback_ = error_callback;
46 return dispatcher;
48 static CallbackDispatcher* Create(const ReadDirectoryCallback& callback,
49 const StatusCallback& error_callback) {
50 CallbackDispatcher* dispatcher = new CallbackDispatcher;
51 dispatcher->directory_callback_ = callback;
52 dispatcher->error_callback_ = error_callback;
53 return dispatcher;
55 static CallbackDispatcher* Create(const OpenFileSystemCallback& callback,
56 const StatusCallback& error_callback) {
57 CallbackDispatcher* dispatcher = new CallbackDispatcher;
58 dispatcher->filesystem_callback_ = callback;
59 dispatcher->error_callback_ = error_callback;
60 return dispatcher;
62 static CallbackDispatcher* Create(const ResolveURLCallback& callback,
63 const StatusCallback& error_callback) {
64 CallbackDispatcher* dispatcher = new CallbackDispatcher;
65 dispatcher->resolve_callback_ = callback;
66 dispatcher->error_callback_ = error_callback;
67 return dispatcher;
69 static CallbackDispatcher* Create(const WriteCallback& callback,
70 const StatusCallback& error_callback) {
71 CallbackDispatcher* dispatcher = new CallbackDispatcher;
72 dispatcher->write_callback_ = callback;
73 dispatcher->error_callback_ = error_callback;
74 return dispatcher;
77 ~CallbackDispatcher() {}
79 void DidSucceed() {
80 status_callback_.Run(base::File::FILE_OK);
83 void DidFail(base::File::Error error_code) {
84 error_callback_.Run(error_code);
87 void DidReadMetadata(
88 const base::File::Info& file_info) {
89 metadata_callback_.Run(file_info);
92 void DidCreateSnapshotFile(
93 const base::File::Info& file_info,
94 const base::FilePath& platform_path,
95 int request_id) {
96 snapshot_callback_.Run(file_info, platform_path, request_id);
99 void DidReadDirectory(
100 const std::vector<fileapi::DirectoryEntry>& entries,
101 bool has_more) {
102 directory_callback_.Run(entries, has_more);
105 void DidOpenFileSystem(const std::string& name,
106 const GURL& root) {
107 filesystem_callback_.Run(name, root);
110 void DidResolveURL(const fileapi::FileSystemInfo& info,
111 const base::FilePath& file_path,
112 bool is_directory) {
113 resolve_callback_.Run(info, file_path, is_directory);
116 void DidWrite(int64 bytes, bool complete) {
117 write_callback_.Run(bytes, complete);
120 void DidOpenFile(base::PlatformFile file,
121 int file_open_id,
122 quota::QuotaLimitType quota_policy) {
123 open_callback_.Run(file, file_open_id, quota_policy);
126 private:
127 CallbackDispatcher() {}
129 StatusCallback status_callback_;
130 MetadataCallback metadata_callback_;
131 CreateSnapshotFileCallback snapshot_callback_;
132 ReadDirectoryCallback directory_callback_;
133 OpenFileSystemCallback filesystem_callback_;
134 ResolveURLCallback resolve_callback_;
135 WriteCallback write_callback_;
136 OpenFileCallback open_callback_;
138 StatusCallback error_callback_;
140 DISALLOW_COPY_AND_ASSIGN(CallbackDispatcher);
143 FileSystemDispatcher::FileSystemDispatcher() {
146 FileSystemDispatcher::~FileSystemDispatcher() {
147 // Make sure we fire all the remaining callbacks.
148 for (IDMap<CallbackDispatcher, IDMapOwnPointer>::iterator
149 iter(&dispatchers_); !iter.IsAtEnd(); iter.Advance()) {
150 int request_id = iter.GetCurrentKey();
151 CallbackDispatcher* dispatcher = iter.GetCurrentValue();
152 DCHECK(dispatcher);
153 dispatcher->DidFail(base::File::FILE_ERROR_ABORT);
154 dispatchers_.Remove(request_id);
158 bool FileSystemDispatcher::OnMessageReceived(const IPC::Message& msg) {
159 bool handled = true;
160 IPC_BEGIN_MESSAGE_MAP(FileSystemDispatcher, msg)
161 IPC_MESSAGE_HANDLER(FileSystemMsg_DidOpenFileSystem, OnDidOpenFileSystem)
162 IPC_MESSAGE_HANDLER(FileSystemMsg_DidResolveURL, OnDidResolveURL)
163 IPC_MESSAGE_HANDLER(FileSystemMsg_DidSucceed, OnDidSucceed)
164 IPC_MESSAGE_HANDLER(FileSystemMsg_DidReadDirectory, OnDidReadDirectory)
165 IPC_MESSAGE_HANDLER(FileSystemMsg_DidReadMetadata, OnDidReadMetadata)
166 IPC_MESSAGE_HANDLER(FileSystemMsg_DidCreateSnapshotFile,
167 OnDidCreateSnapshotFile)
168 IPC_MESSAGE_HANDLER(FileSystemMsg_DidFail, OnDidFail)
169 IPC_MESSAGE_HANDLER(FileSystemMsg_DidWrite, OnDidWrite)
170 IPC_MESSAGE_HANDLER(FileSystemMsg_DidOpenFile, OnDidOpenFile)
171 IPC_MESSAGE_UNHANDLED(handled = false)
172 IPC_END_MESSAGE_MAP()
173 return handled;
176 void FileSystemDispatcher::OpenFileSystem(
177 const GURL& origin_url,
178 fileapi::FileSystemType type,
179 const OpenFileSystemCallback& success_callback,
180 const StatusCallback& error_callback) {
181 int request_id = dispatchers_.Add(
182 CallbackDispatcher::Create(success_callback, error_callback));
183 ChildThread::current()->Send(new FileSystemHostMsg_OpenFileSystem(
184 request_id, origin_url, type));
187 void FileSystemDispatcher::ResolveURL(
188 const GURL& filesystem_url,
189 const ResolveURLCallback& success_callback,
190 const StatusCallback& error_callback) {
191 int request_id = dispatchers_.Add(
192 CallbackDispatcher::Create(success_callback, error_callback));
193 ChildThread::current()->Send(new FileSystemHostMsg_ResolveURL(
194 request_id, filesystem_url));
197 void FileSystemDispatcher::DeleteFileSystem(
198 const GURL& origin_url,
199 fileapi::FileSystemType type,
200 const StatusCallback& callback) {
201 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
202 ChildThread::current()->Send(new FileSystemHostMsg_DeleteFileSystem(
203 request_id, origin_url, type));
206 void FileSystemDispatcher::Move(
207 const GURL& src_path,
208 const GURL& dest_path,
209 const StatusCallback& callback) {
210 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
211 ChildThread::current()->Send(new FileSystemHostMsg_Move(
212 request_id, src_path, dest_path));
215 void FileSystemDispatcher::Copy(
216 const GURL& src_path,
217 const GURL& dest_path,
218 const StatusCallback& callback) {
219 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
220 ChildThread::current()->Send(new FileSystemHostMsg_Copy(
221 request_id, src_path, dest_path));
224 void FileSystemDispatcher::Remove(
225 const GURL& path,
226 bool recursive,
227 const StatusCallback& callback) {
228 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
229 ChildThread::current()->Send(
230 new FileSystemHostMsg_Remove(request_id, path, recursive));
233 void FileSystemDispatcher::ReadMetadata(
234 const GURL& path,
235 const MetadataCallback& success_callback,
236 const StatusCallback& error_callback) {
237 int request_id = dispatchers_.Add(
238 CallbackDispatcher::Create(success_callback, error_callback));
239 ChildThread::current()->Send(
240 new FileSystemHostMsg_ReadMetadata(request_id, path));
243 void FileSystemDispatcher::CreateFile(
244 const GURL& path,
245 bool exclusive,
246 const StatusCallback& callback) {
247 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
248 ChildThread::current()->Send(new FileSystemHostMsg_Create(
249 request_id, path, exclusive,
250 false /* is_directory */, false /* recursive */));
253 void FileSystemDispatcher::CreateDirectory(
254 const GURL& path,
255 bool exclusive,
256 bool recursive,
257 const StatusCallback& callback) {
258 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
259 ChildThread::current()->Send(new FileSystemHostMsg_Create(
260 request_id, path, exclusive, true /* is_directory */, recursive));
263 void FileSystemDispatcher::Exists(
264 const GURL& path,
265 bool is_directory,
266 const StatusCallback& callback) {
267 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
268 ChildThread::current()->Send(
269 new FileSystemHostMsg_Exists(request_id, path, is_directory));
272 void FileSystemDispatcher::ReadDirectory(
273 const GURL& path,
274 const ReadDirectoryCallback& success_callback,
275 const StatusCallback& error_callback) {
276 int request_id = dispatchers_.Add(
277 CallbackDispatcher::Create(success_callback, error_callback));
278 ChildThread::current()->Send(
279 new FileSystemHostMsg_ReadDirectory(request_id, path));
282 void FileSystemDispatcher::Truncate(
283 const GURL& path,
284 int64 offset,
285 int* request_id_out,
286 const StatusCallback& callback) {
287 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
288 ChildThread::current()->Send(
289 new FileSystemHostMsg_Truncate(request_id, path, offset));
291 if (request_id_out)
292 *request_id_out = request_id;
295 void FileSystemDispatcher::Write(
296 const GURL& path,
297 const std::string& blob_id,
298 int64 offset,
299 int* request_id_out,
300 const WriteCallback& success_callback,
301 const StatusCallback& error_callback) {
302 int request_id = dispatchers_.Add(
303 CallbackDispatcher::Create(success_callback, error_callback));
304 ChildThread::current()->Send(
305 new FileSystemHostMsg_Write(request_id, path, blob_id, offset));
307 if (request_id_out)
308 *request_id_out = request_id;
311 void FileSystemDispatcher::Cancel(
312 int request_id_to_cancel,
313 const StatusCallback& callback) {
314 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
315 ChildThread::current()->Send(new FileSystemHostMsg_CancelWrite(
316 request_id, request_id_to_cancel));
319 void FileSystemDispatcher::TouchFile(
320 const GURL& path,
321 const base::Time& last_access_time,
322 const base::Time& last_modified_time,
323 const StatusCallback& callback) {
324 int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
325 ChildThread::current()->Send(
326 new FileSystemHostMsg_TouchFile(
327 request_id, path, last_access_time, last_modified_time));
330 void FileSystemDispatcher::CreateSnapshotFile(
331 const GURL& file_path,
332 const CreateSnapshotFileCallback& success_callback,
333 const StatusCallback& error_callback) {
334 int request_id = dispatchers_.Add(
335 CallbackDispatcher::Create(success_callback, error_callback));
336 ChildThread::current()->Send(
337 new FileSystemHostMsg_CreateSnapshotFile(
338 request_id, file_path));
341 void FileSystemDispatcher::OnDidOpenFileSystem(int request_id,
342 const std::string& name,
343 const GURL& root) {
344 DCHECK(root.is_valid());
345 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
346 DCHECK(dispatcher);
347 dispatcher->DidOpenFileSystem(name, root);
348 dispatchers_.Remove(request_id);
351 void FileSystemDispatcher::OnDidResolveURL(int request_id,
352 const fileapi::FileSystemInfo& info,
353 const base::FilePath& file_path,
354 bool is_directory) {
355 DCHECK(info.root_url.is_valid());
356 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
357 DCHECK(dispatcher);
358 dispatcher->DidResolveURL(info, file_path, is_directory);
359 dispatchers_.Remove(request_id);
362 void FileSystemDispatcher::OnDidSucceed(int request_id) {
363 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
364 DCHECK(dispatcher);
365 dispatcher->DidSucceed();
366 dispatchers_.Remove(request_id);
369 void FileSystemDispatcher::OnDidReadMetadata(
370 int request_id, const base::File::Info& file_info) {
371 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
372 DCHECK(dispatcher);
373 dispatcher->DidReadMetadata(file_info);
374 dispatchers_.Remove(request_id);
377 void FileSystemDispatcher::OnDidCreateSnapshotFile(
378 int request_id, const base::File::Info& file_info,
379 const base::FilePath& platform_path) {
380 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
381 DCHECK(dispatcher);
382 dispatcher->DidCreateSnapshotFile(file_info, platform_path, request_id);
383 dispatchers_.Remove(request_id);
386 void FileSystemDispatcher::OnDidReadDirectory(
387 int request_id,
388 const std::vector<fileapi::DirectoryEntry>& entries,
389 bool has_more) {
390 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
391 DCHECK(dispatcher);
392 dispatcher->DidReadDirectory(entries, has_more);
393 if (!has_more)
394 dispatchers_.Remove(request_id);
397 void FileSystemDispatcher::OnDidFail(
398 int request_id, base::File::Error error_code) {
399 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
400 DCHECK(dispatcher);
401 dispatcher->DidFail(error_code);
402 dispatchers_.Remove(request_id);
405 void FileSystemDispatcher::OnDidWrite(
406 int request_id, int64 bytes, bool complete) {
407 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
408 DCHECK(dispatcher);
409 dispatcher->DidWrite(bytes, complete);
410 if (complete)
411 dispatchers_.Remove(request_id);
414 void FileSystemDispatcher::OnDidOpenFile(
415 int request_id,
416 IPC::PlatformFileForTransit file,
417 int file_open_id,
418 quota::QuotaLimitType quota_policy) {
419 CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
420 DCHECK(dispatcher);
421 dispatcher->DidOpenFile(IPC::PlatformFileForTransitToPlatformFile(file),
422 file_open_id,
423 quota_policy);
424 dispatchers_.Remove(request_id);
427 } // namespace content