OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/browser/ui/webui/settings/chromeos/cups_printers_handler.h" | 5 #include "chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
12 #include "base/json/json_string_value_serializer.h" | 12 #include "base/json/json_string_value_serializer.h" |
13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
14 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
15 #include "base/path_service.h" | 15 #include "base/path_service.h" |
16 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
17 #include "base/threading/sequenced_task_runner_handle.h" | 17 #include "base/threading/sequenced_task_runner_handle.h" |
18 #include "base/values.h" | 18 #include "base/values.h" |
19 #include "chrome/browser/browser_process.h" | 19 #include "chrome/browser/browser_process.h" |
| 20 #include "chrome/browser/chromeos/printing/combining_printer_detector.h" |
20 #include "chrome/browser/chromeos/printing/ppd_provider_factory.h" | 21 #include "chrome/browser/chromeos/printing/ppd_provider_factory.h" |
21 #include "chrome/browser/chromeos/printing/printer_configurer.h" | 22 #include "chrome/browser/chromeos/printing/printer_configurer.h" |
22 #include "chrome/browser/chromeos/printing/printer_discoverer.h" | |
23 #include "chrome/browser/chromeos/printing/printer_info.h" | 23 #include "chrome/browser/chromeos/printing/printer_info.h" |
24 #include "chrome/browser/chromeos/printing/printers_manager_factory.h" | 24 #include "chrome/browser/chromeos/printing/printers_manager_factory.h" |
| 25 #include "chrome/browser/chromeos/printing/usb_printer_detector.h" |
| 26 #include "chrome/browser/chromeos/printing/usb_printer_detector_factory.h" |
25 #include "chrome/browser/download/download_prefs.h" | 27 #include "chrome/browser/download/download_prefs.h" |
26 #include "chrome/browser/profiles/profile.h" | 28 #include "chrome/browser/profiles/profile.h" |
27 #include "chrome/browser/ui/browser_finder.h" | 29 #include "chrome/browser/ui/browser_finder.h" |
28 #include "chrome/browser/ui/browser_window.h" | 30 #include "chrome/browser/ui/browser_window.h" |
29 #include "chrome/browser/ui/chrome_select_file_policy.h" | 31 #include "chrome/browser/ui/chrome_select_file_policy.h" |
30 #include "chrome/common/chrome_paths.h" | 32 #include "chrome/common/chrome_paths.h" |
31 #include "chromeos/dbus/dbus_thread_manager.h" | 33 #include "chromeos/dbus/dbus_thread_manager.h" |
32 #include "chromeos/dbus/debug_daemon_client.h" | 34 #include "chromeos/dbus/debug_daemon_client.h" |
33 #include "chromeos/printing/ppd_cache.h" | 35 #include "chromeos/printing/ppd_cache.h" |
34 #include "chromeos/printing/ppd_provider.h" | 36 #include "chromeos/printing/ppd_provider.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 // empty string if the input is just a backslash. | 121 // empty string if the input is just a backslash. |
120 queue = queue.substr(1); | 122 queue = queue.substr(1); |
121 } | 123 } |
122 | 124 |
123 return queue; | 125 return queue; |
124 } | 126 } |
125 | 127 |
126 } // namespace | 128 } // namespace |
127 | 129 |
128 CupsPrintersHandler::CupsPrintersHandler(content::WebUI* webui) | 130 CupsPrintersHandler::CupsPrintersHandler(content::WebUI* webui) |
129 : printer_discoverer_(nullptr), | 131 : printer_detector_(nullptr), |
130 profile_(Profile::FromWebUI(webui)), | 132 profile_(Profile::FromWebUI(webui)), |
131 weak_factory_(this) { | 133 weak_factory_(this) { |
132 ppd_provider_ = printing::CreateProvider(profile_); | 134 ppd_provider_ = printing::CreateProvider(profile_); |
133 printer_configurer_ = chromeos::PrinterConfigurer::Create(profile_); | 135 printer_configurer_ = PrinterConfigurer::Create(profile_); |
134 } | 136 } |
135 | 137 |
136 CupsPrintersHandler::~CupsPrintersHandler() {} | 138 CupsPrintersHandler::~CupsPrintersHandler() {} |
137 | 139 |
138 void CupsPrintersHandler::RegisterMessages() { | 140 void CupsPrintersHandler::RegisterMessages() { |
139 web_ui()->RegisterMessageCallback( | 141 web_ui()->RegisterMessageCallback( |
140 "getCupsPrintersList", | 142 "getCupsPrintersList", |
141 base::Bind(&CupsPrintersHandler::HandleGetCupsPrintersList, | 143 base::Bind(&CupsPrintersHandler::HandleGetCupsPrintersList, |
142 base::Unretained(this))); | 144 base::Unretained(this))); |
143 web_ui()->RegisterMessageCallback( | 145 web_ui()->RegisterMessageCallback( |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 CHECK(args->GetString(1, &printer_name)); | 219 CHECK(args->GetString(1, &printer_name)); |
218 PrintersManager* prefs = | 220 PrintersManager* prefs = |
219 PrintersManagerFactory::GetForBrowserContext(profile_); | 221 PrintersManagerFactory::GetForBrowserContext(profile_); |
220 auto printer = prefs->GetPrinter(printer_id); | 222 auto printer = prefs->GetPrinter(printer_id); |
221 if (!printer) | 223 if (!printer) |
222 return; | 224 return; |
223 | 225 |
224 Printer::PrinterProtocol protocol = printer->GetProtocol(); | 226 Printer::PrinterProtocol protocol = printer->GetProtocol(); |
225 prefs->RemovePrinter(printer_id); | 227 prefs->RemovePrinter(printer_id); |
226 | 228 |
227 chromeos::DebugDaemonClient* client = | 229 DebugDaemonClient* client = DBusThreadManager::Get()->GetDebugDaemonClient(); |
228 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); | |
229 client->CupsRemovePrinter(printer_name, | 230 client->CupsRemovePrinter(printer_name, |
230 base::Bind(&OnRemovedPrinter, protocol), | 231 base::Bind(&OnRemovedPrinter, protocol), |
231 base::Bind(&base::DoNothing)); | 232 base::Bind(&base::DoNothing)); |
232 } | 233 } |
233 | 234 |
234 void CupsPrintersHandler::HandleGetPrinterInfo(const base::ListValue* args) { | 235 void CupsPrintersHandler::HandleGetPrinterInfo(const base::ListValue* args) { |
235 DCHECK(args); | 236 DCHECK(args); |
236 std::string callback_id; | 237 std::string callback_id; |
237 if (!args->GetString(0, &callback_id)) { | 238 if (!args->GetString(0, &callback_id)) { |
238 NOTREACHED() << "Expected request for a promise"; | 239 NOTREACHED() << "Expected request for a promise"; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 if (printer_protocol == kIppScheme) { | 284 if (printer_protocol == kIppScheme) { |
284 port = kIppPort; | 285 port = kIppPort; |
285 } else if (printer_protocol == kIppsScheme) { | 286 } else if (printer_protocol == kIppsScheme) { |
286 // ipps is ipp over https so it uses the https port. | 287 // ipps is ipp over https so it uses the https port. |
287 port = kIppsPort; | 288 port = kIppsPort; |
288 } else { | 289 } else { |
289 NOTREACHED() << "Unrecognized protocol. Port was not set."; | 290 NOTREACHED() << "Unrecognized protocol. Port was not set."; |
290 } | 291 } |
291 } | 292 } |
292 | 293 |
293 ::chromeos::QueryIppPrinter( | 294 QueryIppPrinter(host.as_string(), port, printer_queue, |
294 host.as_string(), port, printer_queue, | 295 base::Bind(&CupsPrintersHandler::OnPrinterInfo, |
295 base::Bind(&CupsPrintersHandler::OnPrinterInfo, | 296 weak_factory_.GetWeakPtr(), callback_id)); |
296 weak_factory_.GetWeakPtr(), callback_id)); | |
297 } | 297 } |
298 | 298 |
299 void CupsPrintersHandler::OnPrinterInfo(const std::string& callback_id, | 299 void CupsPrintersHandler::OnPrinterInfo(const std::string& callback_id, |
300 bool success, | 300 bool success, |
301 const std::string& make, | 301 const std::string& make, |
302 const std::string& model, | 302 const std::string& model, |
303 bool ipp_everywhere) { | 303 bool ipp_everywhere) { |
304 if (!success) { | 304 if (!success) { |
305 base::DictionaryValue reject; | 305 base::DictionaryValue reject; |
306 reject.SetString("message", "Querying printer failed"); | 306 reject.SetString("message", "Querying printer failed"); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 | 383 |
384 // Copy the printer for the configurer. Ownership needs to be transfered to | 384 // Copy the printer for the configurer. Ownership needs to be transfered to |
385 // the receiver of the callback. | 385 // the receiver of the callback. |
386 const Printer printer_copy = *printer; | 386 const Printer printer_copy = *printer; |
387 printer_configurer_->SetUpPrinter( | 387 printer_configurer_->SetUpPrinter( |
388 printer_copy, | 388 printer_copy, |
389 base::Bind(&CupsPrintersHandler::OnAddedPrinter, | 389 base::Bind(&CupsPrintersHandler::OnAddedPrinter, |
390 weak_factory_.GetWeakPtr(), base::Passed(&printer))); | 390 weak_factory_.GetWeakPtr(), base::Passed(&printer))); |
391 } | 391 } |
392 | 392 |
393 void CupsPrintersHandler::OnAddedPrinter( | 393 void CupsPrintersHandler::OnAddedPrinter(std::unique_ptr<Printer> printer, |
394 std::unique_ptr<Printer> printer, | 394 PrinterSetupResult result_code) { |
395 chromeos::PrinterSetupResult result_code) { | |
396 std::string printer_name = printer->display_name(); | 395 std::string printer_name = printer->display_name(); |
397 UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterSetupResult", result_code, | 396 UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterSetupResult", result_code, |
398 chromeos::PrinterSetupResult::kMaxValue); | 397 PrinterSetupResult::kMaxValue); |
399 switch (result_code) { | 398 switch (result_code) { |
400 case chromeos::PrinterSetupResult::kSuccess: { | 399 case PrinterSetupResult::kSuccess: { |
401 UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterAdded", | 400 UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterAdded", |
402 printer->GetProtocol(), Printer::kProtocolMax); | 401 printer->GetProtocol(), Printer::kProtocolMax); |
403 auto* manager = PrintersManagerFactory::GetForBrowserContext(profile_); | 402 auto* manager = PrintersManagerFactory::GetForBrowserContext(profile_); |
404 manager->PrinterInstalled(*printer); | 403 manager->PrinterInstalled(*printer); |
405 manager->RegisterPrinter(std::move(printer)); | 404 manager->RegisterPrinter(std::move(printer)); |
406 break; | 405 break; |
407 } | 406 } |
408 case chromeos::PrinterSetupResult::kPpdNotFound: | 407 case PrinterSetupResult::kPpdNotFound: |
409 LOG(WARNING) << "Could not locate requested PPD"; | 408 LOG(WARNING) << "Could not locate requested PPD"; |
410 break; | 409 break; |
411 case chromeos::PrinterSetupResult::kPpdTooLarge: | 410 case PrinterSetupResult::kPpdTooLarge: |
412 LOG(WARNING) << "PPD is too large"; | 411 LOG(WARNING) << "PPD is too large"; |
413 break; | 412 break; |
414 case chromeos::PrinterSetupResult::kPpdUnretrievable: | 413 case PrinterSetupResult::kPpdUnretrievable: |
415 LOG(WARNING) << "Could not retrieve PPD from server"; | 414 LOG(WARNING) << "Could not retrieve PPD from server"; |
416 break; | 415 break; |
417 case chromeos::PrinterSetupResult::kInvalidPpd: | 416 case PrinterSetupResult::kInvalidPpd: |
418 LOG(WARNING) << "Provided PPD is invalid."; | 417 LOG(WARNING) << "Provided PPD is invalid."; |
419 break; | 418 break; |
420 case chromeos::PrinterSetupResult::kPrinterUnreachable: | 419 case PrinterSetupResult::kPrinterUnreachable: |
421 LOG(WARNING) << "Could not contact printer for configuration"; | 420 LOG(WARNING) << "Could not contact printer for configuration"; |
422 break; | 421 break; |
423 case chromeos::PrinterSetupResult::kDbusError: | 422 case PrinterSetupResult::kDbusError: |
424 case chromeos::PrinterSetupResult::kFatalError: | 423 case PrinterSetupResult::kFatalError: |
425 LOG(ERROR) << "Unrecoverable error. Reboot required."; | 424 LOG(ERROR) << "Unrecoverable error. Reboot required."; |
426 break; | 425 break; |
427 case chromeos::PrinterSetupResult::kMaxValue: | 426 case PrinterSetupResult::kMaxValue: |
428 NOTREACHED() << "This is not an expected value"; | 427 NOTREACHED() << "This is not an expected value"; |
429 break; | 428 break; |
430 } | 429 } |
431 CallJavascriptFunction( | 430 CallJavascriptFunction( |
432 "cr.webUIListenerCallback", base::Value("on-add-cups-printer"), | 431 "cr.webUIListenerCallback", base::Value("on-add-cups-printer"), |
433 base::Value(result_code == chromeos::PrinterSetupResult::kSuccess), | 432 base::Value(result_code == PrinterSetupResult::kSuccess), |
434 base::Value(printer_name)); | 433 base::Value(printer_name)); |
435 } | 434 } |
436 | 435 |
437 void CupsPrintersHandler::OnAddPrinterError() { | 436 void CupsPrintersHandler::OnAddPrinterError() { |
438 FireWebUIListener("on-add-cups-printer", base::Value(false), base::Value("")); | 437 FireWebUIListener("on-add-cups-printer", base::Value(false), base::Value("")); |
439 } | 438 } |
440 | 439 |
441 void CupsPrintersHandler::HandleGetCupsPrinterManufacturers( | 440 void CupsPrintersHandler::HandleGetCupsPrinterManufacturers( |
442 const base::ListValue* args) { | 441 const base::ListValue* args) { |
443 AllowJavascript(); | 442 AllowJavascript(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()) | 487 chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()) |
489 ->window() | 488 ->window() |
490 ->GetNativeWindow(); | 489 ->GetNativeWindow(); |
491 select_file_dialog_->SelectFile( | 490 select_file_dialog_->SelectFile( |
492 ui::SelectFileDialog::SELECT_OPEN_FILE, base::string16(), downloads_path, | 491 ui::SelectFileDialog::SELECT_OPEN_FILE, base::string16(), downloads_path, |
493 nullptr, 0, FILE_PATH_LITERAL(""), owning_window, nullptr); | 492 nullptr, 0, FILE_PATH_LITERAL(""), owning_window, nullptr); |
494 } | 493 } |
495 | 494 |
496 void CupsPrintersHandler::ResolveManufacturersDone( | 495 void CupsPrintersHandler::ResolveManufacturersDone( |
497 const std::string& js_callback, | 496 const std::string& js_callback, |
498 chromeos::printing::PpdProvider::CallbackResultCode result_code, | 497 printing::PpdProvider::CallbackResultCode result_code, |
499 const std::vector<std::string>& manufacturers) { | 498 const std::vector<std::string>& manufacturers) { |
500 auto manufacturers_value = base::MakeUnique<base::ListValue>(); | 499 auto manufacturers_value = base::MakeUnique<base::ListValue>(); |
501 if (result_code == chromeos::printing::PpdProvider::SUCCESS) { | 500 if (result_code == printing::PpdProvider::SUCCESS) { |
502 manufacturers_value->AppendStrings(manufacturers); | 501 manufacturers_value->AppendStrings(manufacturers); |
503 } | 502 } |
504 base::DictionaryValue response; | 503 base::DictionaryValue response; |
505 response.SetBoolean("success", | 504 response.SetBoolean("success", result_code == printing::PpdProvider::SUCCESS); |
506 result_code == chromeos::printing::PpdProvider::SUCCESS); | |
507 response.Set("manufacturers", std::move(manufacturers_value)); | 505 response.Set("manufacturers", std::move(manufacturers_value)); |
508 ResolveJavascriptCallback(base::Value(js_callback), response); | 506 ResolveJavascriptCallback(base::Value(js_callback), response); |
509 } | 507 } |
510 | 508 |
511 void CupsPrintersHandler::ResolvePrintersDone( | 509 void CupsPrintersHandler::ResolvePrintersDone( |
512 const std::string& js_callback, | 510 const std::string& js_callback, |
513 chromeos::printing::PpdProvider::CallbackResultCode result_code, | 511 printing::PpdProvider::CallbackResultCode result_code, |
514 const std::vector<std::string>& printers) { | 512 const std::vector<std::string>& printers) { |
515 auto printers_value = base::MakeUnique<base::ListValue>(); | 513 auto printers_value = base::MakeUnique<base::ListValue>(); |
516 if (result_code == chromeos::printing::PpdProvider::SUCCESS) { | 514 if (result_code == printing::PpdProvider::SUCCESS) { |
517 printers_value->AppendStrings(printers); | 515 printers_value->AppendStrings(printers); |
518 } | 516 } |
519 base::DictionaryValue response; | 517 base::DictionaryValue response; |
520 response.SetBoolean("success", | 518 response.SetBoolean("success", result_code == printing::PpdProvider::SUCCESS); |
521 result_code == chromeos::printing::PpdProvider::SUCCESS); | |
522 response.Set("models", std::move(printers_value)); | 519 response.Set("models", std::move(printers_value)); |
523 ResolveJavascriptCallback(base::Value(js_callback), response); | 520 ResolveJavascriptCallback(base::Value(js_callback), response); |
524 } | 521 } |
525 | 522 |
526 void CupsPrintersHandler::FileSelected(const base::FilePath& path, | 523 void CupsPrintersHandler::FileSelected(const base::FilePath& path, |
527 int index, | 524 int index, |
528 void* params) { | 525 void* params) { |
529 DCHECK(!webui_callback_id_.empty()); | 526 DCHECK(!webui_callback_id_.empty()); |
530 ResolveJavascriptCallback(base::Value(webui_callback_id_), | 527 ResolveJavascriptCallback(base::Value(webui_callback_id_), |
531 base::Value(path.value())); | 528 base::Value(path.value())); |
532 webui_callback_id_.clear(); | 529 webui_callback_id_.clear(); |
533 } | 530 } |
534 | 531 |
535 void CupsPrintersHandler::HandleStartDiscovery(const base::ListValue* args) { | 532 void CupsPrintersHandler::HandleStartDiscovery(const base::ListValue* args) { |
536 if (!printer_discoverer_.get()) { | 533 // Create (or recreate) the printer_detector_. If one already existed, we |
537 printer_discoverer_ = | 534 // want to start over anyways. |
538 chromeos::PrinterDiscoverer::CreateForProfile(profile_); | 535 printer_detector_ = CombiningPrinterDetector::Create(); |
539 } | 536 PrinterDetector* usb_detector = |
540 | 537 UsbPrinterDetectorFactory::GetInstance()->Get(profile_); |
541 printer_discoverer_->AddObserver(this); | 538 DCHECK(usb_detector); |
| 539 printer_detector_->AddDetector(usb_detector); |
| 540 printer_detector_->AddObserver(this); |
| 541 OnPrintersFound(printer_detector_->GetPrinters()); |
| 542 printer_detector_->Start(); |
542 } | 543 } |
543 | 544 |
544 void CupsPrintersHandler::HandleStopDiscovery(const base::ListValue* args) { | 545 void CupsPrintersHandler::HandleStopDiscovery(const base::ListValue* args) { |
545 printer_discoverer_.reset(); | 546 printer_detector_.reset(); |
546 } | 547 } |
547 | 548 |
548 void CupsPrintersHandler::OnPrintersFound( | 549 void CupsPrintersHandler::OnPrintersFound( |
549 const std::vector<Printer>& printers) { | 550 const std::vector<Printer>& printers) { |
550 std::unique_ptr<base::ListValue> printers_list = | 551 std::unique_ptr<base::ListValue> printers_list = |
551 base::MakeUnique<base::ListValue>(); | 552 base::MakeUnique<base::ListValue>(); |
552 for (const auto& printer : printers) { | 553 // Filter out already-configured printers as we go. |
553 printers_list->Append(GetPrinterInfo(printer)); | 554 PrintersManager* printers_manager = |
| 555 PrintersManagerFactory::GetForBrowserContext(profile_); |
| 556 if (printers_manager != nullptr) { |
| 557 for (const auto& printer : printers) { |
| 558 if (printers_manager->GetPrinter(printer.id()).get() == nullptr) { |
| 559 printers_list->Append(GetPrinterInfo(printer)); |
| 560 } |
| 561 } |
| 562 } else { |
| 563 LOG(WARNING) << "Failing to get available printers because no " |
| 564 "PrintersManager exists."; |
554 } | 565 } |
555 | |
556 FireWebUIListener("on-printer-discovered", *printers_list); | 566 FireWebUIListener("on-printer-discovered", *printers_list); |
557 } | 567 } |
558 | 568 |
559 void CupsPrintersHandler::OnDiscoveryInitialScanDone(int printer_count) { | 569 void CupsPrintersHandler::OnPrinterScanComplete() { |
560 UMA_HISTOGRAM_COUNTS_100("Printing.CUPS.PrintersDiscovered", printer_count); | 570 UMA_HISTOGRAM_COUNTS_100("Printing.CUPS.PrintersDiscovered", |
| 571 printer_detector_->GetPrinters().size()); |
561 FireWebUIListener("on-printer-discovery-done"); | 572 FireWebUIListener("on-printer-discovery-done"); |
562 } | 573 } |
563 | 574 |
564 } // namespace settings | 575 } // namespace settings |
565 } // namespace chromeos | 576 } // namespace chromeos |
OLD | NEW |