Index: chrome/service/cloud_print/printer_job_handler.cc |
diff --git a/chrome/service/cloud_print/printer_job_handler.cc b/chrome/service/cloud_print/printer_job_handler.cc |
index d7f562dacbe24a9d0e7b0affd4317f507ecaa642..b071de427563ef51b3b7b0df27921aefeaac4428 100644 |
--- a/chrome/service/cloud_print/printer_job_handler.cc |
+++ b/chrome/service/cloud_print/printer_job_handler.cc |
@@ -69,73 +69,10 @@ bool PrinterJobHandler::Initialize() { |
return true; |
} |
-PrinterJobHandler::~PrinterJobHandler() { |
- if (printer_watcher_) |
- printer_watcher_->StopWatching(); |
-} |
- |
-void PrinterJobHandler::Reset() { |
- print_data_url_.clear(); |
- job_details_.Clear(); |
- request_ = NULL; |
- print_thread_.Stop(); |
-} |
- |
std::string PrinterJobHandler::GetPrinterName() const { |
return printer_info_.printer_name; |
} |
-void PrinterJobHandler::Start() { |
- VLOG(1) << "CP_CONNECTOR: Start printer job handler, id: " |
- << printer_info_cloud_.printer_id |
- << ", task in progress: " << task_in_progress_; |
- if (task_in_progress_) { |
- // Multiple Starts can get posted because of multiple notifications |
- // We want to ignore the other ones that happen when a task is in progress. |
- return; |
- } |
- Reset(); |
- if (!shutting_down_) { |
- // Check if we have work to do. |
- if (HavePendingTasks()) { |
- if (!task_in_progress_ && printer_update_pending_) { |
- printer_update_pending_ = false; |
- task_in_progress_ = UpdatePrinterInfo(); |
- } |
- if (!task_in_progress_ && job_check_pending_) { |
- task_in_progress_ = true; |
- job_check_pending_ = false; |
- // We need to fetch any pending jobs for this printer |
- SetNextJSONHandler(&PrinterJobHandler::HandleJobMetadataResponse); |
- request_ = new CloudPrintURLFetcher; |
- request_->StartGetRequest( |
- CloudPrintHelpers::GetUrlForJobFetch( |
- cloud_print_server_url_, printer_info_cloud_.printer_id, |
- job_fetch_reason_), |
- this, |
- kCloudPrintAPIMaxRetryCount, |
- std::string()); |
- last_job_fetch_time_ = base::TimeTicks::Now(); |
- VLOG(1) << "Last job fetch time for printer " |
- << printer_info_.printer_name.c_str() << " is " |
- << last_job_fetch_time_.ToInternalValue(); |
- job_fetch_reason_.clear(); |
- } |
- } |
- } |
-} |
- |
-void PrinterJobHandler::Stop() { |
- VLOG(1) << "CP_CONNECTOR: Stop printer job handler, id: " |
- << printer_info_cloud_.printer_id; |
- task_in_progress_ = false; |
- Reset(); |
- if (HavePendingTasks()) { |
- MessageLoop::current()->PostTask( |
- FROM_HERE, base::Bind(&PrinterJobHandler::Start, this)); |
- } |
-} |
- |
void PrinterJobHandler::CheckForJobs(const std::string& reason) { |
VLOG(1) << "CP_CONNECTOR: CheckForJobs, id: " |
<< printer_info_cloud_.printer_id |
@@ -149,114 +86,15 @@ void PrinterJobHandler::CheckForJobs(const std::string& reason) { |
} |
} |
-bool PrinterJobHandler::UpdatePrinterInfo() { |
- if (!printer_watcher_) { |
- LOG(ERROR) << "CP_CONNECTOR: Printer watcher is missing." |
- << "Check printer server url for printer id: " |
- << printer_info_cloud_.printer_id; |
- return false; |
- } |
- |
- VLOG(1) << "CP_CONNECTOR: Update printer info, id: " |
+void PrinterJobHandler::Shutdown() { |
+ VLOG(1) << "CP_CONNECTOR: Printer job handler shutdown, id: " |
<< printer_info_cloud_.printer_id; |
- // We need to update the parts of the printer info that have changed |
- // (could be printer name, description, status or capabilities). |
- // First asynchronously fetch the capabilities. |
- printing::PrinterBasicInfo printer_info; |
- printer_watcher_->GetCurrentPrinterInfo(&printer_info); |
- |
- // Asynchronously fetch the printer caps and defaults. The story will |
- // continue in OnReceivePrinterCaps. |
- print_system_->GetPrinterCapsAndDefaults( |
- printer_info.printer_name.c_str(), |
- base::Bind(&PrinterJobHandler::OnReceivePrinterCaps, |
- weak_ptr_factory_.GetWeakPtr())); |
- |
- // While we are waiting for the data, pretend we have work to do and return |
- // true. |
- return true; |
-} |
- |
-void PrinterJobHandler::OnReceivePrinterCaps( |
- bool succeeded, |
- const std::string& printer_name, |
- const printing::PrinterCapsAndDefaults& caps_and_defaults) { |
- printing::PrinterBasicInfo printer_info; |
- if (printer_watcher_) |
- printer_watcher_->GetCurrentPrinterInfo(&printer_info); |
- |
- std::string post_data; |
- std::string mime_boundary; |
- cloud_print::CreateMimeBoundaryForUpload(&mime_boundary); |
- |
- if (succeeded) { |
- std::string caps_hash = |
- base::MD5String(caps_and_defaults.printer_capabilities); |
- if (caps_hash != printer_info_cloud_.caps_hash) { |
- // Hashes don't match, we need to upload new capabilities (the defaults |
- // go for free along with the capabilities) |
- printer_info_cloud_.caps_hash = caps_hash; |
- cloud_print::AddMultipartValueForUpload(kPrinterCapsValue, |
- caps_and_defaults.printer_capabilities, mime_boundary, |
- caps_and_defaults.caps_mime_type, &post_data); |
- cloud_print::AddMultipartValueForUpload(kPrinterDefaultsValue, |
- caps_and_defaults.printer_defaults, mime_boundary, |
- caps_and_defaults.defaults_mime_type, &post_data); |
- cloud_print::AddMultipartValueForUpload(kPrinterCapsHashValue, |
- caps_hash, mime_boundary, std::string(), &post_data); |
- } |
- } else { |
- LOG(ERROR) << "Failed to get printer caps and defaults for printer: " |
- << printer_name; |
- } |
- |
- std::string tags_hash = |
- CloudPrintHelpers::GenerateHashOfStringMap(printer_info.options); |
- if (tags_hash != printer_info_cloud_.tags_hash) { |
- printer_info_cloud_.tags_hash = tags_hash; |
- CloudPrintHelpers::GenerateMultipartPostDataForPrinterTags( |
- printer_info.options, mime_boundary, &post_data); |
- // Remove all the exising proxy tags. |
- std::string cp_tag_wildcard(kProxyTagPrefix); |
- cp_tag_wildcard += ".*"; |
- cloud_print::AddMultipartValueForUpload(kPrinterRemoveTagValue, |
- cp_tag_wildcard, mime_boundary, std::string(), &post_data); |
- } |
- |
- if (printer_info.printer_name != printer_info_.printer_name) { |
- cloud_print::AddMultipartValueForUpload(kPrinterNameValue, |
- printer_info.printer_name, mime_boundary, std::string(), &post_data); |
- } |
- if (printer_info.printer_description != printer_info_.printer_description) { |
- cloud_print::AddMultipartValueForUpload(kPrinterDescValue, |
- printer_info.printer_description, mime_boundary, |
- std::string(), &post_data); |
- } |
- if (printer_info.printer_status != printer_info_.printer_status) { |
- cloud_print::AddMultipartValueForUpload(kPrinterStatusValue, |
- base::StringPrintf("%d", printer_info.printer_status), mime_boundary, |
- std::string(), &post_data); |
- } |
- printer_info_ = printer_info; |
- if (!post_data.empty()) { |
- // Terminate the request body |
- post_data.append("--" + mime_boundary + "--\r\n"); |
- std::string mime_type("multipart/form-data; boundary="); |
- mime_type += mime_boundary; |
- SetNextJSONHandler(&PrinterJobHandler::HandlePrinterUpdateResponse); |
- request_ = new CloudPrintURLFetcher; |
- request_->StartPostRequest( |
- CloudPrintHelpers::GetUrlForPrinterUpdate( |
- cloud_print_server_url_, printer_info_cloud_.printer_id), |
- this, |
- kCloudPrintAPIMaxRetryCount, |
- mime_type, |
- post_data, |
- std::string()); |
- } else { |
- // We are done here. Go to the Stop state |
- MessageLoop::current()->PostTask( |
- FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this)); |
+ Reset(); |
+ shutting_down_ = true; |
+ while (!job_status_updater_list_.empty()) { |
+ // Calling Stop() will cause the OnJobCompleted to be called which will |
+ // remove the updater object from the list. |
+ job_status_updater_list_.front()->Stop(); |
} |
} |
@@ -363,6 +201,26 @@ void PrinterJobHandler::OnJobChanged() { |
} |
} |
+void PrinterJobHandler::OnJobSpoolSucceeded( |
+ const cloud_print::PlatformJobId& job_id) { |
+ DCHECK(MessageLoop::current() == print_thread_.message_loop()); |
+ job_spooler_ = NULL; |
+ job_handler_message_loop_proxy_->PostTask( |
+ FROM_HERE, base::Bind(&PrinterJobHandler::JobSpooled, this, job_id)); |
+} |
+ |
+void PrinterJobHandler::OnJobSpoolFailed() { |
+ DCHECK(MessageLoop::current() == print_thread_.message_loop()); |
+ job_spooler_ = NULL; |
+ job_handler_message_loop_proxy_->PostTask( |
+ FROM_HERE, base::Bind(&PrinterJobHandler::JobFailed, this, PRINT_FAILED)); |
+} |
+ |
+PrinterJobHandler::~PrinterJobHandler() { |
+ if (printer_watcher_) |
+ printer_watcher_->StopWatching(); |
+} |
+ |
// Begin Response handlers |
CloudPrintURLFetcher::ResponseAction |
PrinterJobHandler::HandlePrinterUpdateResponse( |
@@ -517,7 +375,57 @@ PrinterJobHandler::HandleFailureStatusUpdateResponse( |
FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this)); |
return CloudPrintURLFetcher::STOP_PROCESSING; |
} |
-// End Response handlers |
+ |
+void PrinterJobHandler::Start() { |
+ VLOG(1) << "CP_CONNECTOR: Start printer job handler, id: " |
+ << printer_info_cloud_.printer_id |
+ << ", task in progress: " << task_in_progress_; |
+ if (task_in_progress_) { |
+ // Multiple Starts can get posted because of multiple notifications |
+ // We want to ignore the other ones that happen when a task is in progress. |
+ return; |
+ } |
+ Reset(); |
+ if (!shutting_down_) { |
+ // Check if we have work to do. |
+ if (HavePendingTasks()) { |
+ if (!task_in_progress_ && printer_update_pending_) { |
+ printer_update_pending_ = false; |
+ task_in_progress_ = UpdatePrinterInfo(); |
+ } |
+ if (!task_in_progress_ && job_check_pending_) { |
+ task_in_progress_ = true; |
+ job_check_pending_ = false; |
+ // We need to fetch any pending jobs for this printer |
+ SetNextJSONHandler(&PrinterJobHandler::HandleJobMetadataResponse); |
+ request_ = new CloudPrintURLFetcher; |
+ request_->StartGetRequest( |
+ CloudPrintHelpers::GetUrlForJobFetch( |
+ cloud_print_server_url_, printer_info_cloud_.printer_id, |
+ job_fetch_reason_), |
+ this, |
+ kCloudPrintAPIMaxRetryCount, |
+ std::string()); |
+ last_job_fetch_time_ = base::TimeTicks::Now(); |
+ VLOG(1) << "Last job fetch time for printer " |
+ << printer_info_.printer_name.c_str() << " is " |
+ << last_job_fetch_time_.ToInternalValue(); |
+ job_fetch_reason_.clear(); |
+ } |
+ } |
+ } |
+} |
+ |
+void PrinterJobHandler::Stop() { |
+ VLOG(1) << "CP_CONNECTOR: Stop printer job handler, id: " |
+ << printer_info_cloud_.printer_id; |
+ task_in_progress_ = false; |
+ Reset(); |
+ if (HavePendingTasks()) { |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, base::Bind(&PrinterJobHandler::Start, this)); |
+ } |
+} |
void PrinterJobHandler::StartPrinting() { |
VLOG(1) << "CP_CONNECTOR: Start printing, id: " |
@@ -535,33 +443,11 @@ void PrinterJobHandler::StartPrinting() { |
} |
} |
-void PrinterJobHandler::JobFailed(PrintJobError error) { |
- VLOG(1) << "CP_CONNECTOR: Job failed, id: " << printer_info_cloud_.printer_id; |
- if (!shutting_down_) { |
- UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_ERROR, error); |
- } |
-} |
- |
-void PrinterJobHandler::JobSpooled(cloud_print::PlatformJobId local_job_id) { |
- VLOG(1) << "CP_CONNECTOR: Job spooled, printer id: " |
- << printer_info_cloud_.printer_id << ", job id: " << local_job_id; |
- if (!shutting_down_) { |
- local_job_id_ = local_job_id; |
- UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_IN_PROGRESS, SUCCESS); |
- print_thread_.Stop(); |
- } |
-} |
- |
-void PrinterJobHandler::Shutdown() { |
- VLOG(1) << "CP_CONNECTOR: Printer job handler shutdown, id: " |
- << printer_info_cloud_.printer_id; |
- Reset(); |
- shutting_down_ = true; |
- while (!job_status_updater_list_.empty()) { |
- // Calling Stop() will cause the OnJobCompleted to be called which will |
- // remove the updater object from the list. |
- job_status_updater_list_.front()->Stop(); |
- } |
+void PrinterJobHandler::Reset() { |
+ print_data_url_.clear(); |
+ job_details_.Clear(); |
+ request_ = NULL; |
+ print_thread_.Stop(); |
} |
void PrinterJobHandler::UpdateJobStatus(cloud_print::PrintJobStatus status, |
@@ -601,6 +487,51 @@ void PrinterJobHandler::SetNextDataHandler(DataHandler handler) { |
next_json_data_handler_ = NULL; |
} |
+void PrinterJobHandler::JobFailed(PrintJobError error) { |
+ VLOG(1) << "CP_CONNECTOR: Job failed, id: " << printer_info_cloud_.printer_id; |
+ if (!shutting_down_) { |
+ UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_ERROR, error); |
+ } |
+} |
+ |
+void PrinterJobHandler::JobSpooled(cloud_print::PlatformJobId local_job_id) { |
+ VLOG(1) << "CP_CONNECTOR: Job spooled, printer id: " |
+ << printer_info_cloud_.printer_id << ", job id: " << local_job_id; |
+ if (!shutting_down_) { |
+ local_job_id_ = local_job_id; |
+ UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_IN_PROGRESS, SUCCESS); |
+ print_thread_.Stop(); |
+ } |
+} |
+ |
+bool PrinterJobHandler::UpdatePrinterInfo() { |
+ if (!printer_watcher_) { |
+ LOG(ERROR) << "CP_CONNECTOR: Printer watcher is missing." |
+ << "Check printer server url for printer id: " |
+ << printer_info_cloud_.printer_id; |
+ return false; |
+ } |
+ |
+ VLOG(1) << "CP_CONNECTOR: Update printer info, id: " |
+ << printer_info_cloud_.printer_id; |
+ // We need to update the parts of the printer info that have changed |
+ // (could be printer name, description, status or capabilities). |
+ // First asynchronously fetch the capabilities. |
+ printing::PrinterBasicInfo printer_info; |
+ printer_watcher_->GetCurrentPrinterInfo(&printer_info); |
+ |
+ // Asynchronously fetch the printer caps and defaults. The story will |
+ // continue in OnReceivePrinterCaps. |
+ print_system_->GetPrinterCapsAndDefaults( |
+ printer_info.printer_name.c_str(), |
+ base::Bind(&PrinterJobHandler::OnReceivePrinterCaps, |
+ weak_ptr_factory_.GetWeakPtr())); |
+ |
+ // While we are waiting for the data, pretend we have work to do and return |
+ // true. |
+ return true; |
+} |
+ |
bool PrinterJobHandler::HavePendingTasks() { |
return (job_check_pending_ || printer_update_pending_); |
} |
@@ -613,6 +544,89 @@ void PrinterJobHandler::FailedFetchingJobData() { |
} |
} |
+void PrinterJobHandler::OnReceivePrinterCaps( |
+ bool succeeded, |
+ const std::string& printer_name, |
+ const printing::PrinterCapsAndDefaults& caps_and_defaults) { |
+ printing::PrinterBasicInfo printer_info; |
+ if (printer_watcher_) |
+ printer_watcher_->GetCurrentPrinterInfo(&printer_info); |
+ |
+ std::string post_data; |
+ std::string mime_boundary; |
+ cloud_print::CreateMimeBoundaryForUpload(&mime_boundary); |
+ |
+ if (succeeded) { |
+ std::string caps_hash = |
+ base::MD5String(caps_and_defaults.printer_capabilities); |
+ if (caps_hash != printer_info_cloud_.caps_hash) { |
+ // Hashes don't match, we need to upload new capabilities (the defaults |
+ // go for free along with the capabilities) |
+ printer_info_cloud_.caps_hash = caps_hash; |
+ cloud_print::AddMultipartValueForUpload(kPrinterCapsValue, |
+ caps_and_defaults.printer_capabilities, mime_boundary, |
+ caps_and_defaults.caps_mime_type, &post_data); |
+ cloud_print::AddMultipartValueForUpload(kPrinterDefaultsValue, |
+ caps_and_defaults.printer_defaults, mime_boundary, |
+ caps_and_defaults.defaults_mime_type, &post_data); |
+ cloud_print::AddMultipartValueForUpload(kPrinterCapsHashValue, |
+ caps_hash, mime_boundary, std::string(), &post_data); |
+ } |
+ } else { |
+ LOG(ERROR) << "Failed to get printer caps and defaults for printer: " |
+ << printer_name; |
+ } |
+ |
+ std::string tags_hash = |
+ CloudPrintHelpers::GenerateHashOfStringMap(printer_info.options); |
+ if (tags_hash != printer_info_cloud_.tags_hash) { |
+ printer_info_cloud_.tags_hash = tags_hash; |
+ CloudPrintHelpers::GenerateMultipartPostDataForPrinterTags( |
+ printer_info.options, mime_boundary, &post_data); |
+ // Remove all the exising proxy tags. |
+ std::string cp_tag_wildcard(kProxyTagPrefix); |
+ cp_tag_wildcard += ".*"; |
+ cloud_print::AddMultipartValueForUpload(kPrinterRemoveTagValue, |
+ cp_tag_wildcard, mime_boundary, std::string(), &post_data); |
+ } |
+ |
+ if (printer_info.printer_name != printer_info_.printer_name) { |
+ cloud_print::AddMultipartValueForUpload(kPrinterNameValue, |
+ printer_info.printer_name, mime_boundary, std::string(), &post_data); |
+ } |
+ if (printer_info.printer_description != printer_info_.printer_description) { |
+ cloud_print::AddMultipartValueForUpload(kPrinterDescValue, |
+ printer_info.printer_description, mime_boundary, |
+ std::string(), &post_data); |
+ } |
+ if (printer_info.printer_status != printer_info_.printer_status) { |
+ cloud_print::AddMultipartValueForUpload(kPrinterStatusValue, |
+ base::StringPrintf("%d", printer_info.printer_status), mime_boundary, |
+ std::string(), &post_data); |
+ } |
+ printer_info_ = printer_info; |
+ if (!post_data.empty()) { |
+ // Terminate the request body |
+ post_data.append("--" + mime_boundary + "--\r\n"); |
+ std::string mime_type("multipart/form-data; boundary="); |
+ mime_type += mime_boundary; |
+ SetNextJSONHandler(&PrinterJobHandler::HandlePrinterUpdateResponse); |
+ request_ = new CloudPrintURLFetcher; |
+ request_->StartPostRequest( |
+ CloudPrintHelpers::GetUrlForPrinterUpdate( |
+ cloud_print_server_url_, printer_info_cloud_.printer_id), |
+ this, |
+ kCloudPrintAPIMaxRetryCount, |
+ mime_type, |
+ post_data, |
+ std::string()); |
+ } else { |
+ // We are done here. Go to the Stop state |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this)); |
+ } |
+} |
+ |
// The following methods are called on |print_thread_|. It is not safe to |
// access any members other than |job_handler_message_loop_proxy_|, |
// |job_spooler_| and |print_system_|. |
@@ -630,18 +644,3 @@ void PrinterJobHandler::DoPrint(const JobDetails& job_details, |
OnJobSpoolFailed(); |
} |
} |
- |
-void PrinterJobHandler::OnJobSpoolSucceeded( |
- const cloud_print::PlatformJobId& job_id) { |
- DCHECK(MessageLoop::current() == print_thread_.message_loop()); |
- job_spooler_ = NULL; |
- job_handler_message_loop_proxy_->PostTask( |
- FROM_HERE, base::Bind(&PrinterJobHandler::JobSpooled, this, job_id)); |
-} |
- |
-void PrinterJobHandler::OnJobSpoolFailed() { |
- DCHECK(MessageLoop::current() == print_thread_.message_loop()); |
- job_spooler_ = NULL; |
- job_handler_message_loop_proxy_->PostTask( |
- FROM_HERE, base::Bind(&PrinterJobHandler::JobFailed, this, PRINT_FAILED)); |
-} |