Upstream version 9.38.198.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 "base/bind.h"
8 #include "base/format_macros.h"
9 #include "base/location.h"
10 #include "base/strings/stringprintf.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
23 namespace sync_file_system {
24 namespace drive_backend {
25
26 ListChangesTask::ListChangesTask(SyncEngineContext* sync_context)
27     : sync_context_(sync_context),
28       weak_ptr_factory_(this) {
29 }
30
31 ListChangesTask::~ListChangesTask() {
32 }
33
34 void ListChangesTask::RunPreflight(scoped_ptr<SyncTaskToken> token) {
35   token->InitializeTaskLog("List Changes");
36
37   if (!IsContextReady()) {
38     token->RecordLog("Failed to get required service.");
39     SyncTaskManager::NotifyTaskDone(token.Pass(), SYNC_STATUS_FAILED);
40     return;
41   }
42
43   SyncTaskManager::UpdateBlockingFactor(
44       token.Pass(),
45       scoped_ptr<BlockingFactor>(new BlockingFactor),
46       base::Bind(&ListChangesTask::StartListing,
47                  weak_ptr_factory_.GetWeakPtr()));
48 }
49
50 void ListChangesTask::StartListing(scoped_ptr<SyncTaskToken> token) {
51   drive_service()->GetChangeList(
52       metadata_database()->GetLargestFetchedChangeID() + 1,
53       base::Bind(&ListChangesTask::DidListChanges,
54                  weak_ptr_factory_.GetWeakPtr(), base::Passed(&token)));
55 }
56
57 void ListChangesTask::DidListChanges(
58     scoped_ptr<SyncTaskToken> token,
59     google_apis::GDataErrorCode error,
60     scoped_ptr<google_apis::ChangeList> change_list) {
61   SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error);
62   if (status != SYNC_STATUS_OK) {
63     token->RecordLog("Failed to fetch change list.");
64     SyncTaskManager::NotifyTaskDone(
65         token.Pass(), SYNC_STATUS_NETWORK_ERROR);
66     return;
67   }
68
69   if (!change_list) {
70     NOTREACHED();
71     token->RecordLog("Got invalid change list.");
72     SyncTaskManager::NotifyTaskDone(token.Pass(), SYNC_STATUS_FAILED);
73     return;
74   }
75
76   std::vector<google_apis::ChangeResource*> changes;
77   change_list->mutable_items()->release(&changes);
78
79   change_list_.reserve(change_list_.size() + changes.size());
80   for (size_t i = 0; i < changes.size(); ++i)
81     change_list_.push_back(changes[i]);
82
83   if (!change_list->next_link().is_empty()) {
84     drive_service()->GetRemainingChangeList(
85         change_list->next_link(),
86         base::Bind(
87             &ListChangesTask::DidListChanges,
88             weak_ptr_factory_.GetWeakPtr(),
89             base::Passed(&token)));
90     return;
91   }
92
93   if (change_list_.empty()) {
94     token->RecordLog("Got no change.");
95     SyncTaskManager::NotifyTaskDone(
96         token.Pass(), SYNC_STATUS_NO_CHANGE_TO_SYNC);
97     return;
98   }
99
100   scoped_ptr<BlockingFactor> blocking_factor(new BlockingFactor);
101   blocking_factor->exclusive = true;
102   SyncTaskManager::UpdateBlockingFactor(
103       token.Pass(),
104       blocking_factor.Pass(),
105       base::Bind(&ListChangesTask::CheckInChangeList,
106                  weak_ptr_factory_.GetWeakPtr(),
107                  change_list->largest_change_id()));
108 }
109
110 void ListChangesTask::CheckInChangeList(int64 largest_change_id,
111                                         scoped_ptr<SyncTaskToken> token) {
112   token->RecordLog(base::StringPrintf(
113       "Got %" PRIuS " changes, updating MetadataDatabase.",
114       change_list_.size()));
115
116   DCHECK(file_ids_.empty());
117   file_ids_.reserve(change_list_.size());
118   for (size_t i = 0; i < change_list_.size(); ++i)
119     file_ids_.push_back(change_list_[i]->file_id());
120
121   metadata_database()->UpdateByChangeList(
122       largest_change_id,
123       change_list_.Pass(),
124       base::Bind(&ListChangesTask::DidCheckInChangeList,
125                  weak_ptr_factory_.GetWeakPtr(), base::Passed(&token)));
126 }
127
128 void ListChangesTask::DidCheckInChangeList(scoped_ptr<SyncTaskToken> token,
129                                            SyncStatusCode status) {
130   if (status != SYNC_STATUS_OK) {
131     SyncTaskManager::NotifyTaskDone(token.Pass(), status);
132     return;
133   }
134
135   metadata_database()->SweepDirtyTrackers(
136       file_ids_,
137       base::Bind(&SyncTaskManager::NotifyTaskDone, base::Passed(&token)));
138 }
139
140 bool ListChangesTask::IsContextReady() {
141   return sync_context_->GetMetadataDatabase() &&
142       sync_context_->GetDriveService();
143 }
144
145 MetadataDatabase* ListChangesTask::metadata_database() {
146   return sync_context_->GetMetadataDatabase();
147 }
148
149 drive::DriveServiceInterface* ListChangesTask::drive_service() {
150   set_used_network(true);
151   return sync_context_->GetDriveService();
152 }
153
154 }  // namespace drive_backend
155 }  // namespace sync_file_system