| 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/service/cloud_print/printer_job_handler.h" | 5 #include "chrome/service/cloud_print/printer_job_handler.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| 11 #include "base/location.h" | 11 #include "base/location.h" |
| 12 #include "base/md5.h" | 12 #include "base/md5.h" |
| 13 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
| 14 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" |
| 15 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
| 16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 17 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 18 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
| 19 #include "base/values.h" | 19 #include "base/values.h" |
| 20 #include "build/build_config.h" | 20 #include "build/build_config.h" |
| 21 #include "chrome/common/cloud_print/cloud_print_constants.h" | 21 #include "chrome/common/cloud_print/cloud_print_constants.h" |
| 22 #include "chrome/common/cloud_print/cloud_print_helpers.h" | 22 #include "chrome/common/cloud_print/cloud_print_helpers.h" |
| 23 #include "chrome/grit/generated_resources.h" | 23 #include "chrome/grit/generated_resources.h" |
| 24 #include "chrome/service/cloud_print/cloud_print_service_helpers.h" | 24 #include "chrome/service/cloud_print/cloud_print_service_helpers.h" |
| 25 #include "chrome/service/cloud_print/job_status_updater.h" | 25 #include "chrome/service/cloud_print/job_status_updater.h" |
| 26 #include "net/base/mime_util.h" | 26 #include "net/base/mime_util.h" |
| 27 #include "net/http/http_response_headers.h" | 27 #include "net/http/http_response_headers.h" |
| 28 #include "net/http/http_status_code.h" | 28 #include "net/http/http_status_code.h" |
| 29 #include "net/traffic_annotation/network_traffic_annotation.h" |
| 29 #include "printing/printing_utils.h" | 30 #include "printing/printing_utils.h" |
| 30 #include "ui/base/l10n/l10n_util.h" | 31 #include "ui/base/l10n/l10n_util.h" |
| 31 #include "url/gurl.h" | 32 #include "url/gurl.h" |
| 32 | 33 |
| 33 namespace cloud_print { | 34 namespace cloud_print { |
| 34 | 35 |
| 35 namespace { | 36 namespace { |
| 36 | 37 |
| 37 base::subtle::Atomic32 g_total_jobs_started = 0; | 38 base::subtle::Atomic32 g_total_jobs_started = 0; |
| 38 base::subtle::Atomic32 g_total_jobs_done = 0; | 39 base::subtle::Atomic32 g_total_jobs_done = 0; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 49 JOB_HANDLER_SET_IN_PROGRESS, | 50 JOB_HANDLER_SET_IN_PROGRESS, |
| 50 JOB_HANDLER_SET_START_PRINTING, | 51 JOB_HANDLER_SET_START_PRINTING, |
| 51 JOB_HANDLER_START_SPOOLING, | 52 JOB_HANDLER_START_SPOOLING, |
| 52 JOB_HANDLER_SPOOLED, | 53 JOB_HANDLER_SPOOLED, |
| 53 JOB_HANDLER_JOB_COMPLETED, | 54 JOB_HANDLER_JOB_COMPLETED, |
| 54 JOB_HANDLER_INVALID_TICKET, | 55 JOB_HANDLER_INVALID_TICKET, |
| 55 JOB_HANDLER_INVALID_DATA, | 56 JOB_HANDLER_INVALID_DATA, |
| 56 JOB_HANDLER_MAX, | 57 JOB_HANDLER_MAX, |
| 57 }; | 58 }; |
| 58 | 59 |
| 60 net::PartialNetworkTrafficAnnotationTag kPartialTrafficAnnotation = |
| 61 net::DefinePartialNetworkTrafficAnnotation("printer_job_handler", |
| 62 "cloud_print", |
| 63 R"( |
| 64 semantics { |
| 65 description: |
| 66 "Handles Cloud Print jobs for a particular printer, including " |
| 67 "connecting to printer, sending jobs, updating jobs, and getting " |
| 68 "status." |
| 69 trigger: |
| 70 "Automatic checking if printer is available, registering printer, " |
| 71 "and starting or continuing a printer task." |
| 72 data: |
| 73 "Cloud Print server URL, printer id, job details." |
| 74 })"); |
| 75 |
| 59 } // namespace | 76 } // namespace |
| 60 | 77 |
| 61 PrinterJobHandler::PrinterInfoFromCloud::PrinterInfoFromCloud() | 78 PrinterJobHandler::PrinterInfoFromCloud::PrinterInfoFromCloud() |
| 62 : current_xmpp_timeout(0), pending_xmpp_timeout(0) { | 79 : current_xmpp_timeout(0), pending_xmpp_timeout(0) { |
| 63 } | 80 } |
| 64 | 81 |
| 65 PrinterJobHandler::PrinterInfoFromCloud::PrinterInfoFromCloud( | 82 PrinterJobHandler::PrinterInfoFromCloud::PrinterInfoFromCloud( |
| 66 const PrinterInfoFromCloud& other) = default; | 83 const PrinterInfoFromCloud& other) = default; |
| 67 | 84 |
| 68 PrinterJobHandler::PrinterJobHandler( | 85 PrinterJobHandler::PrinterJobHandler( |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 job_queue_handler_.GetJobsFromQueue(*json_data); | 327 job_queue_handler_.GetJobsFromQueue(*json_data); |
| 311 if (!jobs.empty()) { | 328 if (!jobs.empty()) { |
| 312 if (jobs[0].time_remaining_.is_zero()) { | 329 if (jobs[0].time_remaining_.is_zero()) { |
| 313 job_available = true; | 330 job_available = true; |
| 314 job_details_ = jobs[0]; | 331 job_details_ = jobs[0]; |
| 315 job_start_time_ = base::Time::Now(); | 332 job_start_time_ = base::Time::Now(); |
| 316 base::subtle::NoBarrier_AtomicIncrement(&g_total_jobs_started, 1); | 333 base::subtle::NoBarrier_AtomicIncrement(&g_total_jobs_started, 1); |
| 317 UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", | 334 UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", |
| 318 JOB_HANDLER_JOB_STARTED, JOB_HANDLER_MAX); | 335 JOB_HANDLER_JOB_STARTED, JOB_HANDLER_MAX); |
| 319 SetNextDataHandler(&PrinterJobHandler::HandlePrintTicketResponse); | 336 SetNextDataHandler(&PrinterJobHandler::HandlePrintTicketResponse); |
| 320 request_ = CloudPrintURLFetcher::Create(); | 337 request_ = CloudPrintURLFetcher::Create(kPartialTrafficAnnotation); |
| 321 if (print_system_->UseCddAndCjt()) { | 338 if (print_system_->UseCddAndCjt()) { |
| 322 request_->StartGetRequest( | 339 request_->StartGetRequest( |
| 323 CloudPrintURLFetcher::REQUEST_TICKET, | 340 CloudPrintURLFetcher::REQUEST_TICKET, |
| 324 GetUrlForJobCjt(cloud_print_server_url_, job_details_.job_id_, | 341 GetUrlForJobCjt(cloud_print_server_url_, job_details_.job_id_, |
| 325 job_fetch_reason_), | 342 job_fetch_reason_), |
| 326 this, kJobDataMaxRetryCount, std::string()); | 343 this, kJobDataMaxRetryCount, std::string()); |
| 327 } else { | 344 } else { |
| 328 request_->StartGetRequest( | 345 request_->StartGetRequest( |
| 329 CloudPrintURLFetcher::REQUEST_TICKET, | 346 CloudPrintURLFetcher::REQUEST_TICKET, |
| 330 GURL(job_details_.print_ticket_url_), this, kJobDataMaxRetryCount, | 347 GURL(job_details_.print_ticket_url_), this, kJobDataMaxRetryCount, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 358 << ", printer id: " << printer_info_cloud_.printer_id; | 375 << ", printer id: " << printer_info_cloud_.printer_id; |
| 359 std::string mime_type; | 376 std::string mime_type; |
| 360 source->GetResponseHeaders()->GetMimeType(&mime_type); | 377 source->GetResponseHeaders()->GetMimeType(&mime_type); |
| 361 if (print_system_->ValidatePrintTicket(printer_info_.printer_name, data, | 378 if (print_system_->ValidatePrintTicket(printer_info_.printer_name, data, |
| 362 mime_type)) { | 379 mime_type)) { |
| 363 UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", | 380 UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", |
| 364 JOB_HANDLER_VALID_TICKET, JOB_HANDLER_MAX); | 381 JOB_HANDLER_VALID_TICKET, JOB_HANDLER_MAX); |
| 365 job_details_.print_ticket_ = data; | 382 job_details_.print_ticket_ = data; |
| 366 job_details_.print_ticket_mime_type_ = mime_type; | 383 job_details_.print_ticket_mime_type_ = mime_type; |
| 367 SetNextDataHandler(&PrinterJobHandler::HandlePrintDataResponse); | 384 SetNextDataHandler(&PrinterJobHandler::HandlePrintDataResponse); |
| 368 request_ = CloudPrintURLFetcher::Create(); | 385 request_ = CloudPrintURLFetcher::Create(kPartialTrafficAnnotation); |
| 369 std::string accept_headers = "Accept: "; | 386 std::string accept_headers = "Accept: "; |
| 370 accept_headers += print_system_->GetSupportedMimeTypes(); | 387 accept_headers += print_system_->GetSupportedMimeTypes(); |
| 371 request_->StartGetRequest(CloudPrintURLFetcher::REQUEST_DATA, | 388 request_->StartGetRequest(CloudPrintURLFetcher::REQUEST_DATA, |
| 372 GURL(job_details_.print_data_url_), this, kJobDataMaxRetryCount, | 389 GURL(job_details_.print_data_url_), this, kJobDataMaxRetryCount, |
| 373 accept_headers); | 390 accept_headers); |
| 374 } else { | 391 } else { |
| 375 UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", | 392 UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", |
| 376 JOB_HANDLER_INVALID_TICKET, JOB_HANDLER_MAX); | 393 JOB_HANDLER_INVALID_TICKET, JOB_HANDLER_MAX); |
| 377 // The print ticket was not valid. We are done here. | 394 // The print ticket was not valid. We are done here. |
| 378 ValidatePrintTicketFailed(); | 395 ValidatePrintTicketFailed(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 if (!task_in_progress_ && job_check_pending_) { | 483 if (!task_in_progress_ && job_check_pending_) { |
| 467 UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", | 484 UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", |
| 468 JOB_HANDLER_JOB_CHECK, JOB_HANDLER_MAX); | 485 JOB_HANDLER_JOB_CHECK, JOB_HANDLER_MAX); |
| 469 task_in_progress_ = true; | 486 task_in_progress_ = true; |
| 470 VLOG(1) << "CP_CONNECTOR: Changed task in progress" | 487 VLOG(1) << "CP_CONNECTOR: Changed task in progress" |
| 471 ", printer id: " << printer_info_cloud_.printer_id | 488 ", printer id: " << printer_info_cloud_.printer_id |
| 472 << ", task in progress: " << task_in_progress_; | 489 << ", task in progress: " << task_in_progress_; |
| 473 job_check_pending_ = false; | 490 job_check_pending_ = false; |
| 474 // We need to fetch any pending jobs for this printer | 491 // We need to fetch any pending jobs for this printer |
| 475 SetNextJSONHandler(&PrinterJobHandler::HandleJobMetadataResponse); | 492 SetNextJSONHandler(&PrinterJobHandler::HandleJobMetadataResponse); |
| 476 request_ = CloudPrintURLFetcher::Create(); | 493 request_ = CloudPrintURLFetcher::Create(kPartialTrafficAnnotation); |
| 477 request_->StartGetRequest( | 494 request_->StartGetRequest( |
| 478 CloudPrintURLFetcher::REQUEST_JOB_FETCH, | 495 CloudPrintURLFetcher::REQUEST_JOB_FETCH, |
| 479 GetUrlForJobFetch( | 496 GetUrlForJobFetch( |
| 480 cloud_print_server_url_, printer_info_cloud_.printer_id, | 497 cloud_print_server_url_, printer_info_cloud_.printer_id, |
| 481 job_fetch_reason_), | 498 job_fetch_reason_), |
| 482 this, | 499 this, |
| 483 kCloudPrintAPIMaxRetryCount, | 500 kCloudPrintAPIMaxRetryCount, |
| 484 std::string()); | 501 std::string()); |
| 485 last_job_fetch_time_ = base::TimeTicks::Now(); | 502 last_job_fetch_time_ = base::TimeTicks::Now(); |
| 486 VLOG(1) << "CP_CONNECTOR: Last job fetch time" | 503 VLOG(1) << "CP_CONNECTOR: Last job fetch time" |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 if (error == JOB_SUCCESS) { | 575 if (error == JOB_SUCCESS) { |
| 559 DCHECK_EQ(status, PRINT_JOB_STATUS_IN_PROGRESS); | 576 DCHECK_EQ(status, PRINT_JOB_STATUS_IN_PROGRESS); |
| 560 UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", | 577 UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", |
| 561 JOB_HANDLER_SET_IN_PROGRESS, JOB_HANDLER_MAX); | 578 JOB_HANDLER_SET_IN_PROGRESS, JOB_HANDLER_MAX); |
| 562 SetNextJSONHandler( | 579 SetNextJSONHandler( |
| 563 &PrinterJobHandler::HandleInProgressStatusUpdateResponse); | 580 &PrinterJobHandler::HandleInProgressStatusUpdateResponse); |
| 564 } else { | 581 } else { |
| 565 SetNextJSONHandler( | 582 SetNextJSONHandler( |
| 566 &PrinterJobHandler::HandleFailureStatusUpdateResponse); | 583 &PrinterJobHandler::HandleFailureStatusUpdateResponse); |
| 567 } | 584 } |
| 568 request_ = CloudPrintURLFetcher::Create(); | 585 request_ = CloudPrintURLFetcher::Create(kPartialTrafficAnnotation); |
| 569 request_->StartGetRequest( | 586 request_->StartGetRequest( |
| 570 CloudPrintURLFetcher::REQUEST_UPDATE_JOB, | 587 CloudPrintURLFetcher::REQUEST_UPDATE_JOB, |
| 571 GetUrlForJobStatusUpdate(cloud_print_server_url_, job_details_.job_id_, | 588 GetUrlForJobStatusUpdate(cloud_print_server_url_, job_details_.job_id_, |
| 572 status, error), | 589 status, error), |
| 573 this, kCloudPrintAPIMaxRetryCount, std::string()); | 590 this, kCloudPrintAPIMaxRetryCount, std::string()); |
| 574 } | 591 } |
| 575 | 592 |
| 576 void PrinterJobHandler::RunScheduledJobCheck() { | 593 void PrinterJobHandler::RunScheduledJobCheck() { |
| 577 CheckForJobs(kJobFetchReasonRetry); | 594 CheckForJobs(kJobFetchReasonRetry); |
| 578 } | 595 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 609 UMA_HISTOGRAM_LONG_TIMES("CloudPrint.SpoolingTime", | 626 UMA_HISTOGRAM_LONG_TIMES("CloudPrint.SpoolingTime", |
| 610 base::Time::Now() - spooling_start_time_); | 627 base::Time::Now() - spooling_start_time_); |
| 611 if (shutting_down_) | 628 if (shutting_down_) |
| 612 return; | 629 return; |
| 613 | 630 |
| 614 local_job_id_ = local_job_id; | 631 local_job_id_ = local_job_id; |
| 615 print_thread_.Stop(); | 632 print_thread_.Stop(); |
| 616 | 633 |
| 617 // The print job has been spooled locally. We now need to create an object | 634 // The print job has been spooled locally. We now need to create an object |
| 618 // that monitors the status of the job and updates the server. | 635 // that monitors the status of the job and updates the server. |
| 619 scoped_refptr<JobStatusUpdater> job_status_updater( | 636 scoped_refptr<JobStatusUpdater> job_status_updater(new JobStatusUpdater( |
| 620 new JobStatusUpdater(printer_info_.printer_name, job_details_.job_id_, | 637 printer_info_.printer_name, job_details_.job_id_, local_job_id_, |
| 621 local_job_id_, cloud_print_server_url_, | 638 cloud_print_server_url_, print_system_.get(), this, |
| 622 print_system_.get(), this)); | 639 kPartialTrafficAnnotation)); |
| 623 job_status_updater_list_.push_back(job_status_updater); | 640 job_status_updater_list_.push_back(job_status_updater); |
| 624 base::ThreadTaskRunnerHandle::Get()->PostTask( | 641 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 625 FROM_HERE, | 642 FROM_HERE, |
| 626 base::Bind(&JobStatusUpdater::UpdateStatus, job_status_updater)); | 643 base::Bind(&JobStatusUpdater::UpdateStatus, job_status_updater)); |
| 627 | 644 |
| 628 CheckForJobs(kJobFetchReasonQueryMore); | 645 CheckForJobs(kJobFetchReasonQueryMore); |
| 629 | 646 |
| 630 VLOG(1) << "CP_CONNECTOR: Stopping printer job handler" | 647 VLOG(1) << "CP_CONNECTOR: Stopping printer job handler" |
| 631 << ", printer id: " << printer_info_cloud_.printer_id; | 648 << ", printer id: " << printer_info_cloud_.printer_id; |
| 632 base::ThreadTaskRunnerHandle::Get()->PostTask( | 649 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 printer_info_cloud_.current_xmpp_timeout), | 762 printer_info_cloud_.current_xmpp_timeout), |
| 746 mime_boundary, std::string(), &post_data); | 763 mime_boundary, std::string(), &post_data); |
| 747 } | 764 } |
| 748 | 765 |
| 749 printer_info_ = printer_info; | 766 printer_info_ = printer_info; |
| 750 if (!post_data.empty()) { | 767 if (!post_data.empty()) { |
| 751 net::AddMultipartFinalDelimiterForUpload(mime_boundary, &post_data); | 768 net::AddMultipartFinalDelimiterForUpload(mime_boundary, &post_data); |
| 752 std::string mime_type("multipart/form-data; boundary="); | 769 std::string mime_type("multipart/form-data; boundary="); |
| 753 mime_type += mime_boundary; | 770 mime_type += mime_boundary; |
| 754 SetNextJSONHandler(&PrinterJobHandler::HandlePrinterUpdateResponse); | 771 SetNextJSONHandler(&PrinterJobHandler::HandlePrinterUpdateResponse); |
| 755 request_ = CloudPrintURLFetcher::Create(); | 772 request_ = CloudPrintURLFetcher::Create(kPartialTrafficAnnotation); |
| 756 request_->StartPostRequest( | 773 request_->StartPostRequest( |
| 757 CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER, | 774 CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER, |
| 758 GetUrlForPrinterUpdate( | 775 GetUrlForPrinterUpdate( |
| 759 cloud_print_server_url_, printer_info_cloud_.printer_id), | 776 cloud_print_server_url_, printer_info_cloud_.printer_id), |
| 760 this, | 777 this, |
| 761 kCloudPrintAPIMaxRetryCount, | 778 kCloudPrintAPIMaxRetryCount, |
| 762 mime_type, | 779 mime_type, |
| 763 post_data, | 780 post_data, |
| 764 std::string()); | 781 std::string()); |
| 765 } else { | 782 } else { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 this)) { | 817 this)) { |
| 801 OnJobSpoolFailed(); | 818 OnJobSpoolFailed(); |
| 802 } | 819 } |
| 803 } | 820 } |
| 804 | 821 |
| 805 bool PrinterJobHandler::CurrentlyOnPrintThread() const { | 822 bool PrinterJobHandler::CurrentlyOnPrintThread() const { |
| 806 return print_thread_.task_runner()->BelongsToCurrentThread(); | 823 return print_thread_.task_runner()->BelongsToCurrentThread(); |
| 807 } | 824 } |
| 808 | 825 |
| 809 } // namespace cloud_print | 826 } // namespace cloud_print |
| OLD | NEW |