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/print_system.h" | 5 #include "chrome/service/cloud_print/print_system.h" |
6 | 6 |
7 #include <cups/cups.h> | 7 #include <cups/cups.h> |
8 #include <dlfcn.h> | 8 #include <dlfcn.h> |
9 #include <errno.h> | 9 #include <errno.h> |
10 #include <pthread.h> | 10 #include <pthread.h> |
11 | 11 |
12 #include <algorithm> | 12 #include <algorithm> |
13 #include <list> | 13 #include <list> |
14 #include <map> | 14 #include <map> |
15 | 15 |
16 #include "base/bind.h" | 16 #include "base/bind.h" |
17 #include "base/files/file_path.h" | 17 #include "base/files/file_path.h" |
18 #include "base/json/json_reader.h" | 18 #include "base/json/json_reader.h" |
| 19 #include "base/location.h" |
19 #include "base/logging.h" | 20 #include "base/logging.h" |
20 #include "base/md5.h" | 21 #include "base/md5.h" |
21 #include "base/memory/scoped_ptr.h" | 22 #include "base/memory/scoped_ptr.h" |
22 #include "base/message_loop/message_loop.h" | |
23 #include "base/rand_util.h" | 23 #include "base/rand_util.h" |
| 24 #include "base/single_thread_task_runner.h" |
24 #include "base/strings/string_number_conversions.h" | 25 #include "base/strings/string_number_conversions.h" |
25 #include "base/strings/string_util.h" | 26 #include "base/strings/string_util.h" |
26 #include "base/strings/utf_string_conversions.h" | 27 #include "base/strings/utf_string_conversions.h" |
| 28 #include "base/thread_task_runner_handle.h" |
27 #include "base/values.h" | 29 #include "base/values.h" |
28 #include "chrome/common/cloud_print/cloud_print_constants.h" | 30 #include "chrome/common/cloud_print/cloud_print_constants.h" |
29 #include "chrome/common/crash_keys.h" | 31 #include "chrome/common/crash_keys.h" |
30 #include "chrome/service/cloud_print/cloud_print_service_helpers.h" | 32 #include "chrome/service/cloud_print/cloud_print_service_helpers.h" |
31 #include "printing/backend/cups_helper.h" | 33 #include "printing/backend/cups_helper.h" |
32 #include "printing/backend/print_backend.h" | 34 #include "printing/backend/print_backend.h" |
33 #include "printing/backend/print_backend_consts.h" | 35 #include "printing/backend/print_backend_consts.h" |
34 #include "url/gurl.h" | 36 #include "url/gurl.h" |
35 | 37 |
36 namespace { | 38 namespace { |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 explicit PrintServerWatcherCUPS(PrintSystemCUPS* print_system) | 178 explicit PrintServerWatcherCUPS(PrintSystemCUPS* print_system) |
177 : print_system_(print_system), | 179 : print_system_(print_system), |
178 delegate_(NULL) { | 180 delegate_(NULL) { |
179 } | 181 } |
180 | 182 |
181 // PrintSystem::PrintServerWatcher implementation. | 183 // PrintSystem::PrintServerWatcher implementation. |
182 bool StartWatching( | 184 bool StartWatching( |
183 PrintSystem::PrintServerWatcher::Delegate* delegate) override { | 185 PrintSystem::PrintServerWatcher::Delegate* delegate) override { |
184 delegate_ = delegate; | 186 delegate_ = delegate; |
185 printers_hash_ = GetPrintersHash(); | 187 printers_hash_ = GetPrintersHash(); |
186 base::MessageLoop::current()->PostDelayedTask( | 188 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
187 FROM_HERE, | 189 FROM_HERE, base::Bind(&PrintServerWatcherCUPS::CheckForUpdates, this), |
188 base::Bind(&PrintServerWatcherCUPS::CheckForUpdates, this), | |
189 print_system_->GetUpdateTimeout()); | 190 print_system_->GetUpdateTimeout()); |
190 return true; | 191 return true; |
191 } | 192 } |
192 | 193 |
193 bool StopWatching() override { | 194 bool StopWatching() override { |
194 delegate_ = NULL; | 195 delegate_ = NULL; |
195 return true; | 196 return true; |
196 } | 197 } |
197 | 198 |
198 void CheckForUpdates() { | 199 void CheckForUpdates() { |
199 if (delegate_ == NULL) | 200 if (delegate_ == NULL) |
200 return; // Orphan call. We have been stopped already. | 201 return; // Orphan call. We have been stopped already. |
201 VLOG(1) << "CP_CUPS: Checking for new printers"; | 202 VLOG(1) << "CP_CUPS: Checking for new printers"; |
202 std::string new_hash = GetPrintersHash(); | 203 std::string new_hash = GetPrintersHash(); |
203 if (printers_hash_ != new_hash) { | 204 if (printers_hash_ != new_hash) { |
204 printers_hash_ = new_hash; | 205 printers_hash_ = new_hash; |
205 delegate_->OnPrinterAdded(); | 206 delegate_->OnPrinterAdded(); |
206 } | 207 } |
207 base::MessageLoop::current()->PostDelayedTask( | 208 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
208 FROM_HERE, | 209 FROM_HERE, base::Bind(&PrintServerWatcherCUPS::CheckForUpdates, this), |
209 base::Bind(&PrintServerWatcherCUPS::CheckForUpdates, this), | |
210 print_system_->GetUpdateTimeout()); | 210 print_system_->GetUpdateTimeout()); |
211 } | 211 } |
212 | 212 |
213 protected: | 213 protected: |
214 ~PrintServerWatcherCUPS() override { StopWatching(); } | 214 ~PrintServerWatcherCUPS() override { StopWatching(); } |
215 | 215 |
216 private: | 216 private: |
217 std::string GetPrintersHash() { | 217 std::string GetPrintersHash() { |
218 printing::PrinterList printer_list; | 218 printing::PrinterList printer_list; |
219 print_system_->EnumeratePrinters(&printer_list); | 219 print_system_->EnumeratePrinters(&printer_list); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 bool StartWatching(PrintSystem::PrinterWatcher::Delegate* delegate) override { | 253 bool StartWatching(PrintSystem::PrinterWatcher::Delegate* delegate) override { |
254 scoped_refptr<printing::PrintBackend> print_backend( | 254 scoped_refptr<printing::PrintBackend> print_backend( |
255 printing::PrintBackend::CreateInstance(NULL)); | 255 printing::PrintBackend::CreateInstance(NULL)); |
256 crash_keys::ScopedPrinterInfo crash_key( | 256 crash_keys::ScopedPrinterInfo crash_key( |
257 print_backend->GetPrinterDriverInfo(printer_name_)); | 257 print_backend->GetPrinterDriverInfo(printer_name_)); |
258 if (delegate_ != NULL) | 258 if (delegate_ != NULL) |
259 StopWatching(); | 259 StopWatching(); |
260 delegate_ = delegate; | 260 delegate_ = delegate; |
261 settings_hash_ = GetSettingsHash(); | 261 settings_hash_ = GetSettingsHash(); |
262 // Schedule next job status update. | 262 // Schedule next job status update. |
263 base::MessageLoop::current()->PostDelayedTask( | 263 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
264 FROM_HERE, | 264 FROM_HERE, base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), |
265 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), | |
266 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); | 265 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); |
267 // Schedule next printer check. | 266 // Schedule next printer check. |
268 // TODO(gene): Randomize time for the next printer update. | 267 // TODO(gene): Randomize time for the next printer update. |
269 base::MessageLoop::current()->PostDelayedTask( | 268 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
270 FROM_HERE, | 269 FROM_HERE, base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), |
271 base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), | |
272 print_system_->GetUpdateTimeout()); | 270 print_system_->GetUpdateTimeout()); |
273 return true; | 271 return true; |
274 } | 272 } |
275 | 273 |
276 bool StopWatching() override { | 274 bool StopWatching() override { |
277 delegate_ = NULL; | 275 delegate_ = NULL; |
278 return true; | 276 return true; |
279 } | 277 } |
280 | 278 |
281 bool GetCurrentPrinterInfo( | 279 bool GetCurrentPrinterInfo( |
282 printing::PrinterBasicInfo* printer_info) override { | 280 printing::PrinterBasicInfo* printer_info) override { |
283 DCHECK(printer_info); | 281 DCHECK(printer_info); |
284 return print_system_->GetPrinterInfo(printer_name_, printer_info); | 282 return print_system_->GetPrinterInfo(printer_name_, printer_info); |
285 } | 283 } |
286 | 284 |
287 void JobStatusUpdate() { | 285 void JobStatusUpdate() { |
288 if (delegate_ == NULL) | 286 if (delegate_ == NULL) |
289 return; // Orphan call. We have been stopped already. | 287 return; // Orphan call. We have been stopped already. |
290 // For CUPS proxy, we are going to fire OnJobChanged notification | 288 // For CUPS proxy, we are going to fire OnJobChanged notification |
291 // periodically. Higher level will check if there are any outstanding | 289 // periodically. Higher level will check if there are any outstanding |
292 // jobs for this printer and check their status. If printer has no | 290 // jobs for this printer and check their status. If printer has no |
293 // outstanding jobs, OnJobChanged() will do nothing. | 291 // outstanding jobs, OnJobChanged() will do nothing. |
294 delegate_->OnJobChanged(); | 292 delegate_->OnJobChanged(); |
295 base::MessageLoop::current()->PostDelayedTask( | 293 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
296 FROM_HERE, | 294 FROM_HERE, base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), |
297 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), | |
298 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); | 295 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); |
299 } | 296 } |
300 | 297 |
301 void PrinterUpdate() { | 298 void PrinterUpdate() { |
302 if (delegate_ == NULL) | 299 if (delegate_ == NULL) |
303 return; // Orphan call. We have been stopped already. | 300 return; // Orphan call. We have been stopped already. |
304 VLOG(1) << "CP_CUPS: Checking for updates" | 301 VLOG(1) << "CP_CUPS: Checking for updates" |
305 << ", printer name: " << printer_name_; | 302 << ", printer name: " << printer_name_; |
306 if (print_system_->NotifyDelete() && | 303 if (print_system_->NotifyDelete() && |
307 !print_system_->IsValidPrinter(printer_name_)) { | 304 !print_system_->IsValidPrinter(printer_name_)) { |
308 delegate_->OnPrinterDeleted(); | 305 delegate_->OnPrinterDeleted(); |
309 VLOG(1) << "CP_CUPS: Printer deleted" | 306 VLOG(1) << "CP_CUPS: Printer deleted" |
310 << ", printer name: " << printer_name_; | 307 << ", printer name: " << printer_name_; |
311 } else { | 308 } else { |
312 std::string new_hash = GetSettingsHash(); | 309 std::string new_hash = GetSettingsHash(); |
313 if (settings_hash_ != new_hash) { | 310 if (settings_hash_ != new_hash) { |
314 settings_hash_ = new_hash; | 311 settings_hash_ = new_hash; |
315 delegate_->OnPrinterChanged(); | 312 delegate_->OnPrinterChanged(); |
316 VLOG(1) << "CP_CUPS: Printer configuration changed" | 313 VLOG(1) << "CP_CUPS: Printer configuration changed" |
317 << ", printer name: " << printer_name_; | 314 << ", printer name: " << printer_name_; |
318 } | 315 } |
319 } | 316 } |
320 base::MessageLoop::current()->PostDelayedTask( | 317 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
321 FROM_HERE, | 318 FROM_HERE, base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), |
322 base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), | |
323 print_system_->GetUpdateTimeout()); | 319 print_system_->GetUpdateTimeout()); |
324 } | 320 } |
325 | 321 |
326 protected: | 322 protected: |
327 ~PrinterWatcherCUPS() override { StopWatching(); } | 323 ~PrinterWatcherCUPS() override { StopWatching(); } |
328 | 324 |
329 private: | 325 private: |
330 std::string GetSettingsHash() { | 326 std::string GetSettingsHash() { |
331 printing::PrinterBasicInfo info; | 327 printing::PrinterBasicInfo info; |
332 if (!print_system_->GetPrinterInfo(printer_name_, &info)) | 328 if (!print_system_->GetPrinterInfo(printer_name_, &info)) |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 const std::string& print_data_mime_type, | 369 const std::string& print_data_mime_type, |
374 const std::string& printer_name, | 370 const std::string& printer_name, |
375 const std::string& job_title, | 371 const std::string& job_title, |
376 const std::vector<std::string>& tags, | 372 const std::vector<std::string>& tags, |
377 JobSpooler::Delegate* delegate) override { | 373 JobSpooler::Delegate* delegate) override { |
378 DCHECK(delegate); | 374 DCHECK(delegate); |
379 bool dry_run = false; | 375 bool dry_run = false; |
380 int job_id = print_system_->SpoolPrintJob( | 376 int job_id = print_system_->SpoolPrintJob( |
381 print_ticket, print_data_file_path, print_data_mime_type, | 377 print_ticket, print_data_file_path, print_data_mime_type, |
382 printer_name, job_title, tags, &dry_run); | 378 printer_name, job_title, tags, &dry_run); |
383 base::MessageLoop::current()->PostTask( | 379 base::ThreadTaskRunnerHandle::Get()->PostTask( |
384 FROM_HERE, | 380 FROM_HERE, |
385 base::Bind(&JobSpoolerCUPS::NotifyDelegate, delegate, job_id, dry_run)); | 381 base::Bind(&JobSpoolerCUPS::NotifyDelegate, delegate, job_id, dry_run)); |
386 return true; | 382 return true; |
387 } | 383 } |
388 | 384 |
389 static void NotifyDelegate(JobSpooler::Delegate* delegate, | 385 static void NotifyDelegate(JobSpooler::Delegate* delegate, |
390 int job_id, bool dry_run) { | 386 int job_id, bool dry_run) { |
391 if (dry_run || job_id) | 387 if (dry_run || job_id) |
392 delegate->OnJobSpoolSucceeded(job_id); | 388 delegate->OnJobSpoolSucceeded(job_id); |
393 else | 389 else |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 printer_it != it->printers.end(); ++printer_it) { | 487 printer_it != it->printers.end(); ++printer_it) { |
492 printer_it->printer_name = MakeFullPrinterName(it->url, | 488 printer_it->printer_name = MakeFullPrinterName(it->url, |
493 printer_it->printer_name); | 489 printer_it->printer_name); |
494 } | 490 } |
495 VLOG(1) << "CP_CUPS: Updated printers list" | 491 VLOG(1) << "CP_CUPS: Updated printers list" |
496 << ", server: " << it->url | 492 << ", server: " << it->url |
497 << ", # of printers: " << it->printers.size(); | 493 << ", # of printers: " << it->printers.size(); |
498 } | 494 } |
499 | 495 |
500 // Schedule next update. | 496 // Schedule next update. |
501 base::MessageLoop::current()->PostDelayedTask( | 497 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
502 FROM_HERE, | 498 FROM_HERE, base::Bind(&PrintSystemCUPS::UpdatePrinters, this), |
503 base::Bind(&PrintSystemCUPS::UpdatePrinters, this), | |
504 GetUpdateTimeout()); | 499 GetUpdateTimeout()); |
505 } | 500 } |
506 | 501 |
507 PrintSystem::PrintSystemResult PrintSystemCUPS::EnumeratePrinters( | 502 PrintSystem::PrintSystemResult PrintSystemCUPS::EnumeratePrinters( |
508 printing::PrinterList* printer_list) { | 503 printing::PrinterList* printer_list) { |
509 DCHECK(initialized_); | 504 DCHECK(initialized_); |
510 printer_list->clear(); | 505 printer_list->clear(); |
511 PrintServerList::iterator it; | 506 PrintServerList::iterator it; |
512 for (it = print_servers_.begin(); it != print_servers_.end(); ++it) { | 507 for (it = print_servers_.begin(); it != print_servers_.end(); ++it) { |
513 printer_list->insert(printer_list->end(), | 508 printer_list->insert(printer_list->end(), |
514 it->printers.begin(), it->printers.end()); | 509 it->printers.begin(), it->printers.end()); |
515 } | 510 } |
516 VLOG(1) << "CP_CUPS: Total printers enumerated: " << printer_list->size(); | 511 VLOG(1) << "CP_CUPS: Total printers enumerated: " << printer_list->size(); |
517 // TODO(sanjeevr): Maybe some day we want to report the actual server names | 512 // TODO(sanjeevr): Maybe some day we want to report the actual server names |
518 // for which the enumeration failed. | 513 // for which the enumeration failed. |
519 return PrintSystemResult(printer_enum_succeeded_, std::string()); | 514 return PrintSystemResult(printer_enum_succeeded_, std::string()); |
520 } | 515 } |
521 | 516 |
522 void PrintSystemCUPS::GetPrinterCapsAndDefaults( | 517 void PrintSystemCUPS::GetPrinterCapsAndDefaults( |
523 const std::string& printer_name, | 518 const std::string& printer_name, |
524 const PrinterCapsAndDefaultsCallback& callback) { | 519 const PrinterCapsAndDefaultsCallback& callback) { |
525 printing::PrinterCapsAndDefaults printer_info; | 520 printing::PrinterCapsAndDefaults printer_info; |
526 bool succeeded = GetPrinterCapsAndDefaults(printer_name, &printer_info); | 521 bool succeeded = GetPrinterCapsAndDefaults(printer_name, &printer_info); |
527 base::MessageLoop::current()->PostTask( | 522 base::ThreadTaskRunnerHandle::Get()->PostTask( |
528 FROM_HERE, | 523 FROM_HERE, base::Bind(&PrintSystemCUPS::RunCapsCallback, callback, |
529 base::Bind(&PrintSystemCUPS::RunCapsCallback, | 524 succeeded, printer_name, printer_info)); |
530 callback, | |
531 succeeded, | |
532 printer_name, | |
533 printer_info)); | |
534 } | 525 } |
535 | 526 |
536 bool PrintSystemCUPS::IsValidPrinter(const std::string& printer_name) { | 527 bool PrintSystemCUPS::IsValidPrinter(const std::string& printer_name) { |
537 return GetPrinterInfo(printer_name, NULL); | 528 return GetPrinterInfo(printer_name, NULL); |
538 } | 529 } |
539 | 530 |
540 bool PrintSystemCUPS::ValidatePrintTicket( | 531 bool PrintSystemCUPS::ValidatePrintTicket( |
541 const std::string& printer_name, | 532 const std::string& printer_name, |
542 const std::string& print_ticket_data, | 533 const std::string& print_ticket_data, |
543 const std::string& print_ticket_mime_type) { | 534 const std::string& print_ticket_mime_type) { |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 | 857 |
867 void PrintSystemCUPS::RunCapsCallback( | 858 void PrintSystemCUPS::RunCapsCallback( |
868 const PrinterCapsAndDefaultsCallback& callback, | 859 const PrinterCapsAndDefaultsCallback& callback, |
869 bool succeeded, | 860 bool succeeded, |
870 const std::string& printer_name, | 861 const std::string& printer_name, |
871 const printing::PrinterCapsAndDefaults& printer_info) { | 862 const printing::PrinterCapsAndDefaults& printer_info) { |
872 callback.Run(succeeded, printer_name, printer_info); | 863 callback.Run(succeeded, printer_name, printer_info); |
873 } | 864 } |
874 | 865 |
875 } // namespace cloud_print | 866 } // namespace cloud_print |
OLD | NEW |