Index: chrome/browser/chromeos/drive/drive_scheduler.cc |
diff --git a/chrome/browser/chromeos/drive/drive_scheduler.cc b/chrome/browser/chromeos/drive/drive_scheduler.cc |
index 8dfd21c5188c34f4cf669024bb574248823e46da..aa91c183dff62db718191fd7ad388815e379c29c 100644 |
--- a/chrome/browser/chromeos/drive/drive_scheduler.cc |
+++ b/chrome/browser/chromeos/drive/drive_scheduler.cc |
@@ -8,6 +8,7 @@ |
#include "base/message_loop.h" |
#include "base/rand_util.h" |
+#include "chrome/browser/chromeos/drive/drive_file_system_util.h" |
#include "chrome/browser/chromeos/drive/file_system/drive_operations.h" |
#include "chrome/browser/chromeos/drive/file_system/remove_operation.h" |
#include "chrome/browser/prefs/pref_service.h" |
@@ -33,23 +34,24 @@ DriveScheduler::JobInfo::JobInfo(JobType in_job_type, FilePath in_file_path) |
} |
DriveScheduler::QueueEntry::QueueEntry(JobType in_job_type, |
- FilePath in_file_path, |
- FileOperationCallback in_callback) |
+ FilePath in_file_path) |
: job_info(in_job_type, in_file_path), |
- callback(in_callback), |
is_recursive(false) { |
} |
DriveScheduler::QueueEntry::~QueueEntry() { |
} |
-DriveScheduler::DriveScheduler(Profile* profile, |
- file_system::DriveOperations* drive_operations) |
+DriveScheduler::DriveScheduler( |
+ Profile* profile, |
+ google_apis::DriveServiceInterface* drive_service, |
+ file_system::DriveOperations* drive_operations) |
: job_loop_is_running_(false), |
next_job_id_(0), |
throttle_count_(0), |
disable_throttling_(false), |
drive_operations_(drive_operations), |
+ drive_service_(drive_service), |
profile_(profile), |
weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
initialized_(false) { |
@@ -79,9 +81,32 @@ void DriveScheduler::Copy(const FilePath& src_file_path, |
const FileOperationCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- scoped_ptr<QueueEntry> new_job( |
- new QueueEntry(TYPE_COPY, src_file_path, callback)); |
+ scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_COPY, src_file_path)); |
new_job->dest_file_path = dest_file_path; |
+ new_job->file_operation_callback = callback; |
+ |
+ QueueJob(new_job.Pass()); |
+ |
+ StartJobLoop(); |
+} |
+ |
+void DriveScheduler::GetDocuments( |
+ const GURL& feed_url, |
+ int64 start_changestamp, |
+ const std::string& search_query, |
+ bool shared_with_me, |
+ const std::string& directory_resource_id, |
+ const google_apis::GetDataCallback& callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ scoped_ptr<QueueEntry> new_job( |
+ new QueueEntry(TYPE_GET_DOCUMENTS, FilePath())); |
+ new_job->feed_url = feed_url; |
+ new_job->start_changestamp = start_changestamp; |
+ new_job->search_query = search_query; |
+ new_job->shared_with_me = shared_with_me; |
+ new_job->directory_resource_id = directory_resource_id; |
+ new_job->get_data_callback = callback; |
QueueJob(new_job.Pass()); |
@@ -95,9 +120,9 @@ void DriveScheduler::TransferFileFromRemoteToLocal( |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_TRANSFER_REMOTE_TO_LOCAL, |
- remote_src_file_path, |
- callback)); |
+ remote_src_file_path)); |
new_job->dest_file_path = local_dest_file_path; |
+ new_job->file_operation_callback = callback; |
QueueJob(new_job.Pass()); |
@@ -111,9 +136,9 @@ void DriveScheduler::TransferFileFromLocalToRemote( |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_TRANSFER_LOCAL_TO_REMOTE, |
- local_src_file_path, |
- callback)); |
+ local_src_file_path)); |
new_job->dest_file_path = remote_dest_file_path; |
+ new_job->file_operation_callback = callback; |
QueueJob(new_job.Pass()); |
@@ -127,9 +152,9 @@ void DriveScheduler::TransferRegularFile( |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_TRANSFER_REGULAR_FILE, |
- local_src_file_path, |
- callback)); |
+ local_src_file_path)); |
new_job->dest_file_path = remote_dest_file_path; |
+ new_job->file_operation_callback = callback; |
QueueJob(new_job.Pass()); |
@@ -141,9 +166,9 @@ void DriveScheduler::Move(const FilePath& src_file_path, |
const FileOperationCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- scoped_ptr<QueueEntry> new_job( |
- new QueueEntry(TYPE_MOVE, src_file_path, callback)); |
+ scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_MOVE, src_file_path)); |
new_job->dest_file_path = dest_file_path; |
+ new_job->file_operation_callback = callback; |
QueueJob(new_job.Pass()); |
@@ -155,9 +180,9 @@ void DriveScheduler::Remove(const FilePath& file_path, |
const FileOperationCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- scoped_ptr<QueueEntry> new_job( |
- new QueueEntry(TYPE_REMOVE, file_path, callback)); |
+ scoped_ptr<QueueEntry> new_job(new QueueEntry(TYPE_REMOVE, file_path)); |
new_job->is_recursive = is_recursive; |
+ new_job->file_operation_callback = callback; |
QueueJob(new_job.Pass()); |
@@ -205,13 +230,27 @@ void DriveScheduler::DoJobLoop() { |
JobInfo& job_info = job_iter->second->job_info; |
job_info.state = STATE_RUNNING; |
+ const QueueEntry* queue_entry = job_iter->second.get(); |
switch (job_info.job_type) { |
case TYPE_COPY: { |
drive_operations_->Copy( |
job_info.file_path, |
- job_iter->second->dest_file_path, |
- base::Bind(&DriveScheduler::OnJobDone, |
+ queue_entry->dest_file_path, |
+ base::Bind(&DriveScheduler::OnFileOperationJobDone, |
+ weak_ptr_factory_.GetWeakPtr(), |
+ job_id)); |
+ } |
+ break; |
+ |
+ case TYPE_GET_DOCUMENTS: { |
+ drive_service_->GetDocuments( |
+ queue_entry->feed_url, |
+ queue_entry->start_changestamp, |
+ queue_entry->search_query, |
+ queue_entry->shared_with_me, |
+ queue_entry->directory_resource_id, |
+ base::Bind(&DriveScheduler::OnGetDataJobDone, |
weak_ptr_factory_.GetWeakPtr(), |
job_id)); |
} |
@@ -220,8 +259,8 @@ void DriveScheduler::DoJobLoop() { |
case TYPE_MOVE: { |
drive_operations_->Move( |
job_info.file_path, |
- job_iter->second->dest_file_path, |
- base::Bind(&DriveScheduler::OnJobDone, |
+ queue_entry->dest_file_path, |
+ base::Bind(&DriveScheduler::OnFileOperationJobDone, |
weak_ptr_factory_.GetWeakPtr(), |
job_id)); |
} |
@@ -230,8 +269,8 @@ void DriveScheduler::DoJobLoop() { |
case TYPE_REMOVE: { |
drive_operations_->Remove( |
job_info.file_path, |
- job_iter->second->is_recursive, |
- base::Bind(&DriveScheduler::OnJobDone, |
+ queue_entry->is_recursive, |
+ base::Bind(&DriveScheduler::OnFileOperationJobDone, |
weak_ptr_factory_.GetWeakPtr(), |
job_id)); |
} |
@@ -240,8 +279,8 @@ void DriveScheduler::DoJobLoop() { |
case TYPE_TRANSFER_LOCAL_TO_REMOTE: { |
drive_operations_->TransferFileFromLocalToRemote( |
job_info.file_path, |
- job_iter->second->dest_file_path, |
- base::Bind(&DriveScheduler::OnJobDone, |
+ queue_entry->dest_file_path, |
+ base::Bind(&DriveScheduler::OnFileOperationJobDone, |
weak_ptr_factory_.GetWeakPtr(), |
job_id)); |
} |
@@ -250,8 +289,8 @@ void DriveScheduler::DoJobLoop() { |
case TYPE_TRANSFER_REGULAR_FILE: { |
drive_operations_->TransferRegularFile( |
job_info.file_path, |
- job_iter->second->dest_file_path, |
- base::Bind(&DriveScheduler::OnJobDone, |
+ queue_entry->dest_file_path, |
+ base::Bind(&DriveScheduler::OnFileOperationJobDone, |
weak_ptr_factory_.GetWeakPtr(), |
job_id)); |
} |
@@ -260,8 +299,8 @@ void DriveScheduler::DoJobLoop() { |
case TYPE_TRANSFER_REMOTE_TO_LOCAL: { |
drive_operations_->TransferFileFromRemoteToLocal( |
job_info.file_path, |
- job_iter->second->dest_file_path, |
- base::Bind(&DriveScheduler::OnJobDone, |
+ queue_entry->dest_file_path, |
+ base::Bind(&DriveScheduler::OnFileOperationJobDone, |
weak_ptr_factory_.GetWeakPtr(), |
job_id)); |
} |
@@ -319,32 +358,69 @@ void DriveScheduler::ThrottleAndContinueJobLoop() { |
void DriveScheduler::ResetThrottleAndContinueJobLoop() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ // Post a task to continue the job loop. This allows us to finish handling |
+ // the current job before starting the next one. |
throttle_count_ = 0; |
- DoJobLoop(); |
+ base::MessageLoopProxy::current()->PostTask(FROM_HERE, |
+ base::Bind(&DriveScheduler::DoJobLoop, |
+ weak_ptr_factory_.GetWeakPtr())); |
} |
-void DriveScheduler::OnJobDone(int job_id, DriveFileError error) { |
+scoped_ptr<DriveScheduler::QueueEntry> DriveScheduler::OnJobDone( |
+ int job_id, |
+ DriveFileError error) { |
JobMap::iterator job_iter = job_info_map_.find(job_id); |
DCHECK(job_iter != job_info_map_.end()); |
// Retry, depending on the error. |
- if (error == DRIVE_FILE_ERROR_THROTTLED || |
- error == DRIVE_FILE_ERROR_NO_CONNECTION) { |
+ if (error == DRIVE_FILE_ERROR_THROTTLED) { |
job_iter->second->job_info.state = STATE_RETRY; |
// Requeue the job. |
queue_.push_back(job_id); |
ThrottleAndContinueJobLoop(); |
+ |
+ return scoped_ptr<DriveScheduler::QueueEntry>(); |
} else { |
- // Handle the callback. |
- if (!job_iter->second->callback.is_null()) { |
- MessageLoop::current()->PostTask(FROM_HERE, |
- base::Bind(job_iter->second->callback, error)); |
- } |
+ scoped_ptr<DriveScheduler::QueueEntry> job_info(job_iter->second.release()); |
// Delete the job. |
job_info_map_.erase(job_id); |
ResetThrottleAndContinueJobLoop(); |
+ |
+ return job_info.Pass(); |
+ } |
+} |
+ |
+void DriveScheduler::OnFileOperationJobDone(int job_id, DriveFileError error) { |
+ scoped_ptr<DriveScheduler::QueueEntry> job_info = OnJobDone(job_id, error); |
+ |
+ if (!job_info) |
+ return; |
+ |
+ // Handle the callback. |
+ if (!job_info->file_operation_callback.is_null()) { |
+ MessageLoop::current()->PostTask(FROM_HERE, |
+ base::Bind(job_info->file_operation_callback, error)); |
+ } |
+} |
+ |
+void DriveScheduler::OnGetDataJobDone(int job_id, |
+ google_apis::GDataErrorCode error, |
+ scoped_ptr<base::Value> feed_data) { |
+ DriveFileError drive_error(util::GDataToDriveFileError(error)); |
+ |
+ scoped_ptr<QueueEntry> job_info = OnJobDone(job_id, drive_error); |
+ |
+ if (!job_info) |
+ return; |
+ |
+ // Handle the callback. |
+ if (!job_info->get_data_callback.is_null()) { |
+ MessageLoop::current()->PostTask(FROM_HERE, |
+ base::Bind(job_info->get_data_callback, |
+ error, |
+ base::Passed(&feed_data))); |
} |
} |