Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync_file_system / drive_backend / list_changes_task.cc
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 <vector>
8
9 #include "base/bind.h"
10 #include "base/format_macros.h"
11 #include "base/location.h"
12 #include "base/strings/stringprintf.h"
13 #include "chrome/browser/drive/drive_service_interface.h"
14 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h"
15 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
16 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
17 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
18 #include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h"
19 #include "chrome/browser/sync_file_system/drive_backend/sync_task_token.h"
20 #include "chrome/browser/sync_file_system/logger.h"
21 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
22 #include "google_apis/drive/drive_api_parser.h"
23 #include "google_apis/drive/gdata_wapi_parser.h"
24
25 namespace sync_file_system {
26 namespace drive_backend {
27
28 ListChangesTask::ListChangesTask(SyncEngineContext* sync_context)
29     : sync_context_(sync_context),
30       weak_ptr_factory_(this) {
31 }
32
33 ListChangesTask::~ListChangesTask() {
34 }
35
36 void ListChangesTask::RunPreflight(scoped_ptr<SyncTaskToken> token) {
37   token->InitializeTaskLog("List Changes");
38
39   if (!IsContextReady()) {
40     token->RecordLog("Failed to get required service.");
41     SyncTaskManager::NotifyTaskDone(token.Pass(), SYNC_STATUS_FAILED);
42     return;
43   }
44
45   SyncTaskManager::UpdateTaskBlocker(
46       token.Pass(),
47       scoped_ptr<TaskBlocker>(new TaskBlocker),
48       base::Bind(&ListChangesTask::StartListing,
49                  weak_ptr_factory_.GetWeakPtr()));
50 }
51
52 void 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
59 void 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     token->RecordLog("Failed to fetch change list.");
66     SyncTaskManager::NotifyTaskDone(
67         token.Pass(), SYNC_STATUS_NETWORK_ERROR);
68     return;
69   }
70
71   if (!change_list) {
72     NOTREACHED();
73     token->RecordLog("Got invalid change list.");
74     SyncTaskManager::NotifyTaskDone(token.Pass(), SYNC_STATUS_FAILED);
75     return;
76   }
77
78   std::vector<google_apis::ChangeResource*> changes;
79   change_list->mutable_items()->release(&changes);
80
81   change_list_.reserve(change_list_.size() + changes.size());
82   for (size_t i = 0; i < changes.size(); ++i)
83     change_list_.push_back(changes[i]);
84
85   if (!change_list->next_link().is_empty()) {
86     drive_service()->GetRemainingChangeList(
87         change_list->next_link(),
88         base::Bind(
89             &ListChangesTask::DidListChanges,
90             weak_ptr_factory_.GetWeakPtr(),
91             base::Passed(&token)));
92     return;
93   }
94
95   if (change_list_.empty()) {
96     token->RecordLog("Got no change.");
97     SyncTaskManager::NotifyTaskDone(
98         token.Pass(), SYNC_STATUS_NO_CHANGE_TO_SYNC);
99     return;
100   }
101
102   scoped_ptr<TaskBlocker> task_blocker(new TaskBlocker);
103   task_blocker->exclusive = true;
104   SyncTaskManager::UpdateTaskBlocker(
105       token.Pass(),
106       task_blocker.Pass(),
107       base::Bind(&ListChangesTask::CheckInChangeList,
108                  weak_ptr_factory_.GetWeakPtr(),
109                  change_list->largest_change_id()));
110 }
111
112 void ListChangesTask::CheckInChangeList(int64 largest_change_id,
113                                         scoped_ptr<SyncTaskToken> token) {
114   token->RecordLog(base::StringPrintf(
115       "Got %" PRIuS " changes, updating MetadataDatabase.",
116       change_list_.size()));
117
118   DCHECK(file_ids_.empty());
119   file_ids_.reserve(change_list_.size());
120   for (size_t i = 0; i < change_list_.size(); ++i)
121     file_ids_.push_back(change_list_[i]->file_id());
122
123   SyncStatusCode status =
124       metadata_database()->UpdateByChangeList(
125           largest_change_id, change_list_.Pass());
126   if (status != SYNC_STATUS_OK) {
127     SyncTaskManager::NotifyTaskDone(token.Pass(), status);
128     return;
129   }
130
131   status = metadata_database()->SweepDirtyTrackers(file_ids_);
132   SyncTaskManager::NotifyTaskDone(token.Pass(), status);
133 }
134
135 bool ListChangesTask::IsContextReady() {
136   return sync_context_->GetMetadataDatabase() &&
137       sync_context_->GetDriveService();
138 }
139
140 MetadataDatabase* ListChangesTask::metadata_database() {
141   return sync_context_->GetMetadataDatabase();
142 }
143
144 drive::DriveServiceInterface* ListChangesTask::drive_service() {
145   set_used_network(true);
146   return sync_context_->GetDriveService();
147 }
148
149 }  // namespace drive_backend
150 }  // namespace sync_file_system