Chromium Code Reviews| 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/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 67 printer_watcher_->StartWatching(this); | 67 printer_watcher_->StartWatching(this); |
| 68 CheckForJobs(kJobFetchReasonStartup); | 68 CheckForJobs(kJobFetchReasonStartup); |
| 69 return true; | 69 return true; |
| 70 } | 70 } |
| 71 | 71 |
| 72 std::string PrinterJobHandler::GetPrinterName() const { | 72 std::string PrinterJobHandler::GetPrinterName() const { |
| 73 return printer_info_.printer_name; | 73 return printer_info_.printer_name; |
| 74 } | 74 } |
| 75 | 75 |
| 76 void PrinterJobHandler::CheckForJobs(const std::string& reason) { | 76 void PrinterJobHandler::CheckForJobs(const std::string& reason) { |
| 77 VLOG(1) << "CP_CONNECTOR: CheckForJobs, id: " | 77 VLOG(1) << "CP_CONNECTOR: Checking for jobs" |
| 78 << printer_info_cloud_.printer_id | 78 << ", printer id: " << printer_info_cloud_.printer_id |
| 79 << ", reason: " << reason | 79 << ", reason: " << reason |
| 80 << ", task in progress: " << task_in_progress_; | 80 << ", task in progress: " << task_in_progress_; |
| 81 job_fetch_reason_ = reason; | 81 job_fetch_reason_ = reason; |
| 82 job_check_pending_ = true; | 82 job_check_pending_ = true; |
| 83 if (!task_in_progress_) { | 83 if (!task_in_progress_) { |
| 84 MessageLoop::current()->PostTask( | 84 MessageLoop::current()->PostTask( |
| 85 FROM_HERE, base::Bind(&PrinterJobHandler::Start, this)); | 85 FROM_HERE, base::Bind(&PrinterJobHandler::Start, this)); |
| 86 } | 86 } |
| 87 } | 87 } |
| 88 | 88 |
| 89 void PrinterJobHandler::Shutdown() { | 89 void PrinterJobHandler::Shutdown() { |
| 90 VLOG(1) << "CP_CONNECTOR: Printer job handler shutdown, id: " | 90 VLOG(1) << "CP_CONNECTOR: Shutting down printer job handler" |
| 91 << printer_info_cloud_.printer_id; | 91 << ", printer id: " << printer_info_cloud_.printer_id; |
| 92 Reset(); | 92 Reset(); |
| 93 shutting_down_ = true; | 93 shutting_down_ = true; |
| 94 while (!job_status_updater_list_.empty()) { | 94 while (!job_status_updater_list_.empty()) { |
| 95 // Calling Stop() will cause the OnJobCompleted to be called which will | 95 // Calling Stop() will cause the OnJobCompleted to be called which will |
| 96 // remove the updater object from the list. | 96 // remove the updater object from the list. |
| 97 job_status_updater_list_.front()->Stop(); | 97 job_status_updater_list_.front()->Stop(); |
| 98 } | 98 } |
| 99 } | 99 } |
| 100 | 100 |
| 101 // CloudPrintURLFetcher::Delegate implementation. | 101 // CloudPrintURLFetcher::Delegate implementation. |
| 102 CloudPrintURLFetcher::ResponseAction PrinterJobHandler::HandleRawResponse( | 102 CloudPrintURLFetcher::ResponseAction PrinterJobHandler::HandleRawResponse( |
| 103 const net::URLFetcher* source, | 103 const net::URLFetcher* source, |
| 104 const GURL& url, | 104 const GURL& url, |
| 105 const net::URLRequestStatus& status, | 105 const net::URLRequestStatus& status, |
| 106 int response_code, | 106 int response_code, |
| 107 const net::ResponseCookies& cookies, | 107 const net::ResponseCookies& cookies, |
| 108 const std::string& data) { | 108 const std::string& data) { |
| 109 // 415 (Unsupported media type) error while fetching data from the server | 109 // 415 (Unsupported media type) error while fetching data from the server |
| 110 // means data conversion error. Stop fetching process and mark job as error. | 110 // means data conversion error. Stop fetching process and mark job as error. |
| 111 if (next_data_handler_ == (&PrinterJobHandler::HandlePrintDataResponse) && | 111 if (next_data_handler_ == (&PrinterJobHandler::HandlePrintDataResponse) && |
| 112 response_code == net::HTTP_UNSUPPORTED_MEDIA_TYPE) { | 112 response_code == net::HTTP_UNSUPPORTED_MEDIA_TYPE) { |
| 113 VLOG(1) << "CP_CONNECTOR: Job failed. Unsupported media type."; | 113 VLOG(1) << "CP_CONNECTOR: Job failed (unsupported media type)"; |
| 114 MessageLoop::current()->PostTask( | 114 MessageLoop::current()->PostTask( |
| 115 FROM_HERE, | 115 FROM_HERE, |
| 116 base::Bind(&PrinterJobHandler::JobFailed, this, JOB_DOWNLOAD_FAILED)); | 116 base::Bind(&PrinterJobHandler::JobFailed, this, JOB_DOWNLOAD_FAILED)); |
| 117 return CloudPrintURLFetcher::STOP_PROCESSING; | 117 return CloudPrintURLFetcher::STOP_PROCESSING; |
| 118 } | 118 } |
| 119 return CloudPrintURLFetcher::CONTINUE_PROCESSING; | 119 return CloudPrintURLFetcher::CONTINUE_PROCESSING; |
| 120 } | 120 } |
| 121 | 121 |
| 122 CloudPrintURLFetcher::ResponseAction PrinterJobHandler::HandleRawData( | 122 CloudPrintURLFetcher::ResponseAction PrinterJobHandler::HandleRawData( |
| 123 const net::URLFetcher* source, | 123 const net::URLFetcher* source, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 135 bool succeeded) { | 135 bool succeeded) { |
| 136 DCHECK(next_json_data_handler_); | 136 DCHECK(next_json_data_handler_); |
| 137 return (this->*next_json_data_handler_)(source, url, json_data, succeeded); | 137 return (this->*next_json_data_handler_)(source, url, json_data, succeeded); |
| 138 } | 138 } |
| 139 | 139 |
| 140 void PrinterJobHandler::OnRequestGiveUp() { | 140 void PrinterJobHandler::OnRequestGiveUp() { |
| 141 // The only time we call CloudPrintURLFetcher::StartGetRequest() with a | 141 // The only time we call CloudPrintURLFetcher::StartGetRequest() with a |
| 142 // specified number of retries, is when we are trying to fetch print job | 142 // specified number of retries, is when we are trying to fetch print job |
| 143 // data. So, this function will be reached only if we failed to get job data. | 143 // data. So, this function will be reached only if we failed to get job data. |
| 144 // In that case, we should make job as error and should not try it later. | 144 // In that case, we should make job as error and should not try it later. |
| 145 VLOG(1) << "CP_CONNECTOR: Job failed. Giving up."; | 145 VLOG(1) << "CP_CONNECTOR: Job failed (giving up)"; |
| 146 MessageLoop::current()->PostTask( | 146 MessageLoop::current()->PostTask( |
| 147 FROM_HERE, | 147 FROM_HERE, |
| 148 base::Bind(&PrinterJobHandler::JobFailed, this, JOB_DOWNLOAD_FAILED)); | 148 base::Bind(&PrinterJobHandler::JobFailed, this, JOB_DOWNLOAD_FAILED)); |
| 149 } | 149 } |
| 150 | 150 |
| 151 CloudPrintURLFetcher::ResponseAction PrinterJobHandler::OnRequestAuthError() { | 151 CloudPrintURLFetcher::ResponseAction PrinterJobHandler::OnRequestAuthError() { |
| 152 // We got an Auth error and have no idea how long it will take to refresh | 152 // We got an Auth error and have no idea how long it will take to refresh |
| 153 // auth information (may take forever). We'll drop current request and | 153 // auth information (may take forever). We'll drop current request and |
| 154 // propagate this error to the upper level. After auth issues will be | 154 // propagate this error to the upper level. After auth issues will be |
| 155 // resolved, GCP connector will restart. | 155 // resolved, GCP connector will restart. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 const cloud_print::PlatformJobId& job_id) { | 207 const cloud_print::PlatformJobId& job_id) { |
| 208 DCHECK(MessageLoop::current() == print_thread_.message_loop()); | 208 DCHECK(MessageLoop::current() == print_thread_.message_loop()); |
| 209 job_spooler_ = NULL; | 209 job_spooler_ = NULL; |
| 210 job_handler_message_loop_proxy_->PostTask( | 210 job_handler_message_loop_proxy_->PostTask( |
| 211 FROM_HERE, base::Bind(&PrinterJobHandler::JobSpooled, this, job_id)); | 211 FROM_HERE, base::Bind(&PrinterJobHandler::JobSpooled, this, job_id)); |
| 212 } | 212 } |
| 213 | 213 |
| 214 void PrinterJobHandler::OnJobSpoolFailed() { | 214 void PrinterJobHandler::OnJobSpoolFailed() { |
| 215 DCHECK(MessageLoop::current() == print_thread_.message_loop()); | 215 DCHECK(MessageLoop::current() == print_thread_.message_loop()); |
| 216 job_spooler_ = NULL; | 216 job_spooler_ = NULL; |
| 217 VLOG(1) << "CP_CONNECTOR: Job failed. Job Spool Failed."; | 217 VLOG(1) << "CP_CONNECTOR: Job spool failed"; |
|
Albert Bodenhamer
2012/07/23 20:49:02
Should probably be "Job failed (spool failed)
Alex Yu
2012/07/23 21:16:51
Done.
| |
| 218 job_handler_message_loop_proxy_->PostTask( | 218 job_handler_message_loop_proxy_->PostTask( |
| 219 FROM_HERE, base::Bind(&PrinterJobHandler::JobFailed, this, PRINT_FAILED)); | 219 FROM_HERE, base::Bind(&PrinterJobHandler::JobFailed, this, PRINT_FAILED)); |
| 220 } | 220 } |
| 221 | 221 |
| 222 PrinterJobHandler::~PrinterJobHandler() { | 222 PrinterJobHandler::~PrinterJobHandler() { |
| 223 if (printer_watcher_) | 223 if (printer_watcher_) |
| 224 printer_watcher_->StopWatching(); | 224 printer_watcher_->StopWatching(); |
| 225 } | 225 } |
| 226 | 226 |
| 227 // Begin Response handlers | 227 // Begin Response handlers |
| 228 CloudPrintURLFetcher::ResponseAction | 228 CloudPrintURLFetcher::ResponseAction |
| 229 PrinterJobHandler::HandlePrinterUpdateResponse( | 229 PrinterJobHandler::HandlePrinterUpdateResponse( |
| 230 const net::URLFetcher* source, | 230 const net::URLFetcher* source, |
| 231 const GURL& url, | 231 const GURL& url, |
| 232 DictionaryValue* json_data, | 232 DictionaryValue* json_data, |
| 233 bool succeeded) { | 233 bool succeeded) { |
| 234 VLOG(1) << "CP_CONNECTOR: Handle printer update response, id: " | 234 VLOG(1) << "CP_CONNECTOR: Handling printer update response" |
| 235 << printer_info_cloud_.printer_id; | 235 << ", printer id: " << printer_info_cloud_.printer_id; |
| 236 // We are done here. Go to the Stop state | 236 // We are done here. Go to the Stop state |
| 237 VLOG(1) << "CP_CONNECTOR: Stopping PrinterJobHandler"; | 237 VLOG(1) << "CP_CONNECTOR: Stopping printer job handler" |
| 238 << ", printer id: " << printer_info_cloud_.printer_id; | |
| 238 MessageLoop::current()->PostTask( | 239 MessageLoop::current()->PostTask( |
| 239 FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this)); | 240 FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this)); |
| 240 return CloudPrintURLFetcher::STOP_PROCESSING; | 241 return CloudPrintURLFetcher::STOP_PROCESSING; |
| 241 } | 242 } |
| 242 | 243 |
| 243 CloudPrintURLFetcher::ResponseAction | 244 CloudPrintURLFetcher::ResponseAction |
| 244 PrinterJobHandler::HandleJobMetadataResponse( | 245 PrinterJobHandler::HandleJobMetadataResponse( |
| 245 const net::URLFetcher* source, | 246 const net::URLFetcher* source, |
| 246 const GURL& url, | 247 const GURL& url, |
| 247 DictionaryValue* json_data, | 248 DictionaryValue* json_data, |
| 248 bool succeeded) { | 249 bool succeeded) { |
| 249 VLOG(1) << "CP_CONNECTOR: Handle job metadata response, id: " | 250 VLOG(1) << "CP_CONNECTOR: Handling job metadata response" |
| 250 << printer_info_cloud_.printer_id; | 251 << ", printer id: " << printer_info_cloud_.printer_id; |
| 251 bool job_available = false; | 252 bool job_available = false; |
| 252 if (succeeded) { | 253 if (succeeded) { |
| 253 ListValue* job_list = NULL; | 254 ListValue* job_list = NULL; |
| 254 if (json_data->GetList(kJobListValue, &job_list) && job_list) { | 255 if (json_data->GetList(kJobListValue, &job_list) && job_list) { |
| 255 // Even though it is a job list, for now we are only interested in the | 256 // Even though it is a job list, for now we are only interested in the |
| 256 // first job | 257 // first job |
| 257 DictionaryValue* job_data = NULL; | 258 DictionaryValue* job_data = NULL; |
| 258 if (job_list->GetDictionary(0, &job_data)) { | 259 if (job_list->GetDictionary(0, &job_data)) { |
| 259 job_available = true; | 260 job_available = true; |
| 260 job_data->GetString(kIdValue, &job_details_.job_id_); | 261 job_data->GetString(kIdValue, &job_details_.job_id_); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 277 request_ = new CloudPrintURLFetcher; | 278 request_ = new CloudPrintURLFetcher; |
| 278 request_->StartGetRequest(GURL(print_ticket_url.c_str()), | 279 request_->StartGetRequest(GURL(print_ticket_url.c_str()), |
| 279 this, | 280 this, |
| 280 kCloudPrintAPIMaxRetryCount, | 281 kCloudPrintAPIMaxRetryCount, |
| 281 std::string()); | 282 std::string()); |
| 282 } | 283 } |
| 283 } | 284 } |
| 284 } | 285 } |
| 285 // If no jobs are available, go to the Stop state. | 286 // If no jobs are available, go to the Stop state. |
| 286 if (!job_available) { | 287 if (!job_available) { |
| 287 VLOG(1) << "CP_CONNECTOR: Stopping PrinterJobHandler"; | 288 VLOG(1) << "CP_CONNECTOR: Stopping printer job handler" |
| 289 << ", printer id: " << printer_info_cloud_.printer_id; | |
| 288 MessageLoop::current()->PostTask( | 290 MessageLoop::current()->PostTask( |
| 289 FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this)); | 291 FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this)); |
| 290 } | 292 } |
| 291 return CloudPrintURLFetcher::STOP_PROCESSING; | 293 return CloudPrintURLFetcher::STOP_PROCESSING; |
| 292 } | 294 } |
| 293 | 295 |
| 294 CloudPrintURLFetcher::ResponseAction | 296 CloudPrintURLFetcher::ResponseAction |
| 295 PrinterJobHandler::HandlePrintTicketResponse(const net::URLFetcher* source, | 297 PrinterJobHandler::HandlePrintTicketResponse(const net::URLFetcher* source, |
| 296 const GURL& url, | 298 const GURL& url, |
| 297 const std::string& data) { | 299 const std::string& data) { |
| 298 VLOG(1) << "CP_CONNECTOR: Handle print ticket response, id: " | 300 VLOG(1) << "CP_CONNECTOR: Handling print ticket response" |
| 299 << printer_info_cloud_.printer_id; | 301 << ", printer id: " << printer_info_cloud_.printer_id; |
| 300 if (print_system_->ValidatePrintTicket(printer_info_.printer_name, data)) { | 302 if (print_system_->ValidatePrintTicket(printer_info_.printer_name, data)) { |
| 301 job_details_.print_ticket_ = data; | 303 job_details_.print_ticket_ = data; |
| 302 SetNextDataHandler(&PrinterJobHandler::HandlePrintDataResponse); | 304 SetNextDataHandler(&PrinterJobHandler::HandlePrintDataResponse); |
| 303 request_ = new CloudPrintURLFetcher; | 305 request_ = new CloudPrintURLFetcher; |
| 304 std::string accept_headers = "Accept: "; | 306 std::string accept_headers = "Accept: "; |
| 305 accept_headers += print_system_->GetSupportedMimeTypes(); | 307 accept_headers += print_system_->GetSupportedMimeTypes(); |
| 306 request_->StartGetRequest(GURL(print_data_url_.c_str()), | 308 request_->StartGetRequest(GURL(print_data_url_.c_str()), |
| 307 this, | 309 this, |
| 308 kJobDataMaxRetryCount, | 310 kJobDataMaxRetryCount, |
| 309 accept_headers); | 311 accept_headers); |
| 310 } else { | 312 } else { |
| 311 // The print ticket was not valid. We are done here. | 313 // The print ticket was not valid. We are done here. |
| 312 FailedFetchingJobData(); | 314 FailedFetchingJobData(); |
| 313 } | 315 } |
| 314 return CloudPrintURLFetcher::STOP_PROCESSING; | 316 return CloudPrintURLFetcher::STOP_PROCESSING; |
| 315 } | 317 } |
| 316 | 318 |
| 317 CloudPrintURLFetcher::ResponseAction | 319 CloudPrintURLFetcher::ResponseAction |
| 318 PrinterJobHandler::HandlePrintDataResponse(const net::URLFetcher* source, | 320 PrinterJobHandler::HandlePrintDataResponse(const net::URLFetcher* source, |
| 319 const GURL& url, | 321 const GURL& url, |
| 320 const std::string& data) { | 322 const std::string& data) { |
| 321 VLOG(1) << "CP_CONNECTOR: Handle print data response, id: " | 323 VLOG(1) << "CP_CONNECTOR: Handling print data response" |
| 322 << printer_info_cloud_.printer_id; | 324 << ", printer id: " << printer_info_cloud_.printer_id; |
| 323 base::Closure next_task; | 325 base::Closure next_task; |
| 324 if (file_util::CreateTemporaryFile(&job_details_.print_data_file_path_)) { | 326 if (file_util::CreateTemporaryFile(&job_details_.print_data_file_path_)) { |
| 325 int ret = file_util::WriteFile(job_details_.print_data_file_path_, | 327 int ret = file_util::WriteFile(job_details_.print_data_file_path_, |
| 326 data.c_str(), | 328 data.c_str(), |
| 327 data.length()); | 329 data.length()); |
| 328 source->GetResponseHeaders()->GetMimeType( | 330 source->GetResponseHeaders()->GetMimeType( |
| 329 &job_details_.print_data_mime_type_); | 331 &job_details_.print_data_mime_type_); |
| 330 DCHECK(ret == static_cast<int>(data.length())); | 332 DCHECK(ret == static_cast<int>(data.length())); |
| 331 if (ret == static_cast<int>(data.length())) { | 333 if (ret == static_cast<int>(data.length())) { |
| 332 next_task = base::Bind(&PrinterJobHandler::StartPrinting, this); | 334 next_task = base::Bind(&PrinterJobHandler::StartPrinting, this); |
| 333 } | 335 } |
| 334 } | 336 } |
| 335 // If there was no task allocated above, then there was an error in | 337 // If there was no task allocated above, then there was an error in |
| 336 // saving the print data, bail out here. | 338 // saving the print data, bail out here. |
| 337 if (next_task.is_null()) { | 339 if (next_task.is_null()) { |
| 338 VLOG(1) << "CP_CONNECTOR: Job failed. Error saving print data."; | 340 VLOG(1) << "CP_CONNECTOR: Error saving print data" |
| 341 << ", printer id: " << printer_info_cloud_.printer_id; | |
| 339 next_task = base::Bind(&PrinterJobHandler::JobFailed, this, | 342 next_task = base::Bind(&PrinterJobHandler::JobFailed, this, |
| 340 JOB_DOWNLOAD_FAILED); | 343 JOB_DOWNLOAD_FAILED); |
| 341 } | 344 } |
| 342 MessageLoop::current()->PostTask(FROM_HERE, next_task); | 345 MessageLoop::current()->PostTask(FROM_HERE, next_task); |
| 343 return CloudPrintURLFetcher::STOP_PROCESSING; | 346 return CloudPrintURLFetcher::STOP_PROCESSING; |
| 344 } | 347 } |
| 345 | 348 |
| 346 CloudPrintURLFetcher::ResponseAction | 349 CloudPrintURLFetcher::ResponseAction |
| 347 PrinterJobHandler::HandleSuccessStatusUpdateResponse( | 350 PrinterJobHandler::HandleSuccessStatusUpdateResponse( |
| 348 const net::URLFetcher* source, | 351 const net::URLFetcher* source, |
| 349 const GURL& url, | 352 const GURL& url, |
| 350 DictionaryValue* json_data, | 353 DictionaryValue* json_data, |
| 351 bool succeeded) { | 354 bool succeeded) { |
| 352 VLOG(1) << "CP_CONNECTOR: Handle success status update response, id: " | 355 VLOG(1) << "CP_CONNECTOR: Handling success status update response" |
| 353 << printer_info_cloud_.printer_id; | 356 << ", printer id: " << printer_info_cloud_.printer_id; |
| 354 // The print job has been spooled locally. We now need to create an object | 357 // The print job has been spooled locally. We now need to create an object |
| 355 // that monitors the status of the job and updates the server. | 358 // that monitors the status of the job and updates the server. |
| 356 scoped_refptr<JobStatusUpdater> job_status_updater( | 359 scoped_refptr<JobStatusUpdater> job_status_updater( |
| 357 new JobStatusUpdater(printer_info_.printer_name, job_details_.job_id_, | 360 new JobStatusUpdater(printer_info_.printer_name, job_details_.job_id_, |
| 358 local_job_id_, cloud_print_server_url_, | 361 local_job_id_, cloud_print_server_url_, |
| 359 print_system_.get(), this)); | 362 print_system_.get(), this)); |
| 360 job_status_updater_list_.push_back(job_status_updater); | 363 job_status_updater_list_.push_back(job_status_updater); |
| 361 MessageLoop::current()->PostTask( | 364 MessageLoop::current()->PostTask( |
| 362 FROM_HERE, base::Bind(&JobStatusUpdater::UpdateStatus, | 365 FROM_HERE, base::Bind(&JobStatusUpdater::UpdateStatus, |
| 363 job_status_updater.get())); | 366 job_status_updater.get())); |
| 364 if (succeeded) { | 367 if (succeeded) { |
| 365 // Since we just printed successfully, we want to look for more jobs. | 368 // Since we just printed successfully, we want to look for more jobs. |
| 366 CheckForJobs(kJobFetchReasonQueryMore); | 369 CheckForJobs(kJobFetchReasonQueryMore); |
| 367 } | 370 } |
| 368 VLOG(1) << "CP_CONNECTOR: Stopping PrinterJobHandler"; | 371 VLOG(1) << "CP_CONNECTOR: Stopping printer job handler" |
| 372 << ", printer id: " << printer_info_cloud_.printer_id; | |
| 369 MessageLoop::current()->PostTask( | 373 MessageLoop::current()->PostTask( |
| 370 FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this)); | 374 FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this)); |
| 371 return CloudPrintURLFetcher::STOP_PROCESSING; | 375 return CloudPrintURLFetcher::STOP_PROCESSING; |
| 372 } | 376 } |
| 373 | 377 |
| 374 CloudPrintURLFetcher::ResponseAction | 378 CloudPrintURLFetcher::ResponseAction |
| 375 PrinterJobHandler::HandleFailureStatusUpdateResponse( | 379 PrinterJobHandler::HandleFailureStatusUpdateResponse( |
| 376 const net::URLFetcher* source, | 380 const net::URLFetcher* source, |
| 377 const GURL& url, | 381 const GURL& url, |
| 378 DictionaryValue* json_data, | 382 DictionaryValue* json_data, |
| 379 bool succeeded) { | 383 bool succeeded) { |
| 380 VLOG(1) << "CP_CONNECTOR: Handle failure status update response, id: " | 384 VLOG(1) << "CP_CONNECTOR: Handling failure status update response" |
| 381 << printer_info_cloud_.printer_id; | 385 << ", printer id: " << printer_info_cloud_.printer_id; |
| 382 MessageLoop::current()->PostTask( | 386 MessageLoop::current()->PostTask( |
| 383 FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this)); | 387 FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this)); |
| 384 return CloudPrintURLFetcher::STOP_PROCESSING; | 388 return CloudPrintURLFetcher::STOP_PROCESSING; |
| 385 } | 389 } |
| 386 | 390 |
| 387 void PrinterJobHandler::Start() { | 391 void PrinterJobHandler::Start() { |
| 388 VLOG(1) << "CP_CONNECTOR: Start printer job handler, id: " | 392 VLOG(1) << "CP_CONNECTOR: Starting printer job handler" |
| 389 << printer_info_cloud_.printer_id | 393 << ", printer id: " << printer_info_cloud_.printer_id |
| 390 << ", task in progress: " << task_in_progress_; | 394 << ", task in progress: " << task_in_progress_; |
| 391 if (task_in_progress_) { | 395 if (task_in_progress_) { |
| 392 // Multiple Starts can get posted because of multiple notifications | 396 // Multiple Starts can get posted because of multiple notifications |
| 393 // We want to ignore the other ones that happen when a task is in progress. | 397 // We want to ignore the other ones that happen when a task is in progress. |
| 394 return; | 398 return; |
| 395 } | 399 } |
| 396 Reset(); | 400 Reset(); |
| 397 if (!shutting_down_) { | 401 if (!shutting_down_) { |
| 398 // Check if we have work to do. | 402 // Check if we have work to do. |
| 399 if (HavePendingTasks()) { | 403 if (HavePendingTasks()) { |
| 400 if (!task_in_progress_ && printer_update_pending_) { | 404 if (!task_in_progress_ && printer_update_pending_) { |
| 401 printer_update_pending_ = false; | 405 printer_update_pending_ = false; |
| 402 task_in_progress_ = UpdatePrinterInfo(); | 406 task_in_progress_ = UpdatePrinterInfo(); |
| 403 VLOG(1) << "CP_CONNECTOR: Changed task in progress to: " << | 407 VLOG(1) << "CP_CONNECTOR: Changed task in progress" |
| 404 task_in_progress_; | 408 << ", printer id: " << printer_info_cloud_.printer_id |
| 409 << ", task in progress: " << task_in_progress_; | |
| 405 } | 410 } |
| 406 if (!task_in_progress_ && job_check_pending_) { | 411 if (!task_in_progress_ && job_check_pending_) { |
| 407 task_in_progress_ = true; | 412 task_in_progress_ = true; |
| 408 VLOG(1) << "CP_CONNECTOR: Changed task in progress to: " << | 413 VLOG(1) << "CP_CONNECTOR: Changed task in progress" |
| 409 task_in_progress_; | 414 ", printer id: " << printer_info_cloud_.printer_id |
| 415 << ", task in progress: " << task_in_progress_; | |
| 410 job_check_pending_ = false; | 416 job_check_pending_ = false; |
| 411 // We need to fetch any pending jobs for this printer | 417 // We need to fetch any pending jobs for this printer |
| 412 SetNextJSONHandler(&PrinterJobHandler::HandleJobMetadataResponse); | 418 SetNextJSONHandler(&PrinterJobHandler::HandleJobMetadataResponse); |
| 413 request_ = new CloudPrintURLFetcher; | 419 request_ = new CloudPrintURLFetcher; |
| 414 request_->StartGetRequest( | 420 request_->StartGetRequest( |
| 415 CloudPrintHelpers::GetUrlForJobFetch( | 421 CloudPrintHelpers::GetUrlForJobFetch( |
| 416 cloud_print_server_url_, printer_info_cloud_.printer_id, | 422 cloud_print_server_url_, printer_info_cloud_.printer_id, |
| 417 job_fetch_reason_), | 423 job_fetch_reason_), |
| 418 this, | 424 this, |
| 419 kCloudPrintAPIMaxRetryCount, | 425 kCloudPrintAPIMaxRetryCount, |
| 420 std::string()); | 426 std::string()); |
| 421 last_job_fetch_time_ = base::TimeTicks::Now(); | 427 last_job_fetch_time_ = base::TimeTicks::Now(); |
| 422 VLOG(1) << "Last job fetch time for printer " | 428 VLOG(1) << "CP_CONNECTOR: Last job fetch time" |
| 423 << printer_info_.printer_name.c_str() << " is " | 429 << ", printer name: " << printer_info_.printer_name.c_str() |
| 424 << last_job_fetch_time_.ToInternalValue(); | 430 << ", timestamp: " << last_job_fetch_time_.ToInternalValue(); |
| 425 job_fetch_reason_.clear(); | 431 job_fetch_reason_.clear(); |
| 426 } | 432 } |
| 427 } | 433 } |
| 428 } | 434 } |
| 429 } | 435 } |
| 430 | 436 |
| 431 void PrinterJobHandler::Stop() { | 437 void PrinterJobHandler::Stop() { |
| 432 VLOG(1) << "CP_CONNECTOR: Stop printer job handler, id: " | 438 VLOG(1) << "CP_CONNECTOR: Stopping printer job handler" |
| 433 << printer_info_cloud_.printer_id; | 439 << ", printer id: " << printer_info_cloud_.printer_id; |
| 434 task_in_progress_ = false; | 440 task_in_progress_ = false; |
| 435 VLOG(1) << "CP_CONNECTOR: Changed task in progress to: " << | 441 VLOG(1) << "CP_CONNECTOR: Changed task in progress" |
| 436 task_in_progress_; | 442 << ", printer id: " << printer_info_cloud_.printer_id |
| 443 << ", task in progress: " << task_in_progress_; | |
| 437 Reset(); | 444 Reset(); |
| 438 if (HavePendingTasks()) { | 445 if (HavePendingTasks()) { |
| 439 MessageLoop::current()->PostTask( | 446 MessageLoop::current()->PostTask( |
| 440 FROM_HERE, base::Bind(&PrinterJobHandler::Start, this)); | 447 FROM_HERE, base::Bind(&PrinterJobHandler::Start, this)); |
| 441 } | 448 } |
| 442 } | 449 } |
| 443 | 450 |
| 444 void PrinterJobHandler::StartPrinting() { | 451 void PrinterJobHandler::StartPrinting() { |
| 445 VLOG(1) << "CP_CONNECTOR: Start printing, id: " | 452 VLOG(1) << "CP_CONNECTOR: Starting printing" |
| 446 << printer_info_cloud_.printer_id; | 453 << ", printer id: " << printer_info_cloud_.printer_id; |
| 447 // We are done with the request object for now. | 454 // We are done with the request object for now. |
| 448 request_ = NULL; | 455 request_ = NULL; |
| 449 if (!shutting_down_) { | 456 if (!shutting_down_) { |
| 450 if (!print_thread_.Start()) { | 457 if (!print_thread_.Start()) { |
| 451 VLOG(1) << "CP_CONNECTOR: Failed to start print thread."; | 458 VLOG(1) << "CP_CONNECTOR: Failed to start print thread" |
| 459 << ", printer id: " << printer_info_cloud_.printer_id; | |
| 452 JobFailed(PRINT_FAILED); | 460 JobFailed(PRINT_FAILED); |
| 453 } else { | 461 } else { |
| 454 print_thread_.message_loop()->PostTask( | 462 print_thread_.message_loop()->PostTask( |
| 455 FROM_HERE, base::Bind(&PrinterJobHandler::DoPrint, this, job_details_, | 463 FROM_HERE, base::Bind(&PrinterJobHandler::DoPrint, this, job_details_, |
| 456 printer_info_.printer_name)); | 464 printer_info_.printer_name)); |
| 457 } | 465 } |
| 458 } | 466 } |
| 459 } | 467 } |
| 460 | 468 |
| 461 void PrinterJobHandler::Reset() { | 469 void PrinterJobHandler::Reset() { |
| 462 print_data_url_.clear(); | 470 print_data_url_.clear(); |
| 463 job_details_.Clear(); | 471 job_details_.Clear(); |
| 464 request_ = NULL; | 472 request_ = NULL; |
| 465 print_thread_.Stop(); | 473 print_thread_.Stop(); |
| 466 } | 474 } |
| 467 | 475 |
| 468 void PrinterJobHandler::UpdateJobStatus(cloud_print::PrintJobStatus status, | 476 void PrinterJobHandler::UpdateJobStatus(cloud_print::PrintJobStatus status, |
| 469 PrintJobError error) { | 477 PrintJobError error) { |
| 470 VLOG(1) << "CP_CONNECTOR: Update job status, id: " | 478 VLOG(1) << "CP_CONNECTOR: Updating job status" |
| 471 << printer_info_cloud_.printer_id; | 479 << ", printer id: " << printer_info_cloud_.printer_id |
| 480 << ", job id: " << job_details_.job_id_ | |
| 481 << ", job status: " << status; | |
| 472 if (shutting_down_) { | 482 if (shutting_down_) { |
| 473 VLOG(1) << "CP_CONNECTOR: Update job status aborted. Shutting down."; | 483 VLOG(1) << "CP_CONNECTOR: Job status update aborted (shutting down)" |
| 484 << ", printer id: " << printer_info_cloud_.printer_id | |
| 485 << ", job id: " << job_details_.job_id_; | |
| 474 return; | 486 return; |
| 475 } | 487 } |
| 476 if (job_details_.job_id_.empty()) { | 488 if (job_details_.job_id_.empty()) { |
| 477 VLOG(1) << "CP_CONNECTOR: Update job status aborted. Emtpy job id."; | 489 VLOG(1) << "CP_CONNECTOR: Job status update aborted (empty job id)" |
| 490 << ", printer id: " << printer_info_cloud_.printer_id; | |
| 478 return; | 491 return; |
| 479 } | 492 } |
| 480 | 493 |
| 481 VLOG(1) << "CP_CONNECTOR: Updating status, job id: " | |
| 482 << job_details_.job_id_ << ", status: " << status; | |
| 483 if (error == SUCCESS) { | 494 if (error == SUCCESS) { |
| 484 SetNextJSONHandler( | 495 SetNextJSONHandler( |
| 485 &PrinterJobHandler::HandleSuccessStatusUpdateResponse); | 496 &PrinterJobHandler::HandleSuccessStatusUpdateResponse); |
| 486 } else { | 497 } else { |
| 487 SetNextJSONHandler( | 498 SetNextJSONHandler( |
| 488 &PrinterJobHandler::HandleFailureStatusUpdateResponse); | 499 &PrinterJobHandler::HandleFailureStatusUpdateResponse); |
| 489 } | 500 } |
| 490 request_ = new CloudPrintURLFetcher; | 501 request_ = new CloudPrintURLFetcher; |
| 491 request_->StartGetRequest( | 502 request_->StartGetRequest( |
| 492 CloudPrintHelpers::GetUrlForJobStatusUpdate(cloud_print_server_url_, | 503 CloudPrintHelpers::GetUrlForJobStatusUpdate(cloud_print_server_url_, |
| 493 job_details_.job_id_, | 504 job_details_.job_id_, |
| 494 status), | 505 status), |
| 495 this, | 506 this, |
| 496 kCloudPrintAPIMaxRetryCount, | 507 kCloudPrintAPIMaxRetryCount, |
| 497 std::string()); | 508 std::string()); |
| 498 } | 509 } |
| 499 | 510 |
| 500 void PrinterJobHandler::SetNextJSONHandler(JSONDataHandler handler) { | 511 void PrinterJobHandler::SetNextJSONHandler(JSONDataHandler handler) { |
| 501 next_json_data_handler_ = handler; | 512 next_json_data_handler_ = handler; |
| 502 next_data_handler_ = NULL; | 513 next_data_handler_ = NULL; |
| 503 } | 514 } |
| 504 | 515 |
| 505 void PrinterJobHandler::SetNextDataHandler(DataHandler handler) { | 516 void PrinterJobHandler::SetNextDataHandler(DataHandler handler) { |
| 506 next_data_handler_ = handler; | 517 next_data_handler_ = handler; |
| 507 next_json_data_handler_ = NULL; | 518 next_json_data_handler_ = NULL; |
| 508 } | 519 } |
| 509 | 520 |
| 510 void PrinterJobHandler::JobFailed(PrintJobError error) { | 521 void PrinterJobHandler::JobFailed(PrintJobError error) { |
| 511 VLOG(1) << "CP_CONNECTOR: Job failed, printer id: " << | 522 VLOG(1) << "CP_CONNECTOR: Job failed" |
| 512 printer_info_cloud_.printer_id << " job id: " << job_details_.job_id_ << | 523 << ", printer id: " << printer_info_cloud_.printer_id |
| 513 " error: " << error; | 524 << ", job id: " << job_details_.job_id_ |
| 525 << ", error: " << error; | |
| 514 if (!shutting_down_) { | 526 if (!shutting_down_) { |
| 515 UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_ERROR, error); | 527 UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_ERROR, error); |
| 516 // This job failed, but others may be pending. Schedule a check. | 528 // This job failed, but others may be pending. Schedule a check. |
| 517 job_check_pending_ = true; | 529 job_check_pending_ = true; |
| 518 } | 530 } |
| 519 } | 531 } |
| 520 | 532 |
| 521 void PrinterJobHandler::JobSpooled(cloud_print::PlatformJobId local_job_id) { | 533 void PrinterJobHandler::JobSpooled(cloud_print::PlatformJobId local_job_id) { |
| 522 VLOG(1) << "CP_CONNECTOR: Job spooled, printer id: " | 534 VLOG(1) << "CP_CONNECTOR: Job spooled" |
| 523 << printer_info_cloud_.printer_id << ", job id: " << local_job_id; | 535 << ", printer id: " << printer_info_cloud_.printer_id |
| 536 << ", job id: " << local_job_id; | |
| 524 if (!shutting_down_) { | 537 if (!shutting_down_) { |
| 525 local_job_id_ = local_job_id; | 538 local_job_id_ = local_job_id; |
| 526 UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_IN_PROGRESS, SUCCESS); | 539 UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_IN_PROGRESS, SUCCESS); |
| 527 print_thread_.Stop(); | 540 print_thread_.Stop(); |
| 528 } | 541 } |
| 529 } | 542 } |
| 530 | 543 |
| 531 bool PrinterJobHandler::UpdatePrinterInfo() { | 544 bool PrinterJobHandler::UpdatePrinterInfo() { |
| 532 if (!printer_watcher_) { | 545 if (!printer_watcher_) { |
| 533 LOG(ERROR) << "CP_CONNECTOR: Printer watcher is missing." | 546 LOG(ERROR) << "CP_CONNECTOR: Printer watcher is missing." |
| 534 << "Check printer server url for printer id: " | 547 << " Check printer server url for printer id: " |
| 535 << printer_info_cloud_.printer_id; | 548 << printer_info_cloud_.printer_id; |
| 536 return false; | 549 return false; |
| 537 } | 550 } |
| 538 | 551 |
| 539 VLOG(1) << "CP_CONNECTOR: Update printer info, id: " | 552 VLOG(1) << "CP_CONNECTOR: Updating printer info" |
| 540 << printer_info_cloud_.printer_id; | 553 << ", printer id: " << printer_info_cloud_.printer_id; |
| 541 // We need to update the parts of the printer info that have changed | 554 // We need to update the parts of the printer info that have changed |
| 542 // (could be printer name, description, status or capabilities). | 555 // (could be printer name, description, status or capabilities). |
| 543 // First asynchronously fetch the capabilities. | 556 // First asynchronously fetch the capabilities. |
| 544 printing::PrinterBasicInfo printer_info; | 557 printing::PrinterBasicInfo printer_info; |
| 545 printer_watcher_->GetCurrentPrinterInfo(&printer_info); | 558 printer_watcher_->GetCurrentPrinterInfo(&printer_info); |
| 546 | 559 |
| 547 // Asynchronously fetch the printer caps and defaults. The story will | 560 // Asynchronously fetch the printer caps and defaults. The story will |
| 548 // continue in OnReceivePrinterCaps. | 561 // continue in OnReceivePrinterCaps. |
| 549 print_system_->GetPrinterCapsAndDefaults( | 562 print_system_->GetPrinterCapsAndDefaults( |
| 550 printer_info.printer_name.c_str(), | 563 printer_info.printer_name.c_str(), |
| 551 base::Bind(&PrinterJobHandler::OnReceivePrinterCaps, | 564 base::Bind(&PrinterJobHandler::OnReceivePrinterCaps, |
| 552 weak_ptr_factory_.GetWeakPtr())); | 565 weak_ptr_factory_.GetWeakPtr())); |
| 553 | 566 |
| 554 // While we are waiting for the data, pretend we have work to do and return | 567 // While we are waiting for the data, pretend we have work to do and return |
| 555 // true. | 568 // true. |
| 556 return true; | 569 return true; |
| 557 } | 570 } |
| 558 | 571 |
| 559 bool PrinterJobHandler::HavePendingTasks() { | 572 bool PrinterJobHandler::HavePendingTasks() { |
| 560 return (job_check_pending_ || printer_update_pending_); | 573 return (job_check_pending_ || printer_update_pending_); |
| 561 } | 574 } |
| 562 | 575 |
| 563 void PrinterJobHandler::FailedFetchingJobData() { | 576 void PrinterJobHandler::FailedFetchingJobData() { |
| 564 if (!shutting_down_) { | 577 if (!shutting_down_) { |
| 565 LOG(ERROR) << "CP_CONNECTOR: Failed fetching job data for printer: " << | 578 LOG(ERROR) << "CP_CONNECTOR: Failed fetching job data" |
| 566 printer_info_.printer_name << ", job id: " << job_details_.job_id_; | 579 << ", printer name: " << printer_info_.printer_name |
| 580 << ", job id: " << job_details_.job_id_; | |
| 567 JobFailed(INVALID_JOB_DATA); | 581 JobFailed(INVALID_JOB_DATA); |
| 568 } | 582 } |
| 569 } | 583 } |
| 570 | 584 |
| 571 void PrinterJobHandler::OnReceivePrinterCaps( | 585 void PrinterJobHandler::OnReceivePrinterCaps( |
| 572 bool succeeded, | 586 bool succeeded, |
| 573 const std::string& printer_name, | 587 const std::string& printer_name, |
| 574 const printing::PrinterCapsAndDefaults& caps_and_defaults) { | 588 const printing::PrinterCapsAndDefaults& caps_and_defaults) { |
| 575 printing::PrinterBasicInfo printer_info; | 589 printing::PrinterBasicInfo printer_info; |
| 576 if (printer_watcher_) | 590 if (printer_watcher_) |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 590 cloud_print::AddMultipartValueForUpload(kPrinterCapsValue, | 604 cloud_print::AddMultipartValueForUpload(kPrinterCapsValue, |
| 591 caps_and_defaults.printer_capabilities, mime_boundary, | 605 caps_and_defaults.printer_capabilities, mime_boundary, |
| 592 caps_and_defaults.caps_mime_type, &post_data); | 606 caps_and_defaults.caps_mime_type, &post_data); |
| 593 cloud_print::AddMultipartValueForUpload(kPrinterDefaultsValue, | 607 cloud_print::AddMultipartValueForUpload(kPrinterDefaultsValue, |
| 594 caps_and_defaults.printer_defaults, mime_boundary, | 608 caps_and_defaults.printer_defaults, mime_boundary, |
| 595 caps_and_defaults.defaults_mime_type, &post_data); | 609 caps_and_defaults.defaults_mime_type, &post_data); |
| 596 cloud_print::AddMultipartValueForUpload(kPrinterCapsHashValue, | 610 cloud_print::AddMultipartValueForUpload(kPrinterCapsHashValue, |
| 597 caps_hash, mime_boundary, std::string(), &post_data); | 611 caps_hash, mime_boundary, std::string(), &post_data); |
| 598 } | 612 } |
| 599 } else { | 613 } else { |
| 600 LOG(ERROR) << "Failed to get printer caps and defaults for printer: " | 614 LOG(ERROR) << "Failed to get printer caps and defaults" |
| 601 << printer_name; | 615 << ", printer name: " << printer_name; |
| 602 } | 616 } |
| 603 | 617 |
| 604 std::string tags_hash = | 618 std::string tags_hash = |
| 605 CloudPrintHelpers::GenerateHashOfStringMap(printer_info.options); | 619 CloudPrintHelpers::GenerateHashOfStringMap(printer_info.options); |
| 606 if (tags_hash != printer_info_cloud_.tags_hash) { | 620 if (tags_hash != printer_info_cloud_.tags_hash) { |
| 607 printer_info_cloud_.tags_hash = tags_hash; | 621 printer_info_cloud_.tags_hash = tags_hash; |
| 608 CloudPrintHelpers::GenerateMultipartPostDataForPrinterTags( | 622 CloudPrintHelpers::GenerateMultipartPostDataForPrinterTags( |
| 609 printer_info.options, mime_boundary, &post_data); | 623 printer_info.options, mime_boundary, &post_data); |
| 610 // Remove all the exising proxy tags. | 624 // Remove all the exising proxy tags. |
| 611 std::string cp_tag_wildcard(kProxyTagPrefix); | 625 std::string cp_tag_wildcard(kProxyTagPrefix); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 639 request_->StartPostRequest( | 653 request_->StartPostRequest( |
| 640 CloudPrintHelpers::GetUrlForPrinterUpdate( | 654 CloudPrintHelpers::GetUrlForPrinterUpdate( |
| 641 cloud_print_server_url_, printer_info_cloud_.printer_id), | 655 cloud_print_server_url_, printer_info_cloud_.printer_id), |
| 642 this, | 656 this, |
| 643 kCloudPrintAPIMaxRetryCount, | 657 kCloudPrintAPIMaxRetryCount, |
| 644 mime_type, | 658 mime_type, |
| 645 post_data, | 659 post_data, |
| 646 std::string()); | 660 std::string()); |
| 647 } else { | 661 } else { |
| 648 // We are done here. Go to the Stop state | 662 // We are done here. Go to the Stop state |
| 649 VLOG(1) << "CP_CONNECTOR: Stopping PrinterJobHandler"; | 663 VLOG(1) << "CP_CONNECTOR: Stopping printer job handler" |
| 664 << ", printer name: " << printer_name; | |
| 650 MessageLoop::current()->PostTask( | 665 MessageLoop::current()->PostTask( |
| 651 FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this)); | 666 FROM_HERE, base::Bind(&PrinterJobHandler::Stop, this)); |
| 652 } | 667 } |
| 653 } | 668 } |
| 654 | 669 |
| 655 // The following methods are called on |print_thread_|. It is not safe to | 670 // The following methods are called on |print_thread_|. It is not safe to |
| 656 // access any members other than |job_handler_message_loop_proxy_|, | 671 // access any members other than |job_handler_message_loop_proxy_|, |
| 657 // |job_spooler_| and |print_system_|. | 672 // |job_spooler_| and |print_system_|. |
| 658 void PrinterJobHandler::DoPrint(const JobDetails& job_details, | 673 void PrinterJobHandler::DoPrint(const JobDetails& job_details, |
| 659 const std::string& printer_name) { | 674 const std::string& printer_name) { |
| 660 job_spooler_ = print_system_->CreateJobSpooler(); | 675 job_spooler_ = print_system_->CreateJobSpooler(); |
| 661 DCHECK(job_spooler_); | 676 DCHECK(job_spooler_); |
| 662 if (!job_spooler_ || !job_spooler_->Spool(job_details.print_ticket_, | 677 if (!job_spooler_ || !job_spooler_->Spool(job_details.print_ticket_, |
| 663 job_details.print_data_file_path_, | 678 job_details.print_data_file_path_, |
| 664 job_details.print_data_mime_type_, | 679 job_details.print_data_mime_type_, |
| 665 printer_name, | 680 printer_name, |
| 666 job_details.job_title_, | 681 job_details.job_title_, |
| 667 job_details.tags_, | 682 job_details.tags_, |
| 668 this)) { | 683 this)) { |
| 669 OnJobSpoolFailed(); | 684 OnJobSpoolFailed(); |
| 670 } | 685 } |
| 671 } | 686 } |
| OLD | NEW |