Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: chrome/browser/chromeos/gdata/gdata_file_system_proxy.cc

Issue 10874028: Rename GDataFileSystem* to DriveFileSystem* (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/chromeos/gdata/gdata_file_system_proxy.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/platform_file.h"
12 #include "base/string_util.h"
13 #include "base/values.h"
14 #include "chrome/browser/chromeos/gdata/drive.pb.h"
15 #include "chrome/browser/chromeos/gdata/drive_files.h"
16 #include "chrome/browser/chromeos/gdata/gdata_file_system_interface.h"
17 #include "chrome/browser/chromeos/gdata/gdata_system_service.h"
18 #include "chrome/browser/chromeos/gdata/gdata_util.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "webkit/blob/shareable_file_reference.h"
21 #include "webkit/fileapi/file_system_file_util_proxy.h"
22 #include "webkit/fileapi/file_system_types.h"
23 #include "webkit/fileapi/file_system_url.h"
24 #include "webkit/fileapi/file_system_util.h"
25
26 using base::MessageLoopProxy;
27 using content::BrowserThread;
28 using fileapi::FileSystemURL;
29 using fileapi::FileSystemOperationInterface;
30 using webkit_blob::ShareableFileReference;
31
32 namespace gdata {
33
34 namespace {
35
36 const char kDriveRootDirectory[] = "drive";
37 const char kFeedField[] = "feed";
38
39 // Helper function that creates platform file on blocking IO thread pool.
40 void OpenPlatformFileOnIOPool(const FilePath& local_path,
41 int file_flags,
42 base::PlatformFile* platform_file,
43 base::PlatformFileError* open_error) {
44 bool created;
45 *platform_file = base::CreatePlatformFile(local_path,
46 file_flags,
47 &created,
48 open_error);
49 }
50
51 // Helper function to run reply on results of OpenPlatformFileOnIOPool() on
52 // IO thread.
53 void OnPlatformFileOpened(
54 const FileSystemOperationInterface::OpenFileCallback& callback,
55 base::ProcessHandle peer_handle,
56 base::PlatformFile* platform_file,
57 base::PlatformFileError* open_error) {
58 callback.Run(*open_error, *platform_file, peer_handle);
59 }
60
61 // Helper function to run OpenFileCallback from
62 // GDataFileSystemProxy::OpenFile().
63 void OnGetFileByPathForOpen(
64 const FileSystemOperationInterface::OpenFileCallback& callback,
65 int file_flags,
66 base::ProcessHandle peer_handle,
67 DriveFileError file_error,
68 const FilePath& local_path,
69 const std::string& unused_mime_type,
70 DriveFileType file_type) {
71 base::PlatformFileError error =
72 util::DriveFileErrorToPlatformError(file_error);
73 if (error != base::PLATFORM_FILE_OK) {
74 callback.Run(error, base::kInvalidPlatformFileValue, peer_handle);
75 return;
76 }
77
78 base::PlatformFile* platform_file = new base::PlatformFile(
79 base::kInvalidPlatformFileValue);
80 base::PlatformFileError* open_error =
81 new base::PlatformFileError(base::PLATFORM_FILE_ERROR_FAILED);
82 BrowserThread::GetBlockingPool()->PostTaskAndReply(FROM_HERE,
83 base::Bind(&OpenPlatformFileOnIOPool,
84 local_path,
85 file_flags,
86 platform_file,
87 open_error),
88 base::Bind(&OnPlatformFileOpened,
89 callback,
90 peer_handle,
91 base::Owned(platform_file),
92 base::Owned(open_error)));
93 }
94
95 // Helper function to run SnapshotFileCallback from
96 // GDataFileSystemProxy::CreateSnapshotFile().
97 void CallSnapshotFileCallback(
98 const FileSystemOperationInterface::SnapshotFileCallback& callback,
99 const base::PlatformFileInfo& file_info,
100 DriveFileError file_error,
101 const FilePath& local_path,
102 const std::string& unused_mime_type,
103 DriveFileType file_type) {
104 scoped_refptr<ShareableFileReference> file_ref;
105 base::PlatformFileError error =
106 util::DriveFileErrorToPlatformError(file_error);
107
108 // If the file is a hosted document, a temporary JSON file is created to
109 // represent the document. The JSON file is not cached and its lifetime
110 // is managed by ShareableFileReference.
111 if (error == base::PLATFORM_FILE_OK && file_type == HOSTED_DOCUMENT) {
112 file_ref = ShareableFileReference::GetOrCreate(
113 local_path, ShareableFileReference::DELETE_ON_FINAL_RELEASE,
114 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
115 }
116
117 // When reading file, last modified time specified in file info will be
118 // compared to the last modified time of the local version of the drive file.
119 // Since those two values don't generally match (last modification time on the
120 // drive server vs. last modification time of the local, downloaded file), so
121 // we have to opt out from this check. We do this by unsetting last_modified
122 // value in the file info passed to the CreateSnapshot caller.
123 base::PlatformFileInfo final_file_info(file_info);
124 final_file_info.last_modified = base::Time();
125
126 callback.Run(error, final_file_info, local_path, file_ref);
127 }
128
129 // Emits debug log when GDataFileSystem::CloseFile() is complete.
130 void EmitDebugLogForCloseFile(const FilePath& local_path,
131 DriveFileError error_code) {
132 DVLOG(1) << "Closed: " << local_path.AsUTF8Unsafe() << ": " << error_code;
133 }
134
135 void DoTruncateOnFileThread(
136 const FilePath& local_cache_path,
137 int64 length,
138 base::PlatformFileError* result) {
139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
140
141 base::PlatformFile file = base::CreatePlatformFile(
142 local_cache_path,
143 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
144 NULL,
145 result);
146 if (*result == base::PLATFORM_FILE_OK) {
147 DCHECK_NE(base::kInvalidPlatformFileValue, file);
148 if (!base::TruncatePlatformFile(file, length))
149 *result = base::PLATFORM_FILE_ERROR_FAILED;
150 base::ClosePlatformFile(file);
151 }
152 }
153
154 void DidCloseFileForTruncate(
155 const FileSystemOperationInterface::StatusCallback& callback,
156 base::PlatformFileError truncate_result,
157 DriveFileError close_result) {
158 // Reports the first error.
159 callback.Run(truncate_result == base::PLATFORM_FILE_OK ?
160 util::DriveFileErrorToPlatformError(close_result) :
161 truncate_result);
162 }
163
164 } // namespace
165
166 base::FileUtilProxy::Entry DriveEntryProtoToFileUtilProxyEntry(
167 const DriveEntryProto& proto) {
168 base::PlatformFileInfo file_info;
169 DriveEntry::ConvertProtoToPlatformFileInfo(proto.file_info(), &file_info);
170
171 base::FileUtilProxy::Entry entry;
172 entry.name = proto.base_name();
173 entry.is_directory = file_info.is_directory;
174 entry.size = file_info.size;
175 entry.last_modified_time = file_info.last_modified;
176 return entry;
177 }
178
179 // GDataFileSystemProxy class implementation.
180
181 GDataFileSystemProxy::GDataFileSystemProxy(
182 GDataFileSystemInterface* file_system)
183 : file_system_(file_system) {
184 // Should be created from the file browser extension API (AddMountFunction)
185 // on UI thread.
186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
187 }
188
189 void GDataFileSystemProxy::GetFileInfo(const FileSystemURL& file_url,
190 const FileSystemOperationInterface::GetMetadataCallback& callback) {
191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
192 FilePath file_path;
193 if (!ValidateUrl(file_url, &file_path)) {
194 MessageLoopProxy::current()->PostTask(FROM_HERE,
195 base::Bind(callback,
196 base::PLATFORM_FILE_ERROR_NOT_FOUND,
197 base::PlatformFileInfo(),
198 FilePath()));
199 return;
200 }
201
202 file_system_->GetEntryInfoByPath(
203 file_path,
204 base::Bind(&GDataFileSystemProxy::OnGetMetadata,
205 this,
206 file_path,
207 callback));
208 }
209
210 void GDataFileSystemProxy::Copy(const FileSystemURL& src_file_url,
211 const FileSystemURL& dest_file_url,
212 const FileSystemOperationInterface::StatusCallback& callback) {
213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
214
215 FilePath src_file_path, dest_file_path;
216 if (!ValidateUrl(src_file_url, &src_file_path) ||
217 !ValidateUrl(dest_file_url, &dest_file_path)) {
218 MessageLoopProxy::current()->PostTask(FROM_HERE,
219 base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
220 return;
221 }
222
223 file_system_->Copy(
224 src_file_path,
225 dest_file_path,
226 base::Bind(&GDataFileSystemProxy::OnStatusCallback, this, callback));
227 }
228
229 void GDataFileSystemProxy::Move(const FileSystemURL& src_file_url,
230 const FileSystemURL& dest_file_url,
231 const FileSystemOperationInterface::StatusCallback& callback) {
232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
233
234 FilePath src_file_path, dest_file_path;
235 if (!ValidateUrl(src_file_url, &src_file_path) ||
236 !ValidateUrl(dest_file_url, &dest_file_path)) {
237 MessageLoopProxy::current()->PostTask(FROM_HERE,
238 base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
239 return;
240 }
241
242 file_system_->Move(
243 src_file_path,
244 dest_file_path,
245 base::Bind(&GDataFileSystemProxy::OnStatusCallback, this, callback));
246 }
247
248 void GDataFileSystemProxy::ReadDirectory(const FileSystemURL& file_url,
249 const FileSystemOperationInterface::ReadDirectoryCallback& callback) {
250 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
251
252 FilePath file_path;
253 if (!ValidateUrl(file_url, &file_path)) {
254 base::MessageLoopProxy::current()->PostTask(
255 FROM_HERE,
256 base::Bind(callback,
257 base::PLATFORM_FILE_ERROR_NOT_FOUND,
258 std::vector<base::FileUtilProxy::Entry>(),
259 false));
260 return;
261 }
262
263 file_system_->ReadDirectoryByPath(
264 file_path,
265 base::Bind(&GDataFileSystemProxy::OnReadDirectory,
266 this,
267 callback));
268 }
269
270 void GDataFileSystemProxy::Remove(const FileSystemURL& file_url, bool recursive,
271 const FileSystemOperationInterface::StatusCallback& callback) {
272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
273
274 FilePath file_path;
275 if (!ValidateUrl(file_url, &file_path)) {
276 MessageLoopProxy::current()->PostTask(FROM_HERE,
277 base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
278 return;
279 }
280
281 file_system_->Remove(
282 file_path,
283 recursive,
284 base::Bind(&GDataFileSystemProxy::OnStatusCallback, this, callback));
285 }
286
287 void GDataFileSystemProxy::CreateDirectory(
288 const FileSystemURL& file_url,
289 bool exclusive,
290 bool recursive,
291 const FileSystemOperationInterface::StatusCallback& callback) {
292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
293
294 FilePath file_path;
295 if (!ValidateUrl(file_url, &file_path)) {
296 MessageLoopProxy::current()->PostTask(FROM_HERE,
297 base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
298 return;
299 }
300
301 file_system_->CreateDirectory(
302 file_path,
303 exclusive,
304 recursive,
305 base::Bind(&GDataFileSystemProxy::OnStatusCallback, this, callback));
306 }
307
308 void GDataFileSystemProxy::CreateFile(
309 const FileSystemURL& file_url,
310 bool exclusive,
311 const FileSystemOperationInterface::StatusCallback& callback) {
312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
313
314 FilePath file_path;
315 if (!ValidateUrl(file_url, &file_path)) {
316 MessageLoopProxy::current()->PostTask(FROM_HERE,
317 base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
318 return;
319 }
320
321 file_system_->CreateFile(
322 file_path,
323 exclusive,
324 base::Bind(&GDataFileSystemProxy::OnStatusCallback, this, callback));
325 }
326
327 void GDataFileSystemProxy::Truncate(
328 const FileSystemURL& file_url, int64 length,
329 const FileSystemOperationInterface::StatusCallback& callback) {
330 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
331
332 if (length < 0) {
333 MessageLoopProxy::current()->PostTask(FROM_HERE,
334 base::Bind(callback, base::PLATFORM_FILE_ERROR_INVALID_OPERATION));
335 return;
336 }
337
338 FilePath file_path;
339 if (!ValidateUrl(file_url, &file_path)) {
340 MessageLoopProxy::current()->PostTask(FROM_HERE,
341 base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
342 return;
343 }
344
345 // TODO(kinaba): http://crbug.com/132780.
346 // Optimize the cases for small |length|, at least for |length| == 0.
347 // CreateWritableSnapshotFile downloads the whole content unnecessarily.
348 file_system_->OpenFile(
349 file_path,
350 base::Bind(&GDataFileSystemProxy::OnFileOpenedForTruncate,
351 this,
352 file_path,
353 length,
354 callback));
355 }
356
357 void GDataFileSystemProxy::OnOpenFileForWriting(
358 int file_flags,
359 base::ProcessHandle peer_handle,
360 const FileSystemOperationInterface::OpenFileCallback& callback,
361 DriveFileError file_error,
362 const FilePath& local_cache_path) {
363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
364
365 base::PlatformFileError error =
366 util::DriveFileErrorToPlatformError(file_error);
367
368 if (error != base::PLATFORM_FILE_OK) {
369 callback.Run(error, base::kInvalidPlatformFileValue, peer_handle);
370 return;
371 }
372
373 // Cache file prepared for modification is available. Truncate it.
374 // File operation must be done on FILE thread, so relay the operation.
375 base::PlatformFileError* result =
376 new base::PlatformFileError(base::PLATFORM_FILE_ERROR_FAILED);
377 base::PlatformFile* platform_file = new base::PlatformFile(
378 base::kInvalidPlatformFileValue);
379 bool posted = BrowserThread::GetBlockingPool()->PostTaskAndReply(FROM_HERE,
380 base::Bind(&OpenPlatformFileOnIOPool,
381 local_cache_path,
382 file_flags,
383 platform_file,
384 result),
385 base::Bind(&OnPlatformFileOpened,
386 callback,
387 peer_handle,
388 base::Owned(platform_file),
389 base::Owned(result)));
390 DCHECK(posted);
391 }
392
393 void GDataFileSystemProxy::OnCreateFileForOpen(
394 const FilePath& file_path,
395 int file_flags,
396 base::ProcessHandle peer_handle,
397 const FileSystemOperationInterface::OpenFileCallback& callback,
398 DriveFileError file_error) {
399 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
400 base::PlatformFileError create_result =
401 util::DriveFileErrorToPlatformError(file_error);
402
403 if ((create_result == base::PLATFORM_FILE_OK) ||
404 ((create_result == base::PLATFORM_FILE_ERROR_EXISTS) &&
405 (file_flags & base::PLATFORM_FILE_CREATE_ALWAYS))) {
406 // If we are trying to always create an existing file, then
407 // if it really exists open it as truncated.
408 file_flags &= ~base::PLATFORM_FILE_CREATE;
409 file_flags &= ~base::PLATFORM_FILE_CREATE_ALWAYS;
410 file_flags |= base::PLATFORM_FILE_OPEN_TRUNCATED;
411 } else {
412 callback.Run(create_result, base::kInvalidPlatformFileValue, peer_handle);
413 return;
414 }
415
416 // Open created (or existing) file for writing.
417 file_system_->OpenFile(
418 file_path,
419 base::Bind(&GDataFileSystemProxy::OnOpenFileForWriting,
420 this,
421 file_flags,
422 peer_handle,
423 callback));
424 }
425
426 void GDataFileSystemProxy::OnFileOpenedForTruncate(
427 const FilePath& virtual_path,
428 int64 length,
429 const fileapi::FileSystemOperationInterface::StatusCallback& callback,
430 DriveFileError open_result,
431 const FilePath& local_cache_path) {
432 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
433
434 if (open_result != DRIVE_FILE_OK) {
435 callback.Run(util::DriveFileErrorToPlatformError(open_result));
436 return;
437 }
438
439 // Cache file prepared for modification is available. Truncate it.
440 // File operation must be done on FILE thread, so relay the operation.
441 base::PlatformFileError* result =
442 new base::PlatformFileError(base::PLATFORM_FILE_ERROR_FAILED);
443 bool posted = BrowserThread::GetMessageLoopProxyForThread(
444 BrowserThread::FILE)->PostTaskAndReply(
445 FROM_HERE,
446 base::Bind(&DoTruncateOnFileThread,
447 local_cache_path,
448 length,
449 result),
450 base::Bind(&GDataFileSystemProxy::DidTruncate,
451 this,
452 virtual_path,
453 callback,
454 base::Owned(result)));
455 DCHECK(posted);
456 }
457
458 void GDataFileSystemProxy::DidTruncate(
459 const FilePath& virtual_path,
460 const FileSystemOperationInterface::StatusCallback& callback,
461 base::PlatformFileError* truncate_result) {
462 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
463
464 // Truncation finished. We must close the file no matter |truncate_result|
465 // indicates an error or not.
466 file_system_->CloseFile(
467 virtual_path,
468 base::Bind(&DidCloseFileForTruncate,
469 callback,
470 base::PlatformFileError(*truncate_result)));
471 }
472
473 void GDataFileSystemProxy::OpenFile(
474 const FileSystemURL& file_url,
475 int file_flags,
476 base::ProcessHandle peer_handle,
477 const FileSystemOperationInterface::OpenFileCallback& callback) {
478 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
479
480 FilePath file_path;
481 if (!ValidateUrl(file_url, &file_path)) {
482 MessageLoopProxy::current()->PostTask(FROM_HERE,
483 base::Bind(callback,
484 base::PLATFORM_FILE_ERROR_NOT_FOUND,
485 base::kInvalidPlatformFileValue,
486 peer_handle));
487 return;
488 }
489
490 // TODO(zelidrag): Wire all other file open operations.
491 if ((file_flags & base::PLATFORM_FILE_DELETE_ON_CLOSE)) {
492 NOTIMPLEMENTED() << "File create/write operations not yet supported "
493 << file_path.value();
494 MessageLoopProxy::current()->PostTask(FROM_HERE,
495 base::Bind(callback,
496 base::PLATFORM_FILE_ERROR_FAILED,
497 base::kInvalidPlatformFileValue,
498 peer_handle));
499 return;
500 }
501
502 if ((file_flags & base::PLATFORM_FILE_OPEN) ||
503 (file_flags & base::PLATFORM_FILE_OPEN_ALWAYS) ||
504 (file_flags & base::PLATFORM_FILE_OPEN_TRUNCATED)) {
505 if ((file_flags & base::PLATFORM_FILE_OPEN_TRUNCATED) ||
506 (file_flags & base::PLATFORM_FILE_OPEN_ALWAYS) ||
507 (file_flags & base::PLATFORM_FILE_WRITE) ||
508 (file_flags & base::PLATFORM_FILE_EXCLUSIVE_WRITE)) {
509 // Open existing file for writing.
510 file_system_->OpenFile(
511 file_path,
512 base::Bind(&GDataFileSystemProxy::OnOpenFileForWriting,
513 this,
514 file_flags,
515 peer_handle,
516 callback));
517 } else {
518 // Read-only file open.
519 file_system_->GetFileByPath(file_path,
520 base::Bind(&OnGetFileByPathForOpen,
521 callback,
522 file_flags,
523 peer_handle),
524 GetContentCallback());
525 }
526 } else if ((file_flags & base::PLATFORM_FILE_CREATE) ||
527 (file_flags & base::PLATFORM_FILE_CREATE_ALWAYS)) {
528 // Open existing file for writing.
529 file_system_->CreateFile(
530 file_path,
531 file_flags & base::PLATFORM_FILE_EXCLUSIVE_WRITE,
532 base::Bind(&GDataFileSystemProxy::OnCreateFileForOpen,
533 this,
534 file_path,
535 file_flags,
536 peer_handle,
537 callback));
538 } else {
539 NOTREACHED() << "Unhandled file flags combination " << file_flags;
540 MessageLoopProxy::current()->PostTask(FROM_HERE,
541 base::Bind(callback,
542 base::PLATFORM_FILE_ERROR_FAILED,
543 base::kInvalidPlatformFileValue,
544 peer_handle));
545 }
546 }
547
548 void GDataFileSystemProxy::NotifyCloseFile(const FileSystemURL& url) {
549 FilePath file_path;
550 if (!ValidateUrl(url, &file_path))
551 return;
552
553 file_system_->CloseFile(file_path,
554 base::Bind(&EmitDebugLogForCloseFile, file_path));
555 }
556
557 void GDataFileSystemProxy::CreateSnapshotFile(
558 const FileSystemURL& file_url,
559 const FileSystemOperationInterface::SnapshotFileCallback& callback) {
560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
561
562 FilePath file_path;
563 if (!ValidateUrl(file_url, &file_path)) {
564 MessageLoopProxy::current()->PostTask(FROM_HERE,
565 base::Bind(callback,
566 base::PLATFORM_FILE_ERROR_NOT_FOUND,
567 base::PlatformFileInfo(),
568 FilePath(),
569 scoped_refptr<ShareableFileReference>(NULL)));
570 return;
571 }
572
573 file_system_->GetEntryInfoByPath(
574 file_path,
575 base::Bind(&GDataFileSystemProxy::OnGetEntryInfoByPath,
576 this,
577 file_path,
578 callback));
579 }
580
581 void GDataFileSystemProxy::OnGetEntryInfoByPath(
582 const FilePath& entry_path,
583 const FileSystemOperationInterface::SnapshotFileCallback& callback,
584 DriveFileError error,
585 scoped_ptr<DriveEntryProto> entry_proto) {
586 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
587
588 if (error != DRIVE_FILE_OK || !entry_proto.get()) {
589 MessageLoopProxy::current()->PostTask(FROM_HERE,
590 base::Bind(callback,
591 base::PLATFORM_FILE_ERROR_NOT_FOUND,
592 base::PlatformFileInfo(),
593 FilePath(),
594 scoped_refptr<ShareableFileReference>(NULL)));
595 return;
596 }
597
598 base::PlatformFileInfo file_info;
599 DriveEntry::ConvertProtoToPlatformFileInfo(
600 entry_proto->file_info(),
601 &file_info);
602
603 file_system_->GetFileByPath(entry_path,
604 base::Bind(&CallSnapshotFileCallback,
605 callback,
606 file_info),
607 GetContentCallback());
608 }
609
610 void GDataFileSystemProxy::CreateWritableSnapshotFile(
611 const FileSystemURL& file_url,
612 const fileapi::WritableSnapshotFile& callback) {
613 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
614
615 FilePath file_path;
616 if (!ValidateUrl(file_url, &file_path)) {
617 MessageLoopProxy::current()->PostTask(FROM_HERE,
618 base::Bind(callback,
619 base::PLATFORM_FILE_ERROR_NOT_FOUND,
620 FilePath(),
621 scoped_refptr<ShareableFileReference>(NULL)));
622 return;
623 }
624
625 file_system_->OpenFile(
626 file_path,
627 base::Bind(&GDataFileSystemProxy::OnCreateWritableSnapshotFile,
628 this,
629 file_path,
630 callback));
631 }
632
633 GDataFileSystemProxy::~GDataFileSystemProxy() {
634 // Should be deleted from the CrosMountPointProvider on UI thread.
635 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
636 }
637
638 // static.
639 bool GDataFileSystemProxy::ValidateUrl(
640 const FileSystemURL& url, FilePath* file_path) {
641 // what platform you're on.
642 if (!url.is_valid() || url.type() != fileapi::kFileSystemTypeDrive) {
643 return false;
644 }
645 *file_path = url.virtual_path();
646 return true;
647 }
648
649 void GDataFileSystemProxy::OnStatusCallback(
650 const fileapi::FileSystemOperationInterface::StatusCallback& callback,
651 DriveFileError error) {
652 callback.Run(util::DriveFileErrorToPlatformError(error));
653 }
654
655 void GDataFileSystemProxy::OnGetMetadata(
656 const FilePath& file_path,
657 const FileSystemOperationInterface::GetMetadataCallback& callback,
658 DriveFileError error,
659 scoped_ptr<DriveEntryProto> entry_proto) {
660 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
661
662 if (error != DRIVE_FILE_OK) {
663 callback.Run(util::DriveFileErrorToPlatformError(error),
664 base::PlatformFileInfo(),
665 FilePath());
666 return;
667 }
668 DCHECK(entry_proto.get());
669
670 base::PlatformFileInfo file_info;
671 DriveEntry::ConvertProtoToPlatformFileInfo(
672 entry_proto->file_info(),
673 &file_info);
674
675 callback.Run(base::PLATFORM_FILE_OK, file_info, file_path);
676 }
677
678 void GDataFileSystemProxy::OnReadDirectory(
679 const FileSystemOperationInterface::ReadDirectoryCallback&
680 callback,
681 DriveFileError error,
682 bool hide_hosted_documents,
683 scoped_ptr<DriveEntryProtoVector> proto_entries) {
684 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
685
686 if (error != DRIVE_FILE_OK) {
687 callback.Run(util::DriveFileErrorToPlatformError(error),
688 std::vector<base::FileUtilProxy::Entry>(),
689 false);
690 return;
691 }
692 DCHECK(proto_entries.get());
693
694 std::vector<base::FileUtilProxy::Entry> entries;
695 // Convert gdata files to something File API stack can understand.
696 for (size_t i = 0; i < proto_entries->size(); ++i) {
697 const DriveEntryProto& proto = (*proto_entries)[i];
698 if (proto.has_file_specific_info() &&
699 proto.file_specific_info().is_hosted_document() &&
700 hide_hosted_documents) {
701 continue;
702 }
703 entries.push_back(DriveEntryProtoToFileUtilProxyEntry(proto));
704 }
705
706 callback.Run(base::PLATFORM_FILE_OK, entries, false);
707 }
708
709 void GDataFileSystemProxy::OnCreateWritableSnapshotFile(
710 const FilePath& virtual_path,
711 const fileapi::WritableSnapshotFile& callback,
712 DriveFileError result,
713 const FilePath& local_path) {
714 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
715
716 scoped_refptr<ShareableFileReference> file_ref;
717
718 if (result == DRIVE_FILE_OK) {
719 file_ref = ShareableFileReference::GetOrCreate(
720 local_path,
721 ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE,
722 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
723 file_ref->AddFinalReleaseCallback(
724 base::Bind(&GDataFileSystemProxy::CloseWritableSnapshotFile,
725 this,
726 virtual_path));
727 }
728
729 callback.Run(
730 util::DriveFileErrorToPlatformError(result), local_path, file_ref);
731 }
732
733 void GDataFileSystemProxy::CloseWritableSnapshotFile(
734 const FilePath& virtual_path,
735 const FilePath& local_path) {
736 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
737
738 file_system_->CloseFile(virtual_path,
739 base::Bind(&EmitDebugLogForCloseFile, virtual_path));
740 }
741
742 } // namespace gdata
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/gdata/gdata_file_system_proxy.h ('k') | chrome/browser/chromeos/gdata/gdata_file_system_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698