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 content::URLFetcher* source, | 297 const content::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 might consider 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 content::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 content::URLFetcher* source, | 387 const content::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 |