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

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

Issue 11418127: Pass calls to GetDocuments through the scheduler (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add missing comment Created 8 years, 1 month 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
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/drive_scheduler.h" 5 #include "chrome/browser/chromeos/drive/drive_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/rand_util.h" 10 #include "base/rand_util.h"
11 #include "chrome/browser/chromeos/drive/drive_file_system_util.h"
11 #include "chrome/browser/chromeos/drive/file_system/drive_operations.h" 12 #include "chrome/browser/chromeos/drive/file_system/drive_operations.h"
12 #include "chrome/browser/chromeos/drive/file_system/remove_operation.h" 13 #include "chrome/browser/chromeos/drive/file_system/remove_operation.h"
13 #include "chrome/browser/prefs/pref_service.h" 14 #include "chrome/browser/prefs/pref_service.h"
14 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/common/pref_names.h" 16 #include "chrome/common/pref_names.h"
16 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
17 18
18 using content::BrowserThread; 19 using content::BrowserThread;
19 20
20 namespace drive { 21 namespace drive {
21 22
22 namespace { 23 namespace {
23 const int kMaxThrottleCount = 5; 24 const int kMaxThrottleCount = 5;
24 } 25 }
25 26
26 DriveScheduler::JobInfo::JobInfo(JobType in_job_type, FilePath in_file_path) 27 DriveScheduler::JobInfo::JobInfo(JobType in_job_type, FilePath in_file_path)
27 : job_type(in_job_type), 28 : job_type(in_job_type),
28 job_id(-1), 29 job_id(-1),
29 completed_bytes(0), 30 completed_bytes(0),
30 total_bytes(0), 31 total_bytes(0),
31 file_path(in_file_path), 32 file_path(in_file_path),
32 state(STATE_NONE) { 33 state(STATE_NONE) {
33 } 34 }
34 35
35 DriveScheduler::QueueEntry::QueueEntry(JobType in_job_type, 36 DriveScheduler::QueueEntry::QueueEntry(JobType in_job_type,
36 FilePath in_file_path, 37 FilePath in_file_path)
37 FileOperationCallback in_callback)
38 : job_info(in_job_type, in_file_path), 38 : job_info(in_job_type, in_file_path),
39 callback(in_callback),
40 is_recursive(false) { 39 is_recursive(false) {
41 } 40 }
42 41
43 DriveScheduler::QueueEntry::~QueueEntry() { 42 DriveScheduler::QueueEntry::~QueueEntry() {
44 } 43 }
45 44
46 DriveScheduler::DriveScheduler(Profile* profile, 45 DriveScheduler::DriveScheduler(
47 file_system::DriveOperations* drive_operations) 46 Profile* profile,
47 google_apis::DriveServiceInterface* drive_service,
48 file_system::DriveOperations* drive_operations)
48 : job_loop_is_running_(false), 49 : job_loop_is_running_(false),
49 next_job_id_(0), 50 next_job_id_(0),
50 throttle_count_(0), 51 throttle_count_(0),
51 disable_throttling_(false), 52 disable_throttling_(false),
52 drive_operations_(drive_operations), 53 drive_operations_(drive_operations),
54 drive_service_(drive_service),
53 profile_(profile), 55 profile_(profile),
54 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 56 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
55 initialized_(false) { 57 initialized_(false) {
56 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 58 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
57 } 59 }
58 60
59 DriveScheduler::~DriveScheduler() { 61 DriveScheduler::~DriveScheduler() {
60 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
61 DCHECK(initialized_); 63 DCHECK(initialized_);
62 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 64 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
63 } 65 }
64 66
65 void DriveScheduler::Initialize() { 67 void DriveScheduler::Initialize() {
66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
67 69
68 // Initialize() may be called more than once for the lifetime when the 70 // Initialize() may be called more than once for the lifetime when the
69 // file system is remounted. 71 // file system is remounted.
70 if (initialized_) 72 if (initialized_)
71 return; 73 return;
72 74
73 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); 75 net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
74 initialized_ = true; 76 initialized_ = true;
75 } 77 }
76 78
77 void DriveScheduler::Copy(const FilePath& src_file_path, 79 void DriveScheduler::Copy(const FilePath& src_file_path,
78 const FilePath& dest_file_path, 80 const FilePath& dest_file_path,
79 const FileOperationCallback& callback) { 81 const FileOperationCallback& callback) {
80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 82 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
81 83
82 scoped_ptr<QueueEntry> new_job( 84 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_COPY, src_file_path));
83 new QueueEntry(TYPE_COPY, src_file_path, callback));
84 new_job->dest_file_path = dest_file_path; 85 new_job->dest_file_path = dest_file_path;
86 new_job->file_operation_callback = callback;
85 87
86 QueueJob(new_job.Pass()); 88 QueueJob(new_job.Pass());
87 89
90 StartJobLoop();
91 }
92
93 void DriveScheduler::GetDocuments(
94 const GURL& feed_url,
95 int64 start_changestamp,
96 const std::string& search_query,
97 bool shared_with_me,
98 const std::string& directory_resource_id,
99 const google_apis::GetDataCallback& callback) {
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
101
102 scoped_ptr<QueueEntry> new_job(
103 new QueueEntry(TYPE_GET_DOCUMENTS, FilePath()));
104 new_job->feed_url = feed_url;
105 new_job->start_changestamp = start_changestamp;
106 new_job->search_query = search_query;
107 new_job->shared_with_me = shared_with_me;
108 new_job->directory_resource_id = directory_resource_id;
109 new_job->get_data_callback = callback;
110
111 QueueJob(new_job.Pass());
112
88 StartJobLoop(); 113 StartJobLoop();
89 } 114 }
90 115
91 void DriveScheduler::TransferFileFromRemoteToLocal( 116 void DriveScheduler::TransferFileFromRemoteToLocal(
92 const FilePath& remote_src_file_path, 117 const FilePath& remote_src_file_path,
93 const FilePath& local_dest_file_path, 118 const FilePath& local_dest_file_path,
94 const FileOperationCallback& callback) { 119 const FileOperationCallback& callback) {
95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
96 121
97 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_TRANSFER_REMOTE_TO_LOCAL, 122 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_TRANSFER_REMOTE_TO_LOCAL,
98 remote_src_file_path, 123 remote_src_file_path));
99 callback));
100 new_job->dest_file_path = local_dest_file_path; 124 new_job->dest_file_path = local_dest_file_path;
125 new_job->file_operation_callback = callback;
101 126
102 QueueJob(new_job.Pass()); 127 QueueJob(new_job.Pass());
103 128
104 StartJobLoop(); 129 StartJobLoop();
105 } 130 }
106 131
107 void DriveScheduler::TransferFileFromLocalToRemote( 132 void DriveScheduler::TransferFileFromLocalToRemote(
108 const FilePath& local_src_file_path, 133 const FilePath& local_src_file_path,
109 const FilePath& remote_dest_file_path, 134 const FilePath& remote_dest_file_path,
110 const FileOperationCallback& callback) { 135 const FileOperationCallback& callback) {
111 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
112 137
113 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_TRANSFER_LOCAL_TO_REMOTE, 138 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_TRANSFER_LOCAL_TO_REMOTE,
114 local_src_file_path, 139 local_src_file_path));
115 callback));
116 new_job->dest_file_path = remote_dest_file_path; 140 new_job->dest_file_path = remote_dest_file_path;
141 new_job->file_operation_callback = callback;
117 142
118 QueueJob(new_job.Pass()); 143 QueueJob(new_job.Pass());
119 144
120 StartJobLoop(); 145 StartJobLoop();
121 } 146 }
122 147
123 void DriveScheduler::TransferRegularFile( 148 void DriveScheduler::TransferRegularFile(
124 const FilePath& local_src_file_path, 149 const FilePath& local_src_file_path,
125 const FilePath& remote_dest_file_path, 150 const FilePath& remote_dest_file_path,
126 const FileOperationCallback& callback) { 151 const FileOperationCallback& callback) {
127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
128 153
129 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_TRANSFER_REGULAR_FILE, 154 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_TRANSFER_REGULAR_FILE,
130 local_src_file_path, 155 local_src_file_path));
131 callback));
132 new_job->dest_file_path = remote_dest_file_path; 156 new_job->dest_file_path = remote_dest_file_path;
157 new_job->file_operation_callback = callback;
133 158
134 QueueJob(new_job.Pass()); 159 QueueJob(new_job.Pass());
135 160
136 StartJobLoop(); 161 StartJobLoop();
137 } 162 }
138 163
139 void DriveScheduler::Move(const FilePath& src_file_path, 164 void DriveScheduler::Move(const FilePath& src_file_path,
140 const FilePath& dest_file_path, 165 const FilePath& dest_file_path,
141 const FileOperationCallback& callback) { 166 const FileOperationCallback& callback) {
142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
143 168
144 scoped_ptr<QueueEntry> new_job( 169 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_MOVE, src_file_path));
145 new QueueEntry(TYPE_MOVE, src_file_path, callback));
146 new_job->dest_file_path = dest_file_path; 170 new_job->dest_file_path = dest_file_path;
171 new_job->file_operation_callback = callback;
147 172
148 QueueJob(new_job.Pass()); 173 QueueJob(new_job.Pass());
149 174
150 StartJobLoop(); 175 StartJobLoop();
151 } 176 }
152 177
153 void DriveScheduler::Remove(const FilePath& file_path, 178 void DriveScheduler::Remove(const FilePath& file_path,
154 bool is_recursive, 179 bool is_recursive,
155 const FileOperationCallback& callback) { 180 const FileOperationCallback& callback) {
156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
157 182
158 scoped_ptr<QueueEntry> new_job( 183 scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_REMOVE, file_path));
159 new QueueEntry(TYPE_REMOVE, file_path, callback));
160 new_job->is_recursive = is_recursive; 184 new_job->is_recursive = is_recursive;
185 new_job->file_operation_callback = callback;
161 186
162 QueueJob(new_job.Pass()); 187 QueueJob(new_job.Pass());
163 188
164 StartJobLoop(); 189 StartJobLoop();
165 } 190 }
166 191
167 int DriveScheduler::QueueJob(scoped_ptr<QueueEntry> job) { 192 int DriveScheduler::QueueJob(scoped_ptr<QueueEntry> job) {
168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
169 194
170 int job_id = next_job_id_; 195 int job_id = next_job_id_;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 DCHECK(job_iter != job_info_map_.end()); 229 DCHECK(job_iter != job_info_map_.end());
205 230
206 JobInfo& job_info = job_iter->second->job_info; 231 JobInfo& job_info = job_iter->second->job_info;
207 job_info.state = STATE_RUNNING; 232 job_info.state = STATE_RUNNING;
208 233
209 switch (job_info.job_type) { 234 switch (job_info.job_type) {
210 case TYPE_COPY: { 235 case TYPE_COPY: {
211 drive_operations_->Copy( 236 drive_operations_->Copy(
212 job_info.file_path, 237 job_info.file_path,
213 job_iter->second->dest_file_path, 238 job_iter->second->dest_file_path,
214 base::Bind(&DriveScheduler::OnJobDone, 239 base::Bind(&DriveScheduler::OnFileOperationJobDone,
215 weak_ptr_factory_.GetWeakPtr(), 240 weak_ptr_factory_.GetWeakPtr(),
216 job_id)); 241 job_id));
217 } 242 }
243 break;
244
245 case TYPE_GET_DOCUMENTS: {
246 drive_service_->GetDocuments(
247 job_iter->second->feed_url,
248 job_iter->second->start_changestamp,
249 job_iter->second->search_query,
250 job_iter->second->shared_with_me,
251 job_iter->second->directory_resource_id,
252 base::Bind(&DriveScheduler::OnGetDataJobDone,
253 weak_ptr_factory_.GetWeakPtr(),
254 job_id));
255 }
218 break; 256 break;
219 257
220 case TYPE_MOVE: { 258 case TYPE_MOVE: {
221 drive_operations_->Move( 259 drive_operations_->Move(
222 job_info.file_path, 260 job_info.file_path,
223 job_iter->second->dest_file_path, 261 job_iter->second->dest_file_path,
224 base::Bind(&DriveScheduler::OnJobDone, 262 base::Bind(&DriveScheduler::OnFileOperationJobDone,
225 weak_ptr_factory_.GetWeakPtr(), 263 weak_ptr_factory_.GetWeakPtr(),
226 job_id)); 264 job_id));
227 } 265 }
228 break; 266 break;
229 267
230 case TYPE_REMOVE: { 268 case TYPE_REMOVE: {
231 drive_operations_->Remove( 269 drive_operations_->Remove(
232 job_info.file_path, 270 job_info.file_path,
233 job_iter->second->is_recursive, 271 job_iter->second->is_recursive,
234 base::Bind(&DriveScheduler::OnJobDone, 272 base::Bind(&DriveScheduler::OnFileOperationJobDone,
235 weak_ptr_factory_.GetWeakPtr(), 273 weak_ptr_factory_.GetWeakPtr(),
236 job_id)); 274 job_id));
237 } 275 }
238 break; 276 break;
239 277
240 case TYPE_TRANSFER_LOCAL_TO_REMOTE: { 278 case TYPE_TRANSFER_LOCAL_TO_REMOTE: {
241 drive_operations_->TransferFileFromLocalToRemote( 279 drive_operations_->TransferFileFromLocalToRemote(
242 job_info.file_path, 280 job_info.file_path,
243 job_iter->second->dest_file_path, 281 job_iter->second->dest_file_path,
244 base::Bind(&DriveScheduler::OnJobDone, 282 base::Bind(&DriveScheduler::OnFileOperationJobDone,
245 weak_ptr_factory_.GetWeakPtr(), 283 weak_ptr_factory_.GetWeakPtr(),
246 job_id)); 284 job_id));
247 } 285 }
248 break; 286 break;
249 287
250 case TYPE_TRANSFER_REGULAR_FILE: { 288 case TYPE_TRANSFER_REGULAR_FILE: {
251 drive_operations_->TransferRegularFile( 289 drive_operations_->TransferRegularFile(
252 job_info.file_path, 290 job_info.file_path,
253 job_iter->second->dest_file_path, 291 job_iter->second->dest_file_path,
254 base::Bind(&DriveScheduler::OnJobDone, 292 base::Bind(&DriveScheduler::OnFileOperationJobDone,
255 weak_ptr_factory_.GetWeakPtr(), 293 weak_ptr_factory_.GetWeakPtr(),
256 job_id)); 294 job_id));
257 } 295 }
258 break; 296 break;
259 297
260 case TYPE_TRANSFER_REMOTE_TO_LOCAL: { 298 case TYPE_TRANSFER_REMOTE_TO_LOCAL: {
261 drive_operations_->TransferFileFromRemoteToLocal( 299 drive_operations_->TransferFileFromRemoteToLocal(
262 job_info.file_path, 300 job_info.file_path,
263 job_iter->second->dest_file_path, 301 job_iter->second->dest_file_path,
264 base::Bind(&DriveScheduler::OnJobDone, 302 base::Bind(&DriveScheduler::OnFileOperationJobDone,
265 weak_ptr_factory_.GetWeakPtr(), 303 weak_ptr_factory_.GetWeakPtr(),
266 job_id)); 304 job_id));
267 } 305 }
268 break; 306 break;
269 307
270 // There is no default case so that there will be a compiler error if a type 308 // There is no default case so that there will be a compiler error if a type
271 // is added but unhandled. 309 // is added but unhandled.
272 } 310 }
273 } 311 }
274 312
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 DCHECK(posted); 354 DCHECK(posted);
317 } 355 }
318 356
319 void DriveScheduler::ResetThrottleAndContinueJobLoop() { 357 void DriveScheduler::ResetThrottleAndContinueJobLoop() {
320 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 358 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
321 359
322 throttle_count_ = 0; 360 throttle_count_ = 0;
323 DoJobLoop(); 361 DoJobLoop();
324 } 362 }
325 363
326 void DriveScheduler::OnJobDone(int job_id, DriveFileError error) { 364 void DriveScheduler::OnFileOperationJobDone(int job_id, DriveFileError error) {
kinaba 2012/11/22 08:04:07 This duplication worries me a bit. How about facto
Zachary Kuznia 2012/11/28 06:54:56 Done.
327 JobMap::iterator job_iter = job_info_map_.find(job_id); 365 JobMap::iterator job_iter = job_info_map_.find(job_id);
328 DCHECK(job_iter != job_info_map_.end()); 366 DCHECK(job_iter != job_info_map_.end());
329 367
330 // Retry, depending on the error. 368 // Retry, depending on the error.
331 if (error == DRIVE_FILE_ERROR_THROTTLED || 369 if (error == DRIVE_FILE_ERROR_THROTTLED ||
332 error == DRIVE_FILE_ERROR_NO_CONNECTION) { 370 error == DRIVE_FILE_ERROR_NO_CONNECTION) {
333 job_iter->second->job_info.state = STATE_RETRY; 371 job_iter->second->job_info.state = STATE_RETRY;
334 372
335 // Requeue the job. 373 // Requeue the job.
336 queue_.push_back(job_id); 374 queue_.push_back(job_id);
337 ThrottleAndContinueJobLoop(); 375 ThrottleAndContinueJobLoop();
338 } else { 376 } else {
339 // Handle the callback. 377 // Handle the callback.
340 if (!job_iter->second->callback.is_null()) { 378 if (!job_iter->second->file_operation_callback.is_null()) {
341 MessageLoop::current()->PostTask(FROM_HERE, 379 MessageLoop::current()->PostTask(FROM_HERE,
342 base::Bind(job_iter->second->callback, error)); 380 base::Bind(job_iter->second->file_operation_callback, error));
343 } 381 }
344 382
345 // Delete the job. 383 // Delete the job.
384 job_info_map_.erase(job_id);
385 ResetThrottleAndContinueJobLoop();
386 }
387 }
388
389 void DriveScheduler::OnGetDataJobDone(int job_id,
390 google_apis::GDataErrorCode error,
391 scoped_ptr<base::Value> feed_data) {
392 JobMap::iterator job_iter = job_info_map_.find(job_id);
393 DCHECK(job_iter != job_info_map_.end());
394
395 DriveFileError drive_error(util::GDataToDriveFileError(error));
396 // Retry, depending on the error.
397 if (drive_error == DRIVE_FILE_ERROR_THROTTLED) {
398 job_iter->second->job_info.state = STATE_RETRY;
399
400 // Requeue the job.
401 queue_.push_back(job_id);
402 ThrottleAndContinueJobLoop();
403 } else {
404 // Handle the callback.
405 if (!job_iter->second->get_data_callback.is_null()) {
406 MessageLoop::current()->PostTask(FROM_HERE,
407 base::Bind(job_iter->second->get_data_callback,
408 error,
409 base::Passed(&feed_data)));
410 }
411
412 // Delete the job.
346 job_info_map_.erase(job_id); 413 job_info_map_.erase(job_id);
347 ResetThrottleAndContinueJobLoop(); 414 ResetThrottleAndContinueJobLoop();
348 } 415 }
349 } 416 }
350 417
351 void DriveScheduler::OnConnectionTypeChanged( 418 void DriveScheduler::OnConnectionTypeChanged(
352 net::NetworkChangeNotifier::ConnectionType type) { 419 net::NetworkChangeNotifier::ConnectionType type) {
353 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 420 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
354 421
355 // Resume the job loop if the network is back online. Note that we don't 422 // Resume the job loop if the network is back online. Note that we don't
356 // need to check the type of the network as it will be checked in 423 // need to check the type of the network as it will be checked in
357 // ShouldStopJobLoop() as soon as the loop is resumed. 424 // ShouldStopJobLoop() as soon as the loop is resumed.
358 if (!net::NetworkChangeNotifier::IsOffline()) 425 if (!net::NetworkChangeNotifier::IsOffline())
359 StartJobLoop(); 426 StartJobLoop();
360 } 427 }
361 428
362 } // namespace drive 429 } // namespace drive
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698