| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/stringprintf.h" | 10 #include "base/stringprintf.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 local_job_id_(-1), | 44 local_job_id_(-1), |
| 45 next_json_data_handler_(NULL), | 45 next_json_data_handler_(NULL), |
| 46 next_data_handler_(NULL), | 46 next_data_handler_(NULL), |
| 47 server_error_count_(0), | 47 server_error_count_(0), |
| 48 print_thread_("Chrome_CloudPrintJobPrintThread"), | 48 print_thread_("Chrome_CloudPrintJobPrintThread"), |
| 49 job_handler_message_loop_proxy_( | 49 job_handler_message_loop_proxy_( |
| 50 base::MessageLoopProxy::current()), | 50 base::MessageLoopProxy::current()), |
| 51 shutting_down_(false), | 51 shutting_down_(false), |
| 52 job_check_pending_(false), | 52 job_check_pending_(false), |
| 53 printer_update_pending_(true), | 53 printer_update_pending_(true), |
| 54 printer_delete_pending_(false), | |
| 55 task_in_progress_(false) { | 54 task_in_progress_(false) { |
| 56 } | 55 } |
| 57 | 56 |
| 58 bool PrinterJobHandler::Initialize() { | 57 bool PrinterJobHandler::Initialize() { |
| 59 if (print_system_->IsValidPrinter( | 58 if (!print_system_->IsValidPrinter(printer_info_.printer_name)) |
| 60 printer_info_.printer_name)) { | 59 return false; |
| 61 printer_watcher_ = print_system_->CreatePrinterWatcher( | 60 |
| 62 printer_info_.printer_name); | 61 printer_watcher_ = print_system_->CreatePrinterWatcher( |
| 63 printer_watcher_->StartWatching(this); | 62 printer_info_.printer_name); |
| 64 CheckForJobs(kJobFetchReasonStartup); | 63 printer_watcher_->StartWatching(this); |
| 65 } else { | 64 CheckForJobs(kJobFetchReasonStartup); |
| 66 // This printer does not exist any more. Check if we should delete it from | |
| 67 // the server. | |
| 68 bool delete_from_server = false; | |
| 69 delegate_->OnPrinterNotFound(printer_info_.printer_name, | |
| 70 &delete_from_server); | |
| 71 if (delete_from_server) | |
| 72 OnPrinterDeleted(); | |
| 73 } | |
| 74 return true; | 65 return true; |
| 75 } | 66 } |
| 76 | 67 |
| 77 PrinterJobHandler::~PrinterJobHandler() { | 68 PrinterJobHandler::~PrinterJobHandler() { |
| 78 if (printer_watcher_) | 69 if (printer_watcher_) |
| 79 printer_watcher_->StopWatching(); | 70 printer_watcher_->StopWatching(); |
| 80 } | 71 } |
| 81 | 72 |
| 82 void PrinterJobHandler::Reset() { | 73 void PrinterJobHandler::Reset() { |
| 83 print_data_url_.clear(); | 74 print_data_url_.clear(); |
| 84 job_details_.Clear(); | 75 job_details_.Clear(); |
| 85 request_ = NULL; | 76 request_ = NULL; |
| 86 print_thread_.Stop(); | 77 print_thread_.Stop(); |
| 87 } | 78 } |
| 88 | 79 |
| 80 std::string PrinterJobHandler::GetPrinterName() const { |
| 81 return printer_info_.printer_name; |
| 82 } |
| 83 |
| 89 void PrinterJobHandler::Start() { | 84 void PrinterJobHandler::Start() { |
| 90 VLOG(1) << "CP_PROXY: Start printer job handler, id: " | 85 VLOG(1) << "CP_PROXY: Start printer job handler, id: " |
| 91 << printer_info_cloud_.printer_id | 86 << printer_info_cloud_.printer_id |
| 92 << ", task in progress: " << task_in_progress_; | 87 << ", task in progress: " << task_in_progress_; |
| 93 if (task_in_progress_) { | 88 if (task_in_progress_) { |
| 94 // Multiple Starts can get posted because of multiple notifications | 89 // Multiple Starts can get posted because of multiple notifications |
| 95 // We want to ignore the other ones that happen when a task is in progress. | 90 // We want to ignore the other ones that happen when a task is in progress. |
| 96 return; | 91 return; |
| 97 } | 92 } |
| 98 Reset(); | 93 Reset(); |
| 99 if (!shutting_down_) { | 94 if (!shutting_down_) { |
| 100 // Check if we have work to do. | 95 // Check if we have work to do. |
| 101 if (HavePendingTasks()) { | 96 if (HavePendingTasks()) { |
| 102 if (printer_delete_pending_) { | |
| 103 printer_delete_pending_ = false; | |
| 104 task_in_progress_ = true; | |
| 105 SetNextJSONHandler(&PrinterJobHandler::HandlePrinterDeleteResponse); | |
| 106 request_ = new CloudPrintURLFetcher; | |
| 107 request_->StartGetRequest( | |
| 108 CloudPrintHelpers::GetUrlForPrinterDelete( | |
| 109 cloud_print_server_url_, printer_info_cloud_.printer_id), | |
| 110 this, | |
| 111 kCloudPrintAPIMaxRetryCount, | |
| 112 std::string()); | |
| 113 } | |
| 114 if (!task_in_progress_ && printer_update_pending_) { | 97 if (!task_in_progress_ && printer_update_pending_) { |
| 115 printer_update_pending_ = false; | 98 printer_update_pending_ = false; |
| 116 task_in_progress_ = UpdatePrinterInfo(); | 99 task_in_progress_ = UpdatePrinterInfo(); |
| 117 } | 100 } |
| 118 if (!task_in_progress_ && job_check_pending_) { | 101 if (!task_in_progress_ && job_check_pending_) { |
| 119 task_in_progress_ = true; | 102 task_in_progress_ = true; |
| 120 job_check_pending_ = false; | 103 job_check_pending_ = false; |
| 121 // We need to fetch any pending jobs for this printer | 104 // We need to fetch any pending jobs for this printer |
| 122 SetNextJSONHandler(&PrinterJobHandler::HandleJobMetadataResponse); | 105 SetNextJSONHandler(&PrinterJobHandler::HandleJobMetadataResponse); |
| 123 request_ = new CloudPrintURLFetcher; | 106 request_ = new CloudPrintURLFetcher; |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 return CloudPrintURLFetcher::CONTINUE_PROCESSING; | 292 return CloudPrintURLFetcher::CONTINUE_PROCESSING; |
| 310 return (this->*next_data_handler_)(source, url, data); | 293 return (this->*next_data_handler_)(source, url, data); |
| 311 } | 294 } |
| 312 | 295 |
| 313 CloudPrintURLFetcher::ResponseAction PrinterJobHandler::HandleJSONData( | 296 CloudPrintURLFetcher::ResponseAction PrinterJobHandler::HandleJSONData( |
| 314 const URLFetcher* source, | 297 const URLFetcher* source, |
| 315 const GURL& url, | 298 const GURL& url, |
| 316 DictionaryValue* json_data, | 299 DictionaryValue* json_data, |
| 317 bool succeeded) { | 300 bool succeeded) { |
| 318 DCHECK(next_json_data_handler_); | 301 DCHECK(next_json_data_handler_); |
| 319 return (this->*next_json_data_handler_)(source, | 302 return (this->*next_json_data_handler_)(source, url, json_data, succeeded); |
| 320 url, | |
| 321 json_data, | |
| 322 succeeded); | |
| 323 } | 303 } |
| 324 | 304 |
| 325 void PrinterJobHandler::OnRequestGiveUp() { | 305 void PrinterJobHandler::OnRequestGiveUp() { |
| 326 // The only time we call CloudPrintURLFetcher::StartGetRequest() with a | 306 // The only time we call CloudPrintURLFetcher::StartGetRequest() with a |
| 327 // specified number of retries, is when we are trying to fetch print job | 307 // specified number of retries, is when we are trying to fetch print job |
| 328 // data. So, this function will be reached only if we failed to get job data. | 308 // data. So, this function will be reached only if we failed to get job data. |
| 329 // In that case, we should make job as error and should not try it later. | 309 // In that case, we should make job as error and should not try it later. |
| 330 MessageLoop::current()->PostTask( | 310 MessageLoop::current()->PostTask( |
| 331 FROM_HERE, | 311 FROM_HERE, |
| 332 NewRunnableMethod(this, &PrinterJobHandler::JobFailed, | 312 NewRunnableMethod(this, &PrinterJobHandler::JobFailed, |
| 333 JOB_DOWNLOAD_FAILED)); | 313 JOB_DOWNLOAD_FAILED)); |
| 334 } | 314 } |
| 335 | 315 |
| 336 void PrinterJobHandler::OnRequestAuthError() { | 316 CloudPrintURLFetcher::ResponseAction PrinterJobHandler::OnRequestAuthError() { |
| 317 // TODO(gene): We should probably stop processing if we get auth error here. |
| 337 OnAuthError(); | 318 OnAuthError(); |
| 319 // Continue processing as a network error. |
| 320 return CloudPrintURLFetcher::CONTINUE_PROCESSING; |
| 321 } |
| 322 |
| 323 std::string PrinterJobHandler::GetAuthHeader() { |
| 324 return CloudPrintHelpers::GetCloudPrintAuthHeader(); |
| 338 } | 325 } |
| 339 | 326 |
| 340 // JobStatusUpdater::Delegate implementation | 327 // JobStatusUpdater::Delegate implementation |
| 341 bool PrinterJobHandler::OnJobCompleted(JobStatusUpdater* updater) { | 328 bool PrinterJobHandler::OnJobCompleted(JobStatusUpdater* updater) { |
| 342 bool ret = false; | 329 bool ret = false; |
| 343 for (JobStatusUpdaterList::iterator index = job_status_updater_list_.begin(); | 330 for (JobStatusUpdaterList::iterator index = job_status_updater_list_.begin(); |
| 344 index != job_status_updater_list_.end(); index++) { | 331 index != job_status_updater_list_.end(); index++) { |
| 345 if (index->get() == updater) { | 332 if (index->get() == updater) { |
| 346 job_status_updater_list_.erase(index); | 333 job_status_updater_list_.erase(index); |
| 347 ret = true; | 334 ret = true; |
| 348 break; | 335 break; |
| 349 } | 336 } |
| 350 } | 337 } |
| 351 return ret; | 338 return ret; |
| 352 } | 339 } |
| 353 | 340 |
| 354 void PrinterJobHandler::OnAuthError() { | 341 void PrinterJobHandler::OnAuthError() { |
| 355 if (delegate_) | 342 if (delegate_) |
| 356 delegate_->OnAuthError(); | 343 delegate_->OnAuthError(); |
| 357 } | 344 } |
| 358 | 345 |
| 359 void PrinterJobHandler::OnPrinterDeleted() { | 346 void PrinterJobHandler::OnPrinterDeleted() { |
| 360 printer_delete_pending_ = true; | 347 if (delegate_) |
| 361 if (!task_in_progress_) { | 348 delegate_->OnPrinterDeleted(printer_info_cloud_.printer_id); |
| 362 MessageLoop::current()->PostTask( | |
| 363 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); | |
| 364 } | |
| 365 } | 349 } |
| 366 | 350 |
| 367 void PrinterJobHandler::OnPrinterChanged() { | 351 void PrinterJobHandler::OnPrinterChanged() { |
| 368 printer_update_pending_ = true; | 352 printer_update_pending_ = true; |
| 369 if (!task_in_progress_) { | 353 if (!task_in_progress_) { |
| 370 MessageLoop::current()->PostTask( | 354 MessageLoop::current()->PostTask( |
| 371 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); | 355 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); |
| 372 } | 356 } |
| 373 } | 357 } |
| 374 | 358 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 392 bool succeeded) { | 376 bool succeeded) { |
| 393 VLOG(1) << "CP_PROXY: Handle printer update response, id: " | 377 VLOG(1) << "CP_PROXY: Handle printer update response, id: " |
| 394 << printer_info_cloud_.printer_id; | 378 << printer_info_cloud_.printer_id; |
| 395 // We are done here. Go to the Stop state | 379 // We are done here. Go to the Stop state |
| 396 MessageLoop::current()->PostTask( | 380 MessageLoop::current()->PostTask( |
| 397 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop)); | 381 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop)); |
| 398 return CloudPrintURLFetcher::STOP_PROCESSING; | 382 return CloudPrintURLFetcher::STOP_PROCESSING; |
| 399 } | 383 } |
| 400 | 384 |
| 401 CloudPrintURLFetcher::ResponseAction | 385 CloudPrintURLFetcher::ResponseAction |
| 402 PrinterJobHandler::HandlePrinterDeleteResponse( | |
| 403 const URLFetcher* source, | |
| 404 const GURL& url, | |
| 405 DictionaryValue* json_data, | |
| 406 bool succeeded) { | |
| 407 VLOG(1) << "CP_PROXY: Handler printer delete response, id: " | |
| 408 << printer_info_cloud_.printer_id; | |
| 409 // The printer has been deleted. Shutdown the handler class. | |
| 410 MessageLoop::current()->PostTask( | |
| 411 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Shutdown)); | |
| 412 return CloudPrintURLFetcher::STOP_PROCESSING; | |
| 413 } | |
| 414 | |
| 415 CloudPrintURLFetcher::ResponseAction | |
| 416 PrinterJobHandler::HandleJobMetadataResponse( | 386 PrinterJobHandler::HandleJobMetadataResponse( |
| 417 const URLFetcher* source, | 387 const URLFetcher* source, |
| 418 const GURL& url, | 388 const GURL& url, |
| 419 DictionaryValue* json_data, | 389 DictionaryValue* json_data, |
| 420 bool succeeded) { | 390 bool succeeded) { |
| 421 VLOG(1) << "CP_PROXY: Handle job metadata response, id: " | 391 VLOG(1) << "CP_PROXY: Handle job metadata response, id: " |
| 422 << printer_info_cloud_.printer_id; | 392 << printer_info_cloud_.printer_id; |
| 423 bool job_available = false; | 393 bool job_available = false; |
| 424 if (succeeded) { | 394 if (succeeded) { |
| 425 ListValue* job_list = NULL; | 395 ListValue* job_list = NULL; |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 void PrinterJobHandler::Shutdown() { | 559 void PrinterJobHandler::Shutdown() { |
| 590 VLOG(1) << "CP_PROXY: Printer job handler shutdown, id: " | 560 VLOG(1) << "CP_PROXY: Printer job handler shutdown, id: " |
| 591 << printer_info_cloud_.printer_id; | 561 << printer_info_cloud_.printer_id; |
| 592 Reset(); | 562 Reset(); |
| 593 shutting_down_ = true; | 563 shutting_down_ = true; |
| 594 while (!job_status_updater_list_.empty()) { | 564 while (!job_status_updater_list_.empty()) { |
| 595 // Calling Stop() will cause the OnJobCompleted to be called which will | 565 // Calling Stop() will cause the OnJobCompleted to be called which will |
| 596 // remove the updater object from the list. | 566 // remove the updater object from the list. |
| 597 job_status_updater_list_.front()->Stop(); | 567 job_status_updater_list_.front()->Stop(); |
| 598 } | 568 } |
| 599 if (delegate_) { | |
| 600 delegate_->OnPrinterJobHandlerShutdown(this, | |
| 601 printer_info_cloud_.printer_id); | |
| 602 } | |
| 603 } | 569 } |
| 604 | 570 |
| 605 void PrinterJobHandler::UpdateJobStatus(cloud_print::PrintJobStatus status, | 571 void PrinterJobHandler::UpdateJobStatus(cloud_print::PrintJobStatus status, |
| 606 PrintJobError error) { | 572 PrintJobError error) { |
| 607 VLOG(1) << "CP_PROXY: Update job status, id: " | 573 VLOG(1) << "CP_PROXY: Update job status, id: " |
| 608 << printer_info_cloud_.printer_id; | 574 << printer_info_cloud_.printer_id; |
| 609 if (!shutting_down_) { | 575 if (!shutting_down_) { |
| 610 if (!job_details_.job_id_.empty()) { | 576 if (!job_details_.job_id_.empty()) { |
| 611 VLOG(1) << "CP_PROXY: Updating status, job id: " << job_details_.job_id_ | 577 VLOG(1) << "CP_PROXY: Updating status, job id: " << job_details_.job_id_ |
| 612 << ", status: " << status; | 578 << ", status: " << status; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 633 next_json_data_handler_ = handler; | 599 next_json_data_handler_ = handler; |
| 634 next_data_handler_ = NULL; | 600 next_data_handler_ = NULL; |
| 635 } | 601 } |
| 636 | 602 |
| 637 void PrinterJobHandler::SetNextDataHandler(DataHandler handler) { | 603 void PrinterJobHandler::SetNextDataHandler(DataHandler handler) { |
| 638 next_data_handler_ = handler; | 604 next_data_handler_ = handler; |
| 639 next_json_data_handler_ = NULL; | 605 next_json_data_handler_ = NULL; |
| 640 } | 606 } |
| 641 | 607 |
| 642 bool PrinterJobHandler::HavePendingTasks() { | 608 bool PrinterJobHandler::HavePendingTasks() { |
| 643 return (job_check_pending_ || printer_update_pending_ || | 609 return (job_check_pending_ || printer_update_pending_); |
| 644 printer_delete_pending_); | |
| 645 } | 610 } |
| 646 | 611 |
| 647 void PrinterJobHandler::FailedFetchingJobData() { | 612 void PrinterJobHandler::FailedFetchingJobData() { |
| 648 if (!shutting_down_) { | 613 if (!shutting_down_) { |
| 649 LOG(ERROR) << "CP_PROXY: Failed fetching job data for printer: " << | 614 LOG(ERROR) << "CP_PROXY: Failed fetching job data for printer: " << |
| 650 printer_info_.printer_name << ", job id: " << job_details_.job_id_; | 615 printer_info_.printer_name << ", job id: " << job_details_.job_id_; |
| 651 JobFailed(INVALID_JOB_DATA); | 616 JobFailed(INVALID_JOB_DATA); |
| 652 } | 617 } |
| 653 } | 618 } |
| 654 | 619 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 681 } | 646 } |
| 682 | 647 |
| 683 void PrinterJobHandler::OnJobSpoolFailed() { | 648 void PrinterJobHandler::OnJobSpoolFailed() { |
| 684 DCHECK(MessageLoop::current() == print_thread_.message_loop()); | 649 DCHECK(MessageLoop::current() == print_thread_.message_loop()); |
| 685 job_spooler_ = NULL; | 650 job_spooler_ = NULL; |
| 686 job_handler_message_loop_proxy_->PostTask(FROM_HERE, | 651 job_handler_message_loop_proxy_->PostTask(FROM_HERE, |
| 687 NewRunnableMethod(this, | 652 NewRunnableMethod(this, |
| 688 &PrinterJobHandler::JobFailed, | 653 &PrinterJobHandler::JobFailed, |
| 689 PRINT_FAILED)); | 654 PRINT_FAILED)); |
| 690 } | 655 } |
| OLD | NEW |