list_changes_task.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
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_api_util.h" 11#include "chrome/browser/drive/drive_service_interface.h" 12#include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h" 13#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h" 14#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h" 15#include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h" 16#include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h" 17#include "chrome/browser/sync_file_system/drive_backend/sync_task_token.h" 18#include "chrome/browser/sync_file_system/logger.h" 19#include "chrome/browser/sync_file_system/syncable_file_system_util.h" 20#include "google_apis/drive/drive_api_parser.h" 21#include "google_apis/drive/gdata_wapi_parser.h" 22 23namespace sync_file_system { 24namespace drive_backend { 25 26namespace { 27 28scoped_ptr<google_apis::ChangeResource> ConvertResourceEntryToChangeResource( 29 const google_apis::ResourceEntry& entry) { 30 scoped_ptr<google_apis::ChangeResource> out(new google_apis::ChangeResource); 31 out->set_file_id(entry.resource_id()); 32 if (!entry.deleted()) 33 out->set_file(drive::util::ConvertResourceEntryToFileResource(entry)); 34 out->set_change_id(entry.changestamp()); 35 out->set_deleted(entry.deleted()); 36 37 return out.Pass(); 38} 39 40} // namespace 41 42ListChangesTask::ListChangesTask(SyncEngineContext* sync_context) 43 : sync_context_(sync_context), 44 weak_ptr_factory_(this) { 45} 46 47ListChangesTask::~ListChangesTask() { 48} 49 50void ListChangesTask::RunPreflight(scoped_ptr<SyncTaskToken> token) { 51 util::Log(logging::LOG_VERBOSE, FROM_HERE, "[Changes] Start."); 52 53 if (!IsContextReady()) { 54 util::Log(logging::LOG_VERBOSE, FROM_HERE, 55 "[Changes] Failed to get required service."); 56 RunSoon(FROM_HERE, base::Bind(&SyncTaskManager::NotifyTaskDone, 57 base::Passed(&token), 58 SYNC_STATUS_FAILED)); 59 return; 60 } 61 62 drive_service()->GetChangeList( 63 metadata_database()->GetLargestFetchedChangeID() + 1, 64 base::Bind(&ListChangesTask::DidListChanges, 65 weak_ptr_factory_.GetWeakPtr(), base::Passed(&token))); 66} 67 68void ListChangesTask::DidListChanges( 69 scoped_ptr<SyncTaskToken> token, 70 google_apis::GDataErrorCode error, 71 scoped_ptr<google_apis::ResourceList> resource_list) { 72 SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); 73 if (status != SYNC_STATUS_OK) { 74 util::Log(logging::LOG_VERBOSE, FROM_HERE, 75 "[Changes] Failed to fetch change list."); 76 SyncTaskManager::NotifyTaskDone( 77 token.Pass(), SYNC_STATUS_NETWORK_ERROR); 78 return; 79 } 80 81 if (!resource_list) { 82 NOTREACHED(); 83 util::Log(logging::LOG_VERBOSE, FROM_HERE, 84 "[Changes] Got invalid change list."); 85 SyncTaskManager::NotifyTaskDone( 86 token.Pass(), SYNC_STATUS_FAILED); 87 return; 88 } 89 90 change_list_.reserve(change_list_.size() + resource_list->entries().size()); 91 for (size_t i = 0; i < resource_list->entries().size(); ++i) { 92 change_list_.push_back(ConvertResourceEntryToChangeResource( 93 *resource_list->entries()[i]).release()); 94 } 95 96 // TODO(tzik): http://crbug.com/310964 97 // This may take long time to run in single task. Run this as a background 98 // task. 99 GURL next_feed; 100 if (resource_list->GetNextFeedURL(&next_feed)) { 101 drive_service()->GetRemainingChangeList( 102 next_feed, 103 base::Bind( 104 &ListChangesTask::DidListChanges, 105 weak_ptr_factory_.GetWeakPtr(), 106 base::Passed(&token))); 107 return; 108 } 109 110 if (change_list_.empty()) { 111 util::Log(logging::LOG_VERBOSE, FROM_HERE, "[Changes] Got no change."); 112 SyncTaskManager::NotifyTaskDone( 113 token.Pass(), SYNC_STATUS_NO_CHANGE_TO_SYNC); 114 return; 115 } 116 117 util::Log(logging::LOG_VERBOSE, FROM_HERE, 118 "[Changes] Got %" PRIuS " changes, updating MetadataDatabase.", 119 change_list_.size()); 120 metadata_database()->UpdateByChangeList( 121 resource_list->largest_changestamp(), 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