1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Copyright 2013 The Chromium Authors. All rights reserved. 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Use of this source code is governed by a BSD-style license that can be 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// found in the LICENSE file. 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "chrome/browser/sync_file_system/drive_backend/list_changes_task.h" 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <vector> 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/bind.h" 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/format_macros.h" 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/location.h" 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/strings/stringprintf.h" 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "chrome/browser/drive/drive_service_interface.h" 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h" 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h" 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h" 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h" 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h" 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "chrome/browser/sync_file_system/drive_backend/sync_task_token.h" 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "chrome/browser/sync_file_system/logger.h" 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "chrome/browser/sync_file_system/syncable_file_system_util.h" 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "google_apis/drive/drive_api_parser.h" 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "google_apis/drive/gdata_wapi_parser.h" 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace sync_file_system { 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace drive_backend { 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgListChangesTask::ListChangesTask(SyncEngineContext* sync_context) 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : sync_context_(sync_context), 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org weak_ptr_factory_(this) { 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgListChangesTask::~ListChangesTask() { 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ListChangesTask::RunPreflight(scoped_ptr<SyncTaskToken> token) { 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token->InitializeTaskLog("List Changes"); 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!IsContextReady()) { 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token->RecordLog("Failed to get required service."); 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SyncTaskManager::NotifyTaskDone(token.Pass(), SYNC_STATUS_FAILED); 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SyncTaskManager::UpdateTaskBlocker( 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token.Pass(), 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scoped_ptr<TaskBlocker>(new TaskBlocker), 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::Bind(&ListChangesTask::StartListing, 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org weak_ptr_factory_.GetWeakPtr())); 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ListChangesTask::StartListing(scoped_ptr<SyncTaskToken> token) { 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org drive_service()->GetChangeList( 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org metadata_database()->GetLargestFetchedChangeID() + 1, 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::Bind(&ListChangesTask::DidListChanges, 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org weak_ptr_factory_.GetWeakPtr(), base::Passed(&token))); 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ListChangesTask::DidListChanges( 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scoped_ptr<SyncTaskToken> token, 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org google_apis::GDataErrorCode error, 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scoped_ptr<google_apis::ChangeList> change_list) { 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (status != SYNC_STATUS_OK) { 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token->RecordLog("Failed to fetch change list."); 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SyncTaskManager::NotifyTaskDone( 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token.Pass(), SYNC_STATUS_NETWORK_ERROR); 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!change_list) { 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NOTREACHED(); 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token->RecordLog("Got invalid change list."); 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SyncTaskManager::NotifyTaskDone(token.Pass(), SYNC_STATUS_FAILED); 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::vector<google_apis::ChangeResource*> changes; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org change_list->mutable_items()->release(&changes); 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org change_list_.reserve(change_list_.size() + changes.size()); 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (size_t i = 0; i < changes.size(); ++i) 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org change_list_.push_back(changes[i]); 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!change_list->next_link().is_empty()) { 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org drive_service()->GetRemainingChangeList( 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org change_list->next_link(), 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::Bind( 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &ListChangesTask::DidListChanges, 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org weak_ptr_factory_.GetWeakPtr(), 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::Passed(&token))); 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (change_list_.empty()) { 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token->RecordLog("Got no change."); 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SyncTaskManager::NotifyTaskDone( 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token.Pass(), SYNC_STATUS_NO_CHANGE_TO_SYNC); 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scoped_ptr<TaskBlocker> task_blocker(new TaskBlocker); 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org task_blocker->exclusive = true; 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SyncTaskManager::UpdateTaskBlocker( 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token.Pass(), 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org task_blocker.Pass(), 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::Bind(&ListChangesTask::CheckInChangeList, 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org weak_ptr_factory_.GetWeakPtr(), 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org change_list->largest_change_id())); 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ListChangesTask::CheckInChangeList(int64 largest_change_id, 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scoped_ptr<SyncTaskToken> token) { 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org token->RecordLog(base::StringPrintf( 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Got %" PRIuS " changes, updating MetadataDatabase.", 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org change_list_.size())); 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DCHECK(file_ids_.empty()); 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org file_ids_.reserve(change_list_.size()); 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (size_t i = 0; i < change_list_.size(); ++i) 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org file_ids_.push_back(change_list_[i]->file_id()); 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SyncStatusCode status = 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org metadata_database()->UpdateByChangeList( 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org largest_change_id, change_list_.Pass()); 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (status != SYNC_STATUS_OK) { 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SyncTaskManager::NotifyTaskDone(token.Pass(), status); 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org status = metadata_database()->SweepDirtyTrackers(file_ids_); 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SyncTaskManager::NotifyTaskDone(token.Pass(), status); 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool ListChangesTask::IsContextReady() { 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return sync_context_->GetMetadataDatabase() && 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sync_context_->GetDriveService(); 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgMetadataDatabase* ListChangesTask::metadata_database() { 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return sync_context_->GetMetadataDatabase(); 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdrive::DriveServiceInterface* ListChangesTask::drive_service() { 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org set_used_network(true); 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return sync_context_->GetDriveService(); 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // namespace drive_backend 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // namespace sync_file_system 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org