| 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));
|
| -}
|
|
|