| 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_CONNECTOR: 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; |
| 124 request_->StartGetRequest( | 107 request_->StartGetRequest( |
| 125 CloudPrintHelpers::GetUrlForJobFetch( | 108 CloudPrintHelpers::GetUrlForJobFetch( |
| 126 cloud_print_server_url_, printer_info_cloud_.printer_id, | 109 cloud_print_server_url_, printer_info_cloud_.printer_id, |
| 127 job_fetch_reason_), | 110 job_fetch_reason_), |
| 128 this, | 111 this, |
| 129 kCloudPrintAPIMaxRetryCount, | 112 kCloudPrintAPIMaxRetryCount, |
| 130 std::string()); | 113 std::string()); |
| 131 last_job_fetch_time_ = base::TimeTicks::Now(); | 114 last_job_fetch_time_ = base::TimeTicks::Now(); |
| 132 VLOG(1) << "Last job fetch time for printer " | 115 VLOG(1) << "Last job fetch time for printer " |
| 133 << printer_info_.printer_name.c_str() << " is " | 116 << printer_info_.printer_name.c_str() << " is " |
| 134 << last_job_fetch_time_.ToInternalValue(); | 117 << last_job_fetch_time_.ToInternalValue(); |
| 135 job_fetch_reason_.clear(); | 118 job_fetch_reason_.clear(); |
| 136 } | 119 } |
| 137 } | 120 } |
| 138 } | 121 } |
| 139 } | 122 } |
| 140 | 123 |
| 141 void PrinterJobHandler::Stop() { | 124 void PrinterJobHandler::Stop() { |
| 142 VLOG(1) << "CP_PROXY: Stop printer job handler, id: " | 125 VLOG(1) << "CP_CONNECTOR: Stop printer job handler, id: " |
| 143 << printer_info_cloud_.printer_id; | 126 << printer_info_cloud_.printer_id; |
| 144 task_in_progress_ = false; | 127 task_in_progress_ = false; |
| 145 Reset(); | 128 Reset(); |
| 146 if (HavePendingTasks()) { | 129 if (HavePendingTasks()) { |
| 147 MessageLoop::current()->PostTask( | 130 MessageLoop::current()->PostTask( |
| 148 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); | 131 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); |
| 149 } | 132 } |
| 150 } | 133 } |
| 151 | 134 |
| 152 void PrinterJobHandler::CheckForJobs(const std::string& reason) { | 135 void PrinterJobHandler::CheckForJobs(const std::string& reason) { |
| 153 VLOG(1) << "CP_PROXY: CheckForJobs, id: " | 136 VLOG(1) << "CP_CONNECTOR: CheckForJobs, id: " |
| 154 << printer_info_cloud_.printer_id | 137 << printer_info_cloud_.printer_id |
| 155 << ", reason: " << reason | 138 << ", reason: " << reason |
| 156 << ", task in progress: " << task_in_progress_; | 139 << ", task in progress: " << task_in_progress_; |
| 157 job_fetch_reason_ = reason; | 140 job_fetch_reason_ = reason; |
| 158 job_check_pending_ = true; | 141 job_check_pending_ = true; |
| 159 if (!task_in_progress_) { | 142 if (!task_in_progress_) { |
| 160 MessageLoop::current()->PostTask( | 143 MessageLoop::current()->PostTask( |
| 161 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); | 144 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); |
| 162 } | 145 } |
| 163 } | 146 } |
| 164 | 147 |
| 165 bool PrinterJobHandler::UpdatePrinterInfo() { | 148 bool PrinterJobHandler::UpdatePrinterInfo() { |
| 166 if (!printer_watcher_) { | 149 if (!printer_watcher_) { |
| 167 LOG(ERROR) << "CP_PROXY: Printer watcher is missing." | 150 LOG(ERROR) << "CP_CONNECTOR: Printer watcher is missing." |
| 168 << "Check printer server url for printer id: " | 151 << "Check printer server url for printer id: " |
| 169 << printer_info_cloud_.printer_id; | 152 << printer_info_cloud_.printer_id; |
| 170 return false; | 153 return false; |
| 171 } | 154 } |
| 172 | 155 |
| 173 VLOG(1) << "CP_PROXY: Update printer info, id: " | 156 VLOG(1) << "CP_CONNECTOR: Update printer info, id: " |
| 174 << printer_info_cloud_.printer_id; | 157 << printer_info_cloud_.printer_id; |
| 175 // We need to update the parts of the printer info that have changed | 158 // We need to update the parts of the printer info that have changed |
| 176 // (could be printer name, description, status or capabilities). | 159 // (could be printer name, description, status or capabilities). |
| 177 // First asynchronously fetch the capabilities. | 160 // First asynchronously fetch the capabilities. |
| 178 printing::PrinterBasicInfo printer_info; | 161 printing::PrinterBasicInfo printer_info; |
| 179 printer_watcher_->GetCurrentPrinterInfo(&printer_info); | 162 printer_watcher_->GetCurrentPrinterInfo(&printer_info); |
| 180 cloud_print::PrintSystem::PrinterCapsAndDefaultsCallback* callback = | 163 cloud_print::PrintSystem::PrinterCapsAndDefaultsCallback* callback = |
| 181 NewCallback(this, | 164 NewCallback(this, |
| 182 &PrinterJobHandler::OnReceivePrinterCaps); | 165 &PrinterJobHandler::OnReceivePrinterCaps); |
| 183 // Asnchronously fetch the printer caps and defaults. The story will | 166 // Asnchronously fetch the printer caps and defaults. The story will |
| (...skipping 125 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 |
| 375 void PrinterJobHandler::OnJobChanged() { | 359 void PrinterJobHandler::OnJobChanged() { |
| 376 // Some job on the printer changed. Loop through all our JobStatusUpdaters | 360 // Some job on the printer changed. Loop through all our JobStatusUpdaters |
| 377 // and have them check for updates. | 361 // and have them check for updates. |
| 378 for (JobStatusUpdaterList::iterator index = job_status_updater_list_.begin(); | 362 for (JobStatusUpdaterList::iterator index = job_status_updater_list_.begin(); |
| 379 index != job_status_updater_list_.end(); index++) { | 363 index != job_status_updater_list_.end(); index++) { |
| 380 MessageLoop::current()->PostTask( | 364 MessageLoop::current()->PostTask( |
| 381 FROM_HERE, NewRunnableMethod(index->get(), | 365 FROM_HERE, NewRunnableMethod(index->get(), |
| 382 &JobStatusUpdater::UpdateStatus)); | 366 &JobStatusUpdater::UpdateStatus)); |
| 383 } | 367 } |
| 384 } | 368 } |
| 385 | 369 |
| 386 // Begin Response handlers | 370 // Begin Response handlers |
| 387 CloudPrintURLFetcher::ResponseAction | 371 CloudPrintURLFetcher::ResponseAction |
| 388 PrinterJobHandler::HandlePrinterUpdateResponse( | 372 PrinterJobHandler::HandlePrinterUpdateResponse( |
| 389 const content::URLFetcher* source, | 373 const content::URLFetcher* source, |
| 390 const GURL& url, | 374 const GURL& url, |
| 391 DictionaryValue* json_data, | 375 DictionaryValue* json_data, |
| 392 bool succeeded) { | 376 bool succeeded) { |
| 393 VLOG(1) << "CP_PROXY: Handle printer update response, id: " | 377 VLOG(1) << "CP_CONNECTOR: 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_CONNECTOR: 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; |
| 426 if (json_data->GetList(kJobListValue, &job_list) && job_list) { | 396 if (json_data->GetList(kJobListValue, &job_list) && job_list) { |
| 427 // Even though it is a job list, for now we are only interested in the | 397 // Even though it is a job list, for now we are only interested in the |
| 428 // first job | 398 // first job |
| 429 DictionaryValue* job_data = NULL; | 399 DictionaryValue* job_data = NULL; |
| 430 if (job_list->GetDictionary(0, &job_data)) { | 400 if (job_list->GetDictionary(0, &job_data)) { |
| 431 job_available = true; | 401 job_available = true; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 458 if (!job_available) | 428 if (!job_available) |
| 459 MessageLoop::current()->PostTask( | 429 MessageLoop::current()->PostTask( |
| 460 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop)); | 430 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop)); |
| 461 return CloudPrintURLFetcher::STOP_PROCESSING; | 431 return CloudPrintURLFetcher::STOP_PROCESSING; |
| 462 } | 432 } |
| 463 | 433 |
| 464 CloudPrintURLFetcher::ResponseAction | 434 CloudPrintURLFetcher::ResponseAction |
| 465 PrinterJobHandler::HandlePrintTicketResponse(const content::URLFetcher* source, | 435 PrinterJobHandler::HandlePrintTicketResponse(const content::URLFetcher* source, |
| 466 const GURL& url, | 436 const GURL& url, |
| 467 const std::string& data) { | 437 const std::string& data) { |
| 468 VLOG(1) << "CP_PROXY: Handle print ticket response, id: " | 438 VLOG(1) << "CP_CONNECTOR: Handle print ticket response, id: " |
| 469 << printer_info_cloud_.printer_id; | 439 << printer_info_cloud_.printer_id; |
| 470 if (print_system_->ValidatePrintTicket(printer_info_.printer_name, data)) { | 440 if (print_system_->ValidatePrintTicket(printer_info_.printer_name, data)) { |
| 471 job_details_.print_ticket_ = data; | 441 job_details_.print_ticket_ = data; |
| 472 SetNextDataHandler(&PrinterJobHandler::HandlePrintDataResponse); | 442 SetNextDataHandler(&PrinterJobHandler::HandlePrintDataResponse); |
| 473 request_ = new CloudPrintURLFetcher; | 443 request_ = new CloudPrintURLFetcher; |
| 474 std::string accept_headers = "Accept: "; | 444 std::string accept_headers = "Accept: "; |
| 475 accept_headers += print_system_->GetSupportedMimeTypes(); | 445 accept_headers += print_system_->GetSupportedMimeTypes(); |
| 476 request_->StartGetRequest(GURL(print_data_url_.c_str()), | 446 request_->StartGetRequest(GURL(print_data_url_.c_str()), |
| 477 this, | 447 this, |
| 478 kJobDataMaxRetryCount, | 448 kJobDataMaxRetryCount, |
| 479 accept_headers); | 449 accept_headers); |
| 480 } else { | 450 } else { |
| 481 // The print ticket was not valid. We are done here. | 451 // The print ticket was not valid. We are done here. |
| 482 FailedFetchingJobData(); | 452 FailedFetchingJobData(); |
| 483 } | 453 } |
| 484 return CloudPrintURLFetcher::STOP_PROCESSING; | 454 return CloudPrintURLFetcher::STOP_PROCESSING; |
| 485 } | 455 } |
| 486 | 456 |
| 487 CloudPrintURLFetcher::ResponseAction | 457 CloudPrintURLFetcher::ResponseAction |
| 488 PrinterJobHandler::HandlePrintDataResponse(const content::URLFetcher* source, | 458 PrinterJobHandler::HandlePrintDataResponse(const content::URLFetcher* source, |
| 489 const GURL& url, | 459 const GURL& url, |
| 490 const std::string& data) { | 460 const std::string& data) { |
| 491 VLOG(1) << "CP_PROXY: Handle print data response, id: " | 461 VLOG(1) << "CP_CONNECTOR: Handle print data response, id: " |
| 492 << printer_info_cloud_.printer_id; | 462 << printer_info_cloud_.printer_id; |
| 493 Task* next_task = NULL; | 463 Task* next_task = NULL; |
| 494 if (file_util::CreateTemporaryFile(&job_details_.print_data_file_path_)) { | 464 if (file_util::CreateTemporaryFile(&job_details_.print_data_file_path_)) { |
| 495 int ret = file_util::WriteFile(job_details_.print_data_file_path_, | 465 int ret = file_util::WriteFile(job_details_.print_data_file_path_, |
| 496 data.c_str(), | 466 data.c_str(), |
| 497 data.length()); | 467 data.length()); |
| 498 source->GetResponseHeaders()->GetMimeType( | 468 source->GetResponseHeaders()->GetMimeType( |
| 499 &job_details_.print_data_mime_type_); | 469 &job_details_.print_data_mime_type_); |
| 500 DCHECK(ret == static_cast<int>(data.length())); | 470 DCHECK(ret == static_cast<int>(data.length())); |
| 501 if (ret == static_cast<int>(data.length())) { | 471 if (ret == static_cast<int>(data.length())) { |
| 502 next_task = NewRunnableMethod(this, &PrinterJobHandler::StartPrinting); | 472 next_task = NewRunnableMethod(this, &PrinterJobHandler::StartPrinting); |
| 503 } | 473 } |
| 504 } | 474 } |
| 505 // If there was no task allocated above, then there was an error in | 475 // If there was no task allocated above, then there was an error in |
| 506 // saving the print data, bail out here. | 476 // saving the print data, bail out here. |
| 507 if (!next_task) { | 477 if (!next_task) { |
| 508 next_task = NewRunnableMethod(this, &PrinterJobHandler::JobFailed, | 478 next_task = NewRunnableMethod(this, &PrinterJobHandler::JobFailed, |
| 509 JOB_DOWNLOAD_FAILED); | 479 JOB_DOWNLOAD_FAILED); |
| 510 } | 480 } |
| 511 MessageLoop::current()->PostTask(FROM_HERE, next_task); | 481 MessageLoop::current()->PostTask(FROM_HERE, next_task); |
| 512 return CloudPrintURLFetcher::STOP_PROCESSING; | 482 return CloudPrintURLFetcher::STOP_PROCESSING; |
| 513 } | 483 } |
| 514 | 484 |
| 515 CloudPrintURLFetcher::ResponseAction | 485 CloudPrintURLFetcher::ResponseAction |
| 516 PrinterJobHandler::HandleSuccessStatusUpdateResponse( | 486 PrinterJobHandler::HandleSuccessStatusUpdateResponse( |
| 517 const content::URLFetcher* source, | 487 const content::URLFetcher* source, |
| 518 const GURL& url, | 488 const GURL& url, |
| 519 DictionaryValue* json_data, | 489 DictionaryValue* json_data, |
| 520 bool succeeded) { | 490 bool succeeded) { |
| 521 VLOG(1) << "CP_PROXY: Handle success status update response, id: " | 491 VLOG(1) << "CP_CONNECTOR: Handle success status update response, id: " |
| 522 << printer_info_cloud_.printer_id; | 492 << printer_info_cloud_.printer_id; |
| 523 // The print job has been spooled locally. We now need to create an object | 493 // The print job has been spooled locally. We now need to create an object |
| 524 // that monitors the status of the job and updates the server. | 494 // that monitors the status of the job and updates the server. |
| 525 scoped_refptr<JobStatusUpdater> job_status_updater( | 495 scoped_refptr<JobStatusUpdater> job_status_updater( |
| 526 new JobStatusUpdater(printer_info_.printer_name, job_details_.job_id_, | 496 new JobStatusUpdater(printer_info_.printer_name, job_details_.job_id_, |
| 527 local_job_id_, cloud_print_server_url_, | 497 local_job_id_, cloud_print_server_url_, |
| 528 print_system_.get(), this)); | 498 print_system_.get(), this)); |
| 529 job_status_updater_list_.push_back(job_status_updater); | 499 job_status_updater_list_.push_back(job_status_updater); |
| 530 MessageLoop::current()->PostTask( | 500 MessageLoop::current()->PostTask( |
| 531 FROM_HERE, NewRunnableMethod(job_status_updater.get(), | 501 FROM_HERE, NewRunnableMethod(job_status_updater.get(), |
| 532 &JobStatusUpdater::UpdateStatus)); | 502 &JobStatusUpdater::UpdateStatus)); |
| 533 if (succeeded) { | 503 if (succeeded) { |
| 534 // 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. |
| 535 CheckForJobs(kJobFetchReasonQueryMore); | 505 CheckForJobs(kJobFetchReasonQueryMore); |
| 536 } | 506 } |
| 537 MessageLoop::current()->PostTask( | 507 MessageLoop::current()->PostTask( |
| 538 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop)); | 508 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop)); |
| 539 return CloudPrintURLFetcher::STOP_PROCESSING; | 509 return CloudPrintURLFetcher::STOP_PROCESSING; |
| 540 } | 510 } |
| 541 | 511 |
| 542 CloudPrintURLFetcher::ResponseAction | 512 CloudPrintURLFetcher::ResponseAction |
| 543 PrinterJobHandler::HandleFailureStatusUpdateResponse( | 513 PrinterJobHandler::HandleFailureStatusUpdateResponse( |
| 544 const content::URLFetcher* source, | 514 const content::URLFetcher* source, |
| 545 const GURL& url, | 515 const GURL& url, |
| 546 DictionaryValue* json_data, | 516 DictionaryValue* json_data, |
| 547 bool succeeded) { | 517 bool succeeded) { |
| 548 VLOG(1) << "CP_PROXY: Handle failure status update response, id: " | 518 VLOG(1) << "CP_CONNECTOR: Handle failure status update response, id: " |
| 549 << printer_info_cloud_.printer_id; | 519 << printer_info_cloud_.printer_id; |
| 550 MessageLoop::current()->PostTask( | 520 MessageLoop::current()->PostTask( |
| 551 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop)); | 521 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop)); |
| 552 return CloudPrintURLFetcher::STOP_PROCESSING; | 522 return CloudPrintURLFetcher::STOP_PROCESSING; |
| 553 } | 523 } |
| 554 // End Response handlers | 524 // End Response handlers |
| 555 | 525 |
| 556 void PrinterJobHandler::StartPrinting() { | 526 void PrinterJobHandler::StartPrinting() { |
| 557 VLOG(1) << "CP_PROXY: Start printing, id: " << printer_info_cloud_.printer_id; | 527 VLOG(1) << "CP_CONNECTOR: Start printing, id: " |
| 528 << printer_info_cloud_.printer_id; |
| 558 // We are done with the request object for now. | 529 // We are done with the request object for now. |
| 559 request_ = NULL; | 530 request_ = NULL; |
| 560 if (!shutting_down_) { | 531 if (!shutting_down_) { |
| 561 if (!print_thread_.Start()) { | 532 if (!print_thread_.Start()) { |
| 562 JobFailed(PRINT_FAILED); | 533 JobFailed(PRINT_FAILED); |
| 563 } else { | 534 } else { |
| 564 print_thread_.message_loop()->PostTask( | 535 print_thread_.message_loop()->PostTask( |
| 565 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::DoPrint, | 536 FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::DoPrint, |
| 566 job_details_, | 537 job_details_, |
| 567 printer_info_.printer_name)); | 538 printer_info_.printer_name)); |
| 568 } | 539 } |
| 569 } | 540 } |
| 570 } | 541 } |
| 571 | 542 |
| 572 void PrinterJobHandler::JobFailed(PrintJobError error) { | 543 void PrinterJobHandler::JobFailed(PrintJobError error) { |
| 573 VLOG(1) << "CP_PROXY: Job failed, id: " << printer_info_cloud_.printer_id; | 544 VLOG(1) << "CP_CONNECTOR: Job failed, id: " << printer_info_cloud_.printer_id; |
| 574 if (!shutting_down_) { | 545 if (!shutting_down_) { |
| 575 UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_ERROR, error); | 546 UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_ERROR, error); |
| 576 } | 547 } |
| 577 } | 548 } |
| 578 | 549 |
| 579 void PrinterJobHandler::JobSpooled(cloud_print::PlatformJobId local_job_id) { | 550 void PrinterJobHandler::JobSpooled(cloud_print::PlatformJobId local_job_id) { |
| 580 VLOG(1) << "CP_PROXY: Job spooled, printer id: " | 551 VLOG(1) << "CP_CONNECTOR: Job spooled, printer id: " |
| 581 << printer_info_cloud_.printer_id << ", job id: " << local_job_id; | 552 << printer_info_cloud_.printer_id << ", job id: " << local_job_id; |
| 582 if (!shutting_down_) { | 553 if (!shutting_down_) { |
| 583 local_job_id_ = local_job_id; | 554 local_job_id_ = local_job_id; |
| 584 UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_IN_PROGRESS, SUCCESS); | 555 UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_IN_PROGRESS, SUCCESS); |
| 585 print_thread_.Stop(); | 556 print_thread_.Stop(); |
| 586 } | 557 } |
| 587 } | 558 } |
| 588 | 559 |
| 589 void PrinterJobHandler::Shutdown() { | 560 void PrinterJobHandler::Shutdown() { |
| 590 VLOG(1) << "CP_PROXY: Printer job handler shutdown, id: " | 561 VLOG(1) << "CP_CONNECTOR: Printer job handler shutdown, id: " |
| 591 << printer_info_cloud_.printer_id; | 562 << printer_info_cloud_.printer_id; |
| 592 Reset(); | 563 Reset(); |
| 593 shutting_down_ = true; | 564 shutting_down_ = true; |
| 594 while (!job_status_updater_list_.empty()) { | 565 while (!job_status_updater_list_.empty()) { |
| 595 // Calling Stop() will cause the OnJobCompleted to be called which will | 566 // Calling Stop() will cause the OnJobCompleted to be called which will |
| 596 // remove the updater object from the list. | 567 // remove the updater object from the list. |
| 597 job_status_updater_list_.front()->Stop(); | 568 job_status_updater_list_.front()->Stop(); |
| 598 } | 569 } |
| 599 if (delegate_) { | |
| 600 delegate_->OnPrinterJobHandlerShutdown(this, | |
| 601 printer_info_cloud_.printer_id); | |
| 602 } | |
| 603 } | 570 } |
| 604 | 571 |
| 605 void PrinterJobHandler::UpdateJobStatus(cloud_print::PrintJobStatus status, | 572 void PrinterJobHandler::UpdateJobStatus(cloud_print::PrintJobStatus status, |
| 606 PrintJobError error) { | 573 PrintJobError error) { |
| 607 VLOG(1) << "CP_PROXY: Update job status, id: " | 574 VLOG(1) << "CP_CONNECTOR: Update job status, id: " |
| 608 << printer_info_cloud_.printer_id; | 575 << printer_info_cloud_.printer_id; |
| 609 if (!shutting_down_) { | 576 if (!shutting_down_) { |
| 610 if (!job_details_.job_id_.empty()) { | 577 if (!job_details_.job_id_.empty()) { |
| 611 VLOG(1) << "CP_PROXY: Updating status, job id: " << job_details_.job_id_ | 578 VLOG(1) << "CP_CONNECTOR: Updating status, job id: " |
| 612 << ", status: " << status; | 579 << job_details_.job_id_ << ", status: " << status; |
| 613 if (error == SUCCESS) { | 580 if (error == SUCCESS) { |
| 614 SetNextJSONHandler( | 581 SetNextJSONHandler( |
| 615 &PrinterJobHandler::HandleSuccessStatusUpdateResponse); | 582 &PrinterJobHandler::HandleSuccessStatusUpdateResponse); |
| 616 } else { | 583 } else { |
| 617 SetNextJSONHandler( | 584 SetNextJSONHandler( |
| 618 &PrinterJobHandler::HandleFailureStatusUpdateResponse); | 585 &PrinterJobHandler::HandleFailureStatusUpdateResponse); |
| 619 } | 586 } |
| 620 request_ = new CloudPrintURLFetcher; | 587 request_ = new CloudPrintURLFetcher; |
| 621 request_->StartGetRequest( | 588 request_->StartGetRequest( |
| 622 CloudPrintHelpers::GetUrlForJobStatusUpdate(cloud_print_server_url_, | 589 CloudPrintHelpers::GetUrlForJobStatusUpdate(cloud_print_server_url_, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 633 next_json_data_handler_ = handler; | 600 next_json_data_handler_ = handler; |
| 634 next_data_handler_ = NULL; | 601 next_data_handler_ = NULL; |
| 635 } | 602 } |
| 636 | 603 |
| 637 void PrinterJobHandler::SetNextDataHandler(DataHandler handler) { | 604 void PrinterJobHandler::SetNextDataHandler(DataHandler handler) { |
| 638 next_data_handler_ = handler; | 605 next_data_handler_ = handler; |
| 639 next_json_data_handler_ = NULL; | 606 next_json_data_handler_ = NULL; |
| 640 } | 607 } |
| 641 | 608 |
| 642 bool PrinterJobHandler::HavePendingTasks() { | 609 bool PrinterJobHandler::HavePendingTasks() { |
| 643 return (job_check_pending_ || printer_update_pending_ || | 610 return (job_check_pending_ || printer_update_pending_); |
| 644 printer_delete_pending_); | |
| 645 } | 611 } |
| 646 | 612 |
| 647 void PrinterJobHandler::FailedFetchingJobData() { | 613 void PrinterJobHandler::FailedFetchingJobData() { |
| 648 if (!shutting_down_) { | 614 if (!shutting_down_) { |
| 649 LOG(ERROR) << "CP_PROXY: Failed fetching job data for printer: " << | 615 LOG(ERROR) << "CP_CONNECTOR: Failed fetching job data for printer: " << |
| 650 printer_info_.printer_name << ", job id: " << job_details_.job_id_; | 616 printer_info_.printer_name << ", job id: " << job_details_.job_id_; |
| 651 JobFailed(INVALID_JOB_DATA); | 617 JobFailed(INVALID_JOB_DATA); |
| 652 } | 618 } |
| 653 } | 619 } |
| 654 | 620 |
| 655 // The following methods are called on |print_thread_|. It is not safe to | 621 // The following methods are called on |print_thread_|. It is not safe to |
| 656 // access any members other than |job_handler_message_loop_proxy_|, | 622 // access any members other than |job_handler_message_loop_proxy_|, |
| 657 // |job_spooler_| and |print_system_|. | 623 // |job_spooler_| and |print_system_|. |
| 658 void PrinterJobHandler::DoPrint(const JobDetails& job_details, | 624 void PrinterJobHandler::DoPrint(const JobDetails& job_details, |
| 659 const std::string& printer_name) { | 625 const std::string& printer_name) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 681 } | 647 } |
| 682 | 648 |
| 683 void PrinterJobHandler::OnJobSpoolFailed() { | 649 void PrinterJobHandler::OnJobSpoolFailed() { |
| 684 DCHECK(MessageLoop::current() == print_thread_.message_loop()); | 650 DCHECK(MessageLoop::current() == print_thread_.message_loop()); |
| 685 job_spooler_ = NULL; | 651 job_spooler_ = NULL; |
| 686 job_handler_message_loop_proxy_->PostTask(FROM_HERE, | 652 job_handler_message_loop_proxy_->PostTask(FROM_HERE, |
| 687 NewRunnableMethod(this, | 653 NewRunnableMethod(this, |
| 688 &PrinterJobHandler::JobFailed, | 654 &PrinterJobHandler::JobFailed, |
| 689 PRINT_FAILED)); | 655 PRINT_FAILED)); |
| 690 } | 656 } |
| OLD | NEW |