Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / drive / file_system.cc
blob0c0d83af617aacb1680ecac1198f564c901740a1
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/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;
41 namespace drive {
42 namespace {
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) {
51 std::string local_id;
52 FileError error = resource_metadata->GetIdByPath(file_path, &local_id);
53 if (error != FILE_ERROR_OK)
54 return error;
56 error = resource_metadata->GetResourceEntryById(local_id, entry);
57 if (error != FILE_ERROR_OK)
58 return error;
60 // For entries that will never be cached, use the original resource entry
61 // as is.
62 if (!entry->has_file_specific_info() ||
63 entry->file_specific_info().is_hosted_document())
64 return FILE_ERROR_OK;
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())
69 return FILE_ERROR_OK;
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)
75 return error;
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);
85 return FILE_ERROR_OK;
88 // Runs the callback with parameters.
89 void RunGetResourceEntryCallback(const GetResourceEntryCallback& callback,
90 scoped_ptr<ResourceEntry> entry,
91 FileError error) {
92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
93 DCHECK(!callback.is_null());
95 if (error != FILE_ERROR_OK)
96 entry.reset();
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)
107 return error;
109 ResourceEntry entry;
110 error = resource_metadata->GetResourceEntryById(*local_id, &entry);
111 if (error != FILE_ERROR_OK)
112 return error;
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)
128 return error;
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)
142 return error;
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,
150 FileError error) {
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) {
160 std::string id;
161 if (resource_metadata->GetIdByPath(drive_file_path, &id) != FILE_ERROR_OK)
162 return false;
164 return cache->GetCacheEntry(id, cache_entry);
167 // Runs the callback with arguments.
168 void RunGetCacheEntryCallback(const GetCacheEntryCallback& callback,
169 const FileCacheEntry* cache_entry,
170 bool success) {
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,
191 FileError error,
192 const base::FilePath& unused_file_path,
193 scoped_ptr<ResourceEntry> unused_entry) {
194 callback.Run(error);
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)
202 return error;
203 return cache->ClearAll() ? FILE_ERROR_OK : FILE_ERROR_FAILED;
206 } // namespace
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),
217 cache_(cache),
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));
227 ResetComponents();
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.
242 ResetComponents();
244 base::PostTaskAndReplyWithResult(
245 blocking_task_runner_,
246 FROM_HERE,
247 base::Bind(&ResetOnBlockingPool, resource_metadata_, cache_),
248 callback);
251 void FileSystem::ResetComponents() {
252 file_system::OperationObserver* observer = this;
253 copy_operation_.reset(
254 new file_system::CopyOperation(
255 blocking_task_runner_.get(),
256 observer,
257 scheduler_,
258 resource_metadata_,
259 cache_,
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(),
265 observer,
266 scheduler_,
267 resource_metadata_,
268 cache_));
269 move_operation_.reset(
270 new file_system::MoveOperation(blocking_task_runner_.get(),
271 observer,
272 resource_metadata_));
273 open_file_operation_.reset(
274 new file_system::OpenFileOperation(blocking_task_runner_.get(),
275 observer,
276 scheduler_,
277 resource_metadata_,
278 cache_,
279 temporary_file_directory_));
280 remove_operation_.reset(
281 new file_system::RemoveOperation(blocking_task_runner_.get(),
282 observer,
283 resource_metadata_,
284 cache_));
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(),
289 observer,
290 scheduler_,
291 resource_metadata_,
292 cache_,
293 temporary_file_directory_));
294 download_operation_.reset(
295 new file_system::DownloadOperation(blocking_task_runner_.get(),
296 observer,
297 scheduler_,
298 resource_metadata_,
299 cache_,
300 temporary_file_directory_));
301 update_operation_.reset(
302 new file_system::UpdateOperation(blocking_task_runner_.get(),
303 observer,
304 scheduler_,
305 resource_metadata_,
306 cache_));
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(),
311 observer,
312 scheduler_,
313 resource_metadata_,
314 cache_,
315 temporary_file_directory_));
317 sync_client_.reset(new internal::SyncClient(blocking_task_runner_.get(),
318 observer,
319 scheduler_,
320 resource_metadata_,
321 cache_,
322 temporary_file_directory_));
324 change_list_loader_.reset(new internal::ChangeListLoader(
325 blocking_task_runner_.get(),
326 resource_metadata_,
327 scheduler_,
328 drive_service_));
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,
365 callback);
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,
389 bool is_recursive,
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,
398 bool is_exclusive,
399 bool is_recursive,
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,
414 bool is_exclusive,
415 bool is_recursive,
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,
429 bool is_exclusive,
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,
451 int64 length,
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_,
466 FROM_HERE,
467 base::Bind(&PinInternal, resource_metadata_, cache_, file_path, local_id),
468 base::Bind(&FileSystem::FinishPin,
469 weak_ptr_factory_.GetWeakPtr(),
470 callback,
471 base::Owned(local_id)));
474 void FileSystem::FinishPin(const FileOperationCallback& callback,
475 const std::string* local_id,
476 FileError error) {
477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
478 DCHECK(!callback.is_null());
480 if (error == FILE_ERROR_OK)
481 sync_client_->AddFetchTask(*local_id);
482 callback.Run(error);
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_,
493 FROM_HERE,
494 base::Bind(&UnpinInternal,
495 resource_metadata_,
496 cache_,
497 file_path,
498 local_id),
499 base::Bind(&FileSystem::FinishUnpin,
500 weak_ptr_factory_.GetWeakPtr(),
501 callback,
502 base::Owned(local_id)));
505 void FileSystem::FinishUnpin(const FileOperationCallback& callback,
506 const std::string* local_id,
507 FileError error) {
508 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
509 DCHECK(!callback.is_null());
511 if (error == FILE_ERROR_OK)
512 sync_client_->RemoveFetchTask(*local_id);
513 callback.Run(error);
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(
522 file_path,
523 ClientContext(USER_INITIATED),
524 GetFileContentInitializedCallback(),
525 google_apis::GetContentCallback(),
526 callback);
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(
548 file_path,
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(
563 file_path.DirName(),
564 base::Bind(&FileSystem::GetResourceEntryAfterLoad,
565 weak_ptr_factory_.GetWeakPtr(),
566 file_path,
567 callback));
570 void FileSystem::GetResourceEntryAfterLoad(
571 const base::FilePath& file_path,
572 const GetResourceEntryCallback& callback,
573 FileError error) {
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_,
584 FROM_HERE,
585 base::Bind(&GetLocallyStoredResourceEntry,
586 resource_metadata_,
587 cache_,
588 file_path,
589 entry_ptr),
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(
600 directory_path,
601 base::Bind(&FileSystem::ReadDirectoryAfterLoad,
602 weak_ptr_factory_.GetWeakPtr(),
603 directory_path,
604 callback));
607 void FileSystem::ReadDirectoryAfterLoad(
608 const base::FilePath& directory_path,
609 const ReadDirectoryCallback& callback,
610 FileError error) {
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(
618 directory_path,
619 base::Bind(&FileSystem::ReadDirectoryAfterRead,
620 weak_ptr_factory_.GetWeakPtr(),
621 directory_path,
622 callback));
625 void FileSystem::ReadDirectoryAfterRead(
626 const base::FilePath& directory_path,
627 const ReadDirectoryCallback& callback,
628 FileError error,
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>());
635 return;
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()) {
646 continue;
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(),
662 callback));
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);
675 return;
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(
693 file_path,
694 base::Bind(&FileSystem::GetShareUrlAfterGetResourceEntry,
695 weak_ptr_factory_.GetWeakPtr(),
696 file_path,
697 embed_origin,
698 callback));
701 void FileSystem::GetShareUrlAfterGetResourceEntry(
702 const base::FilePath& file_path,
703 const GURL& embed_origin,
704 const GetShareUrlCallback& callback,
705 FileError error,
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());
712 return;
714 if (entry->resource_id().empty()) {
715 // This entry does not exist on the server. Just return.
716 callback.Run(FILE_ERROR_FAILED, GURL());
717 return;
720 scheduler_->GetShareUrl(
721 entry->resource_id(),
722 embed_origin,
723 ClientContext(USER_INITIATED),
724 base::Bind(&FileSystem::OnGetResourceEntryForGetShareUrl,
725 weak_ptr_factory_.GetWeakPtr(),
726 callback));
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());
739 return;
742 if (share_url.is_empty()) {
743 callback.Run(FILE_ERROR_FAILED, GURL());
744 return;
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,
759 int options,
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_,
769 resource_metadata_,
770 query,
771 options,
772 at_most_num_matches,
773 callback);
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_,
794 FROM_HERE,
795 base::Bind(&internal::ResourceMetadata::GetFilePath,
796 base::Unretained(resource_metadata_),
797 local_id),
798 base::Bind(&FileSystem::OnDriveSyncErrorAfterGetFilePath,
799 weak_ptr_factory_.GetWeakPtr(),
800 type));
803 void FileSystem::OnDriveSyncErrorAfterGetFilePath(
804 file_system::DriveSyncErrorType type,
805 const base::FilePath& path) {
806 if (path.empty())
807 return;
808 FOR_EACH_OBSERVER(FileSystemObserver,
809 observers_,
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,
831 cache_,
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_,
850 FROM_HERE,
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_,
865 FROM_HERE,
866 base::Bind(&MarkCacheFileAsMountedInternal,
867 resource_metadata_,
868 cache_,
869 drive_file_path,
870 cache_file_path),
871 base::Bind(&RunMarkMountedCallback,
872 callback,
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);
884 return;
887 base::PostTaskAndReplyWithResult(
888 blocking_task_runner_,
889 FROM_HERE,
890 base::Bind(&internal::FileCache::MarkAsUnmounted,
891 base::Unretained(cache_),
892 cache_file_path),
893 callback);
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_,
905 FROM_HERE,
906 base::Bind(&GetCacheEntryInternal,
907 resource_metadata_,
908 cache_,
909 drive_file_path,
910 cache_entry),
911 base::Bind(&RunGetCacheEntryCallback,
912 callback,
913 base::Owned(cache_entry)));
916 void FileSystem::OpenFile(const base::FilePath& file_path,
917 OpenMode open_mode,
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);
926 } // namespace drive