1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/drive/directory_loader.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/callback.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/callback_helpers.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/metrics/histogram.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/time/time.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/drive/change_list_loader.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/drive/change_list_loader_observer.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/drive/change_list_processor.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system_util.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/drive/job_scheduler.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/drive/resource_metadata.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/drive/event_logger.h" 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "google_apis/drive/drive_api_parser.h" 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "url/gurl.h" 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using content::BrowserThread; 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace drive { 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace internal { 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Minimum changestamp gap required to start loading directory. 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kMinimumChangestampGap = 50; 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)FileError CheckLocalState(ResourceMetadata* resource_metadata, 3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const google_apis::AboutResource& about_resource, 3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const std::string& local_id, 3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ResourceEntry* entry, 3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int64* local_changestamp) { 3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Fill My Drive resource ID. 3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ResourceEntry mydrive; 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FileError error = resource_metadata->GetResourceEntryByPath( 4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) util::GetDriveMyDriveRootPath(), &mydrive); 4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (error != FILE_ERROR_OK) 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return error; 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (mydrive.resource_id().empty()) { 4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) mydrive.set_resource_id(about_resource.root_folder_id()); 4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) error = resource_metadata->RefreshEntry(mydrive); 4823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (error != FILE_ERROR_OK) 4923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return error; 5023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 5123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 5223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Get entry. 5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) error = resource_metadata->GetResourceEntryById(local_id, entry); 5423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (error != FILE_ERROR_OK) 5523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return error; 5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Get the local changestamp. 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return resource_metadata->GetLargestChangestamp(local_changestamp); 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 61effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochFileError UpdateChangestamp(ResourceMetadata* resource_metadata, 62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const DirectoryFetchInfo& directory_fetch_info, 63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::FilePath* directory_path) { 64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Update the directory changestamp. 65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ResourceEntry directory; 66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch FileError error = resource_metadata->GetResourceEntryById( 67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch directory_fetch_info.local_id(), &directory); 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error != FILE_ERROR_OK) 69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return error; 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!directory.file_info().is_directory()) 72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return FILE_ERROR_NOT_A_DIRECTORY; 73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch directory.mutable_directory_specific_info()->set_changestamp( 75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch directory_fetch_info.changestamp()); 76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch error = resource_metadata->RefreshEntry(directory); 77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (error != FILE_ERROR_OK) 78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return error; 79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Get the directory path. 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return resource_metadata->GetFilePath(directory_fetch_info.local_id(), 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) directory_path); 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstruct DirectoryLoader::ReadDirectoryCallbackState { 88a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ReadDirectoryEntriesCallback entries_callback; 89a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FileOperationCallback completion_callback; 90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::set<std::string> sent_entry_names; 91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}; 92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Fetches the resource entries in the directory with |directory_resource_id|. 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class DirectoryLoader::FeedFetcher { 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch FeedFetcher(DirectoryLoader* loader, 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const DirectoryFetchInfo& directory_fetch_info, 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& root_folder_id) 99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : loader_(loader), 100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch directory_fetch_info_(directory_fetch_info), 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) root_folder_id_(root_folder_id), 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_(this) { 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ~FeedFetcher() { 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void Run(const FileOperationCallback& callback) { 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!callback.is_null()); 111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(!directory_fetch_info_.resource_id().empty()); 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Remember the time stamp for usage stats. 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) start_time_ = base::TimeTicks::Now(); 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) loader_->scheduler_->GetFileListInDirectory( 1174ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch directory_fetch_info_.resource_id(), 11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&FeedFetcher::OnFileListFetched, 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), callback)); 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void OnFileListFetched(const FileOperationCallback& callback, 12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) google_apis::GDataErrorCode status, 12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<google_apis::FileList> file_list) { 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!callback.is_null()); 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FileError error = GDataToFileError(status); 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error != FILE_ERROR_OK) { 131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch callback.Run(error); 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(file_list); 13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<ChangeList> change_list(new ChangeList(*file_list)); 13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GURL next_url = file_list->next_link(); 138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ResourceEntryVector* entries = new ResourceEntryVector; 140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch loader_->loader_controller_->ScheduleRun(base::Bind( 141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::IgnoreResult( 142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch &base::PostTaskAndReplyWithResult<FileError, FileError>), 143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch loader_->blocking_task_runner_, 144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch FROM_HERE, 145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&ChangeListProcessor::RefreshDirectory, 146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch loader_->resource_metadata_, 147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch directory_fetch_info_, 148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Passed(&change_list), 149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch entries), 150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&FeedFetcher::OnDirectoryRefreshed, 151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_ptr_factory_.GetWeakPtr(), 152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch callback, 153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch next_url, 154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Owned(entries)))); 155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void OnDirectoryRefreshed( 158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const FileOperationCallback& callback, 159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const GURL& next_url, 160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const std::vector<ResourceEntry>* refreshed_entries, 161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch FileError error) { 162effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(!callback.is_null()); 164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 165effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (error != FILE_ERROR_OK) { 166effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch callback.Run(error); 167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 168effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 170a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch loader_->SendEntries(directory_fetch_info_.local_id(), *refreshed_entries); 171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!next_url.is_empty()) { 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There is the remaining result so fetch it. 1744ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch loader_->scheduler_->GetRemainingFileList( 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) next_url, 17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&FeedFetcher::OnFileListFetched, 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), callback)); 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Drive.DirectoryFeedLoadTime", 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeTicks::Now() - start_time_); 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Note: The fetcher is managed by DirectoryLoader, and the instance 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // will be deleted in the callback. Do not touch the fields after this 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // invocation. 187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch callback.Run(FILE_ERROR_OK); 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 190effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DirectoryLoader* loader_; 191effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DirectoryFetchInfo directory_fetch_info_; 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string root_folder_id_; 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeTicks start_time_; 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WeakPtrFactory<FeedFetcher> weak_ptr_factory_; 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FeedFetcher); 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)DirectoryLoader::DirectoryLoader( 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EventLogger* logger, 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::SequencedTaskRunner* blocking_task_runner, 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ResourceMetadata* resource_metadata, 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) JobScheduler* scheduler, 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AboutResourceLoader* about_resource_loader, 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LoaderController* loader_controller) 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : logger_(logger), 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blocking_task_runner_(blocking_task_runner), 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) resource_metadata_(resource_metadata), 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scheduler_(scheduler), 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) about_resource_loader_(about_resource_loader), 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) loader_controller_(loader_controller), 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_(this) { 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)DirectoryLoader::~DirectoryLoader() { 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) STLDeleteElements(&fast_fetch_feed_fetcher_set_); 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void DirectoryLoader::AddObserver(ChangeListLoaderObserver* observer) { 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) observers_.AddObserver(observer); 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void DirectoryLoader::RemoveObserver(ChangeListLoaderObserver* observer) { 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) observers_.RemoveObserver(observer); 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 228a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid DirectoryLoader::ReadDirectory( 229a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const base::FilePath& directory_path, 230a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const ReadDirectoryEntriesCallback& entries_callback, 231a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const FileOperationCallback& completion_callback) { 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 233a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DCHECK(!completion_callback.is_null()); 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ResourceEntry* entry = new ResourceEntry; 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::PostTaskAndReplyWithResult( 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blocking_task_runner_.get(), 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&ResourceMetadata::GetResourceEntryByPath, 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(resource_metadata_), 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) directory_path, 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) entry), 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&DirectoryLoader::ReadDirectoryAfterGetEntry, 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) directory_path, 246a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch entries_callback, 247a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch completion_callback, 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) true, // should_try_loading_parent 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Owned(entry))); 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void DirectoryLoader::ReadDirectoryAfterGetEntry( 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::FilePath& directory_path, 254a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const ReadDirectoryEntriesCallback& entries_callback, 255a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const FileOperationCallback& completion_callback, 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool should_try_loading_parent, 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ResourceEntry* entry, 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FileError error) { 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 260a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DCHECK(!completion_callback.is_null()); 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 26223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (error == FILE_ERROR_NOT_FOUND && 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) should_try_loading_parent && 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) util::GetDriveGrandRootPath().IsParent(directory_path)) { 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This entry may be found after loading the parent. 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ReadDirectory(directory_path.DirName(), 267a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ReadDirectoryEntriesCallback(), 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&DirectoryLoader::ReadDirectoryAfterLoadParent, 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) directory_path, 271a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch entries_callback, 272a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch completion_callback)); 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error != FILE_ERROR_OK) { 276a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch completion_callback.Run(error); 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!entry->file_info().is_directory()) { 281a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch completion_callback.Run(FILE_ERROR_NOT_A_DIRECTORY); 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DirectoryFetchInfo directory_fetch_info( 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) entry->local_id(), 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) entry->resource_id(), 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) entry->directory_specific_info().changestamp()); 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Register the callback function to be called when it is loaded. 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& local_id = directory_fetch_info.local_id(); 292effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ReadDirectoryCallbackState callback_state; 293a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callback_state.entries_callback = entries_callback; 294a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callback_state.completion_callback = completion_callback; 295effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch pending_load_callback_[local_id].push_back(callback_state); 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If loading task for |local_id| is already running, do nothing. 298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (pending_load_callback_[local_id].size() > 1) 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 30123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) about_resource_loader_->GetAboutResource( 30223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&DirectoryLoader::ReadDirectoryAfterGetAboutResource, 30323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), local_id)); 304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void DirectoryLoader::ReadDirectoryAfterLoadParent( 307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::FilePath& directory_path, 308a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const ReadDirectoryEntriesCallback& entries_callback, 309a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const FileOperationCallback& completion_callback, 310a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FileError error) { 311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 312a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DCHECK(!completion_callback.is_null()); 313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error != FILE_ERROR_OK) { 315a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch completion_callback.Run(error); 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ResourceEntry* entry = new ResourceEntry; 320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::PostTaskAndReplyWithResult( 321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blocking_task_runner_.get(), 322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&ResourceMetadata::GetResourceEntryByPath, 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(resource_metadata_), 325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) directory_path, 326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) entry), 327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&DirectoryLoader::ReadDirectoryAfterGetEntry, 328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) directory_path, 330a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch entries_callback, 331a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch completion_callback, 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) false, // should_try_loading_parent 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Owned(entry))); 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void DirectoryLoader::ReadDirectoryAfterGetAboutResource( 33723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const std::string& local_id, 338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) google_apis::GDataErrorCode status, 339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<google_apis::AboutResource> about_resource) { 340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FileError error = GDataToFileError(status); 343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error != FILE_ERROR_OK) { 34423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) OnDirectoryLoadComplete(local_id, error); 345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(about_resource); 349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 35023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Check the current status of local metadata, and start loading if needed. 35123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) google_apis::AboutResource* about_resource_ptr = about_resource.get(); 35223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ResourceEntry* entry = new ResourceEntry; 35323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int64* local_changestamp = new int64; 35423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::PostTaskAndReplyWithResult( 3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blocking_task_runner_.get(), 35623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) FROM_HERE, 35723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&CheckLocalState, 35823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) resource_metadata_, 35923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) *about_resource_ptr, 36023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) local_id, 36123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) entry, 36223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) local_changestamp), 36323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&DirectoryLoader::ReadDirectoryAfterCheckLocalState, 36423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 36523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Passed(&about_resource), 36623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) local_id, 36723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Owned(entry), 36823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Owned(local_changestamp))); 36923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 37023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 37123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void DirectoryLoader::ReadDirectoryAfterCheckLocalState( 37223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<google_apis::AboutResource> about_resource, 37323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const std::string& local_id, 37423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const ResourceEntry* entry, 37523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const int64* local_changestamp, 37623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) FileError error) { 37723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 37823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(about_resource); 37923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 38023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (error != FILE_ERROR_OK) { 38123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) OnDirectoryLoadComplete(local_id, error); 38223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 38323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 38423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // This entry does not exist on the server. 38523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (entry->resource_id().empty()) { 38623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) OnDirectoryLoadComplete(local_id, FILE_ERROR_OK); 38723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 38823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 38923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 remote_changestamp = about_resource->largest_change_id(); 391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 39223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Start loading the directory. 39323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int64 directory_changestamp = std::max( 39423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) entry->directory_specific_info().changestamp(), *local_changestamp); 39523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 39623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DirectoryFetchInfo directory_fetch_info( 39723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) local_id, entry->resource_id(), remote_changestamp); 398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If the directory's changestamp is up-to-date or the global changestamp of 4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // the metadata DB is new enough (which means the normal changelist loading 4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // should finish very soon), just schedule to run the callback, as there is no 4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // need to fetch the directory. 4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (directory_changestamp >= remote_changestamp || 4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *local_changestamp + kMinimumChangestampGap > remote_changestamp) { 40523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) OnDirectoryLoadComplete(local_id, FILE_ERROR_OK); 406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Start fetching the directory content, and mark it with the changestamp 408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // |remote_changestamp|. 40923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) LoadDirectoryFromServer(directory_fetch_info); 410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 41323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void DirectoryLoader::OnDirectoryLoadComplete(const std::string& local_id, 41423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) FileError error) { 415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 417a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch LoadCallbackMap::iterator it = pending_load_callback_.find(local_id); 418a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (it == pending_load_callback_.end()) 419a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 420a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 421a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // No need to read metadata when no one needs entries. 422a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bool needs_to_send_entries = false; 423a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch for (size_t i = 0; i < it->second.size(); ++i) { 424a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const ReadDirectoryCallbackState& callback_state = it->second[i]; 425a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!callback_state.entries_callback.is_null()) 426a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch needs_to_send_entries = true; 427a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 428a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 429a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!needs_to_send_entries) { 430a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch OnDirectoryLoadCompleteAfterRead(local_id, NULL, FILE_ERROR_OK); 431a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 432a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 433effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 434effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ResourceEntryVector* entries = new ResourceEntryVector; 435effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::PostTaskAndReplyWithResult( 436effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blocking_task_runner_.get(), 437effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch FROM_HERE, 438effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&ResourceMetadata::ReadDirectoryById, 439effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Unretained(resource_metadata_), local_id, entries), 440effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&DirectoryLoader::OnDirectoryLoadCompleteAfterRead, 441effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_ptr_factory_.GetWeakPtr(), 442effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch local_id, 443effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Owned(entries))); 444effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 445effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 446effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid DirectoryLoader::OnDirectoryLoadCompleteAfterRead( 447effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const std::string& local_id, 448effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const ResourceEntryVector* entries, 449effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch FileError error) { 450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LoadCallbackMap::iterator it = pending_load_callback_.find(local_id); 451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (it != pending_load_callback_.end()) { 452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << "Running callback for " << local_id; 453effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 454a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (error == FILE_ERROR_OK && entries) 455a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SendEntries(local_id, *entries); 456a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 457a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch for (size_t i = 0; i < it->second.size(); ++i) { 458a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const ReadDirectoryCallbackState& callback_state = it->second[i]; 459a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callback_state.completion_callback.Run(error); 460effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 461a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pending_load_callback_.erase(it); 462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 465effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid DirectoryLoader::SendEntries(const std::string& local_id, 466a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const ResourceEntryVector& entries) { 467effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LoadCallbackMap::iterator it = pending_load_callback_.find(local_id); 468effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(it != pending_load_callback_.end()); 469effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 470effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (size_t i = 0; i < it->second.size(); ++i) { 471effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ReadDirectoryCallbackState* callback_state = &it->second[i]; 472a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (callback_state->entries_callback.is_null()) 473a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch continue; 474effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 475effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Filter out entries which were already sent. 476effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_ptr<ResourceEntryVector> entries_to_send(new ResourceEntryVector); 477effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (size_t i = 0; i < entries.size(); ++i) { 478effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const ResourceEntry& entry = entries[i]; 479effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!callback_state->sent_entry_names.count(entry.base_name())) { 480effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch callback_state->sent_entry_names.insert(entry.base_name()); 481effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch entries_to_send->push_back(entry); 482effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 483effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 484a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callback_state->entries_callback.Run(entries_to_send.Pass()); 485effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 486effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 487effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void DirectoryLoader::LoadDirectoryFromServer( 489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const DirectoryFetchInfo& directory_fetch_info) { 490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!directory_fetch_info.empty()); 492a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << "Start loading directory: " << directory_fetch_info.ToString(); 493a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 494a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const google_apis::AboutResource* about_resource = 495a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch about_resource_loader_->cached_about_resource(); 496a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DCHECK(about_resource); 497a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 498a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch logger_->Log(logging::LOG_INFO, 499a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch "Fast-fetch start: %s; Server changestamp: %s", 500a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch directory_fetch_info.ToString().c_str(), 501a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Int64ToString( 502a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch about_resource->largest_change_id()).c_str()); 503a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 504a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FeedFetcher* fetcher = new FeedFetcher(this, 505a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch directory_fetch_info, 506a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch about_resource->root_folder_id()); 507a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fast_fetch_feed_fetcher_set_.insert(fetcher); 508a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fetcher->Run( 509a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&DirectoryLoader::LoadDirectoryFromServerAfterLoad, 510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 511a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) directory_fetch_info, 512a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fetcher)); 513a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 514a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 515a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void DirectoryLoader::LoadDirectoryFromServerAfterLoad( 516a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const DirectoryFetchInfo& directory_fetch_info, 517a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FeedFetcher* fetcher, 518effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch FileError error) { 519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 520a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!directory_fetch_info.empty()); 521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Delete the fetcher. 523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fast_fetch_feed_fetcher_set_.erase(fetcher); 524a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) delete fetcher; 525a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 526a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch logger_->Log(logging::LOG_INFO, 527a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch "Fast-fetch complete: %s => %s", 528a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch directory_fetch_info.ToString().c_str(), 529a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FileErrorToString(error).c_str()); 530a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 531a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error != FILE_ERROR_OK) { 532a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Failed to load directory: " 533a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << directory_fetch_info.local_id() 534a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << ": " << FileErrorToString(error); 53523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) OnDirectoryLoadComplete(directory_fetch_info.local_id(), error); 536a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 537a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 538a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 539effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Update changestamp and get the directory path. 540a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::FilePath* directory_path = new base::FilePath; 541effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::PostTaskAndReplyWithResult( 542effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blocking_task_runner_.get(), 543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 544effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&UpdateChangestamp, 545a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) resource_metadata_, 546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) directory_fetch_info, 547a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) directory_path), 548effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind( 549effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch &DirectoryLoader::LoadDirectoryFromServerAfterUpdateChangestamp, 550effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_ptr_factory_.GetWeakPtr(), 551effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch directory_fetch_info, 552effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Owned(directory_path))); 553a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 554a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 555effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid DirectoryLoader::LoadDirectoryFromServerAfterUpdateChangestamp( 556a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const DirectoryFetchInfo& directory_fetch_info, 557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::FilePath* directory_path, 558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FileError error) { 559a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 561a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << "Directory loaded: " << directory_fetch_info.ToString(); 56223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) OnDirectoryLoadComplete(directory_fetch_info.local_id(), error); 563a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 564a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Also notify the observers. 565a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error == FILE_ERROR_OK && !directory_path->empty()) { 566116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FOR_EACH_OBSERVER(ChangeListLoaderObserver, 567116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch observers_, 568116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OnDirectoryReloaded(*directory_path)); 569a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 571a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 572a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace internal 573a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace drive 574