Update broken references to image assets
[chromium-blink-merge.git] / chrome / browser / chromeos / drive / file_system.cc
blobca6737d337e96c4e32d3d63424210a8923ac9055
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"
7 #include "base/bind.h"
8 #include "base/files/file_util.h"
9 #include "base/prefs/pref_service.h"
10 #include "chrome/browser/chromeos/drive/change_list_loader.h"
11 #include "chrome/browser/chromeos/drive/directory_loader.h"
12 #include "chrome/browser/chromeos/drive/file_system/copy_operation.h"
13 #include "chrome/browser/chromeos/drive/file_system/create_directory_operation.h"
14 #include "chrome/browser/chromeos/drive/file_system/create_file_operation.h"
15 #include "chrome/browser/chromeos/drive/file_system/download_operation.h"
16 #include "chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation.h"
17 #include "chrome/browser/chromeos/drive/file_system/move_operation.h"
18 #include "chrome/browser/chromeos/drive/file_system/open_file_operation.h"
19 #include "chrome/browser/chromeos/drive/file_system/remove_operation.h"
20 #include "chrome/browser/chromeos/drive/file_system/search_operation.h"
21 #include "chrome/browser/chromeos/drive/file_system/set_property_operation.h"
22 #include "chrome/browser/chromeos/drive/file_system/touch_operation.h"
23 #include "chrome/browser/chromeos/drive/file_system/truncate_operation.h"
24 #include "chrome/browser/chromeos/drive/file_system_observer.h"
25 #include "chrome/browser/chromeos/drive/remove_stale_cache_files.h"
26 #include "chrome/browser/chromeos/drive/search_metadata.h"
27 #include "chrome/browser/chromeos/drive/sync_client.h"
28 #include "components/drive/drive.pb.h"
29 #include "components/drive/drive_pref_names.h"
30 #include "components/drive/file_cache.h"
31 #include "components/drive/file_change.h"
32 #include "components/drive/file_system_core_util.h"
33 #include "components/drive/job_scheduler.h"
34 #include "components/drive/resource_entry_conversion.h"
35 #include "google_apis/drive/drive_api_parser.h"
37 namespace drive {
38 namespace {
40 // Gets a ResourceEntry from the metadata, and overwrites its file info when the
41 // cached file is dirty.
42 FileError GetLocallyStoredResourceEntry(
43 internal::ResourceMetadata* resource_metadata,
44 internal::FileCache* cache,
45 const base::FilePath& file_path,
46 ResourceEntry* entry) {
47 std::string local_id;
48 FileError error = resource_metadata->GetIdByPath(file_path, &local_id);
49 if (error != FILE_ERROR_OK)
50 return error;
52 error = resource_metadata->GetResourceEntryById(local_id, entry);
53 if (error != FILE_ERROR_OK)
54 return error;
56 // For entries that will never be cached, use the original resource entry
57 // as is.
58 if (!entry->has_file_specific_info() ||
59 entry->file_specific_info().is_hosted_document())
60 return FILE_ERROR_OK;
62 // When cache is not found, use the original resource entry as is.
63 if (!entry->file_specific_info().has_cache_state())
64 return FILE_ERROR_OK;
66 // When cache is non-dirty and obsolete (old hash), use the original entry.
67 if (!entry->file_specific_info().cache_state().is_dirty() &&
68 entry->file_specific_info().md5() !=
69 entry->file_specific_info().cache_state().md5())
70 return FILE_ERROR_OK;
72 // If there's a valid cache, obtain the file info from the cache file itself.
73 base::FilePath local_cache_path;
74 error = cache->GetFile(local_id, &local_cache_path);
75 if (error != FILE_ERROR_OK)
76 return error;
78 base::File::Info file_info;
79 if (!base::GetFileInfo(local_cache_path, &file_info))
80 return FILE_ERROR_NOT_FOUND;
82 entry->mutable_file_info()->set_size(file_info.size);
83 return FILE_ERROR_OK;
86 // Runs the callback with parameters.
87 void RunGetResourceEntryCallback(const GetResourceEntryCallback& callback,
88 scoped_ptr<ResourceEntry> entry,
89 FileError error) {
90 DCHECK(!callback.is_null());
92 if (error != FILE_ERROR_OK)
93 entry.reset();
94 callback.Run(error, entry.Pass());
97 // Used to implement Pin().
98 FileError PinInternal(internal::ResourceMetadata* resource_metadata,
99 internal::FileCache* cache,
100 const base::FilePath& file_path,
101 std::string* local_id) {
102 FileError error = resource_metadata->GetIdByPath(file_path, local_id);
103 if (error != FILE_ERROR_OK)
104 return error;
106 ResourceEntry entry;
107 error = resource_metadata->GetResourceEntryById(*local_id, &entry);
108 if (error != FILE_ERROR_OK)
109 return error;
111 // TODO(hashimoto): Support pinning directories. crbug.com/127831
112 if (entry.file_info().is_directory())
113 return FILE_ERROR_NOT_A_FILE;
115 return cache->Pin(*local_id);
118 // Used to implement Unpin().
119 FileError UnpinInternal(internal::ResourceMetadata* resource_metadata,
120 internal::FileCache* cache,
121 const base::FilePath& file_path,
122 std::string* local_id) {
123 FileError error = resource_metadata->GetIdByPath(file_path, local_id);
124 if (error != FILE_ERROR_OK)
125 return error;
127 return cache->Unpin(*local_id);
130 // Used to implement MarkCacheFileAsMounted().
131 FileError MarkCacheFileAsMountedInternal(
132 internal::ResourceMetadata* resource_metadata,
133 internal::FileCache* cache,
134 const base::FilePath& drive_file_path,
135 base::FilePath* cache_file_path) {
136 std::string local_id;
137 FileError error = resource_metadata->GetIdByPath(drive_file_path, &local_id);
138 if (error != FILE_ERROR_OK)
139 return error;
141 return cache->MarkAsMounted(local_id, cache_file_path);
144 // Runs the callback with arguments.
145 void RunMarkMountedCallback(const MarkMountedCallback& callback,
146 base::FilePath* cache_file_path,
147 FileError error) {
148 DCHECK(!callback.is_null());
149 callback.Run(error, *cache_file_path);
152 // Callback for ResourceMetadata::GetLargestChangestamp.
153 // |callback| must not be null.
154 void OnGetLargestChangestamp(
155 FileSystemMetadata metadata, // Will be modified.
156 const GetFilesystemMetadataCallback& callback,
157 const int64* largest_changestamp,
158 FileError error) {
159 DCHECK(!callback.is_null());
161 metadata.largest_changestamp = *largest_changestamp;
162 callback.Run(metadata);
165 // Thin adapter to map GetFileCallback to FileOperationCallback.
166 void GetFileCallbackToFileOperationCallbackAdapter(
167 const FileOperationCallback& callback,
168 FileError error,
169 const base::FilePath& unused_file_path,
170 scoped_ptr<ResourceEntry> unused_entry) {
171 callback.Run(error);
174 // Clears |resource_metadata| and |cache|.
175 FileError ResetOnBlockingPool(internal::ResourceMetadata* resource_metadata,
176 internal::FileCache* cache) {
177 FileError error = resource_metadata->Reset();
178 if (error != FILE_ERROR_OK)
179 return error;
180 return cache->ClearAll() ? FILE_ERROR_OK : FILE_ERROR_FAILED;
183 // Part of GetPathFromResourceId().
184 // Obtains |file_path| from |resource_id|. The function should be run on the
185 // blocking pool.
186 FileError GetPathFromResourceIdOnBlockingPool(
187 internal::ResourceMetadata* resource_metadata,
188 const std::string& resource_id,
189 base::FilePath* file_path) {
190 std::string local_id;
191 const FileError error =
192 resource_metadata->GetIdByResourceId(resource_id, &local_id);
193 if (error != FILE_ERROR_OK)
194 return error;
195 return resource_metadata->GetFilePath(local_id, file_path);
198 // Part of GetPathFromResourceId().
199 // Called when GetPathFromResourceIdInBlockingPool is complete.
200 void GetPathFromResourceIdAfterGetPath(base::FilePath* file_path,
201 const GetFilePathCallback& callback,
202 FileError error) {
203 callback.Run(error, *file_path);
206 bool FreeDiskSpaceIfNeededForOnBlockingPool(internal::FileCache* cache,
207 int64 num_bytes) {
208 return cache->FreeDiskSpaceIfNeededFor(num_bytes);
211 // Excludes hosted documents from the given entries.
212 // Used to implement ReadDirectory().
213 void FilterHostedDocuments(const ReadDirectoryEntriesCallback& callback,
214 scoped_ptr<ResourceEntryVector> entries) {
215 DCHECK(!callback.is_null());
217 if (entries) {
218 // TODO(kinaba): Stop handling hide_hosted_docs here. crbug.com/256520.
219 scoped_ptr<ResourceEntryVector> filtered(new ResourceEntryVector);
220 for (size_t i = 0; i < entries->size(); ++i) {
221 if (entries->at(i).file_specific_info().is_hosted_document()) {
222 continue;
224 filtered->push_back(entries->at(i));
226 entries.swap(filtered);
228 callback.Run(entries.Pass());
231 // Adapter for using FileOperationCallback as google_apis::EntryActionCallback.
232 void RunFileOperationCallbackAsEntryActionCallback(
233 const FileOperationCallback& callback,
234 google_apis::DriveApiErrorCode error) {
235 callback.Run(GDataToFileError(error));
238 // Checks if the |entry|'s hash is included in |hashes|.
239 bool CheckHashes(const std::set<std::string>& hashes,
240 const ResourceEntry& entry) {
241 return hashes.find(entry.file_specific_info().md5()) != hashes.end();
244 // Runs |callback| with |error| and the list of HashAndFilePath obtained from
245 // |original_result|.
246 void RunSearchByHashesCallback(
247 const SearchByHashesCallback& callback,
248 FileError error,
249 scoped_ptr<MetadataSearchResultVector> original_result) {
250 std::vector<HashAndFilePath> result;
251 if (error != FILE_ERROR_OK) {
252 callback.Run(error, result);
253 return;
255 for (const auto& search_result : *original_result) {
256 HashAndFilePath hash_and_path;
257 hash_and_path.hash = search_result.md5;
258 hash_and_path.path = search_result.path;
259 result.push_back(hash_and_path);
261 callback.Run(FILE_ERROR_OK, result);
264 } // namespace
266 struct FileSystem::CreateDirectoryParams {
267 base::FilePath directory_path;
268 bool is_exclusive;
269 bool is_recursive;
270 FileOperationCallback callback;
273 FileSystem::FileSystem(PrefService* pref_service,
274 EventLogger* logger,
275 internal::FileCache* cache,
276 JobScheduler* scheduler,
277 internal::ResourceMetadata* resource_metadata,
278 base::SequencedTaskRunner* blocking_task_runner,
279 base::SingleThreadTaskRunner* file_task_runner,
280 const base::FilePath& temporary_file_directory)
281 : pref_service_(pref_service),
282 logger_(logger),
283 cache_(cache),
284 scheduler_(scheduler),
285 resource_metadata_(resource_metadata),
286 last_update_check_error_(FILE_ERROR_OK),
287 blocking_task_runner_(blocking_task_runner),
288 file_task_runner_(file_task_runner),
289 temporary_file_directory_(temporary_file_directory),
290 weak_ptr_factory_(this) {
291 ResetComponents();
294 FileSystem::~FileSystem() {
295 DCHECK(thread_checker_.CalledOnValidThread());
297 directory_loader_->RemoveObserver(this);
298 change_list_loader_->RemoveObserver(this);
301 void FileSystem::Reset(const FileOperationCallback& callback) {
302 // Discard the current loader and operation objects and renew them. This is to
303 // avoid that changes initiated before the metadata reset is applied after the
304 // reset, which may cause an inconsistent state.
305 // TODO(kinaba): callbacks held in the subcomponents are discarded. We might
306 // want to have a way to abort and flush callbacks in in-flight operations.
307 ResetComponents();
309 base::PostTaskAndReplyWithResult(
310 blocking_task_runner_.get(),
311 FROM_HERE,
312 base::Bind(&ResetOnBlockingPool, resource_metadata_, cache_),
313 callback);
316 void FileSystem::ResetComponents() {
317 file_system::OperationDelegate* delegate = this;
319 about_resource_loader_.reset(new internal::AboutResourceLoader(scheduler_));
320 loader_controller_.reset(new internal::LoaderController);
321 change_list_loader_.reset(new internal::ChangeListLoader(
322 logger_,
323 blocking_task_runner_.get(),
324 resource_metadata_,
325 scheduler_,
326 about_resource_loader_.get(),
327 loader_controller_.get()));
328 change_list_loader_->AddObserver(this);
329 directory_loader_.reset(new internal::DirectoryLoader(
330 logger_,
331 blocking_task_runner_.get(),
332 resource_metadata_,
333 scheduler_,
334 about_resource_loader_.get(),
335 loader_controller_.get()));
336 directory_loader_->AddObserver(this);
338 sync_client_.reset(new internal::SyncClient(blocking_task_runner_.get(),
339 delegate,
340 scheduler_,
341 resource_metadata_,
342 cache_,
343 loader_controller_.get(),
344 temporary_file_directory_));
346 copy_operation_.reset(
347 new file_system::CopyOperation(blocking_task_runner_.get(),
348 delegate,
349 scheduler_,
350 resource_metadata_,
351 cache_));
352 create_directory_operation_.reset(new file_system::CreateDirectoryOperation(
353 blocking_task_runner_.get(), delegate, resource_metadata_));
354 create_file_operation_.reset(
355 new file_system::CreateFileOperation(blocking_task_runner_.get(),
356 delegate,
357 resource_metadata_));
358 move_operation_.reset(
359 new file_system::MoveOperation(blocking_task_runner_.get(),
360 delegate,
361 resource_metadata_));
362 open_file_operation_.reset(
363 new file_system::OpenFileOperation(blocking_task_runner_.get(),
364 delegate,
365 scheduler_,
366 resource_metadata_,
367 cache_,
368 temporary_file_directory_));
369 remove_operation_.reset(
370 new file_system::RemoveOperation(blocking_task_runner_.get(),
371 delegate,
372 resource_metadata_,
373 cache_));
374 touch_operation_.reset(new file_system::TouchOperation(
375 blocking_task_runner_.get(), delegate, resource_metadata_));
376 truncate_operation_.reset(
377 new file_system::TruncateOperation(blocking_task_runner_.get(),
378 delegate,
379 scheduler_,
380 resource_metadata_,
381 cache_,
382 temporary_file_directory_));
383 download_operation_.reset(
384 new file_system::DownloadOperation(blocking_task_runner_.get(),
385 delegate,
386 scheduler_,
387 resource_metadata_,
388 cache_,
389 temporary_file_directory_));
390 search_operation_.reset(new file_system::SearchOperation(
391 blocking_task_runner_.get(), scheduler_, resource_metadata_,
392 loader_controller_.get()));
393 get_file_for_saving_operation_.reset(
394 new file_system::GetFileForSavingOperation(
395 logger_, blocking_task_runner_.get(), file_task_runner_.get(),
396 delegate, scheduler_, resource_metadata_, cache_,
397 temporary_file_directory_));
398 set_property_operation_.reset(new file_system::SetPropertyOperation(
399 blocking_task_runner_.get(), delegate, resource_metadata_));
402 void FileSystem::CheckForUpdates() {
403 DCHECK(thread_checker_.CalledOnValidThread());
404 DVLOG(1) << "CheckForUpdates";
406 change_list_loader_->CheckForUpdates(
407 base::Bind(&FileSystem::OnUpdateChecked, weak_ptr_factory_.GetWeakPtr()));
410 void FileSystem::OnUpdateChecked(FileError error) {
411 DCHECK(thread_checker_.CalledOnValidThread());
412 DVLOG(1) << "CheckForUpdates finished: " << FileErrorToString(error);
413 last_update_check_time_ = base::Time::Now();
414 last_update_check_error_ = error;
417 void FileSystem::AddObserver(FileSystemObserver* observer) {
418 DCHECK(thread_checker_.CalledOnValidThread());
419 observers_.AddObserver(observer);
422 void FileSystem::RemoveObserver(FileSystemObserver* observer) {
423 DCHECK(thread_checker_.CalledOnValidThread());
424 observers_.RemoveObserver(observer);
427 void FileSystem::TransferFileFromLocalToRemote(
428 const base::FilePath& local_src_file_path,
429 const base::FilePath& remote_dest_file_path,
430 const FileOperationCallback& callback) {
431 DCHECK(thread_checker_.CalledOnValidThread());
432 DCHECK(!callback.is_null());
433 copy_operation_->TransferFileFromLocalToRemote(local_src_file_path,
434 remote_dest_file_path,
435 callback);
438 void FileSystem::Copy(const base::FilePath& src_file_path,
439 const base::FilePath& dest_file_path,
440 bool preserve_last_modified,
441 const FileOperationCallback& callback) {
442 DCHECK(thread_checker_.CalledOnValidThread());
443 DCHECK(!callback.is_null());
444 copy_operation_->Copy(
445 src_file_path, dest_file_path, preserve_last_modified, callback);
448 void FileSystem::Move(const base::FilePath& src_file_path,
449 const base::FilePath& dest_file_path,
450 const FileOperationCallback& callback) {
451 DCHECK(thread_checker_.CalledOnValidThread());
452 DCHECK(!callback.is_null());
453 move_operation_->Move(src_file_path, dest_file_path, callback);
456 void FileSystem::Remove(const base::FilePath& file_path,
457 bool is_recursive,
458 const FileOperationCallback& callback) {
459 DCHECK(thread_checker_.CalledOnValidThread());
460 DCHECK(!callback.is_null());
461 remove_operation_->Remove(file_path, is_recursive, callback);
464 void FileSystem::CreateDirectory(
465 const base::FilePath& directory_path,
466 bool is_exclusive,
467 bool is_recursive,
468 const FileOperationCallback& callback) {
469 DCHECK(thread_checker_.CalledOnValidThread());
470 DCHECK(!callback.is_null());
472 CreateDirectoryParams params;
473 params.directory_path = directory_path;
474 params.is_exclusive = is_exclusive;
475 params.is_recursive = is_recursive;
476 params.callback = callback;
478 // Ensure its parent directory is loaded to the local metadata.
479 ReadDirectory(directory_path.DirName(),
480 ReadDirectoryEntriesCallback(),
481 base::Bind(&FileSystem::CreateDirectoryAfterRead,
482 weak_ptr_factory_.GetWeakPtr(), params));
485 void FileSystem::CreateDirectoryAfterRead(const CreateDirectoryParams& params,
486 FileError error) {
487 DCHECK(thread_checker_.CalledOnValidThread());
488 DCHECK(!params.callback.is_null());
490 DVLOG_IF(1, error != FILE_ERROR_OK) << "ReadDirectory failed. "
491 << FileErrorToString(error);
493 create_directory_operation_->CreateDirectory(
494 params.directory_path, params.is_exclusive, params.is_recursive,
495 params.callback);
498 void FileSystem::CreateFile(const base::FilePath& file_path,
499 bool is_exclusive,
500 const std::string& mime_type,
501 const FileOperationCallback& callback) {
502 DCHECK(thread_checker_.CalledOnValidThread());
503 DCHECK(!callback.is_null());
504 create_file_operation_->CreateFile(
505 file_path, is_exclusive, mime_type, callback);
508 void FileSystem::TouchFile(const base::FilePath& file_path,
509 const base::Time& last_access_time,
510 const base::Time& last_modified_time,
511 const FileOperationCallback& callback) {
512 DCHECK(thread_checker_.CalledOnValidThread());
513 DCHECK(!callback.is_null());
514 touch_operation_->TouchFile(
515 file_path, last_access_time, last_modified_time, callback);
518 void FileSystem::TruncateFile(const base::FilePath& file_path,
519 int64 length,
520 const FileOperationCallback& callback) {
521 DCHECK(thread_checker_.CalledOnValidThread());
522 DCHECK(!callback.is_null());
523 truncate_operation_->Truncate(file_path, length, callback);
526 void FileSystem::Pin(const base::FilePath& file_path,
527 const FileOperationCallback& callback) {
528 DCHECK(thread_checker_.CalledOnValidThread());
529 DCHECK(!callback.is_null());
531 std::string* local_id = new std::string;
532 base::PostTaskAndReplyWithResult(
533 blocking_task_runner_.get(),
534 FROM_HERE,
535 base::Bind(&PinInternal, resource_metadata_, cache_, file_path, local_id),
536 base::Bind(&FileSystem::FinishPin,
537 weak_ptr_factory_.GetWeakPtr(),
538 callback,
539 base::Owned(local_id)));
542 void FileSystem::FinishPin(const FileOperationCallback& callback,
543 const std::string* local_id,
544 FileError error) {
545 DCHECK(thread_checker_.CalledOnValidThread());
546 DCHECK(!callback.is_null());
548 if (error == FILE_ERROR_OK)
549 sync_client_->AddFetchTask(*local_id);
550 callback.Run(error);
553 void FileSystem::Unpin(const base::FilePath& file_path,
554 const FileOperationCallback& callback) {
555 DCHECK(thread_checker_.CalledOnValidThread());
556 DCHECK(!callback.is_null());
558 std::string* local_id = new std::string;
559 base::PostTaskAndReplyWithResult(
560 blocking_task_runner_.get(),
561 FROM_HERE,
562 base::Bind(
563 &UnpinInternal, resource_metadata_, cache_, file_path, local_id),
564 base::Bind(&FileSystem::FinishUnpin,
565 weak_ptr_factory_.GetWeakPtr(),
566 callback,
567 base::Owned(local_id)));
570 void FileSystem::FinishUnpin(const FileOperationCallback& callback,
571 const std::string* local_id,
572 FileError error) {
573 DCHECK(thread_checker_.CalledOnValidThread());
574 DCHECK(!callback.is_null());
576 if (error == FILE_ERROR_OK)
577 sync_client_->RemoveFetchTask(*local_id);
578 callback.Run(error);
581 void FileSystem::GetFile(const base::FilePath& file_path,
582 const GetFileCallback& callback) {
583 DCHECK(thread_checker_.CalledOnValidThread());
584 DCHECK(!callback.is_null());
586 download_operation_->EnsureFileDownloadedByPath(
587 file_path,
588 ClientContext(USER_INITIATED),
589 GetFileContentInitializedCallback(),
590 google_apis::GetContentCallback(),
591 callback);
594 void FileSystem::GetFileForSaving(const base::FilePath& file_path,
595 const GetFileCallback& callback) {
596 DCHECK(thread_checker_.CalledOnValidThread());
597 DCHECK(!callback.is_null());
599 get_file_for_saving_operation_->GetFileForSaving(file_path, callback);
602 base::Closure FileSystem::GetFileContent(
603 const base::FilePath& file_path,
604 const GetFileContentInitializedCallback& initialized_callback,
605 const google_apis::GetContentCallback& get_content_callback,
606 const FileOperationCallback& completion_callback) {
607 DCHECK(thread_checker_.CalledOnValidThread());
608 DCHECK(!initialized_callback.is_null());
609 DCHECK(!get_content_callback.is_null());
610 DCHECK(!completion_callback.is_null());
612 return download_operation_->EnsureFileDownloadedByPath(
613 file_path,
614 ClientContext(USER_INITIATED),
615 initialized_callback,
616 get_content_callback,
617 base::Bind(&GetFileCallbackToFileOperationCallbackAdapter,
618 completion_callback));
621 void FileSystem::GetResourceEntry(
622 const base::FilePath& file_path,
623 const GetResourceEntryCallback& callback) {
624 DCHECK(thread_checker_.CalledOnValidThread());
625 DCHECK(!callback.is_null());
627 ReadDirectory(file_path.DirName(),
628 ReadDirectoryEntriesCallback(),
629 base::Bind(&FileSystem::GetResourceEntryAfterRead,
630 weak_ptr_factory_.GetWeakPtr(),
631 file_path,
632 callback));
635 void FileSystem::GetResourceEntryAfterRead(
636 const base::FilePath& file_path,
637 const GetResourceEntryCallback& callback,
638 FileError error) {
639 DCHECK(thread_checker_.CalledOnValidThread());
640 DCHECK(!callback.is_null());
642 DVLOG_IF(1, error != FILE_ERROR_OK) << "ReadDirectory failed. "
643 << FileErrorToString(error);
645 scoped_ptr<ResourceEntry> entry(new ResourceEntry);
646 ResourceEntry* entry_ptr = entry.get();
647 base::PostTaskAndReplyWithResult(
648 blocking_task_runner_.get(),
649 FROM_HERE,
650 base::Bind(&GetLocallyStoredResourceEntry,
651 resource_metadata_,
652 cache_,
653 file_path,
654 entry_ptr),
655 base::Bind(&RunGetResourceEntryCallback, callback, base::Passed(&entry)));
658 void FileSystem::ReadDirectory(
659 const base::FilePath& directory_path,
660 const ReadDirectoryEntriesCallback& entries_callback_in,
661 const FileOperationCallback& completion_callback) {
662 DCHECK(thread_checker_.CalledOnValidThread());
663 DCHECK(!completion_callback.is_null());
665 const bool hide_hosted_docs =
666 pref_service_->GetBoolean(prefs::kDisableDriveHostedFiles);
667 ReadDirectoryEntriesCallback entries_callback = entries_callback_in;
668 if (!entries_callback.is_null() && hide_hosted_docs)
669 entries_callback = base::Bind(&FilterHostedDocuments, entries_callback);
671 directory_loader_->ReadDirectory(
672 directory_path, entries_callback, completion_callback);
674 // Also start loading all of the user's contents.
675 change_list_loader_->LoadIfNeeded(
676 base::Bind(&util::EmptyFileOperationCallback));
679 void FileSystem::GetAvailableSpace(
680 const GetAvailableSpaceCallback& callback) {
681 DCHECK(thread_checker_.CalledOnValidThread());
682 DCHECK(!callback.is_null());
684 about_resource_loader_->GetAboutResource(
685 base::Bind(&FileSystem::OnGetAboutResource,
686 weak_ptr_factory_.GetWeakPtr(),
687 callback));
690 void FileSystem::OnGetAboutResource(
691 const GetAvailableSpaceCallback& callback,
692 google_apis::DriveApiErrorCode status,
693 scoped_ptr<google_apis::AboutResource> about_resource) {
694 DCHECK(thread_checker_.CalledOnValidThread());
695 DCHECK(!callback.is_null());
697 FileError error = GDataToFileError(status);
698 if (error != FILE_ERROR_OK) {
699 callback.Run(error, -1, -1);
700 return;
702 DCHECK(about_resource);
704 callback.Run(FILE_ERROR_OK, about_resource->quota_bytes_total(),
705 about_resource->quota_bytes_used_aggregate());
708 void FileSystem::GetShareUrl(const base::FilePath& file_path,
709 const GURL& embed_origin,
710 const GetShareUrlCallback& callback) {
711 DCHECK(thread_checker_.CalledOnValidThread());
712 DCHECK(!callback.is_null());
714 // Resolve the resource id.
715 ResourceEntry* entry = new ResourceEntry;
716 base::PostTaskAndReplyWithResult(
717 blocking_task_runner_.get(),
718 FROM_HERE,
719 base::Bind(&internal::ResourceMetadata::GetResourceEntryByPath,
720 base::Unretained(resource_metadata_),
721 file_path,
722 entry),
723 base::Bind(&FileSystem::GetShareUrlAfterGetResourceEntry,
724 weak_ptr_factory_.GetWeakPtr(),
725 file_path,
726 embed_origin,
727 callback,
728 base::Owned(entry)));
731 void FileSystem::GetShareUrlAfterGetResourceEntry(
732 const base::FilePath& file_path,
733 const GURL& embed_origin,
734 const GetShareUrlCallback& callback,
735 ResourceEntry* entry,
736 FileError error) {
737 DCHECK(thread_checker_.CalledOnValidThread());
738 DCHECK(!callback.is_null());
740 if (error != FILE_ERROR_OK) {
741 callback.Run(error, GURL());
742 return;
744 if (entry->resource_id().empty()) {
745 // This entry does not exist on the server. Just return.
746 callback.Run(FILE_ERROR_FAILED, GURL());
747 return;
750 scheduler_->GetShareUrl(
751 entry->resource_id(),
752 embed_origin,
753 ClientContext(USER_INITIATED),
754 base::Bind(&FileSystem::OnGetResourceEntryForGetShareUrl,
755 weak_ptr_factory_.GetWeakPtr(),
756 callback));
759 void FileSystem::OnGetResourceEntryForGetShareUrl(
760 const GetShareUrlCallback& callback,
761 google_apis::DriveApiErrorCode status,
762 const GURL& share_url) {
763 DCHECK(thread_checker_.CalledOnValidThread());
764 DCHECK(!callback.is_null());
766 FileError error = GDataToFileError(status);
767 if (error != FILE_ERROR_OK) {
768 callback.Run(error, GURL());
769 return;
772 if (share_url.is_empty()) {
773 callback.Run(FILE_ERROR_FAILED, GURL());
774 return;
777 callback.Run(FILE_ERROR_OK, share_url);
780 void FileSystem::Search(const std::string& search_query,
781 const GURL& next_link,
782 const SearchCallback& callback) {
783 DCHECK(thread_checker_.CalledOnValidThread());
784 DCHECK(!callback.is_null());
785 search_operation_->Search(search_query, next_link, callback);
788 void FileSystem::SearchMetadata(const std::string& query,
789 int options,
790 int at_most_num_matches,
791 const SearchMetadataCallback& callback) {
792 DCHECK(thread_checker_.CalledOnValidThread());
794 // TODO(satorux): Stop handling hide_hosted_docs here. crbug.com/256520.
795 if (pref_service_->GetBoolean(prefs::kDisableDriveHostedFiles))
796 options |= SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS;
798 drive::internal::SearchMetadata(
799 blocking_task_runner_, resource_metadata_, query,
800 base::Bind(&drive::internal::MatchesType, options), at_most_num_matches,
801 callback);
804 void FileSystem::SearchByHashes(const std::set<std::string>& hashes,
805 const SearchByHashesCallback& callback) {
806 DCHECK(thread_checker_.CalledOnValidThread());
807 drive::internal::SearchMetadata(
808 blocking_task_runner_, resource_metadata_,
809 /* any file name */ "", base::Bind(&CheckHashes, hashes),
810 std::numeric_limits<size_t>::max(),
811 base::Bind(&RunSearchByHashesCallback, callback));
814 void FileSystem::OnFileChangedByOperation(const FileChange& changed_files) {
815 DCHECK(thread_checker_.CalledOnValidThread());
817 FOR_EACH_OBSERVER(
818 FileSystemObserver, observers_, OnFileChanged(changed_files));
821 void FileSystem::OnEntryUpdatedByOperation(const ClientContext& context,
822 const std::string& local_id) {
823 sync_client_->AddUpdateTask(context, local_id);
826 void FileSystem::OnDriveSyncError(file_system::DriveSyncErrorType type,
827 const std::string& local_id) {
828 base::FilePath* file_path = new base::FilePath;
829 base::PostTaskAndReplyWithResult(
830 blocking_task_runner_.get(),
831 FROM_HERE,
832 base::Bind(&internal::ResourceMetadata::GetFilePath,
833 base::Unretained(resource_metadata_),
834 local_id,
835 file_path),
836 base::Bind(&FileSystem::OnDriveSyncErrorAfterGetFilePath,
837 weak_ptr_factory_.GetWeakPtr(),
838 type,
839 base::Owned(file_path)));
842 void FileSystem::OnDriveSyncErrorAfterGetFilePath(
843 file_system::DriveSyncErrorType type,
844 const base::FilePath* file_path,
845 FileError error) {
846 if (error != FILE_ERROR_OK)
847 return;
848 FOR_EACH_OBSERVER(FileSystemObserver,
849 observers_,
850 OnDriveSyncError(type, *file_path));
853 bool FileSystem::WaitForSyncComplete(const std::string& local_id,
854 const FileOperationCallback& callback) {
855 return sync_client_->WaitForUpdateTaskToComplete(local_id, callback);
858 void FileSystem::OnDirectoryReloaded(const base::FilePath& directory_path) {
859 DCHECK(thread_checker_.CalledOnValidThread());
861 FOR_EACH_OBSERVER(
862 FileSystemObserver, observers_, OnDirectoryChanged(directory_path));
865 void FileSystem::OnFileChanged(const FileChange& changed_files) {
866 DCHECK(thread_checker_.CalledOnValidThread());
868 FOR_EACH_OBSERVER(
869 FileSystemObserver, observers_, OnFileChanged(changed_files));
872 void FileSystem::OnLoadFromServerComplete() {
873 DCHECK(thread_checker_.CalledOnValidThread());
875 sync_client_->StartCheckingExistingPinnedFiles();
878 void FileSystem::OnInitialLoadComplete() {
879 DCHECK(thread_checker_.CalledOnValidThread());
881 blocking_task_runner_->PostTask(FROM_HERE,
882 base::Bind(&internal::RemoveStaleCacheFiles,
883 cache_,
884 resource_metadata_));
885 sync_client_->StartProcessingBacklog();
888 void FileSystem::GetMetadata(
889 const GetFilesystemMetadataCallback& callback) {
890 DCHECK(thread_checker_.CalledOnValidThread());
891 DCHECK(!callback.is_null());
893 FileSystemMetadata metadata;
894 metadata.refreshing = change_list_loader_->IsRefreshing();
896 // Metadata related to delta update.
897 metadata.last_update_check_time = last_update_check_time_;
898 metadata.last_update_check_error = last_update_check_error_;
900 int64* largest_changestamp = new int64(0);
901 base::PostTaskAndReplyWithResult(
902 blocking_task_runner_.get(),
903 FROM_HERE,
904 base::Bind(&internal::ResourceMetadata::GetLargestChangestamp,
905 base::Unretained(resource_metadata_),
906 largest_changestamp),
907 base::Bind(&OnGetLargestChangestamp,
908 metadata,
909 callback,
910 base::Owned(largest_changestamp)));
913 void FileSystem::MarkCacheFileAsMounted(
914 const base::FilePath& drive_file_path,
915 const MarkMountedCallback& callback) {
916 DCHECK(thread_checker_.CalledOnValidThread());
917 DCHECK(!callback.is_null());
919 base::FilePath* cache_file_path = new base::FilePath;
920 base::PostTaskAndReplyWithResult(
921 blocking_task_runner_.get(),
922 FROM_HERE,
923 base::Bind(&MarkCacheFileAsMountedInternal,
924 resource_metadata_,
925 cache_,
926 drive_file_path,
927 cache_file_path),
928 base::Bind(
929 &RunMarkMountedCallback, callback, base::Owned(cache_file_path)));
932 void FileSystem::MarkCacheFileAsUnmounted(
933 const base::FilePath& cache_file_path,
934 const FileOperationCallback& callback) {
935 DCHECK(thread_checker_.CalledOnValidThread());
936 DCHECK(!callback.is_null());
938 if (!cache_->IsUnderFileCacheDirectory(cache_file_path)) {
939 callback.Run(FILE_ERROR_FAILED);
940 return;
943 base::PostTaskAndReplyWithResult(
944 blocking_task_runner_.get(),
945 FROM_HERE,
946 base::Bind(&internal::FileCache::MarkAsUnmounted,
947 base::Unretained(cache_),
948 cache_file_path),
949 callback);
952 void FileSystem::AddPermission(const base::FilePath& drive_file_path,
953 const std::string& email,
954 google_apis::drive::PermissionRole role,
955 const FileOperationCallback& callback) {
956 DCHECK(thread_checker_.CalledOnValidThread());
957 DCHECK(!callback.is_null());
959 // Resolve the resource id.
960 ResourceEntry* const entry = new ResourceEntry;
961 base::PostTaskAndReplyWithResult(
962 blocking_task_runner_.get(),
963 FROM_HERE,
964 base::Bind(&internal::ResourceMetadata::GetResourceEntryByPath,
965 base::Unretained(resource_metadata_),
966 drive_file_path,
967 entry),
968 base::Bind(&FileSystem::AddPermissionAfterGetResourceEntry,
969 weak_ptr_factory_.GetWeakPtr(),
970 email,
971 role,
972 callback,
973 base::Owned(entry)));
976 void FileSystem::AddPermissionAfterGetResourceEntry(
977 const std::string& email,
978 google_apis::drive::PermissionRole role,
979 const FileOperationCallback& callback,
980 ResourceEntry* entry,
981 FileError error) {
982 DCHECK(thread_checker_.CalledOnValidThread());
984 if (error != FILE_ERROR_OK) {
985 callback.Run(error);
986 return;
989 scheduler_->AddPermission(
990 entry->resource_id(),
991 email,
992 role,
993 base::Bind(&RunFileOperationCallbackAsEntryActionCallback, callback));
996 void FileSystem::SetProperty(
997 const base::FilePath& drive_file_path,
998 google_apis::drive::Property::Visibility visibility,
999 const std::string& key,
1000 const std::string& value,
1001 const FileOperationCallback& callback) {
1002 DCHECK(thread_checker_.CalledOnValidThread());
1003 DCHECK(!callback.is_null());
1005 set_property_operation_->SetProperty(drive_file_path, visibility, key, value,
1006 callback);
1009 void FileSystem::OpenFile(const base::FilePath& file_path,
1010 OpenMode open_mode,
1011 const std::string& mime_type,
1012 const OpenFileCallback& callback) {
1013 DCHECK(thread_checker_.CalledOnValidThread());
1014 DCHECK(!callback.is_null());
1016 open_file_operation_->OpenFile(file_path, open_mode, mime_type, callback);
1019 void FileSystem::GetPathFromResourceId(const std::string& resource_id,
1020 const GetFilePathCallback& callback) {
1021 DCHECK(thread_checker_.CalledOnValidThread());
1022 DCHECK(!callback.is_null());
1024 base::FilePath* const file_path = new base::FilePath();
1025 base::PostTaskAndReplyWithResult(
1026 blocking_task_runner_.get(),
1027 FROM_HERE,
1028 base::Bind(&GetPathFromResourceIdOnBlockingPool,
1029 resource_metadata_,
1030 resource_id,
1031 file_path),
1032 base::Bind(&GetPathFromResourceIdAfterGetPath,
1033 base::Owned(file_path),
1034 callback));
1037 void FileSystem::FreeDiskSpaceIfNeededFor(
1038 int64 num_bytes,
1039 const FreeDiskSpaceCallback& callback) {
1040 DCHECK(thread_checker_.CalledOnValidThread());
1041 DCHECK(!callback.is_null());
1042 base::PostTaskAndReplyWithResult(
1043 blocking_task_runner_.get(), FROM_HERE,
1044 base::Bind(&FreeDiskSpaceIfNeededForOnBlockingPool, cache_, num_bytes),
1045 callback);
1047 } // namespace drive