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 "chrome/browser/chromeos/drive/file_system.h"
8 #include "base/file_util.h"
9 #include "base/platform_file.h"
10 #include "base/prefs/pref_service.h"
11 #include "chrome/browser/chromeos/drive/change_list_loader.h"
12 #include "chrome/browser/chromeos/drive/drive.pb.h"
13 #include "chrome/browser/chromeos/drive/file_cache.h"
14 #include "chrome/browser/chromeos/drive/file_system/copy_operation.h"
15 #include "chrome/browser/chromeos/drive/file_system/create_directory_operation.h"
16 #include "chrome/browser/chromeos/drive/file_system/create_file_operation.h"
17 #include "chrome/browser/chromeos/drive/file_system/download_operation.h"
18 #include "chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation.h"
19 #include "chrome/browser/chromeos/drive/file_system/move_operation.h"
20 #include "chrome/browser/chromeos/drive/file_system/open_file_operation.h"
21 #include "chrome/browser/chromeos/drive/file_system/remove_operation.h"
22 #include "chrome/browser/chromeos/drive/file_system/search_operation.h"
23 #include "chrome/browser/chromeos/drive/file_system/touch_operation.h"
24 #include "chrome/browser/chromeos/drive/file_system/truncate_operation.h"
25 #include "chrome/browser/chromeos/drive/file_system/update_operation.h"
26 #include "chrome/browser/chromeos/drive/file_system_observer.h"
27 #include "chrome/browser/chromeos/drive/file_system_util.h"
28 #include "chrome/browser/chromeos/drive/job_scheduler.h"
29 #include "chrome/browser/chromeos/drive/logging.h"
30 #include "chrome/browser/chromeos/drive/remove_stale_cache_files.h"
31 #include "chrome/browser/chromeos/drive/resource_entry_conversion.h"
32 #include "chrome/browser/chromeos/drive/search_metadata.h"
33 #include "chrome/browser/chromeos/drive/sync_client.h"
34 #include "chrome/browser/drive/drive_service_interface.h"
35 #include "chrome/common/pref_names.h"
36 #include "content/public/browser/browser_thread.h"
37 #include "google_apis/drive/drive_api_parser.h"
39 using content::BrowserThread
;
44 // Gets a ResourceEntry from the metadata, and overwrites its file info when the
45 // cached file is dirty.
46 FileError
GetLocallyStoredResourceEntry(
47 internal::ResourceMetadata
* resource_metadata
,
48 internal::FileCache
* cache
,
49 const base::FilePath
& file_path
,
50 ResourceEntry
* entry
) {
52 FileError error
= resource_metadata
->GetIdByPath(file_path
, &local_id
);
53 if (error
!= FILE_ERROR_OK
)
56 error
= resource_metadata
->GetResourceEntryById(local_id
, entry
);
57 if (error
!= FILE_ERROR_OK
)
60 // For entries that will never be cached, use the original resource entry
62 if (!entry
->has_file_specific_info() ||
63 entry
->file_specific_info().is_hosted_document())
66 // When no dirty cache is found, use the original resource entry as is.
67 FileCacheEntry cache_entry
;
68 if (!cache
->GetCacheEntry(local_id
, &cache_entry
) || !cache_entry
.is_dirty())
71 // If the cache is dirty, obtain the file info from the cache file itself.
72 base::FilePath local_cache_path
;
73 error
= cache
->GetFile(local_id
, &local_cache_path
);
74 if (error
!= FILE_ERROR_OK
)
77 // TODO(rvargas): Convert this code to use base::File::Info.
78 base::PlatformFileInfo file_info
;
79 if (!base::GetFileInfo(local_cache_path
,
80 reinterpret_cast<base::File::Info
*>(&file_info
))) {
81 return FILE_ERROR_NOT_FOUND
;
84 SetPlatformFileInfoToResourceEntry(file_info
, entry
);
88 // Runs the callback with parameters.
89 void RunGetResourceEntryCallback(const GetResourceEntryCallback
& callback
,
90 scoped_ptr
<ResourceEntry
> entry
,
92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
93 DCHECK(!callback
.is_null());
95 if (error
!= FILE_ERROR_OK
)
97 callback
.Run(error
, entry
.Pass());
100 // Used to implement Pin().
101 FileError
PinInternal(internal::ResourceMetadata
* resource_metadata
,
102 internal::FileCache
* cache
,
103 const base::FilePath
& file_path
,
104 std::string
* local_id
) {
105 FileError error
= resource_metadata
->GetIdByPath(file_path
, local_id
);
106 if (error
!= FILE_ERROR_OK
)
110 error
= resource_metadata
->GetResourceEntryById(*local_id
, &entry
);
111 if (error
!= FILE_ERROR_OK
)
114 // TODO(hashimoto): Support pinning directories. crbug.com/127831
115 if (entry
.file_info().is_directory())
116 return FILE_ERROR_NOT_A_FILE
;
118 return cache
->Pin(*local_id
);
121 // Used to implement Unpin().
122 FileError
UnpinInternal(internal::ResourceMetadata
* resource_metadata
,
123 internal::FileCache
* cache
,
124 const base::FilePath
& file_path
,
125 std::string
* local_id
) {
126 FileError error
= resource_metadata
->GetIdByPath(file_path
, local_id
);
127 if (error
!= FILE_ERROR_OK
)
130 return cache
->Unpin(*local_id
);
133 // Used to implement MarkCacheFileAsMounted().
134 FileError
MarkCacheFileAsMountedInternal(
135 internal::ResourceMetadata
* resource_metadata
,
136 internal::FileCache
* cache
,
137 const base::FilePath
& drive_file_path
,
138 base::FilePath
* cache_file_path
) {
139 std::string local_id
;
140 FileError error
= resource_metadata
->GetIdByPath(drive_file_path
, &local_id
);
141 if (error
!= FILE_ERROR_OK
)
144 return cache
->MarkAsMounted(local_id
, cache_file_path
);
147 // Runs the callback with arguments.
148 void RunMarkMountedCallback(const MarkMountedCallback
& callback
,
149 base::FilePath
* cache_file_path
,
151 DCHECK(!callback
.is_null());
152 callback
.Run(error
, *cache_file_path
);
155 // Used to implement GetCacheEntry.
156 bool GetCacheEntryInternal(internal::ResourceMetadata
* resource_metadata
,
157 internal::FileCache
* cache
,
158 const base::FilePath
& drive_file_path
,
159 FileCacheEntry
* cache_entry
) {
161 if (resource_metadata
->GetIdByPath(drive_file_path
, &id
) != FILE_ERROR_OK
)
164 return cache
->GetCacheEntry(id
, cache_entry
);
167 // Runs the callback with arguments.
168 void RunGetCacheEntryCallback(const GetCacheEntryCallback
& callback
,
169 const FileCacheEntry
* cache_entry
,
171 DCHECK(!callback
.is_null());
172 callback
.Run(success
, *cache_entry
);
175 // Callback for ResourceMetadata::GetLargestChangestamp.
176 // |callback| must not be null.
177 void OnGetLargestChangestamp(
178 FileSystemMetadata metadata
, // Will be modified.
179 const GetFilesystemMetadataCallback
& callback
,
180 int64 largest_changestamp
) {
181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
182 DCHECK(!callback
.is_null());
184 metadata
.largest_changestamp
= largest_changestamp
;
185 callback
.Run(metadata
);
188 // Thin adapter to map GetFileCallback to FileOperationCallback.
189 void GetFileCallbackToFileOperationCallbackAdapter(
190 const FileOperationCallback
& callback
,
192 const base::FilePath
& unused_file_path
,
193 scoped_ptr
<ResourceEntry
> unused_entry
) {
197 // Clears |resource_metadata| and |cache|.
198 FileError
ResetOnBlockingPool(internal::ResourceMetadata
* resource_metadata
,
199 internal::FileCache
* cache
) {
200 FileError error
= resource_metadata
->Reset();
201 if (error
!= FILE_ERROR_OK
)
203 return cache
->ClearAll() ? FILE_ERROR_OK
: FILE_ERROR_FAILED
;
208 FileSystem::FileSystem(
209 PrefService
* pref_service
,
210 internal::FileCache
* cache
,
211 DriveServiceInterface
* drive_service
,
212 JobScheduler
* scheduler
,
213 internal::ResourceMetadata
* resource_metadata
,
214 base::SequencedTaskRunner
* blocking_task_runner
,
215 const base::FilePath
& temporary_file_directory
)
216 : pref_service_(pref_service
),
218 drive_service_(drive_service
),
219 scheduler_(scheduler
),
220 resource_metadata_(resource_metadata
),
221 last_update_check_error_(FILE_ERROR_OK
),
222 blocking_task_runner_(blocking_task_runner
),
223 temporary_file_directory_(temporary_file_directory
),
224 weak_ptr_factory_(this) {
225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
230 FileSystem::~FileSystem() {
231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
233 change_list_loader_
->RemoveObserver(this);
236 void FileSystem::Reset(const FileOperationCallback
& callback
) {
237 // Discard the current loader and operation objects and renew them. This is to
238 // avoid that changes initiated before the metadata reset is applied after the
239 // reset, which may cause an inconsistent state.
240 // TODO(kinaba): callbacks held in the subcomponents are discarded. We might
241 // want to have a way to abort and flush callbacks in in-flight operations.
244 base::PostTaskAndReplyWithResult(
245 blocking_task_runner_
,
247 base::Bind(&ResetOnBlockingPool
, resource_metadata_
, cache_
),
251 void FileSystem::ResetComponents() {
252 file_system::OperationObserver
* observer
= this;
253 copy_operation_
.reset(
254 new file_system::CopyOperation(
255 blocking_task_runner_
.get(),
260 drive_service_
->GetResourceIdCanonicalizer()));
261 create_directory_operation_
.reset(new file_system::CreateDirectoryOperation(
262 blocking_task_runner_
.get(), observer
, scheduler_
, resource_metadata_
));
263 create_file_operation_
.reset(
264 new file_system::CreateFileOperation(blocking_task_runner_
.get(),
269 move_operation_
.reset(
270 new file_system::MoveOperation(blocking_task_runner_
.get(),
272 resource_metadata_
));
273 open_file_operation_
.reset(
274 new file_system::OpenFileOperation(blocking_task_runner_
.get(),
279 temporary_file_directory_
));
280 remove_operation_
.reset(
281 new file_system::RemoveOperation(blocking_task_runner_
.get(),
285 touch_operation_
.reset(new file_system::TouchOperation(
286 blocking_task_runner_
.get(), observer
, resource_metadata_
));
287 truncate_operation_
.reset(
288 new file_system::TruncateOperation(blocking_task_runner_
.get(),
293 temporary_file_directory_
));
294 download_operation_
.reset(
295 new file_system::DownloadOperation(blocking_task_runner_
.get(),
300 temporary_file_directory_
));
301 update_operation_
.reset(
302 new file_system::UpdateOperation(blocking_task_runner_
.get(),
307 search_operation_
.reset(new file_system::SearchOperation(
308 blocking_task_runner_
.get(), scheduler_
, resource_metadata_
));
309 get_file_for_saving_operation_
.reset(
310 new file_system::GetFileForSavingOperation(blocking_task_runner_
.get(),
315 temporary_file_directory_
));
317 sync_client_
.reset(new internal::SyncClient(blocking_task_runner_
.get(),
322 temporary_file_directory_
));
324 change_list_loader_
.reset(new internal::ChangeListLoader(
325 blocking_task_runner_
.get(),
329 change_list_loader_
->AddObserver(this);
332 void FileSystem::CheckForUpdates() {
333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
334 DVLOG(1) << "CheckForUpdates";
336 change_list_loader_
->CheckForUpdates(
337 base::Bind(&FileSystem::OnUpdateChecked
, weak_ptr_factory_
.GetWeakPtr()));
340 void FileSystem::OnUpdateChecked(FileError error
) {
341 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
342 DVLOG(1) << "CheckForUpdates finished: " << FileErrorToString(error
);
343 last_update_check_time_
= base::Time::Now();
344 last_update_check_error_
= error
;
347 void FileSystem::AddObserver(FileSystemObserver
* observer
) {
348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
349 observers_
.AddObserver(observer
);
352 void FileSystem::RemoveObserver(FileSystemObserver
* observer
) {
353 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
354 observers_
.RemoveObserver(observer
);
357 void FileSystem::TransferFileFromLocalToRemote(
358 const base::FilePath
& local_src_file_path
,
359 const base::FilePath
& remote_dest_file_path
,
360 const FileOperationCallback
& callback
) {
361 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
362 DCHECK(!callback
.is_null());
363 copy_operation_
->TransferFileFromLocalToRemote(local_src_file_path
,
364 remote_dest_file_path
,
368 void FileSystem::Copy(const base::FilePath
& src_file_path
,
369 const base::FilePath
& dest_file_path
,
370 bool preserve_last_modified
,
371 const FileOperationCallback
& callback
) {
372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
373 DCHECK(!callback
.is_null());
374 copy_operation_
->Copy(
375 src_file_path
, dest_file_path
, preserve_last_modified
, callback
);
378 void FileSystem::Move(const base::FilePath
& src_file_path
,
379 const base::FilePath
& dest_file_path
,
380 bool preserve_last_modified
,
381 const FileOperationCallback
& callback
) {
382 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
383 DCHECK(!callback
.is_null());
384 move_operation_
->Move(
385 src_file_path
, dest_file_path
, preserve_last_modified
, callback
);
388 void FileSystem::Remove(const base::FilePath
& file_path
,
390 const FileOperationCallback
& callback
) {
391 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
392 DCHECK(!callback
.is_null());
393 remove_operation_
->Remove(file_path
, is_recursive
, callback
);
396 void FileSystem::CreateDirectory(
397 const base::FilePath
& directory_path
,
400 const FileOperationCallback
& callback
) {
401 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
402 DCHECK(!callback
.is_null());
404 // Ensure its parent directory is loaded to the local metadata.
405 change_list_loader_
->LoadDirectoryIfNeeded(
406 directory_path
.DirName(),
407 base::Bind(&FileSystem::CreateDirectoryAfterLoad
,
408 weak_ptr_factory_
.GetWeakPtr(),
409 directory_path
, is_exclusive
, is_recursive
, callback
));
412 void FileSystem::CreateDirectoryAfterLoad(
413 const base::FilePath
& directory_path
,
416 const FileOperationCallback
& callback
,
417 FileError load_error
) {
418 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
419 DCHECK(!callback
.is_null());
421 DVLOG_IF(1, load_error
!= FILE_ERROR_OK
) << "LoadDirectoryIfNeeded failed. "
422 << FileErrorToString(load_error
);
424 create_directory_operation_
->CreateDirectory(
425 directory_path
, is_exclusive
, is_recursive
, callback
);
428 void FileSystem::CreateFile(const base::FilePath
& file_path
,
430 const std::string
& mime_type
,
431 const FileOperationCallback
& callback
) {
432 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
433 DCHECK(!callback
.is_null());
434 create_file_operation_
->CreateFile(
435 file_path
, is_exclusive
, mime_type
, callback
);
438 void FileSystem::TouchFile(const base::FilePath
& file_path
,
439 const base::Time
& last_access_time
,
440 const base::Time
& last_modified_time
,
441 const FileOperationCallback
& callback
) {
442 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
443 DCHECK(!last_access_time
.is_null());
444 DCHECK(!last_modified_time
.is_null());
445 DCHECK(!callback
.is_null());
446 touch_operation_
->TouchFile(
447 file_path
, last_access_time
, last_modified_time
, callback
);
450 void FileSystem::TruncateFile(const base::FilePath
& file_path
,
452 const FileOperationCallback
& callback
) {
453 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
454 DCHECK(!callback
.is_null());
455 truncate_operation_
->Truncate(file_path
, length
, callback
);
458 void FileSystem::Pin(const base::FilePath
& file_path
,
459 const FileOperationCallback
& callback
) {
460 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
461 DCHECK(!callback
.is_null());
463 std::string
* local_id
= new std::string
;
464 base::PostTaskAndReplyWithResult(
465 blocking_task_runner_
,
467 base::Bind(&PinInternal
, resource_metadata_
, cache_
, file_path
, local_id
),
468 base::Bind(&FileSystem::FinishPin
,
469 weak_ptr_factory_
.GetWeakPtr(),
471 base::Owned(local_id
)));
474 void FileSystem::FinishPin(const FileOperationCallback
& callback
,
475 const std::string
* local_id
,
477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
478 DCHECK(!callback
.is_null());
480 if (error
== FILE_ERROR_OK
)
481 sync_client_
->AddFetchTask(*local_id
);
485 void FileSystem::Unpin(const base::FilePath
& file_path
,
486 const FileOperationCallback
& callback
) {
487 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
488 DCHECK(!callback
.is_null());
490 std::string
* local_id
= new std::string
;
491 base::PostTaskAndReplyWithResult(
492 blocking_task_runner_
,
494 base::Bind(&UnpinInternal
,
499 base::Bind(&FileSystem::FinishUnpin
,
500 weak_ptr_factory_
.GetWeakPtr(),
502 base::Owned(local_id
)));
505 void FileSystem::FinishUnpin(const FileOperationCallback
& callback
,
506 const std::string
* local_id
,
508 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
509 DCHECK(!callback
.is_null());
511 if (error
== FILE_ERROR_OK
)
512 sync_client_
->RemoveFetchTask(*local_id
);
516 void FileSystem::GetFile(const base::FilePath
& file_path
,
517 const GetFileCallback
& callback
) {
518 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
519 DCHECK(!callback
.is_null());
521 download_operation_
->EnsureFileDownloadedByPath(
523 ClientContext(USER_INITIATED
),
524 GetFileContentInitializedCallback(),
525 google_apis::GetContentCallback(),
529 void FileSystem::GetFileForSaving(const base::FilePath
& file_path
,
530 const GetFileCallback
& callback
) {
531 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
532 DCHECK(!callback
.is_null());
534 get_file_for_saving_operation_
->GetFileForSaving(file_path
, callback
);
537 void FileSystem::GetFileContent(
538 const base::FilePath
& file_path
,
539 const GetFileContentInitializedCallback
& initialized_callback
,
540 const google_apis::GetContentCallback
& get_content_callback
,
541 const FileOperationCallback
& completion_callback
) {
542 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
543 DCHECK(!initialized_callback
.is_null());
544 DCHECK(!get_content_callback
.is_null());
545 DCHECK(!completion_callback
.is_null());
547 download_operation_
->EnsureFileDownloadedByPath(
549 ClientContext(USER_INITIATED
),
550 initialized_callback
,
551 get_content_callback
,
552 base::Bind(&GetFileCallbackToFileOperationCallbackAdapter
,
553 completion_callback
));
556 void FileSystem::GetResourceEntry(
557 const base::FilePath
& file_path
,
558 const GetResourceEntryCallback
& callback
) {
559 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
560 DCHECK(!callback
.is_null());
562 change_list_loader_
->LoadDirectoryIfNeeded(
564 base::Bind(&FileSystem::GetResourceEntryAfterLoad
,
565 weak_ptr_factory_
.GetWeakPtr(),
570 void FileSystem::GetResourceEntryAfterLoad(
571 const base::FilePath
& file_path
,
572 const GetResourceEntryCallback
& callback
,
574 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
575 DCHECK(!callback
.is_null());
577 DVLOG_IF(1, error
!= FILE_ERROR_OK
) << "LoadDirectoryIfNeeded failed. "
578 << FileErrorToString(error
);
580 scoped_ptr
<ResourceEntry
> entry(new ResourceEntry
);
581 ResourceEntry
* entry_ptr
= entry
.get();
582 base::PostTaskAndReplyWithResult(
583 blocking_task_runner_
,
585 base::Bind(&GetLocallyStoredResourceEntry
,
590 base::Bind(&RunGetResourceEntryCallback
, callback
, base::Passed(&entry
)));
593 void FileSystem::ReadDirectory(
594 const base::FilePath
& directory_path
,
595 const ReadDirectoryCallback
& callback
) {
596 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
597 DCHECK(!callback
.is_null());
599 change_list_loader_
->LoadDirectoryIfNeeded(
601 base::Bind(&FileSystem::ReadDirectoryAfterLoad
,
602 weak_ptr_factory_
.GetWeakPtr(),
607 void FileSystem::ReadDirectoryAfterLoad(
608 const base::FilePath
& directory_path
,
609 const ReadDirectoryCallback
& callback
,
611 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
612 DCHECK(!callback
.is_null());
614 DVLOG_IF(1, error
!= FILE_ERROR_OK
) << "LoadDirectoryIfNeeded failed. "
615 << FileErrorToString(error
);
617 resource_metadata_
->ReadDirectoryByPathOnUIThread(
619 base::Bind(&FileSystem::ReadDirectoryAfterRead
,
620 weak_ptr_factory_
.GetWeakPtr(),
625 void FileSystem::ReadDirectoryAfterRead(
626 const base::FilePath
& directory_path
,
627 const ReadDirectoryCallback
& callback
,
629 scoped_ptr
<ResourceEntryVector
> entries
) {
630 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
631 DCHECK(!callback
.is_null());
633 if (error
!= FILE_ERROR_OK
) {
634 callback
.Run(error
, scoped_ptr
<ResourceEntryVector
>());
637 DCHECK(entries
.get()); // This is valid for empty directories too.
639 // TODO(satorux): Stop handling hide_hosted_docs here. crbug.com/256520.
640 const bool hide_hosted_docs
=
641 pref_service_
->GetBoolean(prefs::kDisableDriveHostedFiles
);
642 scoped_ptr
<ResourceEntryVector
> filtered(new ResourceEntryVector
);
643 for (size_t i
= 0; i
< entries
->size(); ++i
) {
644 if (hide_hosted_docs
&&
645 entries
->at(i
).file_specific_info().is_hosted_document()) {
648 filtered
->push_back(entries
->at(i
));
651 callback
.Run(FILE_ERROR_OK
, filtered
.Pass());
654 void FileSystem::GetAvailableSpace(
655 const GetAvailableSpaceCallback
& callback
) {
656 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
657 DCHECK(!callback
.is_null());
659 change_list_loader_
->GetAboutResource(
660 base::Bind(&FileSystem::OnGetAboutResource
,
661 weak_ptr_factory_
.GetWeakPtr(),
665 void FileSystem::OnGetAboutResource(
666 const GetAvailableSpaceCallback
& callback
,
667 google_apis::GDataErrorCode status
,
668 scoped_ptr
<google_apis::AboutResource
> about_resource
) {
669 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
670 DCHECK(!callback
.is_null());
672 FileError error
= GDataToFileError(status
);
673 if (error
!= FILE_ERROR_OK
) {
674 callback
.Run(error
, -1, -1);
677 DCHECK(about_resource
);
679 callback
.Run(FILE_ERROR_OK
,
680 about_resource
->quota_bytes_total(),
681 about_resource
->quota_bytes_used());
684 void FileSystem::GetShareUrl(
685 const base::FilePath
& file_path
,
686 const GURL
& embed_origin
,
687 const GetShareUrlCallback
& callback
) {
688 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
689 DCHECK(!callback
.is_null());
691 // Resolve the resource id.
692 resource_metadata_
->GetResourceEntryByPathOnUIThread(
694 base::Bind(&FileSystem::GetShareUrlAfterGetResourceEntry
,
695 weak_ptr_factory_
.GetWeakPtr(),
701 void FileSystem::GetShareUrlAfterGetResourceEntry(
702 const base::FilePath
& file_path
,
703 const GURL
& embed_origin
,
704 const GetShareUrlCallback
& callback
,
706 scoped_ptr
<ResourceEntry
> entry
) {
707 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
708 DCHECK(!callback
.is_null());
710 if (error
!= FILE_ERROR_OK
) {
711 callback
.Run(error
, GURL());
714 if (entry
->resource_id().empty()) {
715 // This entry does not exist on the server. Just return.
716 callback
.Run(FILE_ERROR_FAILED
, GURL());
720 scheduler_
->GetShareUrl(
721 entry
->resource_id(),
723 ClientContext(USER_INITIATED
),
724 base::Bind(&FileSystem::OnGetResourceEntryForGetShareUrl
,
725 weak_ptr_factory_
.GetWeakPtr(),
729 void FileSystem::OnGetResourceEntryForGetShareUrl(
730 const GetShareUrlCallback
& callback
,
731 google_apis::GDataErrorCode status
,
732 const GURL
& share_url
) {
733 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
734 DCHECK(!callback
.is_null());
736 FileError error
= GDataToFileError(status
);
737 if (error
!= FILE_ERROR_OK
) {
738 callback
.Run(error
, GURL());
742 if (share_url
.is_empty()) {
743 callback
.Run(FILE_ERROR_FAILED
, GURL());
747 callback
.Run(FILE_ERROR_OK
, share_url
);
750 void FileSystem::Search(const std::string
& search_query
,
751 const GURL
& next_link
,
752 const SearchCallback
& callback
) {
753 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
754 DCHECK(!callback
.is_null());
755 search_operation_
->Search(search_query
, next_link
, callback
);
758 void FileSystem::SearchMetadata(const std::string
& query
,
760 int at_most_num_matches
,
761 const SearchMetadataCallback
& callback
) {
762 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
764 // TODO(satorux): Stop handling hide_hosted_docs here. crbug.com/256520.
765 if (pref_service_
->GetBoolean(prefs::kDisableDriveHostedFiles
))
766 options
|= SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS
;
768 drive::internal::SearchMetadata(blocking_task_runner_
,
776 void FileSystem::OnDirectoryChangedByOperation(
777 const base::FilePath
& directory_path
) {
778 OnDirectoryChanged(directory_path
);
781 void FileSystem::OnCacheFileUploadNeededByOperation(
782 const std::string
& local_id
) {
783 sync_client_
->AddUploadTask(ClientContext(USER_INITIATED
), local_id
);
786 void FileSystem::OnEntryUpdatedByOperation(const std::string
& local_id
) {
787 sync_client_
->AddUpdateTask(local_id
);
790 void FileSystem::OnDriveSyncError(file_system::DriveSyncErrorType type
,
791 const std::string
& local_id
) {
792 base::PostTaskAndReplyWithResult(
793 blocking_task_runner_
,
795 base::Bind(&internal::ResourceMetadata::GetFilePath
,
796 base::Unretained(resource_metadata_
),
798 base::Bind(&FileSystem::OnDriveSyncErrorAfterGetFilePath
,
799 weak_ptr_factory_
.GetWeakPtr(),
803 void FileSystem::OnDriveSyncErrorAfterGetFilePath(
804 file_system::DriveSyncErrorType type
,
805 const base::FilePath
& path
) {
808 FOR_EACH_OBSERVER(FileSystemObserver
,
810 OnDriveSyncError(type
, path
));
813 void FileSystem::OnDirectoryChanged(const base::FilePath
& directory_path
) {
814 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
816 FOR_EACH_OBSERVER(FileSystemObserver
, observers_
,
817 OnDirectoryChanged(directory_path
));
820 void FileSystem::OnLoadFromServerComplete() {
821 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
823 sync_client_
->StartCheckingExistingPinnedFiles();
826 void FileSystem::OnInitialLoadComplete() {
827 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
829 blocking_task_runner_
->PostTask(FROM_HERE
,
830 base::Bind(&internal::RemoveStaleCacheFiles
,
832 resource_metadata_
));
833 sync_client_
->StartProcessingBacklog();
836 void FileSystem::GetMetadata(
837 const GetFilesystemMetadataCallback
& callback
) {
838 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
839 DCHECK(!callback
.is_null());
841 FileSystemMetadata metadata
;
842 metadata
.refreshing
= change_list_loader_
->IsRefreshing();
844 // Metadata related to delta update.
845 metadata
.last_update_check_time
= last_update_check_time_
;
846 metadata
.last_update_check_error
= last_update_check_error_
;
848 base::PostTaskAndReplyWithResult(
849 blocking_task_runner_
,
851 base::Bind(&internal::ResourceMetadata::GetLargestChangestamp
,
852 base::Unretained(resource_metadata_
)),
853 base::Bind(&OnGetLargestChangestamp
, metadata
, callback
));
856 void FileSystem::MarkCacheFileAsMounted(
857 const base::FilePath
& drive_file_path
,
858 const MarkMountedCallback
& callback
) {
859 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
860 DCHECK(!callback
.is_null());
862 base::FilePath
* cache_file_path
= new base::FilePath
;
863 base::PostTaskAndReplyWithResult(
864 blocking_task_runner_
,
866 base::Bind(&MarkCacheFileAsMountedInternal
,
871 base::Bind(&RunMarkMountedCallback
,
873 base::Owned(cache_file_path
)));
876 void FileSystem::MarkCacheFileAsUnmounted(
877 const base::FilePath
& cache_file_path
,
878 const FileOperationCallback
& callback
) {
879 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
880 DCHECK(!callback
.is_null());
882 if (!cache_
->IsUnderFileCacheDirectory(cache_file_path
)) {
883 callback
.Run(FILE_ERROR_FAILED
);
887 base::PostTaskAndReplyWithResult(
888 blocking_task_runner_
,
890 base::Bind(&internal::FileCache::MarkAsUnmounted
,
891 base::Unretained(cache_
),
896 void FileSystem::GetCacheEntry(
897 const base::FilePath
& drive_file_path
,
898 const GetCacheEntryCallback
& callback
) {
899 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
900 DCHECK(!callback
.is_null());
902 FileCacheEntry
* cache_entry
= new FileCacheEntry
;
903 base::PostTaskAndReplyWithResult(
904 blocking_task_runner_
,
906 base::Bind(&GetCacheEntryInternal
,
911 base::Bind(&RunGetCacheEntryCallback
,
913 base::Owned(cache_entry
)));
916 void FileSystem::OpenFile(const base::FilePath
& file_path
,
918 const std::string
& mime_type
,
919 const OpenFileCallback
& callback
) {
920 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
921 DCHECK(!callback
.is_null());
923 open_file_operation_
->OpenFile(file_path
, open_mode
, mime_type
, callback
);