OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
9 #include "base/md5.h" | 9 #include "base/md5.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
12 #include "base/values.h" | 12 #include "base/values.h" |
13 #include "chrome/service/cloud_print/cloud_print_consts.h" | 13 #include "chrome/service/cloud_print/cloud_print_consts.h" |
14 #include "chrome/service/cloud_print/cloud_print_helpers.h" | 14 #include "chrome/service/cloud_print/cloud_print_helpers.h" |
15 #include "chrome/service/cloud_print/job_status_updater.h" | 15 #include "chrome/service/cloud_print/job_status_updater.h" |
16 #include "googleurl/src/gurl.h" | 16 #include "googleurl/src/gurl.h" |
17 #include "net/http/http_response_headers.h" | 17 #include "net/http/http_response_headers.h" |
18 | 18 |
19 PrinterJobHandler::PrinterJobHandler( | 19 PrinterJobHandler::PrinterJobHandler( |
20 const cloud_print::PrinterBasicInfo& printer_info, | 20 const cloud_print::PrinterBasicInfo& printer_info, |
21 const std::string& printer_id, | 21 const std::string& printer_id, |
22 const std::string& caps_hash, | 22 const std::string& caps_hash, |
23 const std::string& auth_token, | 23 const std::string& auth_token, |
24 const GURL& cloud_print_server_url, | 24 const GURL& cloud_print_server_url, |
| 25 cloud_print::PrintSystem* print_system, |
25 Delegate* delegate) | 26 Delegate* delegate) |
26 : printer_info_(printer_info), | 27 : print_system_(print_system), |
| 28 printer_info_(printer_info), |
27 printer_id_(printer_id), | 29 printer_id_(printer_id), |
28 auth_token_(auth_token), | 30 auth_token_(auth_token), |
29 last_caps_hash_(caps_hash), | 31 last_caps_hash_(caps_hash), |
30 cloud_print_server_url_(cloud_print_server_url), | 32 cloud_print_server_url_(cloud_print_server_url), |
31 delegate_(delegate), | 33 delegate_(delegate), |
32 local_job_id_(-1), | 34 local_job_id_(-1), |
33 next_response_handler_(NULL), | 35 next_response_handler_(NULL), |
34 server_error_count_(0), | 36 server_error_count_(0), |
35 print_thread_("Chrome_CloudPrintJobPrintThread"), | 37 print_thread_("Chrome_CloudPrintJobPrintThread"), |
36 shutting_down_(false), | 38 shutting_down_(false), |
37 server_job_available_(false), | 39 server_job_available_(false), |
38 printer_update_pending_(true), | 40 printer_update_pending_(true), |
39 printer_delete_pending_(false), | 41 printer_delete_pending_(false), |
40 task_in_progress_(false) { | 42 task_in_progress_(false) { |
41 } | 43 } |
42 | 44 |
43 bool PrinterJobHandler::Initialize() { | 45 bool PrinterJobHandler::Initialize() { |
44 if (cloud_print::IsValidPrinter(printer_info_.printer_name)) { | 46 if (print_system_->IsValidPrinter(printer_info_.printer_name)) { |
45 printer_change_notifier_.StartWatching(printer_info_.printer_name, this); | 47 printer_watcher_ = print_system_->CreatePrinterWatcher( |
| 48 printer_info_.printer_name); |
| 49 printer_watcher_->StartWatching(this); |
46 NotifyJobAvailable(); | 50 NotifyJobAvailable(); |
47 } else { | 51 } else { |
48 // This printer does not exist any more. Delete it from the server. | 52 // This printer does not exist any more. Delete it from the server. |
49 OnPrinterDeleted(); | 53 OnPrinterDeleted(); |
50 } | 54 } |
51 return true; | 55 return true; |
52 } | 56 } |
53 | 57 |
54 PrinterJobHandler::~PrinterJobHandler() { | 58 PrinterJobHandler::~PrinterJobHandler() { |
55 printer_change_notifier_.StopWatching(); | 59 printer_watcher_->StopWatching(); |
56 } | 60 } |
57 | 61 |
58 void PrinterJobHandler::Reset() { | 62 void PrinterJobHandler::Reset() { |
59 print_data_url_.clear(); | 63 print_data_url_.clear(); |
60 job_details_.Clear(); | 64 job_details_.Clear(); |
61 request_.reset(); | 65 request_.reset(); |
62 print_thread_.Stop(); | 66 print_thread_.Stop(); |
63 } | 67 } |
64 | 68 |
65 void PrinterJobHandler::Start() { | 69 void PrinterJobHandler::Start() { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 if (!task_in_progress_) { | 115 if (!task_in_progress_) { |
112 MessageLoop::current()->PostTask( | 116 MessageLoop::current()->PostTask( |
113 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); | 117 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); |
114 } | 118 } |
115 } | 119 } |
116 | 120 |
117 bool PrinterJobHandler::UpdatePrinterInfo() { | 121 bool PrinterJobHandler::UpdatePrinterInfo() { |
118 // We need to update the parts of the printer info that have changed | 122 // We need to update the parts of the printer info that have changed |
119 // (could be printer name, description, status or capabilities). | 123 // (could be printer name, description, status or capabilities). |
120 cloud_print::PrinterBasicInfo printer_info; | 124 cloud_print::PrinterBasicInfo printer_info; |
121 printer_change_notifier_.GetCurrentPrinterInfo(&printer_info); | 125 printer_watcher_->GetCurrentPrinterInfo(&printer_info); |
122 cloud_print::PrinterCapsAndDefaults printer_caps; | 126 cloud_print::PrinterCapsAndDefaults printer_caps; |
123 std::string post_data; | 127 std::string post_data; |
124 std::string mime_boundary; | 128 std::string mime_boundary; |
125 if (cloud_print::GetPrinterCapsAndDefaults(printer_info.printer_name, | 129 if (print_system_->GetPrinterCapsAndDefaults(printer_info.printer_name, |
126 &printer_caps)) { | 130 &printer_caps)) { |
127 std::string caps_hash = MD5String(printer_caps.printer_capabilities); | 131 std::string caps_hash = MD5String(printer_caps.printer_capabilities); |
128 CloudPrintHelpers::CreateMimeBoundaryForUpload(&mime_boundary); | 132 CloudPrintHelpers::CreateMimeBoundaryForUpload(&mime_boundary); |
129 if (caps_hash != last_caps_hash_) { | 133 if (caps_hash != last_caps_hash_) { |
130 // Hashes don't match, we need to upload new capabilities (the defaults | 134 // Hashes don't match, we need to upload new capabilities (the defaults |
131 // go for free along with the capabilities) | 135 // go for free along with the capabilities) |
132 last_caps_hash_ = caps_hash; | 136 last_caps_hash_ = caps_hash; |
133 CloudPrintHelpers::AddMultipartValueForUpload( | 137 CloudPrintHelpers::AddMultipartValueForUpload( |
134 kPrinterCapsValue, printer_caps.printer_capabilities, | 138 kPrinterCapsValue, printer_caps.printer_capabilities, |
135 mime_boundary, printer_caps.caps_mime_type, &post_data); | 139 mime_boundary, printer_caps.caps_mime_type, &post_data); |
136 CloudPrintHelpers::AddMultipartValueForUpload( | 140 CloudPrintHelpers::AddMultipartValueForUpload( |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 index != job_status_updater_list_.end(); index++) { | 210 index != job_status_updater_list_.end(); index++) { |
207 if (index->get() == updater) { | 211 if (index->get() == updater) { |
208 job_status_updater_list_.erase(index); | 212 job_status_updater_list_.erase(index); |
209 ret = true; | 213 ret = true; |
210 break; | 214 break; |
211 } | 215 } |
212 } | 216 } |
213 return ret; | 217 return ret; |
214 } | 218 } |
215 | 219 |
216 // cloud_print::PrinterChangeNotifier::Delegate implementation | |
217 void PrinterJobHandler::OnPrinterAdded() { | |
218 // Should never get this notification for a printer | |
219 NOTREACHED(); | |
220 } | |
221 | |
222 void PrinterJobHandler::OnPrinterDeleted() { | 220 void PrinterJobHandler::OnPrinterDeleted() { |
223 printer_delete_pending_ = true; | 221 printer_delete_pending_ = true; |
224 if (!task_in_progress_) { | 222 if (!task_in_progress_) { |
225 MessageLoop::current()->PostTask( | 223 MessageLoop::current()->PostTask( |
226 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); | 224 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); |
227 } | 225 } |
228 } | 226 } |
229 | 227 |
230 void PrinterJobHandler::OnPrinterChanged() { | 228 void PrinterJobHandler::OnPrinterChanged() { |
231 printer_update_pending_ = true; | 229 printer_update_pending_ = true; |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 | 347 |
350 bool PrinterJobHandler::HandlePrintTicketResponse( | 348 bool PrinterJobHandler::HandlePrintTicketResponse( |
351 const URLFetcher* source, const GURL& url, const URLRequestStatus& status, | 349 const URLFetcher* source, const GURL& url, const URLRequestStatus& status, |
352 int response_code, const ResponseCookies& cookies, | 350 int response_code, const ResponseCookies& cookies, |
353 const std::string& data) { | 351 const std::string& data) { |
354 // If there was a network error or a non-200 response (which, for our purposes | 352 // If there was a network error or a non-200 response (which, for our purposes |
355 // is the same as a network error), we want to retry. | 353 // is the same as a network error), we want to retry. |
356 if (!status.is_success() || (response_code != 200)) { | 354 if (!status.is_success() || (response_code != 200)) { |
357 return false; | 355 return false; |
358 } | 356 } |
359 if (cloud_print::ValidatePrintTicket(printer_info_.printer_name, data)) { | 357 if (print_system_->ValidatePrintTicket(printer_info_.printer_name, data)) { |
360 job_details_.print_ticket_ = data; | 358 job_details_.print_ticket_ = data; |
361 MessageLoop::current()->PostTask( | 359 MessageLoop::current()->PostTask( |
362 FROM_HERE, | 360 FROM_HERE, |
363 NewRunnableMethod(this, | 361 NewRunnableMethod(this, |
364 &PrinterJobHandler::MakeServerRequest, | 362 &PrinterJobHandler::MakeServerRequest, |
365 GURL(print_data_url_.c_str()), | 363 GURL(print_data_url_.c_str()), |
366 &PrinterJobHandler::HandlePrintDataResponse)); | 364 &PrinterJobHandler::HandlePrintDataResponse)); |
367 } else { | 365 } else { |
368 // The print ticket was not valid. We are done here. | 366 // The print ticket was not valid. We are done here. |
369 MessageLoop::current()->PostTask( | 367 MessageLoop::current()->PostTask( |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 void PrinterJobHandler::StartPrinting() { | 407 void PrinterJobHandler::StartPrinting() { |
410 // We are done with the request object for now. | 408 // We are done with the request object for now. |
411 request_.reset(); | 409 request_.reset(); |
412 if (!shutting_down_) { | 410 if (!shutting_down_) { |
413 if (!print_thread_.Start()) { | 411 if (!print_thread_.Start()) { |
414 JobFailed(PRINT_FAILED); | 412 JobFailed(PRINT_FAILED); |
415 } else { | 413 } else { |
416 print_thread_.message_loop()->PostTask( | 414 print_thread_.message_loop()->PostTask( |
417 FROM_HERE, NewRunnableFunction(&PrinterJobHandler::DoPrint, | 415 FROM_HERE, NewRunnableFunction(&PrinterJobHandler::DoPrint, |
418 job_details_, | 416 job_details_, |
419 printer_info_.printer_name, this, | 417 printer_info_.printer_name, |
| 418 print_system_, this, |
420 MessageLoop::current())); | 419 MessageLoop::current())); |
421 } | 420 } |
422 } | 421 } |
423 } | 422 } |
424 | 423 |
425 void PrinterJobHandler::JobFailed(PrintJobError error) { | 424 void PrinterJobHandler::JobFailed(PrintJobError error) { |
426 if (!shutting_down_) { | 425 if (!shutting_down_) { |
427 UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_ERROR, error); | 426 UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_ERROR, error); |
428 } | 427 } |
429 } | 428 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 // If there was a network error or a non-200 response (which, for our purposes | 486 // If there was a network error or a non-200 response (which, for our purposes |
488 // is the same as a network error), we want to retry. | 487 // is the same as a network error), we want to retry. |
489 if (!status.is_success() || (response_code != 200)) { | 488 if (!status.is_success() || (response_code != 200)) { |
490 return false; | 489 return false; |
491 } | 490 } |
492 // The print job has been spooled locally. We now need to create an object | 491 // The print job has been spooled locally. We now need to create an object |
493 // that monitors the status of the job and updates the server. | 492 // that monitors the status of the job and updates the server. |
494 scoped_refptr<JobStatusUpdater> job_status_updater = | 493 scoped_refptr<JobStatusUpdater> job_status_updater = |
495 new JobStatusUpdater(printer_info_.printer_name, job_details_.job_id_, | 494 new JobStatusUpdater(printer_info_.printer_name, job_details_.job_id_, |
496 local_job_id_, auth_token_, cloud_print_server_url_, | 495 local_job_id_, auth_token_, cloud_print_server_url_, |
497 this); | 496 print_system_.get(), this); |
498 job_status_updater_list_.push_back(job_status_updater); | 497 job_status_updater_list_.push_back(job_status_updater); |
499 MessageLoop::current()->PostTask( | 498 MessageLoop::current()->PostTask( |
500 FROM_HERE, NewRunnableMethod(job_status_updater.get(), | 499 FROM_HERE, NewRunnableMethod(job_status_updater.get(), |
501 &JobStatusUpdater::UpdateStatus)); | 500 &JobStatusUpdater::UpdateStatus)); |
502 bool succeeded = false; | 501 bool succeeded = false; |
503 CloudPrintHelpers::ParseResponseJSON(data, &succeeded, NULL); | 502 CloudPrintHelpers::ParseResponseJSON(data, &succeeded, NULL); |
504 if (succeeded) { | 503 if (succeeded) { |
505 // Since we just printed successfully, we want to look for more jobs. | 504 // Since we just printed successfully, we want to look for more jobs. |
506 server_job_available_ = true; | 505 server_job_available_ = true; |
507 } | 506 } |
(...skipping 28 matching lines...) Expand all Loading... |
536 } | 535 } |
537 } | 536 } |
538 | 537 |
539 bool PrinterJobHandler::HavePendingTasks() { | 538 bool PrinterJobHandler::HavePendingTasks() { |
540 return server_job_available_ || printer_update_pending_ || | 539 return server_job_available_ || printer_update_pending_ || |
541 printer_delete_pending_; | 540 printer_delete_pending_; |
542 } | 541 } |
543 | 542 |
544 | 543 |
545 void PrinterJobHandler::DoPrint(const JobDetails& job_details, | 544 void PrinterJobHandler::DoPrint(const JobDetails& job_details, |
546 const std::string& printer_name, | 545 const std::string& printer_name, |
547 PrinterJobHandler* job_handler, | 546 scoped_refptr<cloud_print::PrintSystem> print_system, |
548 MessageLoop* job_message_loop) { | 547 PrinterJobHandler* job_handler, |
| 548 MessageLoop* job_message_loop) { |
549 DCHECK(job_handler); | 549 DCHECK(job_handler); |
550 DCHECK(job_message_loop); | 550 DCHECK(job_message_loop); |
551 cloud_print::PlatformJobId job_id = -1; | 551 cloud_print::PlatformJobId job_id = -1; |
552 if (cloud_print::SpoolPrintJob(job_details.print_ticket_, | 552 if (print_system->SpoolPrintJob(job_details.print_ticket_, |
553 job_details.print_data_file_path_, | 553 job_details.print_data_file_path_, |
554 job_details.print_data_mime_type_, | 554 job_details.print_data_mime_type_, |
555 printer_name, | 555 printer_name, |
556 job_details.job_title_, &job_id)) { | 556 job_details.job_title_, &job_id)) { |
557 job_message_loop->PostTask(FROM_HERE, | 557 job_message_loop->PostTask(FROM_HERE, |
558 NewRunnableMethod(job_handler, | 558 NewRunnableMethod(job_handler, |
559 &PrinterJobHandler::JobSpooled, | 559 &PrinterJobHandler::JobSpooled, |
560 job_id)); | 560 job_id)); |
561 } else { | 561 } else { |
562 job_message_loop->PostTask(FROM_HERE, | 562 job_message_loop->PostTask(FROM_HERE, |
563 NewRunnableMethod(job_handler, | 563 NewRunnableMethod(job_handler, |
564 &PrinterJobHandler::JobFailed, | 564 &PrinterJobHandler::JobFailed, |
565 PRINT_FAILED)); | 565 PRINT_FAILED)); |
566 } | 566 } |
567 } | 567 } |
568 | 568 |
OLD | NEW |