OLD | NEW |
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 "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
8 #include "base/prefs/pref_service.h" | 8 #include "base/prefs/pref_service.h" |
9 #include "base/rand_util.h" | 9 #include "base/rand_util.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
11 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
12 #include "chrome/browser/chromeos/drive/file_system_util.h" | |
13 #include "chrome/browser/drive/drive_api_util.h" | |
14 #include "chrome/browser/drive/event_logger.h" | 12 #include "chrome/browser/drive/event_logger.h" |
15 #include "chrome/common/pref_names.h" | 13 #include "chrome/common/pref_names.h" |
16 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
17 #include "google_apis/drive/drive_api_parser.h" | 15 #include "google_apis/drive/drive_api_parser.h" |
18 #include "google_apis/drive/gdata_wapi_parser.h" | |
19 | 16 |
20 using content::BrowserThread; | 17 using content::BrowserThread; |
21 | 18 |
22 namespace drive { | 19 namespace drive { |
23 | 20 |
24 namespace { | 21 namespace { |
25 | 22 |
26 // All jobs are retried at maximum of kMaxRetryCount when they fail due to | 23 // All jobs are retried at maximum of kMaxRetryCount when they fail due to |
27 // throttling or server error. The delay before retrying a job is shared among | 24 // throttling or server error. The delay before retrying a job is shared among |
28 // jobs. It doubles in length on each failure, upto 2^kMaxThrottleCount seconds. | 25 // jobs. It doubles in length on each failure, upto 2^kMaxThrottleCount seconds. |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 base::Unretained(drive_service_), | 371 base::Unretained(drive_service_), |
375 next_link, | 372 next_link, |
376 base::Bind(&JobScheduler::OnGetFileListJobDone, | 373 base::Bind(&JobScheduler::OnGetFileListJobDone, |
377 weak_ptr_factory_.GetWeakPtr(), | 374 weak_ptr_factory_.GetWeakPtr(), |
378 new_job->job_info.job_id, | 375 new_job->job_info.job_id, |
379 callback)); | 376 callback)); |
380 new_job->abort_callback = CreateErrorRunCallback(callback); | 377 new_job->abort_callback = CreateErrorRunCallback(callback); |
381 StartJob(new_job); | 378 StartJob(new_job); |
382 } | 379 } |
383 | 380 |
384 void JobScheduler::GetResourceEntry( | 381 void JobScheduler::GetFileResource( |
385 const std::string& resource_id, | 382 const std::string& resource_id, |
386 const ClientContext& context, | 383 const ClientContext& context, |
387 const google_apis::GetResourceEntryCallback& callback) { | 384 const google_apis::FileResourceCallback& callback) { |
388 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 385 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
389 DCHECK(!callback.is_null()); | 386 DCHECK(!callback.is_null()); |
390 | 387 |
391 JobEntry* new_job = CreateNewJob(TYPE_GET_RESOURCE_ENTRY); | 388 JobEntry* new_job = CreateNewJob(TYPE_GET_RESOURCE_ENTRY); |
392 new_job->context = context; | 389 new_job->context = context; |
393 new_job->task = base::Bind( | 390 new_job->task = base::Bind( |
394 &DriveServiceInterface::GetFileResource, | 391 &DriveServiceInterface::GetFileResource, |
395 base::Unretained(drive_service_), | 392 base::Unretained(drive_service_), |
396 resource_id, | 393 resource_id, |
397 base::Bind(&JobScheduler::OnGetFileResourceJobDone, | 394 base::Bind(&JobScheduler::OnGetFileResourceJobDone, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 callback)); | 441 callback)); |
445 new_job->abort_callback = callback; | 442 new_job->abort_callback = callback; |
446 StartJob(new_job); | 443 StartJob(new_job); |
447 } | 444 } |
448 | 445 |
449 void JobScheduler::CopyResource( | 446 void JobScheduler::CopyResource( |
450 const std::string& resource_id, | 447 const std::string& resource_id, |
451 const std::string& parent_resource_id, | 448 const std::string& parent_resource_id, |
452 const std::string& new_title, | 449 const std::string& new_title, |
453 const base::Time& last_modified, | 450 const base::Time& last_modified, |
454 const google_apis::GetResourceEntryCallback& callback) { | 451 const google_apis::FileResourceCallback& callback) { |
455 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
456 DCHECK(!callback.is_null()); | 453 DCHECK(!callback.is_null()); |
457 | 454 |
458 JobEntry* new_job = CreateNewJob(TYPE_COPY_RESOURCE); | 455 JobEntry* new_job = CreateNewJob(TYPE_COPY_RESOURCE); |
459 new_job->task = base::Bind( | 456 new_job->task = base::Bind( |
460 &DriveServiceInterface::CopyResource, | 457 &DriveServiceInterface::CopyResource, |
461 base::Unretained(drive_service_), | 458 base::Unretained(drive_service_), |
462 resource_id, | 459 resource_id, |
463 parent_resource_id, | 460 parent_resource_id, |
464 new_title, | 461 new_title, |
465 last_modified, | 462 last_modified, |
466 base::Bind(&JobScheduler::OnGetFileResourceJobDone, | 463 base::Bind(&JobScheduler::OnGetFileResourceJobDone, |
467 weak_ptr_factory_.GetWeakPtr(), | 464 weak_ptr_factory_.GetWeakPtr(), |
468 new_job->job_info.job_id, | 465 new_job->job_info.job_id, |
469 callback)); | 466 callback)); |
470 new_job->abort_callback = CreateErrorRunCallback(callback); | 467 new_job->abort_callback = CreateErrorRunCallback(callback); |
471 StartJob(new_job); | 468 StartJob(new_job); |
472 } | 469 } |
473 | 470 |
474 void JobScheduler::UpdateResource( | 471 void JobScheduler::UpdateResource( |
475 const std::string& resource_id, | 472 const std::string& resource_id, |
476 const std::string& parent_resource_id, | 473 const std::string& parent_resource_id, |
477 const std::string& new_title, | 474 const std::string& new_title, |
478 const base::Time& last_modified, | 475 const base::Time& last_modified, |
479 const base::Time& last_viewed_by_me, | 476 const base::Time& last_viewed_by_me, |
480 const ClientContext& context, | 477 const ClientContext& context, |
481 const google_apis::GetResourceEntryCallback& callback) { | 478 const google_apis::FileResourceCallback& callback) { |
482 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 479 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
483 DCHECK(!callback.is_null()); | 480 DCHECK(!callback.is_null()); |
484 | 481 |
485 JobEntry* new_job = CreateNewJob(TYPE_UPDATE_RESOURCE); | 482 JobEntry* new_job = CreateNewJob(TYPE_UPDATE_RESOURCE); |
486 new_job->context = context; | 483 new_job->context = context; |
487 new_job->task = base::Bind( | 484 new_job->task = base::Bind( |
488 &DriveServiceInterface::UpdateResource, | 485 &DriveServiceInterface::UpdateResource, |
489 base::Unretained(drive_service_), | 486 base::Unretained(drive_service_), |
490 resource_id, | 487 resource_id, |
491 parent_resource_id, | 488 parent_resource_id, |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 callback)); | 559 callback)); |
563 new_job->abort_callback = callback; | 560 new_job->abort_callback = callback; |
564 StartJob(new_job); | 561 StartJob(new_job); |
565 } | 562 } |
566 | 563 |
567 void JobScheduler::AddNewDirectory( | 564 void JobScheduler::AddNewDirectory( |
568 const std::string& parent_resource_id, | 565 const std::string& parent_resource_id, |
569 const std::string& directory_title, | 566 const std::string& directory_title, |
570 const DriveServiceInterface::AddNewDirectoryOptions& options, | 567 const DriveServiceInterface::AddNewDirectoryOptions& options, |
571 const ClientContext& context, | 568 const ClientContext& context, |
572 const google_apis::GetResourceEntryCallback& callback) { | 569 const google_apis::FileResourceCallback& callback) { |
573 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 570 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
574 | 571 |
575 JobEntry* new_job = CreateNewJob(TYPE_ADD_NEW_DIRECTORY); | 572 JobEntry* new_job = CreateNewJob(TYPE_ADD_NEW_DIRECTORY); |
576 new_job->context = context; | 573 new_job->context = context; |
577 new_job->task = base::Bind( | 574 new_job->task = base::Bind( |
578 &DriveServiceInterface::AddNewDirectory, | 575 &DriveServiceInterface::AddNewDirectory, |
579 base::Unretained(drive_service_), | 576 base::Unretained(drive_service_), |
580 parent_resource_id, | 577 parent_resource_id, |
581 directory_title, | 578 directory_title, |
582 options, | 579 options, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 } | 618 } |
622 | 619 |
623 void JobScheduler::UploadNewFile( | 620 void JobScheduler::UploadNewFile( |
624 const std::string& parent_resource_id, | 621 const std::string& parent_resource_id, |
625 const base::FilePath& drive_file_path, | 622 const base::FilePath& drive_file_path, |
626 const base::FilePath& local_file_path, | 623 const base::FilePath& local_file_path, |
627 const std::string& title, | 624 const std::string& title, |
628 const std::string& content_type, | 625 const std::string& content_type, |
629 const DriveUploader::UploadNewFileOptions& options, | 626 const DriveUploader::UploadNewFileOptions& options, |
630 const ClientContext& context, | 627 const ClientContext& context, |
631 const google_apis::GetResourceEntryCallback& callback) { | 628 const google_apis::FileResourceCallback& callback) { |
632 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 629 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
633 | 630 |
634 JobEntry* new_job = CreateNewJob(TYPE_UPLOAD_NEW_FILE); | 631 JobEntry* new_job = CreateNewJob(TYPE_UPLOAD_NEW_FILE); |
635 new_job->job_info.file_path = drive_file_path; | 632 new_job->job_info.file_path = drive_file_path; |
636 new_job->context = context; | 633 new_job->context = context; |
637 | 634 |
638 UploadNewFileParams params; | 635 UploadNewFileParams params; |
639 params.parent_resource_id = parent_resource_id; | 636 params.parent_resource_id = parent_resource_id; |
640 params.local_file_path = local_file_path; | 637 params.local_file_path = local_file_path; |
641 params.title = title; | 638 params.title = title; |
(...skipping 17 matching lines...) Expand all Loading... |
659 StartJob(new_job); | 656 StartJob(new_job); |
660 } | 657 } |
661 | 658 |
662 void JobScheduler::UploadExistingFile( | 659 void JobScheduler::UploadExistingFile( |
663 const std::string& resource_id, | 660 const std::string& resource_id, |
664 const base::FilePath& drive_file_path, | 661 const base::FilePath& drive_file_path, |
665 const base::FilePath& local_file_path, | 662 const base::FilePath& local_file_path, |
666 const std::string& content_type, | 663 const std::string& content_type, |
667 const DriveUploader::UploadExistingFileOptions& options, | 664 const DriveUploader::UploadExistingFileOptions& options, |
668 const ClientContext& context, | 665 const ClientContext& context, |
669 const google_apis::GetResourceEntryCallback& callback) { | 666 const google_apis::FileResourceCallback& callback) { |
670 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 667 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
671 | 668 |
672 JobEntry* new_job = CreateNewJob(TYPE_UPLOAD_EXISTING_FILE); | 669 JobEntry* new_job = CreateNewJob(TYPE_UPLOAD_EXISTING_FILE); |
673 new_job->job_info.file_path = drive_file_path; | 670 new_job->job_info.file_path = drive_file_path; |
674 new_job->context = context; | 671 new_job->context = context; |
675 | 672 |
676 UploadExistingFileParams params; | 673 UploadExistingFileParams params; |
677 params.resource_id = resource_id; | 674 params.resource_id = resource_id; |
678 params.local_file_path = local_file_path; | 675 params.local_file_path = local_file_path; |
679 params.content_type = content_type; | 676 params.content_type = content_type; |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 scoped_ptr<google_apis::ChangeList> change_list) { | 915 scoped_ptr<google_apis::ChangeList> change_list) { |
919 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 916 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
920 DCHECK(!callback.is_null()); | 917 DCHECK(!callback.is_null()); |
921 | 918 |
922 if (OnJobDone(job_id, error)) | 919 if (OnJobDone(job_id, error)) |
923 callback.Run(error, change_list.Pass()); | 920 callback.Run(error, change_list.Pass()); |
924 } | 921 } |
925 | 922 |
926 void JobScheduler::OnGetFileResourceJobDone( | 923 void JobScheduler::OnGetFileResourceJobDone( |
927 JobID job_id, | 924 JobID job_id, |
928 const google_apis::GetResourceEntryCallback& callback, | 925 const google_apis::FileResourceCallback& callback, |
929 google_apis::GDataErrorCode error, | 926 google_apis::GDataErrorCode error, |
930 scoped_ptr<google_apis::FileResource> entry) { | 927 scoped_ptr<google_apis::FileResource> entry) { |
931 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 928 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
932 DCHECK(!callback.is_null()); | 929 DCHECK(!callback.is_null()); |
933 | 930 |
934 if (OnJobDone(job_id, error)) { | 931 if (OnJobDone(job_id, error)) |
935 callback.Run(error, entry ? | 932 callback.Run(error, entry.Pass()); |
936 util::ConvertFileResourceToResourceEntry(*entry) : | |
937 scoped_ptr<google_apis::ResourceEntry>()); | |
938 } | |
939 } | 933 } |
940 | 934 |
941 void JobScheduler::OnGetAboutResourceJobDone( | 935 void JobScheduler::OnGetAboutResourceJobDone( |
942 JobID job_id, | 936 JobID job_id, |
943 const google_apis::AboutResourceCallback& callback, | 937 const google_apis::AboutResourceCallback& callback, |
944 google_apis::GDataErrorCode error, | 938 google_apis::GDataErrorCode error, |
945 scoped_ptr<google_apis::AboutResource> about_resource) { | 939 scoped_ptr<google_apis::AboutResource> about_resource) { |
946 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 940 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
947 DCHECK(!callback.is_null()); | 941 DCHECK(!callback.is_null()); |
948 | 942 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 987 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
994 DCHECK(!callback.is_null()); | 988 DCHECK(!callback.is_null()); |
995 | 989 |
996 if (OnJobDone(job_id, error)) | 990 if (OnJobDone(job_id, error)) |
997 callback.Run(error, temp_file); | 991 callback.Run(error, temp_file); |
998 } | 992 } |
999 | 993 |
1000 void JobScheduler::OnUploadCompletionJobDone( | 994 void JobScheduler::OnUploadCompletionJobDone( |
1001 JobID job_id, | 995 JobID job_id, |
1002 const ResumeUploadParams& resume_params, | 996 const ResumeUploadParams& resume_params, |
1003 const google_apis::GetResourceEntryCallback& callback, | 997 const google_apis::FileResourceCallback& callback, |
1004 google_apis::GDataErrorCode error, | 998 google_apis::GDataErrorCode error, |
1005 const GURL& upload_location, | 999 const GURL& upload_location, |
1006 scoped_ptr<google_apis::FileResource> entry) { | 1000 scoped_ptr<google_apis::FileResource> entry) { |
1007 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1001 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1008 DCHECK(!callback.is_null()); | 1002 DCHECK(!callback.is_null()); |
1009 | 1003 |
1010 if (!upload_location.is_empty()) { | 1004 if (!upload_location.is_empty()) { |
1011 // If upload_location is available, update the task to resume the | 1005 // If upload_location is available, update the task to resume the |
1012 // upload process from the terminated point. | 1006 // upload process from the terminated point. |
1013 // When we need to retry, the error code should be HTTP_SERVICE_UNAVAILABLE | 1007 // When we need to retry, the error code should be HTTP_SERVICE_UNAVAILABLE |
1014 // so OnJobDone called below will be in charge to re-queue the job. | 1008 // so OnJobDone called below will be in charge to re-queue the job. |
1015 JobEntry* job_entry = job_map_.Lookup(job_id); | 1009 JobEntry* job_entry = job_map_.Lookup(job_id); |
1016 DCHECK(job_entry); | 1010 DCHECK(job_entry); |
1017 | 1011 |
1018 ResumeUploadFileParams params; | 1012 ResumeUploadFileParams params; |
1019 params.upload_location = upload_location; | 1013 params.upload_location = upload_location; |
1020 params.local_file_path = resume_params.local_file_path; | 1014 params.local_file_path = resume_params.local_file_path; |
1021 params.content_type = resume_params.content_type; | 1015 params.content_type = resume_params.content_type; |
1022 params.callback = base::Bind(&JobScheduler::OnResumeUploadFileDone, | 1016 params.callback = base::Bind(&JobScheduler::OnResumeUploadFileDone, |
1023 weak_ptr_factory_.GetWeakPtr(), | 1017 weak_ptr_factory_.GetWeakPtr(), |
1024 job_id, | 1018 job_id, |
1025 job_entry->task, | 1019 job_entry->task, |
1026 callback); | 1020 callback); |
1027 params.progress_callback = base::Bind(&JobScheduler::UpdateProgress, | 1021 params.progress_callback = base::Bind(&JobScheduler::UpdateProgress, |
1028 weak_ptr_factory_.GetWeakPtr(), | 1022 weak_ptr_factory_.GetWeakPtr(), |
1029 job_id); | 1023 job_id); |
1030 job_entry->task = base::Bind(&RunResumeUploadFile, uploader_.get(), params); | 1024 job_entry->task = base::Bind(&RunResumeUploadFile, uploader_.get(), params); |
1031 } | 1025 } |
1032 | 1026 |
1033 if (OnJobDone(job_id, error)) { | 1027 if (OnJobDone(job_id, error)) |
1034 callback.Run(error, entry ? | 1028 callback.Run(error, entry.Pass()); |
1035 util::ConvertFileResourceToResourceEntry(*entry) : | |
1036 scoped_ptr<google_apis::ResourceEntry>()); | |
1037 } | |
1038 } | 1029 } |
1039 | 1030 |
1040 void JobScheduler::OnResumeUploadFileDone( | 1031 void JobScheduler::OnResumeUploadFileDone( |
1041 JobID job_id, | 1032 JobID job_id, |
1042 const base::Callback<google_apis::CancelCallback()>& original_task, | 1033 const base::Callback<google_apis::CancelCallback()>& original_task, |
1043 const google_apis::GetResourceEntryCallback& callback, | 1034 const google_apis::FileResourceCallback& callback, |
1044 google_apis::GDataErrorCode error, | 1035 google_apis::GDataErrorCode error, |
1045 const GURL& upload_location, | 1036 const GURL& upload_location, |
1046 scoped_ptr<google_apis::FileResource> entry) { | 1037 scoped_ptr<google_apis::FileResource> entry) { |
1047 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1038 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1048 DCHECK(!original_task.is_null()); | 1039 DCHECK(!original_task.is_null()); |
1049 DCHECK(!callback.is_null()); | 1040 DCHECK(!callback.is_null()); |
1050 | 1041 |
1051 if (upload_location.is_empty()) { | 1042 if (upload_location.is_empty()) { |
1052 // If upload_location is not available, we should discard it and stop trying | 1043 // If upload_location is not available, we should discard it and stop trying |
1053 // to resume. Restore the original task. | 1044 // to resume. Restore the original task. |
1054 JobEntry* job_entry = job_map_.Lookup(job_id); | 1045 JobEntry* job_entry = job_map_.Lookup(job_id); |
1055 DCHECK(job_entry); | 1046 DCHECK(job_entry); |
1056 job_entry->task = original_task; | 1047 job_entry->task = original_task; |
1057 } | 1048 } |
1058 | 1049 |
1059 if (OnJobDone(job_id, error)) { | 1050 if (OnJobDone(job_id, error)) |
1060 callback.Run(error, entry ? | 1051 callback.Run(error, entry.Pass()); |
1061 util::ConvertFileResourceToResourceEntry(*entry) : | |
1062 scoped_ptr<google_apis::ResourceEntry>()); | |
1063 } | |
1064 } | 1052 } |
1065 | 1053 |
1066 void JobScheduler::UpdateProgress(JobID job_id, int64 progress, int64 total) { | 1054 void JobScheduler::UpdateProgress(JobID job_id, int64 progress, int64 total) { |
1067 JobEntry* job_entry = job_map_.Lookup(job_id); | 1055 JobEntry* job_entry = job_map_.Lookup(job_id); |
1068 DCHECK(job_entry); | 1056 DCHECK(job_entry); |
1069 | 1057 |
1070 job_entry->job_info.num_completed_bytes = progress; | 1058 job_entry->job_info.num_completed_bytes = progress; |
1071 if (total != -1) | 1059 if (total != -1) |
1072 job_entry->job_info.num_total_bytes = total; | 1060 job_entry->job_info.num_total_bytes = total; |
1073 NotifyJobUpdated(job_entry->job_info); | 1061 NotifyJobUpdated(job_entry->job_info); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 case FILE_QUEUE: | 1155 case FILE_QUEUE: |
1168 return "FILE_QUEUE"; | 1156 return "FILE_QUEUE"; |
1169 case NUM_QUEUES: | 1157 case NUM_QUEUES: |
1170 break; // This value is just a sentinel. Should never be used. | 1158 break; // This value is just a sentinel. Should never be used. |
1171 } | 1159 } |
1172 NOTREACHED(); | 1160 NOTREACHED(); |
1173 return ""; | 1161 return ""; |
1174 } | 1162 } |
1175 | 1163 |
1176 } // namespace drive | 1164 } // namespace drive |
OLD | NEW |