summaryrefslogtreecommitdiffstats
path: root/chrome/service/cloud_print/printer_job_handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/service/cloud_print/printer_job_handler.cc')
-rw-r--r--chrome/service/cloud_print/printer_job_handler.cc402
1 files changed, 152 insertions, 250 deletions
diff --git a/chrome/service/cloud_print/printer_job_handler.cc b/chrome/service/cloud_print/printer_job_handler.cc
index 9d4f46f..f351c5c 100644
--- a/chrome/service/cloud_print/printer_job_handler.cc
+++ b/chrome/service/cloud_print/printer_job_handler.cc
@@ -31,8 +31,8 @@ PrinterJobHandler::PrinterJobHandler(
cloud_print_server_url_(cloud_print_server_url),
delegate_(delegate),
local_job_id_(-1),
- next_response_handler_(NULL),
- next_failure_handler_(NULL),
+ next_json_data_handler_(NULL),
+ next_data_handler_(NULL),
server_error_count_(0),
print_thread_("Chrome_CloudPrintJobPrintThread"),
job_handler_message_loop_proxy_(
@@ -66,7 +66,7 @@ PrinterJobHandler::~PrinterJobHandler() {
void PrinterJobHandler::Reset() {
print_data_url_.clear();
job_details_.Clear();
- request_.reset();
+ request_ = NULL;
print_thread_.Stop();
}
@@ -86,11 +86,12 @@ void PrinterJobHandler::Start() {
if (printer_delete_pending_) {
printer_delete_pending_ = false;
task_in_progress_ = true;
- MakeServerRequest(
+ SetNextJSONHandler(&PrinterJobHandler::HandlePrinterDeleteResponse);
+ request_ = new CloudPrintURLFetcher;
+ request_->StartGetRequest(
CloudPrintHelpers::GetUrlForPrinterDelete(
cloud_print_server_url_, printer_info_cloud_.printer_id),
- &PrinterJobHandler::HandlePrinterDeleteResponse,
- &PrinterJobHandler::Stop);
+ this, auth_token_, kCloudPrintAPIRetryPolicy);
}
if (!task_in_progress_ && printer_update_pending_) {
printer_update_pending_ = false;
@@ -100,11 +101,12 @@ void PrinterJobHandler::Start() {
task_in_progress_ = true;
server_job_available_ = false;
// We need to fetch any pending jobs for this printer
- MakeServerRequest(
+ SetNextJSONHandler(&PrinterJobHandler::HandleJobMetadataResponse);
+ request_ = new CloudPrintURLFetcher;
+ request_->StartGetRequest(
CloudPrintHelpers::GetUrlForJobFetch(
cloud_print_server_url_, printer_info_cloud_.printer_id),
- &PrinterJobHandler::HandleJobMetadataResponse,
- &PrinterJobHandler::Stop);
+ this, auth_token_, kCloudPrintAPIRetryPolicy);
}
}
}
@@ -199,50 +201,47 @@ bool PrinterJobHandler::UpdatePrinterInfo() {
post_data.append("--" + mime_boundary + "--\r\n");
std::string mime_type("multipart/form-data; boundary=");
mime_type += mime_boundary;
- request_.reset(
- new URLFetcher(CloudPrintHelpers::GetUrlForPrinterUpdate(
- cloud_print_server_url_,
- printer_info_cloud_.printer_id),
- URLFetcher::POST, this));
- CloudPrintHelpers::PrepCloudPrintRequest(request_.get(), auth_token_);
- request_->set_upload_data(mime_type, post_data);
- next_response_handler_ = &PrinterJobHandler::HandlePrinterUpdateResponse;
- next_failure_handler_ = &PrinterJobHandler::Stop;
- request_->Start();
+ SetNextJSONHandler(&PrinterJobHandler::HandlePrinterUpdateResponse);
+ request_ = new CloudPrintURLFetcher;
+ request_->StartPostRequest(
+ CloudPrintHelpers::GetUrlForPrinterUpdate(
+ cloud_print_server_url_, printer_info_cloud_.printer_id),
+ this, auth_token_, kCloudPrintAPIRetryPolicy, mime_type, post_data);
ret = true;
}
return ret;
}
-// URLFetcher::Delegate implementation.
-void PrinterJobHandler::OnURLFetchComplete(
+// CloudPrintURLFetcher::Delegate implementation.
+CloudPrintURLFetcher::ResponseAction PrinterJobHandler::HandleRawData(
const URLFetcher* source,
const GURL& url,
- const URLRequestStatus& status,
- int response_code,
- const ResponseCookies& cookies,
const std::string& data) {
- VLOG(1) << "CP_PROXY: Printer job handler, OnURLFetchComplete, url: " << url
- << ", response code: " << response_code;
- // If there was an auth error, we are done.
- if (RC_FORBIDDEN == response_code) {
- OnAuthError();
- return;
- }
- if (!shutting_down_) {
- DCHECK(source == request_.get());
- // We need a next response handler because we are strictly a sequential
- // state machine. We need each response handler to tell us which state to
- // advance to next.
- DCHECK(next_response_handler_);
- if (!(this->*next_response_handler_)(source, url, status,
- response_code, cookies, data)) {
- // By contract, if the response handler returns false, it wants us to
- // retry the request (upto the usual limit after which we give up and
- // send the state machine to the Stop state);
- HandleServerError(url);
- }
- }
+ if (!next_data_handler_)
+ return CloudPrintURLFetcher::CONTINUE_PROCESSING;
+ return (this->*next_data_handler_)(source, url, data);
+}
+
+CloudPrintURLFetcher::ResponseAction PrinterJobHandler::HandleJSONData(
+ const URLFetcher* source,
+ const GURL& url,
+ DictionaryValue* json_data,
+ bool succeeded) {
+ DCHECK(next_json_data_handler_);
+ return (this->*next_json_data_handler_)(source,
+ url,
+ json_data,
+ succeeded);
+}
+
+void PrinterJobHandler::OnRequestGiveUp() {
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &PrinterJobHandler::Stop));
+}
+
+void PrinterJobHandler::OnRequestAuthError() {
+ OnAuthError();
}
// JobStatusUpdater::Delegate implementation
@@ -291,163 +290,101 @@ void PrinterJobHandler::OnJobChanged() {
}
}
-bool PrinterJobHandler::HandlePrinterUpdateResponse(
+// Begin Response handlers
+CloudPrintURLFetcher::ResponseAction
+PrinterJobHandler::HandlePrinterUpdateResponse(
const URLFetcher* source,
const GURL& url,
- const URLRequestStatus& status,
- int response_code,
- const ResponseCookies& cookies,
- const std::string& data) {
- bool ret = false;
+ DictionaryValue* json_data,
+ bool succeeded) {
VLOG(1) << "CP_PROXY: Handle printer update response, id: "
<< printer_info_cloud_.printer_id;
- // If there was a network error or a non-200 response (which, for our purposes
- // is the same as a network error), we want to retry.
- if (status.is_success() && (response_code == 200)) {
- bool succeeded = false;
- DictionaryValue* response_dict = NULL;
- CloudPrintHelpers::ParseResponseJSON(data, &succeeded, &response_dict);
- // If we get valid JSON back, we are done.
- if (NULL != response_dict) {
- ret = true;
- }
- }
- if (ret) {
- // We are done here. Go to the Stop state
- MessageLoop::current()->PostTask(
- FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop));
- } else {
- // Since we failed to update the server, set the flag again.
- printer_update_pending_ = true;
- }
- return ret;
+ // We are done here. Go to the Stop state
+ MessageLoop::current()->PostTask(
+ FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop));
+ return CloudPrintURLFetcher::STOP_PROCESSING;
}
-bool PrinterJobHandler::HandlePrinterDeleteResponse(
+CloudPrintURLFetcher::ResponseAction
+PrinterJobHandler::HandlePrinterDeleteResponse(
const URLFetcher* source,
const GURL& url,
- const URLRequestStatus& status,
- int response_code,
- const ResponseCookies& cookies,
- const std::string& data) {
- bool ret = false;
+ DictionaryValue* json_data,
+ bool succeeded) {
VLOG(1) << "CP_PROXY: Handler printer delete response, id: "
<< printer_info_cloud_.printer_id;
- // If there was a network error or a non-200 response (which, for our purposes
- // is the same as a network error), we want to retry.
- if (status.is_success() && (response_code == 200)) {
- bool succeeded = false;
- DictionaryValue* response_dict = NULL;
- CloudPrintHelpers::ParseResponseJSON(data, &succeeded, &response_dict);
- // If we get valid JSON back, we are done.
- if (NULL != response_dict) {
- ret = true;
- }
- }
- if (ret) {
- // The printer has been deleted. Shutdown the handler class.
- MessageLoop::current()->PostTask(
- FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Shutdown));
- } else {
- // Since we failed to update the server, set the flag again.
- printer_delete_pending_ = true;
- }
- return ret;
+ // The printer has been deleted. Shutdown the handler class.
+ MessageLoop::current()->PostTask(
+ FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Shutdown));
+ return CloudPrintURLFetcher::STOP_PROCESSING;
}
-bool PrinterJobHandler::HandleJobMetadataResponse(
+CloudPrintURLFetcher::ResponseAction
+PrinterJobHandler::HandleJobMetadataResponse(
const URLFetcher* source,
const GURL& url,
- const URLRequestStatus& status,
- int response_code,
- const ResponseCookies& cookies,
- const std::string& data) {
+ DictionaryValue* json_data,
+ bool succeeded) {
VLOG(1) << "CP_PROXY: Handle job metadata response, id: "
<< printer_info_cloud_.printer_id;
- // If there was a network error or a non-200 response (which, for our purposes
- // is the same as a network error), we want to retry.
- if (!status.is_success() || (response_code != 200)) {
- return false;
- }
- bool succeeded = false;
- DictionaryValue* response_dict = NULL;
- CloudPrintHelpers::ParseResponseJSON(data, &succeeded, &response_dict);
- if (NULL == response_dict) {
- // If we did not get a valid JSON response, we need to retry.
- return false;
- }
- Task* next_task = NULL;
+ bool job_available = false;
if (succeeded) {
ListValue* job_list = NULL;
- response_dict->GetList(kJobListValue, &job_list);
+ json_data->GetList(kJobListValue, &job_list);
if (job_list) {
// Even though it is a job list, for now we are only interested in the
// first job
DictionaryValue* job_data = NULL;
if (job_list->GetDictionary(0, &job_data)) {
+ job_available = true;
job_data->GetString(kIdValue, &job_details_.job_id_);
job_data->GetString(kTitleValue, &job_details_.job_title_);
std::string print_ticket_url;
job_data->GetString(kTicketUrlValue, &print_ticket_url);
job_data->GetString(kFileUrlValue, &print_data_url_);
- next_task = NewRunnableMethod(
- this, &PrinterJobHandler::MakeServerRequest,
- GURL(print_ticket_url.c_str()),
- &PrinterJobHandler::HandlePrintTicketResponse,
- &PrinterJobHandler::FailedFetchingJobData);
+ SetNextDataHandler(&PrinterJobHandler::HandlePrintTicketResponse);
+ request_ = new CloudPrintURLFetcher;
+ request_->StartGetRequest(GURL(print_ticket_url.c_str()),
+ this,
+ auth_token_,
+ kCloudPrintAPIRetryPolicy);
}
}
}
- if (!next_task) {
- // If we got a valid JSON but there were no jobs, we are done
- next_task = NewRunnableMethod(this, &PrinterJobHandler::Stop);
- }
- delete response_dict;
- DCHECK(next_task);
- MessageLoop::current()->PostTask(FROM_HERE, next_task);
- return true;
+ // If no jobs are available, go to the Stop state.
+ if (!job_available)
+ MessageLoop::current()->PostTask(
+ FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop));
+ return CloudPrintURLFetcher::STOP_PROCESSING;
}
-bool PrinterJobHandler::HandlePrintTicketResponse(
- const URLFetcher* source, const GURL& url, const URLRequestStatus& status,
- int response_code, const ResponseCookies& cookies,
- const std::string& data) {
+CloudPrintURLFetcher::ResponseAction
+PrinterJobHandler::HandlePrintTicketResponse(const URLFetcher* source,
+ const GURL& url,
+ const std::string& data) {
VLOG(1) << "CP_PROXY: Handle print ticket response, id: "
<< printer_info_cloud_.printer_id;
- // If there was a network error or a non-200 response (which, for our purposes
- // is the same as a network error), we want to retry.
- if (!status.is_success() || (response_code != 200)) {
- return false;
- }
if (print_system_->ValidatePrintTicket(printer_info_.printer_name, data)) {
job_details_.print_ticket_ = data;
- MessageLoop::current()->PostTask(
- FROM_HERE,
- NewRunnableMethod(this,
- &PrinterJobHandler::MakeServerRequest,
- GURL(print_data_url_.c_str()),
- &PrinterJobHandler::HandlePrintDataResponse,
- &PrinterJobHandler::FailedFetchingJobData));
+ SetNextDataHandler(&PrinterJobHandler::HandlePrintDataResponse);
+ request_ = new CloudPrintURLFetcher;
+ request_->StartGetRequest(GURL(print_data_url_.c_str()),
+ this,
+ auth_token_,
+ kJobDataRetryPolicy);
} else {
// The print ticket was not valid. We are done here.
FailedFetchingJobData();
}
- return true;
+ return CloudPrintURLFetcher::STOP_PROCESSING;
}
-bool PrinterJobHandler::HandlePrintDataResponse(const URLFetcher* source,
- const GURL& url,
- const URLRequestStatus& status,
- int response_code,
- const ResponseCookies& cookies,
- const std::string& data) {
+CloudPrintURLFetcher::ResponseAction
+PrinterJobHandler::HandlePrintDataResponse(const URLFetcher* source,
+ const GURL& url,
+ const std::string& data) {
VLOG(1) << "CP_PROXY: Handle print data response, id: "
<< printer_info_cloud_.printer_id;
- // If there was a network error or a non-200 response (which, for our purposes
- // is the same as a network error), we want to retry.
- if (!status.is_success() || (response_code != 200)) {
- return false;
- }
Task* next_task = NULL;
if (file_util::CreateTemporaryFile(&job_details_.print_data_file_path_)) {
int ret = file_util::WriteFile(job_details_.print_data_file_path_,
@@ -467,13 +404,54 @@ bool PrinterJobHandler::HandlePrintDataResponse(const URLFetcher* source,
JOB_DOWNLOAD_FAILED);
}
MessageLoop::current()->PostTask(FROM_HERE, next_task);
- return true;
+ return CloudPrintURLFetcher::STOP_PROCESSING;
}
+CloudPrintURLFetcher::ResponseAction
+PrinterJobHandler::HandleSuccessStatusUpdateResponse(
+ const URLFetcher* source,
+ const GURL& url,
+ DictionaryValue* json_data,
+ bool succeeded) {
+ VLOG(1) << "CP_PROXY: Handle success status update response, id: "
+ << printer_info_cloud_.printer_id;
+ // The print job has been spooled locally. We now need to create an object
+ // that monitors the status of the job and updates the server.
+ scoped_refptr<JobStatusUpdater> job_status_updater =
+ new JobStatusUpdater(printer_info_.printer_name, job_details_.job_id_,
+ local_job_id_, auth_token_, cloud_print_server_url_,
+ print_system_.get(), this);
+ job_status_updater_list_.push_back(job_status_updater);
+ MessageLoop::current()->PostTask(
+ FROM_HERE, NewRunnableMethod(job_status_updater.get(),
+ &JobStatusUpdater::UpdateStatus));
+ if (succeeded) {
+ // Since we just printed successfully, we want to look for more jobs.
+ server_job_available_ = true;
+ }
+ MessageLoop::current()->PostTask(
+ FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop));
+ return CloudPrintURLFetcher::STOP_PROCESSING;
+}
+
+CloudPrintURLFetcher::ResponseAction
+PrinterJobHandler::HandleFailureStatusUpdateResponse(
+ const URLFetcher* source,
+ const GURL& url,
+ DictionaryValue* json_data,
+ bool succeeded) {
+ VLOG(1) << "CP_PROXY: Handle failure status update response, id: "
+ << printer_info_cloud_.printer_id;
+ MessageLoop::current()->PostTask(
+ FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop));
+ return CloudPrintURLFetcher::STOP_PROCESSING;
+}
+// End Response handlers
+
void PrinterJobHandler::StartPrinting() {
VLOG(1) << "CP_PROXY: Start printing, id: " << printer_info_cloud_.printer_id;
// We are done with the request object for now.
- request_.reset();
+ request_ = NULL;
if (!shutting_down_) {
if (!print_thread_.Start()) {
JobFailed(PRINT_FAILED);
@@ -519,17 +497,6 @@ void PrinterJobHandler::Shutdown() {
}
}
-void PrinterJobHandler::HandleServerError(const GURL& url) {
- VLOG(1) << "CP_PROXY: Handle server error, printer id: "
- << printer_info_cloud_.printer_id << ", url: " << url;
- Task* task_to_retry = NewRunnableMethod(this,
- &PrinterJobHandler::FetchURL, url);
- Task* task_on_give_up = NewRunnableMethod(this, next_failure_handler_);
- CloudPrintHelpers::HandleServerError(&server_error_count_, kMaxRetryCount,
- -1, kBaseRetryInterval, task_to_retry,
- task_on_give_up);
-}
-
void PrinterJobHandler::UpdateJobStatus(cloud_print::PrintJobStatus status,
PrintJobError error) {
VLOG(1) << "CP_PROXY: Update job status, id: "
@@ -538,98 +505,33 @@ void PrinterJobHandler::UpdateJobStatus(cloud_print::PrintJobStatus status,
if (!job_details_.job_id_.empty()) {
VLOG(1) << "CP_PROXY: Updating status, job id: " << job_details_.job_id_
<< ", status: " << status;
-
- ResponseHandler response_handler = NULL;
if (error == SUCCESS) {
- response_handler =
- &PrinterJobHandler::HandleSuccessStatusUpdateResponse;
+ SetNextJSONHandler(
+ &PrinterJobHandler::HandleSuccessStatusUpdateResponse);
} else {
- response_handler =
- &PrinterJobHandler::HandleFailureStatusUpdateResponse;
+ SetNextJSONHandler(
+ &PrinterJobHandler::HandleFailureStatusUpdateResponse);
}
- MakeServerRequest(
+ request_ = new CloudPrintURLFetcher;
+ request_->StartGetRequest(
CloudPrintHelpers::GetUrlForJobStatusUpdate(cloud_print_server_url_,
job_details_.job_id_,
status),
- response_handler,
- &PrinterJobHandler::Stop);
+ this,
+ auth_token_,
+ kCloudPrintAPIRetryPolicy);
}
}
}
-bool PrinterJobHandler::HandleSuccessStatusUpdateResponse(
- const URLFetcher* source,
- const GURL& url,
- const URLRequestStatus& status,
- int response_code,
- const ResponseCookies& cookies,
- const std::string& data) {
- VLOG(1) << "CP_PROXY: Handle success status update response, id: "
- << printer_info_cloud_.printer_id;
- // If there was a network error or a non-200 response (which, for our purposes
- // is the same as a network error), we want to retry.
- if (!status.is_success() || (response_code != 200)) {
- return false;
- }
- // The print job has been spooled locally. We now need to create an object
- // that monitors the status of the job and updates the server.
- scoped_refptr<JobStatusUpdater> job_status_updater =
- new JobStatusUpdater(printer_info_.printer_name, job_details_.job_id_,
- local_job_id_, auth_token_, cloud_print_server_url_,
- print_system_.get(), this);
- job_status_updater_list_.push_back(job_status_updater);
- MessageLoop::current()->PostTask(
- FROM_HERE, NewRunnableMethod(job_status_updater.get(),
- &JobStatusUpdater::UpdateStatus));
- bool succeeded = false;
- CloudPrintHelpers::ParseResponseJSON(data, &succeeded, NULL);
- if (succeeded) {
- // Since we just printed successfully, we want to look for more jobs.
- server_job_available_ = true;
- }
- MessageLoop::current()->PostTask(
- FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop));
- return true;
-}
-
-bool PrinterJobHandler::HandleFailureStatusUpdateResponse(
- const URLFetcher* source,
- const GURL& url,
- const URLRequestStatus& status,
- int response_code,
- const ResponseCookies& cookies,
- const std::string& data) {
- VLOG(1) << "CP_PROXY: Handle failure status update response, id: "
- << printer_info_cloud_.printer_id;
- // If there was a network error or a non-200 response (which, for our purposes
- // is the same as a network error), we want to retry.
- if (!status.is_success() || (response_code != 200)) {
- return false;
- }
- MessageLoop::current()->PostTask(
- FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop));
- return true;
-}
-
-void PrinterJobHandler::MakeServerRequest(const GURL& url,
- ResponseHandler response_handler,
- FailureHandler failure_handler) {
- VLOG(1) << "CP_PROXY: Printer job handle, make server request, id: "
- << printer_info_cloud_.printer_id << ", url: " << url;
- if (!shutting_down_) {
- server_error_count_ = 0;
- // Set up the next response handler
- next_response_handler_ = response_handler;
- next_failure_handler_ = failure_handler;
- FetchURL(url);
- }
+void PrinterJobHandler::SetNextJSONHandler(JSONDataHandler handler) {
+ next_json_data_handler_ = handler;
+ next_data_handler_ = NULL;
}
-void PrinterJobHandler::FetchURL(const GURL& url) {
- VLOG(1) << "CP_PROXY: PrinterJobHandler::FetchURL, url: " << url;
- request_.reset(new URLFetcher(url, URLFetcher::GET, this));
- CloudPrintHelpers::PrepCloudPrintRequest(request_.get(), auth_token_);
- request_->Start();
+void PrinterJobHandler::SetNextDataHandler(DataHandler handler) {
+ next_data_handler_ = handler;
+ next_json_data_handler_ = NULL;
}
bool PrinterJobHandler::HavePendingTasks() {