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/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" | 
| 13 #include "base/path_service.h" | 14 #include "base/path_service.h" | 
| 14 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" | 
| 15 #include "base/threading/sequenced_task_runner_handle.h" | 16 #include "base/threading/sequenced_task_runner_handle.h" | 
| 16 #include "base/values.h" | 17 #include "base/values.h" | 
| 17 #include "chrome/browser/browser_process.h" | 18 #include "chrome/browser/browser_process.h" | 
| 18 #include "chrome/browser/chromeos/printing/ppd_provider_factory.h" | 19 #include "chrome/browser/chromeos/printing/ppd_provider_factory.h" | 
| 19 #include "chrome/browser/chromeos/printing/printer_pref_manager_factory.h" | 20 #include "chrome/browser/chromeos/printing/printer_pref_manager_factory.h" | 
| 20 #include "chrome/browser/download/download_prefs.h" | 21 #include "chrome/browser/download/download_prefs.h" | 
| 21 #include "chrome/browser/profiles/profile.h" | 22 #include "chrome/browser/profiles/profile.h" | 
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 std::string printer_ppd_path; | 191 std::string printer_ppd_path; | 
| 191 CHECK(printer_dict->GetString("printerId", &printer_id)); | 192 CHECK(printer_dict->GetString("printerId", &printer_id)); | 
| 192 CHECK(printer_dict->GetString("printerName", &printer_name)); | 193 CHECK(printer_dict->GetString("printerName", &printer_name)); | 
| 193 CHECK(printer_dict->GetString("printerDescription", &printer_description)); | 194 CHECK(printer_dict->GetString("printerDescription", &printer_description)); | 
| 194 CHECK(printer_dict->GetString("printerManufacturer", &printer_manufacturer)); | 195 CHECK(printer_dict->GetString("printerManufacturer", &printer_manufacturer)); | 
| 195 CHECK(printer_dict->GetString("printerModel", &printer_model)); | 196 CHECK(printer_dict->GetString("printerModel", &printer_model)); | 
| 196 CHECK(printer_dict->GetString("printerAddress", &printer_address)); | 197 CHECK(printer_dict->GetString("printerAddress", &printer_address)); | 
| 197 CHECK(printer_dict->GetString("printerProtocol", &printer_protocol)); | 198 CHECK(printer_dict->GetString("printerProtocol", &printer_protocol)); | 
| 198 // printerQueue might be null for a printer whose protocol is not 'LPD'. | 199 // printerQueue might be null for a printer whose protocol is not 'LPD'. | 
| 199 printer_dict->GetString("printerQueue", &printer_queue); | 200 printer_dict->GetString("printerQueue", &printer_queue); | 
| 201 | |
| 200 // printerPPDPath might be null for an auto-discovered printer. | 202 // printerPPDPath might be null for an auto-discovered printer. | 
| 201 printer_dict->GetString("printerPPDPath", &printer_ppd_path); | 203 printer_dict->GetString("printerPPDPath", &printer_ppd_path); | 
| 202 std::string printer_uri = | 204 std::string printer_uri = | 
| 203 printer_protocol + "://" + printer_address + "/" + printer_queue; | 205 printer_protocol + "://" + printer_address + "/" + printer_queue; | 
| 204 | 206 | 
| 205 std::unique_ptr<Printer> printer = base::MakeUnique<Printer>(printer_id); | 207 std::unique_ptr<Printer> printer = base::MakeUnique<Printer>(printer_id); | 
| 206 printer->set_display_name(printer_name); | 208 printer->set_display_name(printer_name); | 
| 207 printer->set_description(printer_description); | 209 printer->set_description(printer_description); | 
| 208 printer->set_manufacturer(printer_manufacturer); | 210 printer->set_manufacturer(printer_manufacturer); | 
| 209 printer->set_model(printer_model); | 211 printer->set_model(printer_model); | 
| 210 printer->set_uri(printer_uri); | 212 printer->set_uri(printer_uri); | 
| 211 if (!printer_ppd_path.empty()) { | 213 if (!printer_ppd_path.empty()) { | 
| 212 printer->mutable_ppd_reference()->user_supplied_ppd_url = printer_ppd_path; | 214 printer->mutable_ppd_reference()->user_supplied_ppd_url = | 
| 213 if (!ppd_provider_->CachePpd(printer->ppd_reference(), | 215 "file:///" + printer_ppd_path; | 
| 214 base::FilePath(printer_ppd_path))) { | 216 } else if (!printer_manufacturer.empty() && !printer_model.empty()) { | 
| 
 
skau
2017/01/27 01:37:00
Didn't we remove the effective_manufacturer field?
 
Carlson
2017/01/27 18:48:43
This is in the dialog, not the ppd reference; we s
 
 | |
| 215 LOG(WARNING) << "PPD could not be stored in the cache"; | 217 // Using the manufacturer and model, get a ppd reference. | 
| 218 if (!ppd_provider_->GetPpdReference(printer_manufacturer, printer_model, | |
| 219 printer->mutable_ppd_reference())) { | |
| 220 LOG(ERROR) << "Failed to get ppd reference!"; | |
| 216 OnAddPrinterError(); | 221 OnAddPrinterError(); | 
| 217 return; | 222 return; | 
| 218 } | 223 } | 
| 219 } else if (!printer_manufacturer.empty() && !printer_model.empty()) { | |
| 220 Printer::PpdReference* ppd = printer->mutable_ppd_reference(); | |
| 221 ppd->effective_manufacturer = printer_manufacturer; | |
| 222 ppd->effective_model = printer_model; | |
| 223 } | 224 } | 
| 224 | 225 | 
| 225 if (printer->IsIppEverywhere()) { | 226 if (printer->IsIppEverywhere()) { | 
| 226 AddPrinterToCups(std::move(printer), base::FilePath(), true); | 227 std::string printer_id = printer->id(); | 
| 227 return; | 228 std::string printer_uri = printer->uri(); | 
| 229 | |
| 230 chromeos::DebugDaemonClient* client = | |
| 231 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); | |
| 232 | |
| 233 client->CupsAddAutoConfiguredPrinter( | |
| 234 printer_id, printer_uri, | |
| 235 base::Bind(&CupsPrintersHandler::OnAddedPrinter, | |
| 236 weak_factory_.GetWeakPtr(), base::Passed(&printer)), | |
| 237 base::Bind(&CupsPrintersHandler::OnAddPrinterError, | |
| 238 weak_factory_.GetWeakPtr())); | |
| 239 } else { | |
| 240 // We need to save a reference to members of printer since we transfer | |
| 241 // ownership in the bind call. | |
| 242 const Printer::PpdReference& ppd_reference = printer->ppd_reference(); | |
| 243 ppd_provider_->ResolvePpd( | |
| 244 ppd_reference, | |
| 245 base::Bind(&CupsPrintersHandler::ResolvePpdDone, | |
| 246 weak_factory_.GetWeakPtr(), base::Passed(&printer))); | |
| 228 } | 247 } | 
| 229 | |
| 230 // We need to save a reference to members of printer since we transfer | |
| 231 // ownership in the bind call. | |
| 232 const Printer::PpdReference& ppd_reference = printer->ppd_reference(); | |
| 233 ppd_provider_->Resolve( | |
| 234 ppd_reference, | |
| 235 base::Bind(&CupsPrintersHandler::OnPPDResolved, | |
| 236 weak_factory_.GetWeakPtr(), base::Passed(&printer))); | |
| 237 } | 248 } | 
| 238 | 249 | 
| 239 void CupsPrintersHandler::OnAddedPrinter(std::unique_ptr<Printer> printer, | 250 void CupsPrintersHandler::OnAddedPrinter(std::unique_ptr<Printer> printer, | 
| 240 bool success) { | 251 int32_t result_code) { | 
| 241 std::string printer_name = printer->display_name(); | 252 std::string printer_name = printer->display_name(); | 
| 253 bool success = (result_code == 0); | |
| 242 if (success) { | 254 if (success) { | 
| 243 PrinterPrefManagerFactory::GetForBrowserContext(profile_)->RegisterPrinter( | 255 PrinterPrefManagerFactory::GetForBrowserContext(profile_)->RegisterPrinter( | 
| 244 std::move(printer)); | 256 std::move(printer)); | 
| 245 } | 257 } | 
| 246 CallJavascriptFunction( | 258 CallJavascriptFunction( | 
| 247 "cr.webUIListenerCallback", base::StringValue("on-add-cups-printer"), | 259 "cr.webUIListenerCallback", base::StringValue("on-add-cups-printer"), | 
| 248 base::FundamentalValue(success), base::StringValue(printer_name)); | 260 base::FundamentalValue(success), base::StringValue(printer_name)); | 
| 249 } | 261 } | 
| 250 | 262 | 
| 251 void CupsPrintersHandler::OnAddPrinterError() { | 263 void CupsPrintersHandler::OnAddPrinterError() { | 
| 252 CallJavascriptFunction("cr.webUIListenerCallback", | 264 CallJavascriptFunction("cr.webUIListenerCallback", | 
| 253 base::StringValue("on-add-cups-printer"), | 265 base::StringValue("on-add-cups-printer"), | 
| 254 base::FundamentalValue(false), base::StringValue("")); | 266 base::FundamentalValue(false), base::StringValue("")); | 
| 255 } | 267 } | 
| 256 | 268 | 
| 257 void CupsPrintersHandler::HandleGetCupsPrinterManufacturers( | 269 void CupsPrintersHandler::HandleGetCupsPrinterManufacturers( | 
| 258 const base::ListValue* args) { | 270 const base::ListValue* args) { | 
| 271 AllowJavascript(); | |
| 259 std::string js_callback; | 272 std::string js_callback; | 
| 260 CHECK_EQ(1U, args->GetSize()); | 273 CHECK_EQ(1U, args->GetSize()); | 
| 261 CHECK(args->GetString(0, &js_callback)); | 274 CHECK(args->GetString(0, &js_callback)); | 
| 262 ppd_provider_->QueryAvailable( | 275 ppd_provider_->ResolveManufacturers( | 
| 263 base::Bind(&CupsPrintersHandler::QueryAvailableManufacturersDone, | 276 base::Bind(&CupsPrintersHandler::ResolveManufacturersDone, | 
| 264 weak_factory_.GetWeakPtr(), | 277 weak_factory_.GetWeakPtr(), js_callback)); | 
| 265 js_callback)); | |
| 266 } | 278 } | 
| 267 | 279 | 
| 268 void CupsPrintersHandler::HandleGetCupsPrinterModels( | 280 void CupsPrintersHandler::HandleGetCupsPrinterModels( | 
| 269 const base::ListValue* args) { | 281 const base::ListValue* args) { | 
| 282 AllowJavascript(); | |
| 270 std::string js_callback; | 283 std::string js_callback; | 
| 271 std::string manufacturer; | 284 std::string manufacturer; | 
| 272 CHECK_EQ(2U, args->GetSize()); | 285 CHECK_EQ(2U, args->GetSize()); | 
| 273 CHECK(args->GetString(0, &js_callback)); | 286 CHECK(args->GetString(0, &js_callback)); | 
| 274 CHECK(args->GetString(1, &manufacturer)); | 287 CHECK(args->GetString(1, &manufacturer)); | 
| 275 // Special case the "asked with no manufacturer case" since the UI sometimes | 288 | 
| 276 // triggers this and it should yield a trivial (empty) result | 289 // Empty manufacturer queries may be triggered as a part of the ui | 
| 290 // initialization, and should just return empty results. | |
| 277 if (manufacturer.empty()) { | 291 if (manufacturer.empty()) { | 
| 278 base::SequencedTaskRunnerHandle::Get()->PostTask( | 292 base::DictionaryValue response; | 
| 279 FROM_HERE, | 293 response.SetBoolean("success", true); | 
| 280 base::Bind(&CupsPrintersHandler::QueryAvailableModelsDone, | 294 response.Set("models", base::MakeUnique<base::ListValue>()); | 
| 281 weak_factory_.GetWeakPtr(), js_callback, manufacturer, | 295 ResolveJavascriptCallback(base::StringValue(js_callback), response); | 
| 282 chromeos::printing::PpdProvider::SUCCESS, | 296 return; | 
| 283 chromeos::printing::PpdProvider::AvailablePrintersMap())); | |
| 284 } else { | |
| 285 ppd_provider_->QueryAvailable( | |
| 286 base::Bind(&CupsPrintersHandler::QueryAvailableModelsDone, | |
| 287 weak_factory_.GetWeakPtr(), js_callback, manufacturer)); | |
| 288 } | 297 } | 
| 298 | |
| 299 ppd_provider_->ResolvePrinters( | |
| 300 manufacturer, base::Bind(&CupsPrintersHandler::ResolvePrintersDone, | |
| 301 weak_factory_.GetWeakPtr(), js_callback)); | |
| 289 } | 302 } | 
| 290 | 303 | 
| 291 void CupsPrintersHandler::HandleSelectPPDFile(const base::ListValue* args) { | 304 void CupsPrintersHandler::HandleSelectPPDFile(const base::ListValue* args) { | 
| 292 CHECK_EQ(1U, args->GetSize()); | 305 CHECK_EQ(1U, args->GetSize()); | 
| 293 CHECK(args->GetString(0, &webui_callback_id_)); | 306 CHECK(args->GetString(0, &webui_callback_id_)); | 
| 294 | 307 | 
| 295 base::FilePath downloads_path = DownloadPrefs::FromDownloadManager( | 308 base::FilePath downloads_path = | 
| 296 content::BrowserContext::GetDownloadManager(profile_))->DownloadPath(); | 309 DownloadPrefs::FromDownloadManager( | 
| 310 content::BrowserContext::GetDownloadManager(profile_)) | |
| 311 ->DownloadPath(); | |
| 297 | 312 | 
| 298 select_file_dialog_ = ui::SelectFileDialog::Create( | 313 select_file_dialog_ = ui::SelectFileDialog::Create( | 
| 299 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); | 314 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); | 
| 300 gfx::NativeWindow owning_window = | 315 gfx::NativeWindow owning_window = | 
| 301 chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()) | 316 chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()) | 
| 302 ->window() | 317 ->window() | 
| 303 ->GetNativeWindow(); | 318 ->GetNativeWindow(); | 
| 304 select_file_dialog_->SelectFile( | 319 select_file_dialog_->SelectFile( | 
| 305 ui::SelectFileDialog::SELECT_OPEN_FILE, base::string16(), downloads_path, | 320 ui::SelectFileDialog::SELECT_OPEN_FILE, base::string16(), downloads_path, | 
| 306 nullptr, 0, FILE_PATH_LITERAL(""), owning_window, nullptr); | 321 nullptr, 0, FILE_PATH_LITERAL(""), owning_window, nullptr); | 
| 307 } | 322 } | 
| 308 | 323 | 
| 309 void CupsPrintersHandler::QueryAvailableManufacturersDone( | 324 void CupsPrintersHandler::ResolveManufacturersDone( | 
| 310 const std::string& js_callback, | 325 const std::string& js_callback, | 
| 311 chromeos::printing::PpdProvider::CallbackResultCode result_code, | 326 chromeos::printing::PpdProvider::CallbackResultCode result_code, | 
| 312 const chromeos::printing::PpdProvider::AvailablePrintersMap& available) { | 327 const std::vector<std::string>& manufacturers) { | 
| 313 auto manufacturers = base::MakeUnique<base::ListValue>(); | 328 auto manufacturers_value = base::MakeUnique<base::ListValue>(); | 
| 314 if (result_code == chromeos::printing::PpdProvider::SUCCESS) { | 329 if (result_code == chromeos::printing::PpdProvider::SUCCESS) { | 
| 315 for (const auto& entry : available) { | 330 manufacturers_value->AppendStrings(manufacturers); | 
| 316 manufacturers->AppendString(entry.first); | |
| 317 } | |
| 318 } | 331 } | 
| 319 base::DictionaryValue response; | 332 base::DictionaryValue response; | 
| 320 response.SetBoolean("success", | 333 response.SetBoolean("success", | 
| 321 result_code == chromeos::printing::PpdProvider::SUCCESS); | 334 result_code == chromeos::printing::PpdProvider::SUCCESS); | 
| 322 response.Set("manufacturers", std::move(manufacturers)); | 335 response.Set("manufacturers", std::move(manufacturers_value)); | 
| 323 ResolveJavascriptCallback(base::StringValue(js_callback), response); | 336 ResolveJavascriptCallback(base::StringValue(js_callback), response); | 
| 324 } | 337 } | 
| 325 | 338 | 
| 326 void CupsPrintersHandler::QueryAvailableModelsDone( | 339 void CupsPrintersHandler::ResolvePrintersDone( | 
| 327 const std::string& js_callback, | 340 const std::string& js_callback, | 
| 328 const std::string& manufacturer, | |
| 329 chromeos::printing::PpdProvider::CallbackResultCode result_code, | 341 chromeos::printing::PpdProvider::CallbackResultCode result_code, | 
| 330 const chromeos::printing::PpdProvider::AvailablePrintersMap& available) { | 342 const std::vector<std::string>& printers) { | 
| 331 auto models = base::MakeUnique<base::ListValue>(); | 343 auto printers_value = base::MakeUnique<base::ListValue>(); | 
| 332 if (result_code == chromeos::printing::PpdProvider::SUCCESS) { | 344 if (result_code == chromeos::printing::PpdProvider::SUCCESS) { | 
| 333 const auto it = available.find(manufacturer); | 345 printers_value->AppendStrings(printers); | 
| 334 if (it != available.end()) { | |
| 335 // Everything looks good. | |
| 336 models->AppendStrings(it->second); | |
| 337 } | |
| 338 } | 346 } | 
| 339 base::DictionaryValue response; | 347 base::DictionaryValue response; | 
| 340 response.SetBoolean("success", | 348 response.SetBoolean("success", | 
| 341 result_code == chromeos::printing::PpdProvider::SUCCESS); | 349 result_code == chromeos::printing::PpdProvider::SUCCESS); | 
| 342 response.Set("models", std::move(models)); | 350 response.Set("models", std::move(printers_value)); | 
| 343 ResolveJavascriptCallback(base::StringValue(js_callback), response); | 351 ResolveJavascriptCallback(base::StringValue(js_callback), response); | 
| 344 } | 352 } | 
| 345 | 353 | 
| 346 void CupsPrintersHandler::FileSelected(const base::FilePath& path, | 354 void CupsPrintersHandler::FileSelected(const base::FilePath& path, | 
| 347 int index, | 355 int index, | 
| 348 void* params) { | 356 void* params) { | 
| 349 DCHECK(!webui_callback_id_.empty()); | 357 DCHECK(!webui_callback_id_.empty()); | 
| 350 ResolveJavascriptCallback(base::StringValue(webui_callback_id_), | 358 ResolveJavascriptCallback(base::StringValue(webui_callback_id_), | 
| 351 base::StringValue(path.value())); | 359 base::StringValue(path.value())); | 
| 352 webui_callback_id_.clear(); | 360 webui_callback_id_.clear(); | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 CallJavascriptFunction("cr.webUIListenerCallback", | 393 CallJavascriptFunction("cr.webUIListenerCallback", | 
| 386 base::StringValue("on-printer-discovered"), | 394 base::StringValue("on-printer-discovered"), | 
| 387 *printers_list); | 395 *printers_list); | 
| 388 } | 396 } | 
| 389 | 397 | 
| 390 void CupsPrintersHandler::OnDiscoveryDone() { | 398 void CupsPrintersHandler::OnDiscoveryDone() { | 
| 391 CallJavascriptFunction("cr.webUIListenerCallback", | 399 CallJavascriptFunction("cr.webUIListenerCallback", | 
| 392 base::StringValue("on-printer-discovery-done")); | 400 base::StringValue("on-printer-discovery-done")); | 
| 393 } | 401 } | 
| 394 | 402 | 
| 395 void CupsPrintersHandler::AddPrinterToCups(std::unique_ptr<Printer> printer, | 403 void CupsPrintersHandler::ResolvePpdDone( | 
| 396 const base::FilePath& ppd_path, | 404 std::unique_ptr<Printer> printer, | 
| 397 bool ipp_everywhere) { | 405 printing::PpdProvider::CallbackResultCode result, | 
| 406 const std::string& ppd_contents) { | |
| 407 if (result != printing::PpdProvider::SUCCESS) { | |
| 408 // TODO(skau): Add appropriate failure modes crbug.com/670068. | |
| 409 LOG(ERROR) << "Error resolving"; | |
| 410 OnAddPrinterError(); | |
| 411 return; | |
| 412 } | |
| 413 | |
| 398 std::string printer_id = printer->id(); | 414 std::string printer_id = printer->id(); | 
| 399 std::string printer_uri = printer->uri(); | 415 std::string printer_uri = printer->uri(); | 
| 400 | 416 | 
| 401 chromeos::DebugDaemonClient* client = | 417 chromeos::DebugDaemonClient* client = | 
| 402 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); | 418 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); | 
| 403 client->CupsAddPrinter( | 419 | 
| 404 printer_id, printer_uri, ppd_path.value(), ipp_everywhere, | 420 client->CupsAddManuallyConfiguredPrinter( | 
| 421 printer_id, printer_uri, ppd_contents, | |
| 405 base::Bind(&CupsPrintersHandler::OnAddedPrinter, | 422 base::Bind(&CupsPrintersHandler::OnAddedPrinter, | 
| 406 weak_factory_.GetWeakPtr(), base::Passed(&printer)), | 423 weak_factory_.GetWeakPtr(), base::Passed(&printer)), | 
| 407 base::Bind(&CupsPrintersHandler::OnAddPrinterError, | 424 base::Bind(&CupsPrintersHandler::OnAddPrinterError, | 
| 408 weak_factory_.GetWeakPtr())); | 425 weak_factory_.GetWeakPtr())); | 
| 409 } | 426 } | 
| 410 | 427 | 
| 411 void CupsPrintersHandler::OnPPDResolved( | |
| 412 std::unique_ptr<Printer> printer, | |
| 413 printing::PpdProvider::CallbackResultCode result, | |
| 414 base::FilePath path) { | |
| 415 if (result != printing::PpdProvider::SUCCESS) { | |
| 416 // TODO(skau): Add appropriate failure modes crbug.com/670068. | |
| 417 OnAddPrinterError(); | |
| 418 return; | |
| 419 } | |
| 420 | |
| 421 AddPrinterToCups(std::move(printer), path, false /* never ipp everywhere */); | |
| 422 } | |
| 423 | |
| 424 } // namespace settings | 428 } // namespace settings | 
| 425 } // namespace chromeos | 429 } // namespace chromeos | 
| OLD | NEW |