Chromium Code Reviews| 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/ppd_provider_factory.h" | 20 #include "chrome/browser/chromeos/printing/ppd_provider_factory.h" |
| 21 #include "chrome/browser/chromeos/printing/printer_configurer.h" | 21 #include "chrome/browser/chromeos/printing/printer_configurer.h" |
| 22 #include "chrome/browser/chromeos/printing/printer_discoverer.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/printers_manager_factory.h" | 24 #include "chrome/browser/chromeos/printing/printers_manager_factory.h" |
| 24 #include "chrome/browser/download/download_prefs.h" | 25 #include "chrome/browser/download/download_prefs.h" |
| 25 #include "chrome/browser/profiles/profile.h" | 26 #include "chrome/browser/profiles/profile.h" |
| 26 #include "chrome/browser/ui/browser_finder.h" | 27 #include "chrome/browser/ui/browser_finder.h" |
| 27 #include "chrome/browser/ui/browser_window.h" | 28 #include "chrome/browser/ui/browser_window.h" |
| 28 #include "chrome/browser/ui/chrome_select_file_policy.h" | 29 #include "chrome/browser/ui/chrome_select_file_policy.h" |
| 29 #include "chrome/common/chrome_paths.h" | 30 #include "chrome/common/chrome_paths.h" |
| 30 #include "chromeos/dbus/dbus_thread_manager.h" | 31 #include "chromeos/dbus/dbus_thread_manager.h" |
| 31 #include "chromeos/dbus/debug_daemon_client.h" | 32 #include "chromeos/dbus/debug_daemon_client.h" |
| 32 #include "chromeos/printing/ppd_cache.h" | 33 #include "chromeos/printing/ppd_cache.h" |
| 33 #include "chromeos/printing/ppd_provider.h" | 34 #include "chromeos/printing/ppd_provider.h" |
| 34 #include "content/public/browser/browser_context.h" | 35 #include "content/public/browser/browser_context.h" |
| 35 #include "content/public/browser/browser_thread.h" | 36 #include "content/public/browser/browser_thread.h" |
| 36 #include "content/public/browser/web_ui.h" | 37 #include "content/public/browser/web_ui.h" |
| 37 #include "google_apis/google_api_keys.h" | 38 #include "google_apis/google_api_keys.h" |
| 38 #include "net/base/filename_util.h" | 39 #include "net/base/filename_util.h" |
| 39 #include "net/url_request/url_request_context_getter.h" | 40 #include "net/url_request/url_request_context_getter.h" |
| 40 #include "printing/backend/print_backend.h" | 41 #include "printing/backend/print_backend.h" |
| 41 #include "url/third_party/mozilla/url_parse.h" | 42 #include "url/third_party/mozilla/url_parse.h" |
| 42 | 43 |
| 43 namespace chromeos { | 44 namespace chromeos { |
| 44 namespace settings { | 45 namespace settings { |
| 45 | 46 |
| 46 namespace { | 47 namespace { |
| 47 | 48 |
| 49 const char kIppScheme[] = "ipp"; | |
| 50 const char kIppsScheme[] = "ipps"; | |
| 51 | |
| 48 // These values are written to logs. New enum values can be added, but existing | 52 // These values are written to logs. New enum values can be added, but existing |
| 49 // enums must never be renumbered or deleted and reused. | 53 // enums must never be renumbered or deleted and reused. |
| 50 enum PpdSourceForHistogram { kUser = 0, kScs = 1, kPpdSourceMax }; | 54 enum PpdSourceForHistogram { kUser = 0, kScs = 1, kPpdSourceMax }; |
| 51 | 55 |
| 52 void RecordPpdSource(const PpdSourceForHistogram& source) { | 56 void RecordPpdSource(const PpdSourceForHistogram& source) { |
| 53 UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PpdSource", source, kPpdSourceMax); | 57 UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PpdSource", source, kPpdSourceMax); |
| 54 } | 58 } |
| 55 | 59 |
| 56 void OnRemovedPrinter(const Printer::PrinterProtocol& protocol, bool success) { | 60 void OnRemovedPrinter(const Printer::PrinterProtocol& protocol, bool success) { |
| 57 UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterRemoved", protocol, | 61 UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterRemoved", protocol, |
| 58 Printer::PrinterProtocol::kProtocolMax); | 62 Printer::PrinterProtocol::kProtocolMax); |
| 59 } | 63 } |
| 60 | 64 |
| 65 // Returns a JSON representation of |printer| as a CupsPrinterInfo. | |
| 61 std::unique_ptr<base::DictionaryValue> GetPrinterInfo(const Printer& printer) { | 66 std::unique_ptr<base::DictionaryValue> GetPrinterInfo(const Printer& printer) { |
| 62 std::unique_ptr<base::DictionaryValue> printer_info = | 67 std::unique_ptr<base::DictionaryValue> printer_info = |
| 63 base::MakeUnique<base::DictionaryValue>(); | 68 base::MakeUnique<base::DictionaryValue>(); |
| 64 printer_info->SetString("printerId", printer.id()); | 69 printer_info->SetString("printerId", printer.id()); |
| 65 printer_info->SetString("printerName", printer.display_name()); | 70 printer_info->SetString("printerName", printer.display_name()); |
| 66 printer_info->SetString("printerDescription", printer.description()); | 71 printer_info->SetString("printerDescription", printer.description()); |
| 67 printer_info->SetString("printerManufacturer", printer.manufacturer()); | 72 printer_info->SetString("printerManufacturer", printer.manufacturer()); |
| 68 printer_info->SetString("printerModel", printer.model()); | 73 printer_info->SetString("printerModel", printer.model()); |
| 69 // Get protocol, ip address and queue from the printer's URI. | 74 // Get protocol, ip address and queue from the printer's URI. |
| 70 const std::string printer_uri = printer.uri(); | 75 const std::string printer_uri = printer.uri(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 base::Bind(&CupsPrintersHandler::HandleUpdateCupsPrinter, | 125 base::Bind(&CupsPrintersHandler::HandleUpdateCupsPrinter, |
| 121 base::Unretained(this))); | 126 base::Unretained(this))); |
| 122 web_ui()->RegisterMessageCallback( | 127 web_ui()->RegisterMessageCallback( |
| 123 "removeCupsPrinter", | 128 "removeCupsPrinter", |
| 124 base::Bind(&CupsPrintersHandler::HandleRemoveCupsPrinter, | 129 base::Bind(&CupsPrintersHandler::HandleRemoveCupsPrinter, |
| 125 base::Unretained(this))); | 130 base::Unretained(this))); |
| 126 web_ui()->RegisterMessageCallback( | 131 web_ui()->RegisterMessageCallback( |
| 127 "addCupsPrinter", base::Bind(&CupsPrintersHandler::HandleAddCupsPrinter, | 132 "addCupsPrinter", base::Bind(&CupsPrintersHandler::HandleAddCupsPrinter, |
| 128 base::Unretained(this))); | 133 base::Unretained(this))); |
| 129 web_ui()->RegisterMessageCallback( | 134 web_ui()->RegisterMessageCallback( |
| 135 "getPrinterInfo", base::Bind(&CupsPrintersHandler::HandleGetPrinterInfo, | |
| 136 base::Unretained(this))); | |
| 137 web_ui()->RegisterMessageCallback( | |
| 130 "getCupsPrinterManufacturersList", | 138 "getCupsPrinterManufacturersList", |
| 131 base::Bind(&CupsPrintersHandler::HandleGetCupsPrinterManufacturers, | 139 base::Bind(&CupsPrintersHandler::HandleGetCupsPrinterManufacturers, |
| 132 base::Unretained(this))); | 140 base::Unretained(this))); |
| 133 web_ui()->RegisterMessageCallback( | 141 web_ui()->RegisterMessageCallback( |
| 134 "getCupsPrinterModelsList", | 142 "getCupsPrinterModelsList", |
| 135 base::Bind(&CupsPrintersHandler::HandleGetCupsPrinterModels, | 143 base::Bind(&CupsPrintersHandler::HandleGetCupsPrinterModels, |
| 136 base::Unretained(this))); | 144 base::Unretained(this))); |
| 137 web_ui()->RegisterMessageCallback( | 145 web_ui()->RegisterMessageCallback( |
| 138 "selectPPDFile", base::Bind(&CupsPrintersHandler::HandleSelectPPDFile, | 146 "selectPPDFile", base::Bind(&CupsPrintersHandler::HandleSelectPPDFile, |
| 139 base::Unretained(this))); | 147 base::Unretained(this))); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 196 Printer::PrinterProtocol protocol = printer->GetProtocol(); | 204 Printer::PrinterProtocol protocol = printer->GetProtocol(); |
| 197 prefs->RemovePrinter(printer_id); | 205 prefs->RemovePrinter(printer_id); |
| 198 | 206 |
| 199 chromeos::DebugDaemonClient* client = | 207 chromeos::DebugDaemonClient* client = |
| 200 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); | 208 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); |
| 201 client->CupsRemovePrinter(printer_name, | 209 client->CupsRemovePrinter(printer_name, |
| 202 base::Bind(&OnRemovedPrinter, protocol), | 210 base::Bind(&OnRemovedPrinter, protocol), |
| 203 base::Bind(&base::DoNothing)); | 211 base::Bind(&base::DoNothing)); |
| 204 } | 212 } |
| 205 | 213 |
| 214 void CupsPrintersHandler::HandleGetPrinterInfo(const base::ListValue* args) { | |
| 215 DCHECK(args); | |
| 216 std::string callback_id; | |
| 217 if (!args->GetString(0, &callback_id)) { | |
| 218 NOTREACHED() << "Expected request for a promise"; | |
| 219 return; | |
| 220 } | |
| 221 | |
| 222 const base::DictionaryValue* printer_dict = nullptr; | |
| 223 if (!args->GetDictionary(1, &printer_dict)) { | |
| 224 NOTREACHED() << "Dictionary missing"; | |
| 225 return; | |
| 226 } | |
| 227 | |
| 228 AllowJavascript(); | |
| 229 | |
| 230 std::string printer_address; | |
| 231 if (!printer_dict->GetString("printerAddress", &printer_address)) { | |
| 232 NOTREACHED() << "Address missing"; | |
| 233 return; | |
| 234 } | |
| 235 | |
| 236 if (printer_address.empty()) { | |
| 237 // Run the failure callback. | |
| 238 OnPrinterInfo(callback_id, false, "", "", false); | |
| 239 return; | |
| 240 } | |
| 241 | |
| 242 std::string printer_queue; | |
| 243 printer_dict->GetString("printerQueue", &printer_queue); | |
| 244 | |
| 245 std::string printer_protocol; | |
| 246 if (!printer_dict->GetString("printerProtocol", &printer_protocol)) { | |
| 247 NOTREACHED() << "Protocol missing"; | |
| 248 return; | |
| 249 } | |
| 250 | |
| 251 // Parse url to separate address and port. ParseStandardURL expects a scheme, | |
| 252 // so add the printer_protocol. | |
| 253 std::string printer_uri = | |
| 254 printer_protocol + url::kStandardSchemeSeparator + printer_address; | |
| 255 const char* uri_ptr = printer_uri.c_str(); | |
| 256 url::Parsed parsed; | |
| 257 url::ParseStandardURL(uri_ptr, printer_uri.length(), &parsed); | |
| 258 base::StringPiece host(&printer_uri[parsed.host.begin], parsed.host.len); | |
| 259 | |
| 260 int port = ParsePort(uri_ptr, parsed.port); | |
| 261 if (port == url::SpecialPort::PORT_UNSPECIFIED || | |
| 262 port == url::SpecialPort::PORT_INVALID) { | |
| 263 // imply port from protocol | |
| 264 if (printer_protocol == kIppScheme) { | |
| 265 port = 631; | |
|
stevenjb
2017/06/08 15:58:28
These constants should be defined at the top of th
skau
2017/06/08 22:11:26
Done.
| |
| 266 } else if (printer_protocol == kIppsScheme) { | |
| 267 // ipps is ipp over https so it uses the https port. | |
| 268 port = 443; | |
| 269 } else { | |
| 270 NOTREACHED() << "Unrecognized protocol. Port was not set."; | |
|
stevenjb
2017/06/08 15:58:28
nit: No typewriter spacing in strings either :)
skau
2017/06/08 22:11:26
Done.
| |
| 271 } | |
| 272 } | |
| 273 | |
| 274 ::chromeos::QueryIppPrinter( | |
| 275 host.as_string(), port, printer_queue, | |
| 276 base::Bind(&CupsPrintersHandler::OnPrinterInfo, | |
| 277 weak_factory_.GetWeakPtr(), callback_id)); | |
| 278 } | |
| 279 | |
| 280 void CupsPrintersHandler::OnPrinterInfo(const std::string& callback_id, | |
| 281 bool success, | |
| 282 const std::string& make, | |
| 283 const std::string& model, | |
| 284 bool ipp_everywhere) { | |
| 285 if (!success) { | |
| 286 base::DictionaryValue reject; | |
| 287 reject.SetString("message", "Querying printer failed"); | |
| 288 RejectJavascriptCallback(base::Value(callback_id), reject); | |
| 289 return; | |
| 290 } | |
| 291 | |
| 292 base::DictionaryValue info; | |
| 293 info.SetString("manufacturer", make); | |
| 294 info.SetString("model", model); | |
| 295 info.SetBoolean("autoconf", ipp_everywhere); | |
| 296 ResolveJavascriptCallback(base::Value(callback_id), info); | |
| 297 } | |
| 298 | |
| 206 void CupsPrintersHandler::HandleAddCupsPrinter(const base::ListValue* args) { | 299 void CupsPrintersHandler::HandleAddCupsPrinter(const base::ListValue* args) { |
| 207 AllowJavascript(); | 300 AllowJavascript(); |
| 208 | 301 |
| 209 const base::DictionaryValue* printer_dict = nullptr; | 302 const base::DictionaryValue* printer_dict = nullptr; |
| 210 CHECK(args->GetDictionary(0, &printer_dict)); | 303 CHECK(args->GetDictionary(0, &printer_dict)); |
| 211 | 304 |
| 212 std::string printer_id; | 305 std::string printer_id; |
| 213 std::string printer_name; | 306 std::string printer_name; |
| 214 std::string printer_description; | 307 std::string printer_description; |
| 215 std::string printer_manufacturer; | 308 std::string printer_manufacturer; |
| 216 std::string printer_model; | 309 std::string printer_model; |
| 217 std::string printer_address; | 310 std::string printer_address; |
| 218 std::string printer_protocol; | 311 std::string printer_protocol; |
| 219 std::string printer_queue; | 312 std::string printer_queue; |
| 220 std::string printer_ppd_path; | 313 std::string printer_ppd_path; |
| 221 CHECK(printer_dict->GetString("printerId", &printer_id)); | 314 CHECK(printer_dict->GetString("printerId", &printer_id)); |
| 222 CHECK(printer_dict->GetString("printerName", &printer_name)); | 315 CHECK(printer_dict->GetString("printerName", &printer_name)); |
| 223 CHECK(printer_dict->GetString("printerDescription", &printer_description)); | 316 CHECK(printer_dict->GetString("printerDescription", &printer_description)); |
| 224 CHECK(printer_dict->GetString("printerManufacturer", &printer_manufacturer)); | 317 CHECK(printer_dict->GetString("printerManufacturer", &printer_manufacturer)); |
| 225 CHECK(printer_dict->GetString("printerModel", &printer_model)); | 318 CHECK(printer_dict->GetString("printerModel", &printer_model)); |
| 226 CHECK(printer_dict->GetString("printerAddress", &printer_address)); | 319 CHECK(printer_dict->GetString("printerAddress", &printer_address)); |
| 227 CHECK(printer_dict->GetString("printerProtocol", &printer_protocol)); | 320 CHECK(printer_dict->GetString("printerProtocol", &printer_protocol)); |
| 321 | |
| 228 // printerQueue might be null for a printer whose protocol is not 'LPD'. | 322 // printerQueue might be null for a printer whose protocol is not 'LPD'. |
| 229 printer_dict->GetString("printerQueue", &printer_queue); | 323 printer_dict->GetString("printerQueue", &printer_queue); |
| 230 | 324 |
| 231 // printerPPDPath might be null for an auto-discovered printer. | 325 std::string printer_uri = |
| 232 printer_dict->GetString("printerPPDPath", &printer_ppd_path); | 326 printer_protocol + url::kStandardSchemeSeparator + printer_address; |
| 233 std::string printer_uri = printer_protocol + "://" + printer_address; | |
| 234 if (!printer_queue.empty()) { | 327 if (!printer_queue.empty()) { |
| 235 printer_uri += "/" + printer_queue; | 328 printer_uri += "/" + printer_queue; |
| 236 } | 329 } |
| 237 | 330 |
| 331 // printerPPDPath might be null for an auto-discovered printer. | |
| 332 printer_dict->GetString("printerPPDPath", &printer_ppd_path); | |
| 333 | |
| 238 std::unique_ptr<Printer> printer = base::MakeUnique<Printer>(printer_id); | 334 std::unique_ptr<Printer> printer = base::MakeUnique<Printer>(printer_id); |
| 239 printer->set_display_name(printer_name); | 335 printer->set_display_name(printer_name); |
| 240 printer->set_description(printer_description); | 336 printer->set_description(printer_description); |
| 241 printer->set_manufacturer(printer_manufacturer); | 337 printer->set_manufacturer(printer_manufacturer); |
| 242 printer->set_model(printer_model); | 338 printer->set_model(printer_model); |
| 243 printer->set_uri(printer_uri); | 339 printer->set_uri(printer_uri); |
| 244 | 340 |
| 245 // Verify a valid ppd path is present. | 341 bool autoconf = false; |
| 246 if (!printer_ppd_path.empty()) { | 342 printer_dict->GetBoolean("printerAutoconf", &autoconf); |
| 343 | |
| 344 // Verify that the printer is autoconf or a valid ppd path is present. | |
| 345 if (autoconf) { | |
| 346 printer->mutable_ppd_reference()->autoconf = true; | |
| 347 } else if (!printer_ppd_path.empty()) { | |
| 247 RecordPpdSource(kUser); | 348 RecordPpdSource(kUser); |
| 248 GURL tmp = net::FilePathToFileURL(base::FilePath(printer_ppd_path)); | 349 GURL tmp = net::FilePathToFileURL(base::FilePath(printer_ppd_path)); |
| 249 if (!tmp.is_valid()) { | 350 if (!tmp.is_valid()) { |
| 250 LOG(ERROR) << "Invalid ppd path: " << printer_ppd_path; | 351 LOG(ERROR) << "Invalid ppd path: " << printer_ppd_path; |
| 251 OnAddPrinterError(); | 352 OnAddPrinterError(); |
| 252 return; | 353 return; |
| 253 } | 354 } |
| 254 printer->mutable_ppd_reference()->user_supplied_ppd_url = tmp.spec(); | 355 printer->mutable_ppd_reference()->user_supplied_ppd_url = tmp.spec(); |
| 255 } else if (!printer_manufacturer.empty() && !printer_model.empty()) { | 356 } else if (!printer_manufacturer.empty() && !printer_model.empty()) { |
| 256 RecordPpdSource(kScs); | 357 RecordPpdSource(kScs); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 438 FireWebUIListener("on-printer-discovered", *printers_list); | 539 FireWebUIListener("on-printer-discovered", *printers_list); |
| 439 } | 540 } |
| 440 | 541 |
| 441 void CupsPrintersHandler::OnDiscoveryInitialScanDone(int printer_count) { | 542 void CupsPrintersHandler::OnDiscoveryInitialScanDone(int printer_count) { |
| 442 UMA_HISTOGRAM_COUNTS_100("Printing.CUPS.PrintersDiscovered", printer_count); | 543 UMA_HISTOGRAM_COUNTS_100("Printing.CUPS.PrintersDiscovered", printer_count); |
| 443 FireWebUIListener("on-printer-discovery-done"); | 544 FireWebUIListener("on-printer-discovery-done"); |
| 444 } | 545 } |
| 445 | 546 |
| 446 } // namespace settings | 547 } // namespace settings |
| 447 } // namespace chromeos | 548 } // namespace chromeos |
| OLD | NEW |