list_changes_task.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright 2013 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. 4 5#include "chrome/browser/sync_file_system/drive_backend/list_changes_task.h" 6 7#include "base/bind.h" 8#include "base/format_macros.h" 9#include "base/location.h" 10#include "chrome/browser/drive/drive_service_interface.h" 11#include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h" 12#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h" 13#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h" 14#include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h" 15#include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h" 16#include "chrome/browser/sync_file_system/drive_backend/sync_task_token.h" 17#include "chrome/browser/sync_file_system/logger.h" 18#include "chrome/browser/sync_file_system/syncable_file_system_util.h" 19#include "google_apis/drive/drive_api_parser.h" 20#include "google_apis/drive/gdata_wapi_parser.h" 21 22namespace sync_file_system { 23namespace drive_backend { 24 25ListChangesTask::ListChangesTask(SyncEngineContext* sync_context) 26 : sync_context_(sync_context), 27 weak_ptr_factory_(this) { 28} 29 30ListChangesTask::~ListChangesTask() { 31} 32 33void ListChangesTask::RunPreflight(scoped_ptr<SyncTaskToken> token) { 34 util::Log(logging::LOG_VERBOSE, FROM_HERE, "[Changes] Start."); 35 36 if (!IsContextReady()) { 37 util::Log(logging::LOG_VERBOSE, FROM_HERE, 38 "[Changes] Failed to get required service."); 39 RunSoon(FROM_HERE, base::Bind(&SyncTaskManager::NotifyTaskDone, 40 base::Passed(&token), 41 SYNC_STATUS_FAILED)); 42 return; 43 } 44 45 SyncTaskManager::UpdateBlockingFactor( 46 token.Pass(), 47 scoped_ptr<BlockingFactor>(new BlockingFactor), 48 base::Bind(&ListChangesTask::StartListing, 49 weak_ptr_factory_.GetWeakPtr())); 50} 51 52void ListChangesTask::StartListing(scoped_ptr<SyncTaskToken> token) { 53 drive_service()->GetChangeList( 54 metadata_database()->GetLargestFetchedChangeID() + 1, 55 base::Bind(&ListChangesTask::DidListChanges, 56 weak_ptr_factory_.GetWeakPtr(), base::Passed(&token))); 57} 58 59void ListChangesTask::DidListChanges( 60 scoped_ptr<SyncTaskToken> token, 61 google_apis::GDataErrorCode error, 62 scoped_ptr<google_apis::ChangeList> change_list) { 63 SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); 64 if (status != SYNC_STATUS_OK) { 65 util::Log(logging::LOG_VERBOSE, FROM_HERE, 66 "[Changes] Failed to fetch change list."); 67 SyncTaskManager::NotifyTaskDone( 68 token.Pass(), SYNC_STATUS_NETWORK_ERROR); 69 return; 70 } 71 72 if (!change_list) { 73 NOTREACHED(); 74 util::Log(logging::LOG_VERBOSE, FROM_HERE, 75 "[Changes] Got invalid change list."); 76 SyncTaskManager::NotifyTaskDone( 77 token.Pass(), SYNC_STATUS_FAILED); 78 return; 79 } 80 81 std::vector<google_apis::ChangeResource*> changes; 82 change_list->mutable_items()->release(&changes); 83 84 change_list_.reserve(change_list_.size() + changes.size()); 85 for (size_t i = 0; i < changes.size(); ++i) 86 change_list_.push_back(changes[i]); 87 88 if (!change_list->next_link().is_empty()) { 89 drive_service()->GetRemainingChangeList( 90 change_list->next_link(), 91 base::Bind( 92 &ListChangesTask::DidListChanges, 93 weak_ptr_factory_.GetWeakPtr(), 94 base::Passed(&token))); 95 return; 96 } 97 98 if (change_list_.empty()) { 99 util::Log(logging::LOG_VERBOSE, FROM_HERE, "[Changes] Got no change."); 100 SyncTaskManager::NotifyTaskDone( 101 token.Pass(), SYNC_STATUS_NO_CHANGE_TO_SYNC); 102 return; 103 } 104 105 scoped_ptr<BlockingFactor> blocking_factor(new BlockingFactor); 106 blocking_factor->exclusive = true; 107 SyncTaskManager::UpdateBlockingFactor( 108 token.Pass(), 109 blocking_factor.Pass(), 110 base::Bind(&ListChangesTask::CheckInChangeList, 111 weak_ptr_factory_.GetWeakPtr(), 112 change_list->largest_change_id())); 113} 114 115void ListChangesTask::CheckInChangeList(int64 largest_change_id, 116 scoped_ptr<SyncTaskToken> token) { 117 util::Log(logging::LOG_VERBOSE, FROM_HERE, 118 "[Changes] Got %" PRIuS " changes, updating MetadataDatabase.", 119 change_list_.size()); 120 metadata_database()->UpdateByChangeList( 121 largest_change_id, 122 change_list_.Pass(), 123 base::Bind(&SyncTaskManager::NotifyTaskDone, base::Passed(&token))); 124} 125 126bool ListChangesTask::IsContextReady() { 127 return sync_context_->GetMetadataDatabase() && 128 sync_context_->GetDriveService(); 129} 130 131MetadataDatabase* ListChangesTask::metadata_database() { 132 return sync_context_->GetMetadataDatabase(); 133} 134 135drive::DriveServiceInterface* ListChangesTask::drive_service() { 136 set_used_network(true); 137 return sync_context_->GetDriveService(); 138} 139 140} // namespace drive_backend 141} // namespace sync_file_system 142