| Index: chrome/browser/chromeos/drive/change_list_loader.cc
|
| diff --git a/chrome/browser/chromeos/drive/change_list_loader.cc b/chrome/browser/chromeos/drive/change_list_loader.cc
|
| index 8eea57f8474316a1eed663ad5e367839a1d7198c..71fe8d85edceea926263e741e004f93b554728d9 100644
|
| --- a/chrome/browser/chromeos/drive/change_list_loader.cc
|
| +++ b/chrome/browser/chromeos/drive/change_list_loader.cc
|
| @@ -52,6 +52,218 @@ void ChangeListLoader::RemoveObserver(ChangeListLoaderObserver* observer) {
|
| observers_.RemoveObserver(observer);
|
| }
|
|
|
| +void ChangeListLoader::LoadIfNeeded(
|
| + const DirectoryFetchInfo& directory_fetch_info,
|
| + const FileOperationCallback& callback) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK(!callback.is_null());
|
| +
|
| + // If feed has already been loaded, for normal feed fetch (= empty
|
| + // directory_fetch_info), we have nothing to do. For "fast fetch", we need to
|
| + // schedule a fetching if a feed refresh is currently running, because we
|
| + // don't want to wait a possibly large delta feed to arrive.
|
| + if (loaded_ && (directory_fetch_info.empty() || !IsRefreshing())) {
|
| + base::MessageLoopProxy::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(callback, DRIVE_FILE_OK));
|
| + return;
|
| + }
|
| + Load(directory_fetch_info, callback);
|
| +}
|
| +
|
| +void ChangeListLoader::CheckForUpdates(const FileOperationCallback& callback) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK(!callback.is_null());
|
| +
|
| + if (loaded_ && !IsRefreshing())
|
| + Load(DirectoryFetchInfo(), callback);
|
| +}
|
| +
|
| +void ChangeListLoader::LoadDirectoryFromServer(
|
| + const std::string& directory_resource_id,
|
| + const FileOperationCallback& callback) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK(!callback.is_null());
|
| +
|
| + // First fetch the latest changestamp to see if this directory needs to be
|
| + // updated.
|
| + scheduler_->GetAboutResource(
|
| + base::Bind(
|
| + &ChangeListLoader::LoadDirectoryFromServerAfterGetAbout,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + directory_resource_id,
|
| + callback));
|
| +}
|
| +
|
| +void ChangeListLoader::SearchFromServer(
|
| + const std::string& search_query,
|
| + const GURL& next_feed,
|
| + const LoadFeedListCallback& callback) {
|
| + DCHECK(!callback.is_null());
|
| +
|
| + if (next_feed.is_empty()) {
|
| + // This is first request for the |search_query|.
|
| + scheduler_->Search(
|
| + search_query,
|
| + base::Bind(&ChangeListLoader::SearchFromServerAfterGetResourceList,
|
| + weak_ptr_factory_.GetWeakPtr(), callback));
|
| + } else {
|
| + // There is the remaining result so fetch it.
|
| + scheduler_->ContinueGetResourceList(
|
| + next_feed,
|
| + base::Bind(&ChangeListLoader::SearchFromServerAfterGetResourceList,
|
| + weak_ptr_factory_.GetWeakPtr(), callback));
|
| + }
|
| +}
|
| +
|
| +void ChangeListLoader::UpdateFromFeed(
|
| + scoped_ptr<google_apis::AboutResource> about_resource,
|
| + ScopedVector<ChangeList> change_lists,
|
| + bool is_delta_feed,
|
| + const base::Closure& callback) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK(!callback.is_null());
|
| +
|
| + change_list_processor_.reset(new ChangeListProcessor(resource_metadata_));
|
| + // Don't send directory content change notification while performing
|
| + // the initial content retrieval.
|
| + const bool should_notify_changed_directories = is_delta_feed;
|
| +
|
| + change_list_processor_->ApplyFeeds(
|
| + about_resource.Pass(),
|
| + change_lists.Pass(),
|
| + is_delta_feed,
|
| + base::Bind(&ChangeListLoader::NotifyDirectoryChangedAfterApplyFeed,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + should_notify_changed_directories,
|
| + callback));
|
| +}
|
| +
|
| +void ChangeListLoader::Load(const DirectoryFetchInfo& directory_fetch_info,
|
| + const FileOperationCallback& callback) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK(!callback.is_null());
|
| +
|
| + // Check if this is the first time this ChangeListLoader do loading.
|
| + // Note: IsRefreshing() depends on pending_load_callback_ so check in advance.
|
| + const bool is_initial_load = (!loaded_ && !IsRefreshing());
|
| +
|
| + // Register the callback function to be called when it is loaded.
|
| + const std::string& resource_id = directory_fetch_info.resource_id();
|
| + pending_load_callback_[resource_id].push_back(callback);
|
| +
|
| + // If loading task for |resource_id| is already running, do nothing.
|
| + if (pending_load_callback_[resource_id].size() > 1)
|
| + return;
|
| +
|
| + // For initial loading, even for directory fetching, we do load the full
|
| + // feed from the server to sync up. So we register a dummy callback to
|
| + // indicate that update for full hierarchy is running.
|
| + if (is_initial_load && !resource_id.empty()) {
|
| + pending_load_callback_[""].push_back(
|
| + base::Bind(&util::EmptyFileOperationCallback));
|
| + }
|
| +
|
| + // Check the current status of local metadata, and start loading if needed.
|
| + resource_metadata_->GetLargestChangestamp(
|
| + base::Bind(is_initial_load ? &ChangeListLoader::DoInitialLoad
|
| + : &ChangeListLoader::DoUpdateLoad,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + directory_fetch_info));
|
| +}
|
| +
|
| +void ChangeListLoader::DoInitialLoad(
|
| + const DirectoryFetchInfo& directory_fetch_info,
|
| + int64 local_changestamp) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + if (local_changestamp > 0) {
|
| + // The local data is usable. Flush callbacks to tell loading was successful.
|
| + OnChangeListLoadComplete(DRIVE_FILE_OK);
|
| +
|
| + // Continues to load from server in background.
|
| + // Put dummy callbacks to indicate that fetching is still continuing.
|
| + pending_load_callback_[directory_fetch_info.resource_id()].push_back(
|
| + base::Bind(&util::EmptyFileOperationCallback));
|
| + if (!directory_fetch_info.empty()) {
|
| + pending_load_callback_[""].push_back(
|
| + base::Bind(&util::EmptyFileOperationCallback));
|
| + }
|
| + }
|
| + LoadFromServerIfNeeded(directory_fetch_info, local_changestamp);
|
| +}
|
| +
|
| +void ChangeListLoader::DoUpdateLoad(
|
| + const DirectoryFetchInfo& directory_fetch_info,
|
| + int64 local_changestamp) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + if (directory_fetch_info.empty()) {
|
| + LoadFromServerIfNeeded(directory_fetch_info, local_changestamp);
|
| + } else {
|
| + // Note: CheckChangestampAndLoadDirectoryIfNeeded regards
|
| + // last_know_remote_changestamp_ as the remote changestamp. To be precise,
|
| + // we need to call GetAboutResource() here, as we do in other places like
|
| + // LoadFromServerIfNeeded or LoadFromDirectory. However,
|
| + // - It is costly to do GetAboutResource HTTP request every time.
|
| + // - The chance using an old value is small; it only happens when
|
| + // LoadIfNeeded is called during one GetAboutResource roundtrip time
|
| + // of a feed fetching.
|
| + // - Even if the value is old, it just marks the directory as older. It may
|
| + // trigger one future unnecessary re-fetch, but it'll never lose data.
|
| + CheckChangestampAndLoadDirectoryIfNeeed(
|
| + directory_fetch_info,
|
| + local_changestamp,
|
| + base::Bind(&ChangeListLoader::OnDirectoryLoadComplete,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + directory_fetch_info));
|
| + }
|
| +}
|
| +
|
| +void ChangeListLoader::OnChangeListLoadComplete(DriveFileError error) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + if (!loaded_ && error == DRIVE_FILE_OK) {
|
| + loaded_ = true;
|
| + FOR_EACH_OBSERVER(ChangeListLoaderObserver,
|
| + observers_,
|
| + OnInitialFeedLoaded());
|
| + }
|
| +
|
| + for (LoadCallbackMap::iterator it = pending_load_callback_.begin();
|
| + it != pending_load_callback_.end(); ++it) {
|
| + const std::vector<FileOperationCallback>& callbacks = it->second;
|
| + for (size_t i = 0; i < callbacks.size(); ++i) {
|
| + base::MessageLoopProxy::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(callbacks[i], error));
|
| + }
|
| + }
|
| + pending_load_callback_.clear();
|
| +}
|
| +
|
| +void ChangeListLoader::OnDirectoryLoadComplete(
|
| + const DirectoryFetchInfo& directory_fetch_info,
|
| + DriveFileError error) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + DVLOG_IF(1, error == DRIVE_FILE_OK) << "Fast-fetch was successful: "
|
| + << directory_fetch_info.ToString();
|
| +
|
| + const std::string& resource_id = directory_fetch_info.resource_id();
|
| + LoadCallbackMap::iterator it = pending_load_callback_.find(resource_id);
|
| + if (it != pending_load_callback_.end()) {
|
| + DVLOG(1) << "Running callback for " << resource_id;
|
| + const std::vector<FileOperationCallback>& callbacks = it->second;
|
| + for (size_t i = 0; i < callbacks.size(); ++i) {
|
| + base::MessageLoopProxy::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(callbacks[i], error));
|
| + }
|
| + pending_load_callback_.erase(it);
|
| + }
|
| +}
|
| +
|
| void ChangeListLoader::LoadFromServerIfNeeded(
|
| const DirectoryFetchInfo& directory_fetch_info,
|
| int64 local_changestamp) {
|
| @@ -140,6 +352,22 @@ void ChangeListLoader::LoadFromServerIfNeededAfterGetAbout(
|
| }
|
| }
|
|
|
| +void ChangeListLoader::LoadChangeListFromServerAfterLoadDirectory(
|
| + const DirectoryFetchInfo& directory_fetch_info,
|
| + scoped_ptr<google_apis::AboutResource> about_resource,
|
| + int64 start_changestamp,
|
| + DriveFileError error) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + if (error == DRIVE_FILE_OK) {
|
| + // The directory fast-fetch succeeded. Runs the callbacks waiting for the
|
| + // directory loading. If failed, do not flush so they're run after the
|
| + // change list loading is complete.
|
| + OnDirectoryLoadComplete(directory_fetch_info, DRIVE_FILE_OK);
|
| + }
|
| + LoadChangeListFromServer(about_resource.Pass(), start_changestamp);
|
| +}
|
| +
|
| void ChangeListLoader::LoadChangeListFromServer(
|
| scoped_ptr<google_apis::AboutResource> about_resource,
|
| int64 start_changestamp) {
|
| @@ -171,55 +399,6 @@ void ChangeListLoader::LoadChangeListFromServer(
|
| }
|
| }
|
|
|
| -void ChangeListLoader::LoadChangeListFromServerAfterLoadDirectory(
|
| - const DirectoryFetchInfo& directory_fetch_info,
|
| - scoped_ptr<google_apis::AboutResource> about_resource,
|
| - int64 start_changestamp,
|
| - DriveFileError error) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - if (error == DRIVE_FILE_OK) {
|
| - // The directory fast-fetch succeeded. Runs the callbacks waiting for the
|
| - // directory loading. If failed, do not flush so they're run after the
|
| - // change list loading is complete.
|
| - OnDirectoryLoadComplete(directory_fetch_info, DRIVE_FILE_OK);
|
| - }
|
| - LoadChangeListFromServer(about_resource.Pass(), start_changestamp);
|
| -}
|
| -
|
| -void ChangeListLoader::SearchFromServerAfterGetResourceList(
|
| - const LoadFeedListCallback& callback,
|
| - google_apis::GDataErrorCode status,
|
| - scoped_ptr<google_apis::ResourceList> resource_list) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - DCHECK(!callback.is_null());
|
| -
|
| - DriveFileError error = util::GDataToDriveFileError(status);
|
| - if (error != DRIVE_FILE_OK) {
|
| - callback.Run(ScopedVector<ChangeList>(), error);
|
| - return;
|
| - }
|
| -
|
| - DCHECK(resource_list);
|
| -
|
| - ScopedVector<ChangeList> change_lists;
|
| - change_lists.push_back(new ChangeList(*resource_list));
|
| - callback.Run(change_lists.Pass(), DRIVE_FILE_OK);
|
| -}
|
| -
|
| -void ChangeListLoader::OnGetAppList(google_apis::GDataErrorCode status,
|
| - scoped_ptr<google_apis::AppList> app_list) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - DriveFileError error = util::GDataToDriveFileError(status);
|
| - if (error != DRIVE_FILE_OK)
|
| - return;
|
| -
|
| - if (app_list.get()) {
|
| - webapps_registry_->UpdateFromAppList(*app_list);
|
| - }
|
| -}
|
| -
|
| void ChangeListLoader::OnGetResourceList(
|
| ScopedVector<ChangeList> change_lists,
|
| const LoadFeedListCallback& callback,
|
| @@ -268,20 +447,33 @@ void ChangeListLoader::OnGetResourceList(
|
| callback.Run(change_lists.Pass(), DRIVE_FILE_OK);
|
| }
|
|
|
| -void ChangeListLoader::LoadDirectoryFromServer(
|
| - const std::string& directory_resource_id,
|
| - const FileOperationCallback& callback) {
|
| +void ChangeListLoader::UpdateMetadataFromFeedAfterLoadFromServer(
|
| + scoped_ptr<google_apis::AboutResource> about_resource,
|
| + bool is_delta_feed,
|
| + ScopedVector<ChangeList> change_lists,
|
| + DriveFileError error) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - DCHECK(!callback.is_null());
|
|
|
| - // First fetch the latest changestamp to see if this directory needs to be
|
| - // updated.
|
| - scheduler_->GetAboutResource(
|
| - base::Bind(
|
| - &ChangeListLoader::LoadDirectoryFromServerAfterGetAbout,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - directory_resource_id,
|
| - callback));
|
| + if (error != DRIVE_FILE_OK) {
|
| + OnChangeListLoadComplete(error);
|
| + return;
|
| + }
|
| +
|
| + UpdateFromFeed(about_resource.Pass(),
|
| + change_lists.Pass(),
|
| + is_delta_feed,
|
| + base::Bind(&ChangeListLoader::OnUpdateFromFeed,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +void ChangeListLoader::OnUpdateFromFeed() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + OnChangeListLoadComplete(DRIVE_FILE_OK);
|
| +
|
| + FOR_EACH_OBSERVER(ChangeListLoaderObserver,
|
| + observers_,
|
| + OnFeedFromServerLoaded());
|
| }
|
|
|
| void ChangeListLoader::LoadDirectoryFromServerAfterGetAbout(
|
| @@ -303,6 +495,37 @@ void ChangeListLoader::LoadDirectoryFromServerAfterGetAbout(
|
| DoLoadDirectoryFromServer(directory_fetch_info, callback);
|
| }
|
|
|
| +void ChangeListLoader::CheckChangestampAndLoadDirectoryIfNeeed(
|
| + const DirectoryFetchInfo& directory_fetch_info,
|
| + int64 local_changestamp,
|
| + const FileOperationCallback& callback) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK(!directory_fetch_info.empty());
|
| +
|
| + int64 directory_changestamp = std::max(directory_fetch_info.changestamp(),
|
| + local_changestamp);
|
| +
|
| + // If the directory's changestamp is up-to-date, just schedule to run the
|
| + // callback, as there is no need to fetch the directory.
|
| + // Note that |last_known_remote_changestamp_| is 0 when it is not received
|
| + // yet. In that case we conservatively assume that we need to fetch.
|
| + if (last_known_remote_changestamp_ > 0 &&
|
| + directory_changestamp >= last_known_remote_changestamp_) {
|
| + callback.Run(DRIVE_FILE_OK);
|
| + return;
|
| + }
|
| +
|
| + DVLOG(1) << "Fast-fetching directory: " << directory_fetch_info.ToString()
|
| + << "; remote_changestamp: " << last_known_remote_changestamp_;
|
| +
|
| + // Start fetching the directory content, and mark it with the changestamp
|
| + // |last_known_remote_changestamp_|.
|
| + DirectoryFetchInfo new_directory_fetch_info(
|
| + directory_fetch_info.resource_id(),
|
| + std::max(directory_changestamp, last_known_remote_changestamp_));
|
| + DoLoadDirectoryFromServer(new_directory_fetch_info, callback);
|
| +}
|
| +
|
| void ChangeListLoader::DoLoadDirectoryFromServer(
|
| const DirectoryFetchInfo& directory_fetch_info,
|
| const FileOperationCallback& callback) {
|
| @@ -459,214 +682,44 @@ void ChangeListLoader::DoLoadDirectoryFromServerAfterRefresh(
|
| }
|
| }
|
|
|
| -void ChangeListLoader::SearchFromServer(
|
| - const std::string& search_query,
|
| - const GURL& next_feed,
|
| - const LoadFeedListCallback& callback) {
|
| - DCHECK(!callback.is_null());
|
| -
|
| - if (next_feed.is_empty()) {
|
| - // This is first request for the |search_query|.
|
| - scheduler_->Search(
|
| - search_query,
|
| - base::Bind(&ChangeListLoader::SearchFromServerAfterGetResourceList,
|
| - weak_ptr_factory_.GetWeakPtr(), callback));
|
| - } else {
|
| - // There is the remaining result so fetch it.
|
| - scheduler_->ContinueGetResourceList(
|
| - next_feed,
|
| - base::Bind(&ChangeListLoader::SearchFromServerAfterGetResourceList,
|
| - weak_ptr_factory_.GetWeakPtr(), callback));
|
| - }
|
| -}
|
| -
|
| -void ChangeListLoader::UpdateMetadataFromFeedAfterLoadFromServer(
|
| - scoped_ptr<google_apis::AboutResource> about_resource,
|
| - bool is_delta_feed,
|
| - ScopedVector<ChangeList> change_lists,
|
| - DriveFileError error) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - if (error != DRIVE_FILE_OK) {
|
| - OnChangeListLoadComplete(error);
|
| - return;
|
| - }
|
| -
|
| - UpdateFromFeed(about_resource.Pass(),
|
| - change_lists.Pass(),
|
| - is_delta_feed,
|
| - base::Bind(&ChangeListLoader::OnUpdateFromFeed,
|
| - weak_ptr_factory_.GetWeakPtr()));
|
| -}
|
| -
|
| -void ChangeListLoader::LoadIfNeeded(
|
| - const DirectoryFetchInfo& directory_fetch_info,
|
| - const FileOperationCallback& callback) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - DCHECK(!callback.is_null());
|
| -
|
| - // If feed has already been loaded, for normal feed fetch (= empty
|
| - // directory_fetch_info), we have nothing to do. For "fast fetch", we need to
|
| - // schedule a fetching if a feed refresh is currently running, because we
|
| - // don't want to wait a possibly large delta feed to arrive.
|
| - if (loaded_ && (directory_fetch_info.empty() || !IsRefreshing())) {
|
| - base::MessageLoopProxy::current()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(callback, DRIVE_FILE_OK));
|
| - return;
|
| - }
|
| - Load(directory_fetch_info, callback);
|
| -}
|
| -
|
| -void ChangeListLoader::Load(const DirectoryFetchInfo& directory_fetch_info,
|
| - const FileOperationCallback& callback) {
|
| +void ChangeListLoader::OnGetAppList(google_apis::GDataErrorCode status,
|
| + scoped_ptr<google_apis::AppList> app_list) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - DCHECK(!callback.is_null());
|
| -
|
| - // Check if this is the first time this ChangeListLoader do loading.
|
| - // Note: IsRefreshing() depends on pending_load_callback_ so check in advance.
|
| - const bool is_initial_load = (!loaded_ && !IsRefreshing());
|
| -
|
| - // Register the callback function to be called when it is loaded.
|
| - const std::string& resource_id = directory_fetch_info.resource_id();
|
| - pending_load_callback_[resource_id].push_back(callback);
|
|
|
| - // If loading task for |resource_id| is already running, do nothing.
|
| - if (pending_load_callback_[resource_id].size() > 1)
|
| + DriveFileError error = util::GDataToDriveFileError(status);
|
| + if (error != DRIVE_FILE_OK)
|
| return;
|
|
|
| - // For initial loading, even for directory fetching, we do load the full
|
| - // feed from the server to sync up. So we register a dummy callback to
|
| - // indicate that update for full hierarchy is running.
|
| - if (is_initial_load && !resource_id.empty()) {
|
| - pending_load_callback_[""].push_back(
|
| - base::Bind(&util::EmptyFileOperationCallback));
|
| - }
|
| -
|
| - // Check the current status of local metadata, and start loading if needed.
|
| - resource_metadata_->GetLargestChangestamp(
|
| - base::Bind(is_initial_load ? &ChangeListLoader::DoInitialLoad
|
| - : &ChangeListLoader::DoUpdateLoad,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - directory_fetch_info));
|
| -}
|
| -
|
| -void ChangeListLoader::DoInitialLoad(
|
| - const DirectoryFetchInfo& directory_fetch_info,
|
| - int64 local_changestamp) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - if (local_changestamp > 0) {
|
| - // The local data is usable. Flush callbacks to tell loading was successful.
|
| - OnChangeListLoadComplete(DRIVE_FILE_OK);
|
| -
|
| - // Continues to load from server in background.
|
| - // Put dummy callbacks to indicate that fetching is still continuing.
|
| - pending_load_callback_[directory_fetch_info.resource_id()].push_back(
|
| - base::Bind(&util::EmptyFileOperationCallback));
|
| - if (!directory_fetch_info.empty()) {
|
| - pending_load_callback_[""].push_back(
|
| - base::Bind(&util::EmptyFileOperationCallback));
|
| - }
|
| - }
|
| - LoadFromServerIfNeeded(directory_fetch_info, local_changestamp);
|
| -}
|
| -
|
| -void ChangeListLoader::DoUpdateLoad(
|
| - const DirectoryFetchInfo& directory_fetch_info,
|
| - int64 local_changestamp) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - if (directory_fetch_info.empty()) {
|
| - LoadFromServerIfNeeded(directory_fetch_info, local_changestamp);
|
| - } else {
|
| - // Note: CheckChangestampAndLoadDirectoryIfNeeded regards
|
| - // last_know_remote_changestamp_ as the remote changestamp. To be precise,
|
| - // we need to call GetAboutResource() here, as we do in other places like
|
| - // LoadFromServerIfNeeded or LoadFromDirectory. However,
|
| - // - It is costly to do GetAboutResource HTTP request every time.
|
| - // - The chance using an old value is small; it only happens when
|
| - // LoadIfNeeded is called during one GetAboutResource roundtrip time
|
| - // of a feed fetching.
|
| - // - Even if the value is old, it just marks the directory as older. It may
|
| - // trigger one future unnecessary re-fetch, but it'll never lose data.
|
| - CheckChangestampAndLoadDirectoryIfNeeed(
|
| - directory_fetch_info,
|
| - local_changestamp,
|
| - base::Bind(&ChangeListLoader::OnDirectoryLoadComplete,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - directory_fetch_info));
|
| - }
|
| + if (app_list.get())
|
| + webapps_registry_->UpdateFromAppList(*app_list);
|
| }
|
|
|
| -void ChangeListLoader::CheckForUpdates(const FileOperationCallback& callback) {
|
| +void ChangeListLoader::SearchFromServerAfterGetResourceList(
|
| + const LoadFeedListCallback& callback,
|
| + google_apis::GDataErrorCode status,
|
| + scoped_ptr<google_apis::ResourceList> resource_list) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| DCHECK(!callback.is_null());
|
|
|
| - if (loaded_ && !IsRefreshing())
|
| - Load(DirectoryFetchInfo(), callback);
|
| -}
|
| -
|
| -void ChangeListLoader::UpdateFromFeed(
|
| - scoped_ptr<google_apis::AboutResource> about_resource,
|
| - ScopedVector<ChangeList> change_lists,
|
| - bool is_delta_feed,
|
| - const base::Closure& update_finished_callback) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - DCHECK(!update_finished_callback.is_null());
|
| -
|
| - change_list_processor_.reset(new ChangeListProcessor(resource_metadata_));
|
| - // Don't send directory content change notification while performing
|
| - // the initial content retrieval.
|
| - const bool should_notify_changed_directories = is_delta_feed;
|
| -
|
| - change_list_processor_->ApplyFeeds(
|
| - about_resource.Pass(),
|
| - change_lists.Pass(),
|
| - is_delta_feed,
|
| - base::Bind(&ChangeListLoader::NotifyDirectoryChangedAfterApplyFeed,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - should_notify_changed_directories,
|
| - update_finished_callback));
|
| -}
|
| -
|
| -void ChangeListLoader::CheckChangestampAndLoadDirectoryIfNeeed(
|
| - const DirectoryFetchInfo& directory_fetch_info,
|
| - int64 local_changestamp,
|
| - const FileOperationCallback& callback) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - DCHECK(!directory_fetch_info.empty());
|
| -
|
| - int64 directory_changestamp = std::max(directory_fetch_info.changestamp(),
|
| - local_changestamp);
|
| -
|
| - // If the directory's changestamp is up-to-date, just schedule to run the
|
| - // callback, as there is no need to fetch the directory.
|
| - // Note that |last_known_remote_changestamp_| is 0 when it is not received
|
| - // yet. In that case we conservatively assume that we need to fetch.
|
| - if (last_known_remote_changestamp_ > 0 &&
|
| - directory_changestamp >= last_known_remote_changestamp_) {
|
| - callback.Run(DRIVE_FILE_OK);
|
| + DriveFileError error = util::GDataToDriveFileError(status);
|
| + if (error != DRIVE_FILE_OK) {
|
| + callback.Run(ScopedVector<ChangeList>(), error);
|
| return;
|
| }
|
|
|
| - DVLOG(1) << "Fast-fetching directory: " << directory_fetch_info.ToString()
|
| - << "; remote_changestamp: " << last_known_remote_changestamp_;
|
| + DCHECK(resource_list);
|
|
|
| - // Start fetching the directory content, and mark it with the changestamp
|
| - // |last_known_remote_changestamp_|.
|
| - DirectoryFetchInfo new_directory_fetch_info(
|
| - directory_fetch_info.resource_id(),
|
| - std::max(directory_changestamp, last_known_remote_changestamp_));
|
| - DoLoadDirectoryFromServer(new_directory_fetch_info, callback);
|
| + ScopedVector<ChangeList> change_lists;
|
| + change_lists.push_back(new ChangeList(*resource_list));
|
| + callback.Run(change_lists.Pass(), DRIVE_FILE_OK);
|
| }
|
|
|
| void ChangeListLoader::NotifyDirectoryChangedAfterApplyFeed(
|
| bool should_notify_changed_directories,
|
| - const base::Closure& update_finished_callback) {
|
| + const base::Closure& callback) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| DCHECK(change_list_processor_.get());
|
| - DCHECK(!update_finished_callback.is_null());
|
| + DCHECK(!callback.is_null());
|
|
|
| if (should_notify_changed_directories) {
|
| for (std::set<base::FilePath>::iterator dir_iter =
|
| @@ -678,64 +731,10 @@ void ChangeListLoader::NotifyDirectoryChangedAfterApplyFeed(
|
| }
|
| }
|
|
|
| - update_finished_callback.Run();
|
| + callback.Run();
|
|
|
| // Cannot delete change_list_processor_ yet because we are in
|
| // on_complete_callback_, which is owned by change_list_processor_.
|
| }
|
|
|
| -void ChangeListLoader::OnUpdateFromFeed() {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - OnChangeListLoadComplete(DRIVE_FILE_OK);
|
| -
|
| - FOR_EACH_OBSERVER(ChangeListLoaderObserver,
|
| - observers_,
|
| - OnFeedFromServerLoaded());
|
| -}
|
| -
|
| -void ChangeListLoader::OnChangeListLoadComplete(DriveFileError error) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - if (!loaded_ && error == DRIVE_FILE_OK) {
|
| - loaded_ = true;
|
| - FOR_EACH_OBSERVER(ChangeListLoaderObserver,
|
| - observers_,
|
| - OnInitialFeedLoaded());
|
| - }
|
| -
|
| - for (LoadCallbackMap::iterator it = pending_load_callback_.begin();
|
| - it != pending_load_callback_.end(); ++it) {
|
| - const std::vector<FileOperationCallback>& callbacks = it->second;
|
| - for (size_t i = 0; i < callbacks.size(); ++i) {
|
| - base::MessageLoopProxy::current()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(callbacks[i], error));
|
| - }
|
| - }
|
| - pending_load_callback_.clear();
|
| -}
|
| -
|
| -void ChangeListLoader::OnDirectoryLoadComplete(
|
| - const DirectoryFetchInfo& directory_fetch_info,
|
| - DriveFileError error) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - DVLOG_IF(1, error == DRIVE_FILE_OK) << "Fast-fetch was successful: "
|
| - << directory_fetch_info.ToString();
|
| -
|
| - const std::string& resource_id = directory_fetch_info.resource_id();
|
| - LoadCallbackMap::iterator it = pending_load_callback_.find(resource_id);
|
| - if (it != pending_load_callback_.end()) {
|
| - DVLOG(1) << "Running callback for " << resource_id;
|
| - const std::vector<FileOperationCallback>& callbacks = it->second;
|
| - for (size_t i = 0; i < callbacks.size(); ++i) {
|
| - base::MessageLoopProxy::current()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(callbacks[i], error));
|
| - }
|
| - pending_load_callback_.erase(it);
|
| - }
|
| -}
|
| -
|
| } // namespace drive
|
|
|