Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: chrome/browser/chromeos/drive/job_scheduler.cc

Issue 14634002: drive: Rename JobScheduler::QueueEntry to JobEntry (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review fix Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/chromeos/drive/job_scheduler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/drive/job_scheduler.h" 5 #include "chrome/browser/chromeos/drive/job_scheduler.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/prefs/pref_service.h" 10 #include "base/prefs/pref_service.h"
(...skipping 15 matching lines...) Expand all
26 26
27 namespace { 27 namespace {
28 const int kMaxThrottleCount = 5; 28 const int kMaxThrottleCount = 5;
29 } 29 }
30 30
31 const int JobScheduler::kMaxJobCount[] = { 31 const int JobScheduler::kMaxJobCount[] = {
32 5, // METADATA_QUEUE 32 5, // METADATA_QUEUE
33 1, // FILE_QUEUE 33 1, // FILE_QUEUE
34 }; 34 };
35 35
36 JobScheduler::QueueEntry::QueueEntry() 36 JobScheduler::JobEntry::JobEntry(JobType type)
37 : job_id(-1), 37 : job_info(type),
38 context(DriveClientContext(USER_INITIATED)) { 38 context(DriveClientContext(USER_INITIATED)) {
39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
40 } 40 }
41 41
42 JobScheduler::QueueEntry::~QueueEntry() { 42 JobScheduler::JobEntry::~JobEntry() {
43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
44 } 44 }
45 45
46 bool JobScheduler::QueueEntry::Compare( 46 bool JobScheduler::JobEntry::Less(const JobEntry& left, const JobEntry& right) {
47 const JobScheduler::QueueEntry* left,
48 const JobScheduler::QueueEntry* right) {
49 // Lower values of ContextType are higher priority. 47 // Lower values of ContextType are higher priority.
50 // See also the comment at ContextType. 48 // See also the comment at ContextType.
51 return (left->context.type < right->context.type); 49 return (left.context.type < right.context.type);
52 } 50 }
53 51
54 JobScheduler::JobScheduler( 52 JobScheduler::JobScheduler(
55 Profile* profile, 53 Profile* profile,
56 google_apis::DriveServiceInterface* drive_service) 54 google_apis::DriveServiceInterface* drive_service)
57 : throttle_count_(0), 55 : throttle_count_(0),
58 disable_throttling_(false), 56 disable_throttling_(false),
59 drive_service_(drive_service), 57 drive_service_(drive_service),
60 uploader_(new google_apis::DriveUploader(drive_service)), 58 uploader_(new google_apis::DriveUploader(drive_service)),
61 profile_(profile), 59 profile_(profile),
(...skipping 10 matching lines...) Expand all
72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 70 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
73 71
74 size_t num_pending_jobs = 0; 72 size_t num_pending_jobs = 0;
75 size_t num_running_jobs = 0; 73 size_t num_running_jobs = 0;
76 for (int i = 0; i < NUM_QUEUES; ++i) { 74 for (int i = 0; i < NUM_QUEUES; ++i) {
77 num_pending_jobs += queue_[i].size(); 75 num_pending_jobs += queue_[i].size();
78 num_running_jobs += jobs_running_[i]; 76 num_running_jobs += jobs_running_[i];
79 } 77 }
80 DCHECK_EQ(num_pending_jobs + num_running_jobs, job_map_.size()); 78 DCHECK_EQ(num_pending_jobs + num_running_jobs, job_map_.size());
81 79
82 for (int i = 0; i < NUM_QUEUES; ++i) {
83 STLDeleteElements(&queue_[i]);
84 }
85 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 80 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
86 } 81 }
87 82
88 std::vector<JobInfo> JobScheduler::GetJobInfoList() { 83 std::vector<JobInfo> JobScheduler::GetJobInfoList() {
89 std::vector<JobInfo> job_info_list; 84 std::vector<JobInfo> job_info_list;
90 for (JobIDMap::iterator iter(&job_map_); !iter.IsAtEnd(); iter.Advance()) 85 for (JobIDMap::iterator iter(&job_map_); !iter.IsAtEnd(); iter.Advance())
91 job_info_list.push_back(*iter.GetCurrentValue()); 86 job_info_list.push_back(iter.GetCurrentValue()->job_info);
92 return job_info_list; 87 return job_info_list;
93 } 88 }
94 89
95 void JobScheduler::AddObserver(JobListObserver* observer) { 90 void JobScheduler::AddObserver(JobListObserver* observer) {
96 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
97 observer_list_.AddObserver(observer); 92 observer_list_.AddObserver(observer);
98 } 93 }
99 94
100 void JobScheduler::RemoveObserver(JobListObserver* observer) { 95 void JobScheduler::RemoveObserver(JobListObserver* observer) {
101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 96 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
102 observer_list_.RemoveObserver(observer); 97 observer_list_.RemoveObserver(observer);
103 } 98 }
104 99
105 void JobScheduler::CancelJob(JobID job_id) { 100 void JobScheduler::CancelJob(JobID job_id) {
106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
107 102
108 // TODO(kinaba): Move the cancellation feature from DriveService 103 // TODO(kinaba): Move the cancellation feature from DriveService
109 // to JobScheduler. In particular, implement cancel based on job_id. 104 // to JobScheduler. In particular, implement cancel based on job_id.
110 // crbug.com/231029 105 // crbug.com/231029
111 JobInfo* info = job_map_.Lookup(job_id); 106 JobEntry* job = job_map_.Lookup(job_id);
112 if (info) 107 if (job)
113 drive_service_->CancelForFilePath(info->file_path); 108 drive_service_->CancelForFilePath(job->job_info.file_path);
114 } 109 }
115 110
116 void JobScheduler::CancelAllJobs() { 111 void JobScheduler::CancelAllJobs() {
117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
118 113
119 // TODO(kinaba): Move the cancellation feature from DriveService 114 // TODO(kinaba): Move the cancellation feature from DriveService
120 // to JobScheduler. 115 // to JobScheduler.
121 drive_service_->CancelAll(); 116 drive_service_->CancelAll();
122 } 117 }
123 118
124 void JobScheduler::GetAccountMetadata( 119 void JobScheduler::GetAccountMetadata(
125 const google_apis::GetAccountMetadataCallback& callback) { 120 const google_apis::GetAccountMetadataCallback& callback) {
126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
127 DCHECK(!callback.is_null()); 122 DCHECK(!callback.is_null());
128 123
129 scoped_ptr<QueueEntry> new_job(new QueueEntry); 124 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_GET_ACCOUNT_METADATA));
130 new_job->get_account_metadata_callback = callback; 125 new_job->get_account_metadata_callback = callback;
131 126
132 StartNewJob(new_job.Pass(), TYPE_GET_ACCOUNT_METADATA); 127 StartNewJob(new_job.Pass());
133 } 128 }
134 129
135 void JobScheduler::GetAboutResource( 130 void JobScheduler::GetAboutResource(
136 const google_apis::GetAboutResourceCallback& callback) { 131 const google_apis::GetAboutResourceCallback& callback) {
137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
138 DCHECK(!callback.is_null()); 133 DCHECK(!callback.is_null());
139 134
140 scoped_ptr<QueueEntry> new_job(new QueueEntry); 135 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_GET_ABOUT_RESOURCE));
141 new_job->get_about_resource_callback = callback; 136 new_job->get_about_resource_callback = callback;
142 137
143 StartNewJob(new_job.Pass(), TYPE_GET_ABOUT_RESOURCE); 138 StartNewJob(new_job.Pass());
144 } 139 }
145 140
146 void JobScheduler::GetAppList( 141 void JobScheduler::GetAppList(
147 const google_apis::GetAppListCallback& callback) { 142 const google_apis::GetAppListCallback& callback) {
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 143 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
149 DCHECK(!callback.is_null()); 144 DCHECK(!callback.is_null());
150 145
151 scoped_ptr<QueueEntry> new_job(new QueueEntry); 146 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_GET_APP_LIST));
152 new_job->get_app_list_callback = callback; 147 new_job->get_app_list_callback = callback;
153 148
154 StartNewJob(new_job.Pass(), TYPE_GET_APP_LIST); 149 StartNewJob(new_job.Pass());
155 } 150 }
156 151
157 void JobScheduler::GetAllResourceList( 152 void JobScheduler::GetAllResourceList(
158 const google_apis::GetResourceListCallback& callback) { 153 const google_apis::GetResourceListCallback& callback) {
159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
160 DCHECK(!callback.is_null()); 155 DCHECK(!callback.is_null());
161 156
162 scoped_ptr<QueueEntry> new_job(new QueueEntry); 157 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_GET_ALL_RESOURCE_LIST));
163 new_job->get_resource_list_callback = callback; 158 new_job->get_resource_list_callback = callback;
164 159
165 StartNewJob(new_job.Pass(), TYPE_GET_ALL_RESOURCE_LIST); 160 StartNewJob(new_job.Pass());
166 } 161 }
167 162
168 void JobScheduler::GetResourceListInDirectory( 163 void JobScheduler::GetResourceListInDirectory(
169 const std::string& directory_resource_id, 164 const std::string& directory_resource_id,
170 const google_apis::GetResourceListCallback& callback) { 165 const google_apis::GetResourceListCallback& callback) {
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
172 DCHECK(!callback.is_null()); 167 DCHECK(!callback.is_null());
173 168
174 scoped_ptr<QueueEntry> new_job(new QueueEntry); 169 scoped_ptr<JobEntry> new_job(new JobEntry(
170 TYPE_GET_RESOURCE_LIST_IN_DIRECTORY));
175 new_job->directory_resource_id = directory_resource_id; 171 new_job->directory_resource_id = directory_resource_id;
176 new_job->get_resource_list_callback = callback; 172 new_job->get_resource_list_callback = callback;
177 173
178 StartNewJob(new_job.Pass(), TYPE_GET_RESOURCE_LIST_IN_DIRECTORY); 174 StartNewJob(new_job.Pass());
179 } 175 }
180 176
181 void JobScheduler::Search( 177 void JobScheduler::Search(
182 const std::string& search_query, 178 const std::string& search_query,
183 const google_apis::GetResourceListCallback& callback) { 179 const google_apis::GetResourceListCallback& callback) {
184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
185 DCHECK(!callback.is_null()); 181 DCHECK(!callback.is_null());
186 182
187 scoped_ptr<QueueEntry> new_job(new QueueEntry); 183 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_SEARCH));
188 new_job->search_query = search_query; 184 new_job->search_query = search_query;
189 new_job->get_resource_list_callback = callback; 185 new_job->get_resource_list_callback = callback;
190 186
191 StartNewJob(new_job.Pass(), TYPE_SEARCH); 187 StartNewJob(new_job.Pass());
192 } 188 }
193 189
194 void JobScheduler::GetChangeList( 190 void JobScheduler::GetChangeList(
195 int64 start_changestamp, 191 int64 start_changestamp,
196 const google_apis::GetResourceListCallback& callback) { 192 const google_apis::GetResourceListCallback& callback) {
197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
198 DCHECK(!callback.is_null()); 194 DCHECK(!callback.is_null());
199 195
200 scoped_ptr<QueueEntry> new_job(new QueueEntry); 196 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_GET_CHANGE_LIST));
201 new_job->start_changestamp = start_changestamp; 197 new_job->start_changestamp = start_changestamp;
202 new_job->get_resource_list_callback = callback; 198 new_job->get_resource_list_callback = callback;
203 199
204 StartNewJob(new_job.Pass(), TYPE_GET_CHANGE_LIST); 200 StartNewJob(new_job.Pass());
205 } 201 }
206 202
207 void JobScheduler::ContinueGetResourceList( 203 void JobScheduler::ContinueGetResourceList(
208 const GURL& feed_url, 204 const GURL& feed_url,
209 const google_apis::GetResourceListCallback& callback) { 205 const google_apis::GetResourceListCallback& callback) {
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
211 DCHECK(!callback.is_null()); 207 DCHECK(!callback.is_null());
212 208
213 scoped_ptr<QueueEntry> new_job(new QueueEntry); 209 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_CONTINUE_GET_RESOURCE_LIST));
214 new_job->feed_url = feed_url; 210 new_job->feed_url = feed_url;
215 new_job->get_resource_list_callback = callback; 211 new_job->get_resource_list_callback = callback;
216 212
217 StartNewJob(new_job.Pass(), TYPE_CONTINUE_GET_RESOURCE_LIST); 213 StartNewJob(new_job.Pass());
218 } 214 }
219 215
220 void JobScheduler::GetResourceEntry( 216 void JobScheduler::GetResourceEntry(
221 const std::string& resource_id, 217 const std::string& resource_id,
222 const DriveClientContext& context, 218 const DriveClientContext& context,
223 const google_apis::GetResourceEntryCallback& callback) { 219 const google_apis::GetResourceEntryCallback& callback) {
224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
225 DCHECK(!callback.is_null()); 221 DCHECK(!callback.is_null());
226 222
227 scoped_ptr<QueueEntry> new_job(new QueueEntry); 223 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_GET_RESOURCE_ENTRY));
228 new_job->resource_id = resource_id; 224 new_job->resource_id = resource_id;
229 new_job->context = context; 225 new_job->context = context;
230 new_job->get_resource_entry_callback = callback; 226 new_job->get_resource_entry_callback = callback;
231 227
232 StartNewJob(new_job.Pass(), TYPE_GET_RESOURCE_ENTRY); 228 StartNewJob(new_job.Pass());
233 } 229 }
234 230
235 void JobScheduler::DeleteResource( 231 void JobScheduler::DeleteResource(
236 const std::string& resource_id, 232 const std::string& resource_id,
237 const google_apis::EntryActionCallback& callback) { 233 const google_apis::EntryActionCallback& callback) {
238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
239 DCHECK(!callback.is_null()); 235 DCHECK(!callback.is_null());
240 236
241 scoped_ptr<QueueEntry> new_job(new QueueEntry); 237 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_DELETE_RESOURCE));
242 new_job->resource_id = resource_id; 238 new_job->resource_id = resource_id;
243 new_job->entry_action_callback = callback; 239 new_job->entry_action_callback = callback;
244 240
245 StartNewJob(new_job.Pass(), TYPE_DELETE_RESOURCE); 241 StartNewJob(new_job.Pass());
246 } 242 }
247 243
248 244
249 void JobScheduler::CopyHostedDocument( 245 void JobScheduler::CopyHostedDocument(
250 const std::string& resource_id, 246 const std::string& resource_id,
251 const std::string& new_name, 247 const std::string& new_name,
252 const google_apis::GetResourceEntryCallback& callback) { 248 const google_apis::GetResourceEntryCallback& callback) {
253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
254 DCHECK(!callback.is_null()); 250 DCHECK(!callback.is_null());
255 251
256 scoped_ptr<QueueEntry> new_job(new QueueEntry); 252 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_COPY_HOSTED_DOCUMENT));
257 new_job->resource_id = resource_id; 253 new_job->resource_id = resource_id;
258 new_job->new_name = new_name; 254 new_job->new_name = new_name;
259 new_job->get_resource_entry_callback = callback; 255 new_job->get_resource_entry_callback = callback;
260 256
261 StartNewJob(new_job.Pass(), TYPE_COPY_HOSTED_DOCUMENT); 257 StartNewJob(new_job.Pass());
262 } 258 }
263 259
264 void JobScheduler::RenameResource( 260 void JobScheduler::RenameResource(
265 const std::string& resource_id, 261 const std::string& resource_id,
266 const std::string& new_name, 262 const std::string& new_name,
267 const google_apis::EntryActionCallback& callback) { 263 const google_apis::EntryActionCallback& callback) {
268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 264 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
269 DCHECK(!callback.is_null()); 265 DCHECK(!callback.is_null());
270 266
271 scoped_ptr<QueueEntry> new_job(new QueueEntry); 267 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_RENAME_RESOURCE));
272 new_job->resource_id = resource_id; 268 new_job->resource_id = resource_id;
273 new_job->new_name = new_name; 269 new_job->new_name = new_name;
274 new_job->entry_action_callback = callback; 270 new_job->entry_action_callback = callback;
275 271
276 StartNewJob(new_job.Pass(), TYPE_RENAME_RESOURCE); 272 StartNewJob(new_job.Pass());
277 } 273 }
278 274
279 void JobScheduler::AddResourceToDirectory( 275 void JobScheduler::AddResourceToDirectory(
280 const std::string& parent_resource_id, 276 const std::string& parent_resource_id,
281 const std::string& resource_id, 277 const std::string& resource_id,
282 const google_apis::EntryActionCallback& callback) { 278 const google_apis::EntryActionCallback& callback) {
283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
284 DCHECK(!callback.is_null()); 280 DCHECK(!callback.is_null());
285 281
286 scoped_ptr<QueueEntry> new_job(new QueueEntry); 282 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_ADD_RESOURCE_TO_DIRECTORY));
287 new_job->parent_resource_id = parent_resource_id; 283 new_job->parent_resource_id = parent_resource_id;
288 new_job->resource_id = resource_id; 284 new_job->resource_id = resource_id;
289 new_job->entry_action_callback = callback; 285 new_job->entry_action_callback = callback;
290 286
291 StartNewJob(new_job.Pass(), TYPE_ADD_RESOURCE_TO_DIRECTORY); 287 StartNewJob(new_job.Pass());
292 } 288 }
293 289
294 void JobScheduler::RemoveResourceFromDirectory( 290 void JobScheduler::RemoveResourceFromDirectory(
295 const std::string& parent_resource_id, 291 const std::string& parent_resource_id,
296 const std::string& resource_id, 292 const std::string& resource_id,
297 const google_apis::EntryActionCallback& callback) { 293 const google_apis::EntryActionCallback& callback) {
298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
299 295
300 scoped_ptr<QueueEntry> new_job(new QueueEntry); 296 scoped_ptr<JobEntry> new_job(new JobEntry(
297 TYPE_REMOVE_RESOURCE_FROM_DIRECTORY));
301 new_job->parent_resource_id = parent_resource_id; 298 new_job->parent_resource_id = parent_resource_id;
302 new_job->resource_id = resource_id; 299 new_job->resource_id = resource_id;
303 new_job->entry_action_callback = callback; 300 new_job->entry_action_callback = callback;
304 301
305 StartNewJob(new_job.Pass(), TYPE_REMOVE_RESOURCE_FROM_DIRECTORY); 302 StartNewJob(new_job.Pass());
306 } 303 }
307 304
308 void JobScheduler::AddNewDirectory( 305 void JobScheduler::AddNewDirectory(
309 const std::string& parent_resource_id, 306 const std::string& parent_resource_id,
310 const std::string& directory_name, 307 const std::string& directory_name,
311 const google_apis::GetResourceEntryCallback& callback) { 308 const google_apis::GetResourceEntryCallback& callback) {
312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 309 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
313 310
314 scoped_ptr<QueueEntry> new_job(new QueueEntry); 311 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_ADD_NEW_DIRECTORY));
315 new_job->parent_resource_id = parent_resource_id; 312 new_job->parent_resource_id = parent_resource_id;
316 new_job->directory_name = directory_name; 313 new_job->directory_name = directory_name;
317 new_job->get_resource_entry_callback = callback; 314 new_job->get_resource_entry_callback = callback;
318 315
319 StartNewJob(new_job.Pass(), TYPE_ADD_NEW_DIRECTORY); 316 StartNewJob(new_job.Pass());
320 } 317 }
321 318
322 JobID JobScheduler::DownloadFile( 319 JobID JobScheduler::DownloadFile(
323 const base::FilePath& virtual_path, 320 const base::FilePath& virtual_path,
324 const base::FilePath& local_cache_path, 321 const base::FilePath& local_cache_path,
325 const GURL& download_url, 322 const GURL& download_url,
326 const DriveClientContext& context, 323 const DriveClientContext& context,
327 const google_apis::DownloadActionCallback& download_action_callback, 324 const google_apis::DownloadActionCallback& download_action_callback,
328 const google_apis::GetContentCallback& get_content_callback) { 325 const google_apis::GetContentCallback& get_content_callback) {
329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 326 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
330 327
331 scoped_ptr<QueueEntry> new_job(new QueueEntry); 328 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_DOWNLOAD_FILE));
332 new_job->drive_file_path = virtual_path; 329 new_job->drive_file_path = virtual_path;
333 new_job->local_file_path = local_cache_path; 330 new_job->local_file_path = local_cache_path;
334 new_job->download_url = download_url; 331 new_job->download_url = download_url;
335 new_job->context = context; 332 new_job->context = context;
336 new_job->download_action_callback = download_action_callback; 333 new_job->download_action_callback = download_action_callback;
337 new_job->get_content_callback = get_content_callback; 334 new_job->get_content_callback = get_content_callback;
338 335
339 return StartNewJob(new_job.Pass(), TYPE_DOWNLOAD_FILE); 336 return StartNewJob(new_job.Pass());
340 } 337 }
341 338
342 void JobScheduler::UploadNewFile( 339 void JobScheduler::UploadNewFile(
343 const std::string& parent_resource_id, 340 const std::string& parent_resource_id,
344 const base::FilePath& drive_file_path, 341 const base::FilePath& drive_file_path,
345 const base::FilePath& local_file_path, 342 const base::FilePath& local_file_path,
346 const std::string& title, 343 const std::string& title,
347 const std::string& content_type, 344 const std::string& content_type,
348 const DriveClientContext& context, 345 const DriveClientContext& context,
349 const google_apis::UploadCompletionCallback& callback) { 346 const google_apis::UploadCompletionCallback& callback) {
350 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 347 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
351 348
352 scoped_ptr<QueueEntry> new_job(new QueueEntry); 349 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_UPLOAD_NEW_FILE));
353 new_job->resource_id = parent_resource_id; 350 new_job->resource_id = parent_resource_id;
354 new_job->drive_file_path = drive_file_path; 351 new_job->drive_file_path = drive_file_path;
355 new_job->local_file_path = local_file_path; 352 new_job->local_file_path = local_file_path;
356 new_job->title = title; 353 new_job->title = title;
357 new_job->content_type = content_type; 354 new_job->content_type = content_type;
358 new_job->upload_completion_callback = callback; 355 new_job->upload_completion_callback = callback;
359 new_job->context = context; 356 new_job->context = context;
360 357
361 StartNewJob(new_job.Pass(), TYPE_UPLOAD_NEW_FILE); 358 StartNewJob(new_job.Pass());
362 } 359 }
363 360
364 void JobScheduler::UploadExistingFile( 361 void JobScheduler::UploadExistingFile(
365 const std::string& resource_id, 362 const std::string& resource_id,
366 const base::FilePath& drive_file_path, 363 const base::FilePath& drive_file_path,
367 const base::FilePath& local_file_path, 364 const base::FilePath& local_file_path,
368 const std::string& content_type, 365 const std::string& content_type,
369 const std::string& etag, 366 const std::string& etag,
370 const DriveClientContext& context, 367 const DriveClientContext& context,
371 const google_apis::UploadCompletionCallback& upload_completion_callback) { 368 const google_apis::UploadCompletionCallback& upload_completion_callback) {
372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 369 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
373 370
374 scoped_ptr<QueueEntry> new_job(new QueueEntry); 371 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_UPLOAD_EXISTING_FILE));
375 new_job->resource_id = resource_id; 372 new_job->resource_id = resource_id;
376 new_job->drive_file_path = drive_file_path; 373 new_job->drive_file_path = drive_file_path;
377 new_job->local_file_path = local_file_path; 374 new_job->local_file_path = local_file_path;
378 new_job->content_type = content_type; 375 new_job->content_type = content_type;
379 new_job->etag = etag; 376 new_job->etag = etag;
380 new_job->upload_completion_callback = upload_completion_callback; 377 new_job->upload_completion_callback = upload_completion_callback;
381 new_job->context = context; 378 new_job->context = context;
382 379
383 StartNewJob(new_job.Pass(), TYPE_UPLOAD_EXISTING_FILE); 380 StartNewJob(new_job.Pass());
384 } 381 }
385 382
386 void JobScheduler::CreateFile( 383 void JobScheduler::CreateFile(
387 const std::string& parent_resource_id, 384 const std::string& parent_resource_id,
388 const base::FilePath& drive_file_path, 385 const base::FilePath& drive_file_path,
389 const std::string& title, 386 const std::string& title,
390 const std::string& content_type, 387 const std::string& content_type,
391 const DriveClientContext& context, 388 const DriveClientContext& context,
392 const google_apis::UploadCompletionCallback& callback) { 389 const google_apis::UploadCompletionCallback& callback) {
393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 390 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
394 391
395 scoped_ptr<QueueEntry> new_job(new QueueEntry); 392 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_CREATE_FILE));
396 new_job->resource_id = parent_resource_id; 393 new_job->resource_id = parent_resource_id;
397 new_job->drive_file_path = drive_file_path; 394 new_job->drive_file_path = drive_file_path;
398 new_job->title = title; 395 new_job->title = title;
399 new_job->content_type = content_type; 396 new_job->content_type = content_type;
400 new_job->upload_completion_callback = callback; 397 new_job->upload_completion_callback = callback;
401 new_job->context = context; 398 new_job->context = context;
402 399
403 StartNewJob(new_job.Pass(), TYPE_CREATE_FILE); 400 StartNewJob(new_job.Pass());
404 } 401 }
405 402
406 JobID JobScheduler::StartNewJob(scoped_ptr<QueueEntry> job, JobType type) { 403 JobID JobScheduler::StartNewJob(scoped_ptr<JobEntry> job) {
407 // job_info is owned by job_map_ and released when it is removed in OnJobDone. 404 DCHECK(job);
408 JobInfo* job_info = new JobInfo(type); 405
409 job->job_id = job_info->job_id = job_map_.Add(job_info); 406 // |job| is owned by job_map_ and released when it is removed in OnJobDone.
407 JobInfo* job_info = &job->job_info;
410 job_info->file_path = job->drive_file_path; 408 job_info->file_path = job->drive_file_path;
409 job_info->job_id = job_map_.Add(job.release());
411 410
412 QueueJob(job.Pass()); 411 QueueJob(job_info->job_id);
413 NotifyJobAdded(*job_info); 412 NotifyJobAdded(*job_info);
414 StartJobLoop(GetJobQueueType(type)); 413 StartJobLoop(GetJobQueueType(job_info->job_type));
415 return job_info->job_id; 414 return job_info->job_id;
416 } 415 }
417 416
418 void JobScheduler::QueueJob(scoped_ptr<QueueEntry> job) { 417 void JobScheduler::QueueJob(JobID job_id) {
419 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 418 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
420 419
421 JobInfo* job_info = job_map_.Lookup(job->job_id); 420 JobEntry* job_entry = job_map_.Lookup(job_id);
422 DCHECK(job_info); 421 DCHECK(job_entry);
422 const JobInfo& job_info = job_entry->job_info;
423 423
424 QueueType queue_type = GetJobQueueType(job_info->job_type); 424 QueueType queue_type = GetJobQueueType(job_info.job_type);
425 std::list<QueueEntry*>& queue = queue_[queue_type]; 425 std::list<JobID>* queue = &queue_[queue_type];
426 426
427 queue.push_back(job.release()); 427 std::list<JobID>::iterator it = queue->begin();
428 queue.sort(&QueueEntry::Compare); 428 for (; it != queue->end(); ++it) {
429 JobEntry* job_entry2 = job_map_.Lookup(*it);
430 if (JobEntry::Less(*job_entry, *job_entry2))
431 break;
432 }
433 queue->insert(it, job_id);
429 434
430 util::Log("Job queued: %s - %s", job_info->ToString().c_str(), 435 util::Log("Job queued: %s - %s", job_info.ToString().c_str(),
431 GetQueueInfo(queue_type).c_str()); 436 GetQueueInfo(queue_type).c_str());
432 } 437 }
433 438
434 void JobScheduler::StartJobLoop(QueueType queue_type) { 439 void JobScheduler::StartJobLoop(QueueType queue_type) {
435 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 440 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
436 441
437 if (jobs_running_[queue_type] < kMaxJobCount[queue_type]) 442 if (jobs_running_[queue_type] < kMaxJobCount[queue_type])
438 DoJobLoop(queue_type); 443 DoJobLoop(queue_type);
439 } 444 }
440 445
441 void JobScheduler::DoJobLoop(QueueType queue_type) { 446 void JobScheduler::DoJobLoop(QueueType queue_type) {
442 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 447 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
443 448
444 if (queue_[queue_type].empty()) { 449 if (queue_[queue_type].empty()) {
445 return; 450 return;
446 } 451 }
447 452
453 JobID job_id = queue_[queue_type].front();
454 JobEntry* entry = job_map_.Lookup(job_id);
455 DCHECK(entry);
456
448 // Check if we should defer based on the first item in the queue 457 // Check if we should defer based on the first item in the queue
449 if (ShouldStopJobLoop(queue_type, queue_[queue_type].front()->context)) { 458 if (ShouldStopJobLoop(queue_type, entry->context)) {
450 return; 459 return;
451 } 460 }
452 461
453 // Increment the number of jobs. 462 // Increment the number of jobs.
454 ++jobs_running_[queue_type]; 463 ++jobs_running_[queue_type];
455 464
456 // Should copy before calling queue_.pop_front().
457 scoped_ptr<QueueEntry> queue_entry(queue_[queue_type].front());
458 queue_[queue_type].pop_front(); 465 queue_[queue_type].pop_front();
459 466
460 JobInfo* job_info = job_map_.Lookup(queue_entry->job_id); 467 JobInfo* job_info = &entry->job_info;
461 DCHECK(job_info);
462 job_info->state = STATE_RUNNING; 468 job_info->state = STATE_RUNNING;
463 job_info->start_time = base::Time::Now(); 469 job_info->start_time = base::Time::Now();
464 NotifyJobUpdated(*job_info); 470 NotifyJobUpdated(*job_info);
465 471
466 // The some arguments are evaluated after bind, so we copy the pointer to the
467 // QueueEntry
468 QueueEntry* entry = queue_entry.get();
469
470 switch (job_info->job_type) { 472 switch (job_info->job_type) {
471 case TYPE_GET_ABOUT_RESOURCE: { 473 case TYPE_GET_ABOUT_RESOURCE: {
472 drive_service_->GetAboutResource( 474 drive_service_->GetAboutResource(
473 base::Bind(&JobScheduler::OnGetAboutResourceJobDone, 475 base::Bind(&JobScheduler::OnGetAboutResourceJobDone,
474 weak_ptr_factory_.GetWeakPtr(), 476 weak_ptr_factory_.GetWeakPtr(),
475 base::Passed(&queue_entry))); 477 job_id,
478 entry->get_about_resource_callback));
476 } 479 }
477 break; 480 break;
478 481
479 case TYPE_GET_ACCOUNT_METADATA: { 482 case TYPE_GET_ACCOUNT_METADATA: {
480 drive_service_->GetAccountMetadata( 483 drive_service_->GetAccountMetadata(
481 base::Bind(&JobScheduler::OnGetAccountMetadataJobDone, 484 base::Bind(&JobScheduler::OnGetAccountMetadataJobDone,
482 weak_ptr_factory_.GetWeakPtr(), 485 weak_ptr_factory_.GetWeakPtr(),
483 base::Passed(&queue_entry))); 486 job_id,
487 entry->get_account_metadata_callback));
484 } 488 }
485 break; 489 break;
486 490
487 case TYPE_GET_APP_LIST: { 491 case TYPE_GET_APP_LIST: {
488 drive_service_->GetAppList( 492 drive_service_->GetAppList(
489 base::Bind(&JobScheduler::OnGetAppListJobDone, 493 base::Bind(&JobScheduler::OnGetAppListJobDone,
490 weak_ptr_factory_.GetWeakPtr(), 494 weak_ptr_factory_.GetWeakPtr(),
491 base::Passed(&queue_entry))); 495 job_id,
496 entry->get_app_list_callback));
492 } 497 }
493 break; 498 break;
494 499
495 case TYPE_GET_ALL_RESOURCE_LIST: { 500 case TYPE_GET_ALL_RESOURCE_LIST: {
496 drive_service_->GetAllResourceList( 501 drive_service_->GetAllResourceList(
497 base::Bind(&JobScheduler::OnGetResourceListJobDone, 502 base::Bind(&JobScheduler::OnGetResourceListJobDone,
498 weak_ptr_factory_.GetWeakPtr(), 503 weak_ptr_factory_.GetWeakPtr(),
499 base::Passed(&queue_entry))); 504 job_id,
505 entry->get_resource_list_callback));
500 } 506 }
501 break; 507 break;
502 508
503 case TYPE_GET_RESOURCE_LIST_IN_DIRECTORY: { 509 case TYPE_GET_RESOURCE_LIST_IN_DIRECTORY: {
504 drive_service_->GetResourceListInDirectory( 510 drive_service_->GetResourceListInDirectory(
505 entry->directory_resource_id, 511 entry->directory_resource_id,
506 base::Bind(&JobScheduler::OnGetResourceListJobDone, 512 base::Bind(&JobScheduler::OnGetResourceListJobDone,
507 weak_ptr_factory_.GetWeakPtr(), 513 weak_ptr_factory_.GetWeakPtr(),
508 base::Passed(&queue_entry))); 514 job_id,
515 entry->get_resource_list_callback));
509 } 516 }
510 break; 517 break;
511 518
512 case TYPE_SEARCH: { 519 case TYPE_SEARCH: {
513 drive_service_->Search( 520 drive_service_->Search(
514 entry->search_query, 521 entry->search_query,
515 base::Bind(&JobScheduler::OnGetResourceListJobDone, 522 base::Bind(&JobScheduler::OnGetResourceListJobDone,
516 weak_ptr_factory_.GetWeakPtr(), 523 weak_ptr_factory_.GetWeakPtr(),
517 base::Passed(&queue_entry))); 524 job_id,
525 entry->get_resource_list_callback));
518 } 526 }
519 break; 527 break;
520 528
521 case TYPE_GET_CHANGE_LIST: { 529 case TYPE_GET_CHANGE_LIST: {
522 drive_service_->GetChangeList( 530 drive_service_->GetChangeList(
523 entry->start_changestamp, 531 entry->start_changestamp,
524 base::Bind(&JobScheduler::OnGetResourceListJobDone, 532 base::Bind(&JobScheduler::OnGetResourceListJobDone,
525 weak_ptr_factory_.GetWeakPtr(), 533 weak_ptr_factory_.GetWeakPtr(),
526 base::Passed(&queue_entry))); 534 job_id,
535 entry->get_resource_list_callback));
527 } 536 }
528 break; 537 break;
529 538
530 case TYPE_CONTINUE_GET_RESOURCE_LIST: { 539 case TYPE_CONTINUE_GET_RESOURCE_LIST: {
531 drive_service_->ContinueGetResourceList( 540 drive_service_->ContinueGetResourceList(
532 entry->feed_url, 541 entry->feed_url,
533 base::Bind(&JobScheduler::OnGetResourceListJobDone, 542 base::Bind(&JobScheduler::OnGetResourceListJobDone,
534 weak_ptr_factory_.GetWeakPtr(), 543 weak_ptr_factory_.GetWeakPtr(),
535 base::Passed(&queue_entry))); 544 job_id,
545 entry->get_resource_list_callback));
536 } 546 }
537 break; 547 break;
538 548
539 case TYPE_GET_RESOURCE_ENTRY: { 549 case TYPE_GET_RESOURCE_ENTRY: {
540 drive_service_->GetResourceEntry( 550 drive_service_->GetResourceEntry(
541 entry->resource_id, 551 entry->resource_id,
542 base::Bind(&JobScheduler::OnGetResourceEntryJobDone, 552 base::Bind(&JobScheduler::OnGetResourceEntryJobDone,
543 weak_ptr_factory_.GetWeakPtr(), 553 weak_ptr_factory_.GetWeakPtr(),
544 base::Passed(&queue_entry))); 554 job_id,
555 entry->get_resource_entry_callback));
545 } 556 }
546 break; 557 break;
547 558
548 case TYPE_DELETE_RESOURCE: { 559 case TYPE_DELETE_RESOURCE: {
549 drive_service_->DeleteResource( 560 drive_service_->DeleteResource(
550 entry->resource_id, 561 entry->resource_id,
551 "", // etag 562 "", // etag
552 base::Bind(&JobScheduler::OnEntryActionJobDone, 563 base::Bind(&JobScheduler::OnEntryActionJobDone,
553 weak_ptr_factory_.GetWeakPtr(), 564 weak_ptr_factory_.GetWeakPtr(),
554 base::Passed(&queue_entry))); 565 job_id,
566 entry->entry_action_callback));
555 } 567 }
556 break; 568 break;
557 569
558 case TYPE_COPY_HOSTED_DOCUMENT: { 570 case TYPE_COPY_HOSTED_DOCUMENT: {
559 drive_service_->CopyHostedDocument( 571 drive_service_->CopyHostedDocument(
560 entry->resource_id, 572 entry->resource_id,
561 entry->new_name, 573 entry->new_name,
562 base::Bind(&JobScheduler::OnGetResourceEntryJobDone, 574 base::Bind(&JobScheduler::OnGetResourceEntryJobDone,
563 weak_ptr_factory_.GetWeakPtr(), 575 weak_ptr_factory_.GetWeakPtr(),
564 base::Passed(&queue_entry))); 576 job_id,
577 entry->get_resource_entry_callback));
565 } 578 }
566 break; 579 break;
567 580
568 case TYPE_RENAME_RESOURCE: { 581 case TYPE_RENAME_RESOURCE: {
569 drive_service_->RenameResource( 582 drive_service_->RenameResource(
570 entry->resource_id, 583 entry->resource_id,
571 entry->new_name, 584 entry->new_name,
572 base::Bind(&JobScheduler::OnEntryActionJobDone, 585 base::Bind(&JobScheduler::OnEntryActionJobDone,
573 weak_ptr_factory_.GetWeakPtr(), 586 weak_ptr_factory_.GetWeakPtr(),
574 base::Passed(&queue_entry))); 587 job_id,
588 entry->entry_action_callback));
575 } 589 }
576 break; 590 break;
577 591
578 case TYPE_ADD_RESOURCE_TO_DIRECTORY: { 592 case TYPE_ADD_RESOURCE_TO_DIRECTORY: {
579 drive_service_->AddResourceToDirectory( 593 drive_service_->AddResourceToDirectory(
580 entry->parent_resource_id, 594 entry->parent_resource_id,
581 entry->resource_id, 595 entry->resource_id,
582 base::Bind(&JobScheduler::OnEntryActionJobDone, 596 base::Bind(&JobScheduler::OnEntryActionJobDone,
583 weak_ptr_factory_.GetWeakPtr(), 597 weak_ptr_factory_.GetWeakPtr(),
584 base::Passed(&queue_entry))); 598 job_id,
599 entry->entry_action_callback));
585 } 600 }
586 break; 601 break;
587 602
588 case TYPE_REMOVE_RESOURCE_FROM_DIRECTORY: { 603 case TYPE_REMOVE_RESOURCE_FROM_DIRECTORY: {
589 drive_service_->RemoveResourceFromDirectory( 604 drive_service_->RemoveResourceFromDirectory(
590 entry->parent_resource_id, 605 entry->parent_resource_id,
591 entry->resource_id, 606 entry->resource_id,
592 base::Bind(&JobScheduler::OnEntryActionJobDone, 607 base::Bind(&JobScheduler::OnEntryActionJobDone,
593 weak_ptr_factory_.GetWeakPtr(), 608 weak_ptr_factory_.GetWeakPtr(),
594 base::Passed(&queue_entry))); 609 job_id,
610 entry->entry_action_callback));
595 } 611 }
596 break; 612 break;
597 613
598 case TYPE_ADD_NEW_DIRECTORY: { 614 case TYPE_ADD_NEW_DIRECTORY: {
599 drive_service_->AddNewDirectory( 615 drive_service_->AddNewDirectory(
600 entry->parent_resource_id, 616 entry->parent_resource_id,
601 entry->directory_name, 617 entry->directory_name,
602 base::Bind(&JobScheduler::OnGetResourceEntryJobDone, 618 base::Bind(&JobScheduler::OnGetResourceEntryJobDone,
603 weak_ptr_factory_.GetWeakPtr(), 619 weak_ptr_factory_.GetWeakPtr(),
604 base::Passed(&queue_entry))); 620 job_id,
621 entry->get_resource_entry_callback));
605 } 622 }
606 break; 623 break;
607 624
608 case TYPE_DOWNLOAD_FILE: { 625 case TYPE_DOWNLOAD_FILE: {
609 drive_service_->DownloadFile( 626 drive_service_->DownloadFile(
610 entry->drive_file_path, 627 entry->drive_file_path,
611 entry->local_file_path, 628 entry->local_file_path,
612 entry->download_url, 629 entry->download_url,
613 base::Bind(&JobScheduler::OnDownloadActionJobDone, 630 base::Bind(&JobScheduler::OnDownloadActionJobDone,
614 weak_ptr_factory_.GetWeakPtr(), 631 weak_ptr_factory_.GetWeakPtr(),
615 base::Passed(&queue_entry)), 632 job_id,
633 entry->download_action_callback),
616 entry->get_content_callback, 634 entry->get_content_callback,
617 base::Bind(&JobScheduler::UpdateProgress, 635 base::Bind(&JobScheduler::UpdateProgress,
618 weak_ptr_factory_.GetWeakPtr(), 636 weak_ptr_factory_.GetWeakPtr(),
619 job_info->job_id)); 637 job_id));
620 } 638 }
621 break; 639 break;
622 640
623 case TYPE_UPLOAD_NEW_FILE: { 641 case TYPE_UPLOAD_NEW_FILE: {
624 uploader_->UploadNewFile( 642 uploader_->UploadNewFile(
625 entry->resource_id, 643 entry->resource_id,
626 entry->drive_file_path, 644 entry->drive_file_path,
627 entry->local_file_path, 645 entry->local_file_path,
628 entry->title, 646 entry->title,
629 entry->content_type, 647 entry->content_type,
630 base::Bind(&JobScheduler::OnUploadCompletionJobDone, 648 base::Bind(&JobScheduler::OnUploadCompletionJobDone,
631 weak_ptr_factory_.GetWeakPtr(), 649 weak_ptr_factory_.GetWeakPtr(),
632 base::Passed(&queue_entry)), 650 job_id,
651 entry->upload_completion_callback),
633 base::Bind(&JobScheduler::UpdateProgress, 652 base::Bind(&JobScheduler::UpdateProgress,
634 weak_ptr_factory_.GetWeakPtr(), 653 weak_ptr_factory_.GetWeakPtr(),
635 job_info->job_id)); 654 job_id));
636 } 655 }
637 break; 656 break;
638 657
639 case TYPE_UPLOAD_EXISTING_FILE: { 658 case TYPE_UPLOAD_EXISTING_FILE: {
640 uploader_->UploadExistingFile( 659 uploader_->UploadExistingFile(
641 entry->resource_id, 660 entry->resource_id,
642 entry->drive_file_path, 661 entry->drive_file_path,
643 entry->local_file_path, 662 entry->local_file_path,
644 entry->content_type, 663 entry->content_type,
645 entry->etag, 664 entry->etag,
646 base::Bind(&JobScheduler::OnUploadCompletionJobDone, 665 base::Bind(&JobScheduler::OnUploadCompletionJobDone,
647 weak_ptr_factory_.GetWeakPtr(), 666 weak_ptr_factory_.GetWeakPtr(),
648 base::Passed(&queue_entry)), 667 job_id,
668 entry->upload_completion_callback),
649 base::Bind(&JobScheduler::UpdateProgress, 669 base::Bind(&JobScheduler::UpdateProgress,
650 weak_ptr_factory_.GetWeakPtr(), 670 weak_ptr_factory_.GetWeakPtr(),
651 job_info->job_id)); 671 job_id));
652 } 672 }
653 break; 673 break;
654 674
655 case TYPE_CREATE_FILE: { 675 case TYPE_CREATE_FILE: {
656 // For now, creation is implemented by uploading an empty file /dev/null. 676 // For now, creation is implemented by uploading an empty file /dev/null.
657 // TODO(kinaba): http://crbug.com/135143. Implement in a nicer way. 677 // TODO(kinaba): http://crbug.com/135143. Implement in a nicer way.
658 uploader_->UploadNewFile( 678 uploader_->UploadNewFile(
659 entry->resource_id, 679 entry->resource_id,
660 entry->drive_file_path, 680 entry->drive_file_path,
661 base::FilePath(util::kSymLinkToDevNull), 681 base::FilePath(util::kSymLinkToDevNull),
662 entry->title, 682 entry->title,
663 entry->content_type, 683 entry->content_type,
664 base::Bind(&JobScheduler::OnUploadCompletionJobDone, 684 base::Bind(&JobScheduler::OnUploadCompletionJobDone,
665 weak_ptr_factory_.GetWeakPtr(), 685 weak_ptr_factory_.GetWeakPtr(),
666 base::Passed(&queue_entry)), 686 job_id,
687 entry->upload_completion_callback),
667 google_apis::ProgressCallback()); 688 google_apis::ProgressCallback());
668 } 689 }
669 break; 690 break;
670 691
671 // There is no default case so that there will be a compiler error if a type 692 // There is no default case so that there will be a compiler error if a type
672 // is added but unhandled. 693 // is added but unhandled.
673 } 694 }
674 695
675 util::Log("Job started: %s - %s", 696 util::Log("Job started: %s - %s",
676 job_info->ToString().c_str(), 697 job_info->ToString().c_str(),
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 762
742 // Post a task to continue the job loop. This allows us to finish handling 763 // Post a task to continue the job loop. This allows us to finish handling
743 // the current job before starting the next one. 764 // the current job before starting the next one.
744 throttle_count_ = 0; 765 throttle_count_ = 0;
745 base::MessageLoopProxy::current()->PostTask(FROM_HERE, 766 base::MessageLoopProxy::current()->PostTask(FROM_HERE,
746 base::Bind(&JobScheduler::DoJobLoop, 767 base::Bind(&JobScheduler::DoJobLoop,
747 weak_ptr_factory_.GetWeakPtr(), 768 weak_ptr_factory_.GetWeakPtr(),
748 queue_type)); 769 queue_type));
749 } 770 }
750 771
751 bool JobScheduler::OnJobDone(scoped_ptr<JobScheduler::QueueEntry> queue_entry, 772 bool JobScheduler::OnJobDone(JobID job_id, FileError error) {
752 FileError error) {
753 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 773 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
754 774
755 JobInfo* job_info = job_map_.Lookup(queue_entry->job_id); 775 JobEntry* job_entry = job_map_.Lookup(job_id);
756 DCHECK(job_info); 776 DCHECK(job_entry);
777 JobInfo* job_info = &job_entry->job_info;
757 QueueType queue_type = GetJobQueueType(job_info->job_type); 778 QueueType queue_type = GetJobQueueType(job_info->job_type);
758 779
759 const base::TimeDelta elapsed = base::Time::Now() - job_info->start_time; 780 const base::TimeDelta elapsed = base::Time::Now() - job_info->start_time;
760 util::Log("Job done: %s => %s (elapsed time: %sms) - %s", 781 util::Log("Job done: %s => %s (elapsed time: %sms) - %s",
761 job_info->ToString().c_str(), 782 job_info->ToString().c_str(),
762 FileErrorToString(error).c_str(), 783 FileErrorToString(error).c_str(),
763 base::Int64ToString(elapsed.InMilliseconds()).c_str(), 784 base::Int64ToString(elapsed.InMilliseconds()).c_str(),
764 GetQueueInfo(queue_type).c_str()); 785 GetQueueInfo(queue_type).c_str());
765 786
766 // Decrement the number of jobs for this queue. 787 // Decrement the number of jobs for this queue.
767 --jobs_running_[queue_type]; 788 --jobs_running_[queue_type];
768 789
769 // Retry, depending on the error. 790 // Retry, depending on the error.
770 if (error == FILE_ERROR_THROTTLED) { 791 if (error == FILE_ERROR_THROTTLED) {
771 job_info->state = STATE_RETRY; 792 job_info->state = STATE_RETRY;
772 NotifyJobUpdated(*job_info); 793 NotifyJobUpdated(*job_info);
773 794
774 // Requeue the job. 795 // Requeue the job.
775 QueueJob(queue_entry.Pass()); 796 QueueJob(job_id);
776 797
777 ThrottleAndContinueJobLoop(queue_type); 798 ThrottleAndContinueJobLoop(queue_type);
778 return false; 799 return false;
779 } else { 800 } else {
780 NotifyJobDone(*job_info, error); 801 NotifyJobDone(*job_info, error);
781 // The job has finished, no retry will happen in the scheduler. Now we can 802 // The job has finished, no retry will happen in the scheduler. Now we can
782 // remove the job info from the map. This is the only place of the removal. 803 // remove the job info from the map. This is the only place of the removal.
783 job_map_.Remove(queue_entry->job_id); 804 job_map_.Remove(job_id);
784 805
785 ResetThrottleAndContinueJobLoop(queue_type); 806 ResetThrottleAndContinueJobLoop(queue_type);
786 return true; 807 return true;
787 } 808 }
788 } 809 }
789 810
790 void JobScheduler::OnGetResourceListJobDone( 811 void JobScheduler::OnGetResourceListJobDone(
791 scoped_ptr<JobScheduler::QueueEntry> queue_entry, 812 JobID job_id,
813 const google_apis::GetResourceListCallback& callback,
792 google_apis::GDataErrorCode error, 814 google_apis::GDataErrorCode error,
793 scoped_ptr<google_apis::ResourceList> resource_list) { 815 scoped_ptr<google_apis::ResourceList> resource_list) {
794 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 816 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
795 DCHECK(!queue_entry->get_resource_list_callback.is_null()); 817 DCHECK(!callback.is_null());
796 818
797 google_apis::GetResourceListCallback callback = 819 if (OnJobDone(job_id, util::GDataToFileError(error)))
798 queue_entry->get_resource_list_callback;
799 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error)))
800 callback.Run(error, resource_list.Pass()); 820 callback.Run(error, resource_list.Pass());
801 } 821 }
802 822
803 void JobScheduler::OnGetResourceEntryJobDone( 823 void JobScheduler::OnGetResourceEntryJobDone(
804 scoped_ptr<JobScheduler::QueueEntry> queue_entry, 824 JobID job_id,
825 const google_apis::GetResourceEntryCallback& callback,
805 google_apis::GDataErrorCode error, 826 google_apis::GDataErrorCode error,
806 scoped_ptr<google_apis::ResourceEntry> entry) { 827 scoped_ptr<google_apis::ResourceEntry> entry) {
807 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 828 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
808 DCHECK(!queue_entry->get_resource_entry_callback.is_null()); 829 DCHECK(!callback.is_null());
809 830
810 google_apis::GetResourceEntryCallback callback = 831 if (OnJobDone(job_id, util::GDataToFileError(error)))
811 queue_entry->get_resource_entry_callback;
812 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error)))
813 callback.Run(error, entry.Pass()); 832 callback.Run(error, entry.Pass());
814 } 833 }
815 834
816 void JobScheduler::OnGetAboutResourceJobDone( 835 void JobScheduler::OnGetAboutResourceJobDone(
817 scoped_ptr<QueueEntry> queue_entry, 836 JobID job_id,
837 const google_apis::GetAboutResourceCallback& callback,
818 google_apis::GDataErrorCode error, 838 google_apis::GDataErrorCode error,
819 scoped_ptr<google_apis::AboutResource> about_resource) { 839 scoped_ptr<google_apis::AboutResource> about_resource) {
820 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 840 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
821 DCHECK(!queue_entry->get_about_resource_callback.is_null()); 841 DCHECK(!callback.is_null());
822 842
823 google_apis::GetAboutResourceCallback callback = 843 if (OnJobDone(job_id, util::GDataToFileError(error)))
824 queue_entry->get_about_resource_callback;
825 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error)))
826 callback.Run(error, about_resource.Pass()); 844 callback.Run(error, about_resource.Pass());
827 } 845 }
828 846
829 void JobScheduler::OnGetAccountMetadataJobDone( 847 void JobScheduler::OnGetAccountMetadataJobDone(
830 scoped_ptr<QueueEntry> queue_entry, 848 JobID job_id,
849 const google_apis::GetAccountMetadataCallback& callback,
831 google_apis::GDataErrorCode error, 850 google_apis::GDataErrorCode error,
832 scoped_ptr<google_apis::AccountMetadata> account_metadata) { 851 scoped_ptr<google_apis::AccountMetadata> account_metadata) {
833 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 852 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
834 DCHECK(!queue_entry->get_account_metadata_callback.is_null()); 853 DCHECK(!callback.is_null());
835 854
836 google_apis::GetAccountMetadataCallback callback = 855 if (OnJobDone(job_id, util::GDataToFileError(error)))
837 queue_entry->get_account_metadata_callback;
838 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error)))
839 callback.Run(error, account_metadata.Pass()); 856 callback.Run(error, account_metadata.Pass());
840 } 857 }
841 858
842 void JobScheduler::OnGetAppListJobDone( 859 void JobScheduler::OnGetAppListJobDone(
843 scoped_ptr<JobScheduler::QueueEntry> queue_entry, 860 JobID job_id,
861 const google_apis::GetAppListCallback& callback,
844 google_apis::GDataErrorCode error, 862 google_apis::GDataErrorCode error,
845 scoped_ptr<google_apis::AppList> app_list) { 863 scoped_ptr<google_apis::AppList> app_list) {
846 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 864 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
847 DCHECK(!queue_entry->get_app_list_callback.is_null()); 865 DCHECK(!callback.is_null());
848 866
849 google_apis::GetAppListCallback callback = queue_entry->get_app_list_callback; 867 if (OnJobDone(job_id, util::GDataToFileError(error)))
850 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error)))
851 callback.Run(error, app_list.Pass()); 868 callback.Run(error, app_list.Pass());
852 } 869 }
853 870
854 void JobScheduler::OnEntryActionJobDone( 871 void JobScheduler::OnEntryActionJobDone(
855 scoped_ptr<JobScheduler::QueueEntry> queue_entry, 872 JobID job_id,
873 const google_apis::EntryActionCallback& callback,
856 google_apis::GDataErrorCode error) { 874 google_apis::GDataErrorCode error) {
857 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 875 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
858 DCHECK(!queue_entry->entry_action_callback.is_null()); 876 DCHECK(!callback.is_null());
859 877
860 google_apis::EntryActionCallback callback = 878 if (OnJobDone(job_id, util::GDataToFileError(error)))
861 queue_entry->entry_action_callback;
862 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error)))
863 callback.Run(error); 879 callback.Run(error);
864 } 880 }
865 881
866 void JobScheduler::OnDownloadActionJobDone( 882 void JobScheduler::OnDownloadActionJobDone(
867 scoped_ptr<JobScheduler::QueueEntry> queue_entry, 883 JobID job_id,
884 const google_apis::DownloadActionCallback& callback,
868 google_apis::GDataErrorCode error, 885 google_apis::GDataErrorCode error,
869 const base::FilePath& temp_file) { 886 const base::FilePath& temp_file) {
870 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 887 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
871 DCHECK(!queue_entry->download_action_callback.is_null()); 888 DCHECK(!callback.is_null());
872 889
873 google_apis::DownloadActionCallback callback = 890 if (OnJobDone(job_id, util::GDataToFileError(error)))
874 queue_entry->download_action_callback;
875 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error)))
876 callback.Run(error, temp_file); 891 callback.Run(error, temp_file);
877 } 892 }
878 893
879 void JobScheduler::OnUploadCompletionJobDone( 894 void JobScheduler::OnUploadCompletionJobDone(
880 scoped_ptr<QueueEntry> queue_entry, 895 JobID job_id,
896 const google_apis::UploadCompletionCallback& callback,
881 google_apis::GDataErrorCode error, 897 google_apis::GDataErrorCode error,
882 const base::FilePath& drive_path, 898 const base::FilePath& drive_path,
883 const base::FilePath& file_path, 899 const base::FilePath& file_path,
884 scoped_ptr<google_apis::ResourceEntry> resource_entry) { 900 scoped_ptr<google_apis::ResourceEntry> resource_entry) {
885 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 901 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
886 DCHECK(!queue_entry->upload_completion_callback.is_null()); 902 DCHECK(!callback.is_null());
887 903
888 google_apis::UploadCompletionCallback callback = 904 if (OnJobDone(job_id, util::GDataToFileError(error)))
889 queue_entry->upload_completion_callback;
890 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error)))
891 callback.Run(error, drive_path, file_path, resource_entry.Pass()); 905 callback.Run(error, drive_path, file_path, resource_entry.Pass());
892 } 906 }
893 907
894 void JobScheduler::UpdateProgress(JobID job_id, int64 progress, int64 total) { 908 void JobScheduler::UpdateProgress(JobID job_id, int64 progress, int64 total) {
895 JobInfo* job_info = job_map_.Lookup(job_id); 909 JobEntry* job_entry = job_map_.Lookup(job_id);
896 DCHECK(job_info); 910 DCHECK(job_entry);
897 911
898 job_info->num_completed_bytes = progress; 912 job_entry->job_info.num_completed_bytes = progress;
899 job_info->num_total_bytes = total; 913 job_entry->job_info.num_total_bytes = total;
900 NotifyJobUpdated(*job_info); 914 NotifyJobUpdated(job_entry->job_info);
901 } 915 }
902 916
903 void JobScheduler::OnConnectionTypeChanged( 917 void JobScheduler::OnConnectionTypeChanged(
904 net::NetworkChangeNotifier::ConnectionType type) { 918 net::NetworkChangeNotifier::ConnectionType type) {
905 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 919 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
906 920
907 // Resume the job loop if the network is back online. Note that we don't 921 // Resume the job loop if the network is back online. Note that we don't
908 // need to check the type of the network as it will be checked in 922 // need to check the type of the network as it will be checked in
909 // ShouldStopJobLoop() as soon as the loop is resumed. 923 // ShouldStopJobLoop() as soon as the loop is resumed.
910 if (!net::NetworkChangeNotifier::IsOffline()) { 924 if (!net::NetworkChangeNotifier::IsOffline()) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 return "FILE_QUEUE"; 990 return "FILE_QUEUE";
977 case NUM_QUEUES: 991 case NUM_QUEUES:
978 return "NUM_QUEUES"; 992 return "NUM_QUEUES";
979 } 993 }
980 NOTREACHED(); 994 NOTREACHED();
981 return ""; 995 return "";
982 } 996 }
983 997
984 998
985 } // namespace drive 999 } // namespace drive
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/drive/job_scheduler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698