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 |