| Index: chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
 | 
| diff --git a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
 | 
| index 0a1b1abcf30b61135dca8a8ab34c64c36e5b9aa2..41a5635fc30abb6721ce936b89369769e61e8260 100644
 | 
| --- a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
 | 
| +++ b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
 | 
| @@ -9,6 +9,7 @@
 | 
|  #include "base/bind.h"
 | 
|  #include "base/bind_helpers.h"
 | 
|  #include "base/files/file_util.h"
 | 
| +#include "base/json/json_string_value_serializer.h"
 | 
|  #include "base/memory/ptr_util.h"
 | 
|  #include "base/path_service.h"
 | 
|  #include "base/strings/string_util.h"
 | 
| @@ -32,6 +33,7 @@
 | 
|  #include "content/public/browser/browser_thread.h"
 | 
|  #include "content/public/browser/web_ui.h"
 | 
|  #include "google_apis/google_api_keys.h"
 | 
| +#include "net/base/filename_util.h"
 | 
|  #include "net/url_request/url_request_context_getter.h"
 | 
|  #include "printing/backend/print_backend.h"
 | 
|  #include "url/third_party/mozilla/url_parse.h"
 | 
| @@ -197,6 +199,7 @@ void CupsPrintersHandler::HandleAddCupsPrinter(const base::ListValue* args) {
 | 
|    CHECK(printer_dict->GetString("printerProtocol", &printer_protocol));
 | 
|    // printerQueue might be null for a printer whose protocol is not 'LPD'.
 | 
|    printer_dict->GetString("printerQueue", &printer_queue);
 | 
| +
 | 
|    // printerPPDPath might be null for an auto-discovered printer.
 | 
|    printer_dict->GetString("printerPPDPath", &printer_ppd_path);
 | 
|    std::string printer_uri =
 | 
| @@ -209,36 +212,51 @@ void CupsPrintersHandler::HandleAddCupsPrinter(const base::ListValue* args) {
 | 
|    printer->set_model(printer_model);
 | 
|    printer->set_uri(printer_uri);
 | 
|    if (!printer_ppd_path.empty()) {
 | 
| -    printer->mutable_ppd_reference()->user_supplied_ppd_url = printer_ppd_path;
 | 
| -    if (!ppd_provider_->CachePpd(printer->ppd_reference(),
 | 
| -                                 base::FilePath(printer_ppd_path))) {
 | 
| -      LOG(WARNING) << "PPD could not be stored in the cache";
 | 
| +    GURL tmp = net::FilePathToFileURL(base::FilePath(printer_ppd_path));
 | 
| +    if (!tmp.is_valid()) {
 | 
| +      LOG(ERROR) << "Invalid ppd path: " << printer_ppd_path;
 | 
|        OnAddPrinterError();
 | 
|        return;
 | 
|      }
 | 
| +    printer->mutable_ppd_reference()->user_supplied_ppd_url = tmp.spec();
 | 
|    } else if (!printer_manufacturer.empty() && !printer_model.empty()) {
 | 
| -    Printer::PpdReference* ppd = printer->mutable_ppd_reference();
 | 
| -    ppd->effective_manufacturer = printer_manufacturer;
 | 
| -    ppd->effective_model = printer_model;
 | 
| +    // Using the manufacturer and model, get a ppd reference.
 | 
| +    if (!ppd_provider_->GetPpdReference(printer_manufacturer, printer_model,
 | 
| +                                        printer->mutable_ppd_reference())) {
 | 
| +      LOG(ERROR) << "Failed to get ppd reference";
 | 
| +      OnAddPrinterError();
 | 
| +      return;
 | 
| +    }
 | 
|    }
 | 
|  
 | 
|    if (printer->IsIppEverywhere()) {
 | 
| -    AddPrinterToCups(std::move(printer), base::FilePath(), true);
 | 
| -    return;
 | 
| +    std::string printer_id = printer->id();
 | 
| +    std::string printer_uri = printer->uri();
 | 
| +
 | 
| +    chromeos::DebugDaemonClient* client =
 | 
| +        chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
 | 
| +
 | 
| +    client->CupsAddAutoConfiguredPrinter(
 | 
| +        printer_id, printer_uri,
 | 
| +        base::Bind(&CupsPrintersHandler::OnAddedPrinter,
 | 
| +                   weak_factory_.GetWeakPtr(), base::Passed(&printer)),
 | 
| +        base::Bind(&CupsPrintersHandler::OnAddPrinterError,
 | 
| +                   weak_factory_.GetWeakPtr()));
 | 
| +  } else {
 | 
| +    // We need to save a reference to members of printer since we transfer
 | 
| +    // ownership in the bind call.
 | 
| +    const Printer::PpdReference ppd_reference = printer->ppd_reference();
 | 
| +    ppd_provider_->ResolvePpd(
 | 
| +        ppd_reference,
 | 
| +        base::Bind(&CupsPrintersHandler::ResolvePpdDone,
 | 
| +                   weak_factory_.GetWeakPtr(), base::Passed(&printer)));
 | 
|    }
 | 
| -
 | 
| -  // We need to save a reference to members of printer since we transfer
 | 
| -  // ownership in the bind call.
 | 
| -  const Printer::PpdReference& ppd_reference = printer->ppd_reference();
 | 
| -  ppd_provider_->Resolve(
 | 
| -      ppd_reference,
 | 
| -      base::Bind(&CupsPrintersHandler::OnPPDResolved,
 | 
| -                 weak_factory_.GetWeakPtr(), base::Passed(&printer)));
 | 
|  }
 | 
|  
 | 
|  void CupsPrintersHandler::OnAddedPrinter(std::unique_ptr<Printer> printer,
 | 
| -                                         bool success) {
 | 
| +                                         int32_t result_code) {
 | 
|    std::string printer_name = printer->display_name();
 | 
| +  bool success = (result_code == 0);
 | 
|    if (success) {
 | 
|      PrinterPrefManagerFactory::GetForBrowserContext(profile_)->RegisterPrinter(
 | 
|          std::move(printer));
 | 
| @@ -256,44 +274,47 @@ void CupsPrintersHandler::OnAddPrinterError() {
 | 
|  
 | 
|  void CupsPrintersHandler::HandleGetCupsPrinterManufacturers(
 | 
|      const base::ListValue* args) {
 | 
| +  AllowJavascript();
 | 
|    std::string js_callback;
 | 
|    CHECK_EQ(1U, args->GetSize());
 | 
|    CHECK(args->GetString(0, &js_callback));
 | 
| -  ppd_provider_->QueryAvailable(
 | 
| -      base::Bind(&CupsPrintersHandler::QueryAvailableManufacturersDone,
 | 
| -                 weak_factory_.GetWeakPtr(),
 | 
| -                 js_callback));
 | 
| +  ppd_provider_->ResolveManufacturers(
 | 
| +      base::Bind(&CupsPrintersHandler::ResolveManufacturersDone,
 | 
| +                 weak_factory_.GetWeakPtr(), js_callback));
 | 
|  }
 | 
|  
 | 
|  void CupsPrintersHandler::HandleGetCupsPrinterModels(
 | 
|      const base::ListValue* args) {
 | 
| +  AllowJavascript();
 | 
|    std::string js_callback;
 | 
|    std::string manufacturer;
 | 
|    CHECK_EQ(2U, args->GetSize());
 | 
|    CHECK(args->GetString(0, &js_callback));
 | 
|    CHECK(args->GetString(1, &manufacturer));
 | 
| -  // Special case the "asked with no manufacturer case" since the UI sometimes
 | 
| -  // triggers this and it should yield a trivial (empty) result
 | 
| +
 | 
| +  // Empty manufacturer queries may be triggered as a part of the ui
 | 
| +  // initialization, and should just return empty results.
 | 
|    if (manufacturer.empty()) {
 | 
| -    base::SequencedTaskRunnerHandle::Get()->PostTask(
 | 
| -        FROM_HERE,
 | 
| -        base::Bind(&CupsPrintersHandler::QueryAvailableModelsDone,
 | 
| -                   weak_factory_.GetWeakPtr(), js_callback, manufacturer,
 | 
| -                   chromeos::printing::PpdProvider::SUCCESS,
 | 
| -                   chromeos::printing::PpdProvider::AvailablePrintersMap()));
 | 
| -  } else {
 | 
| -    ppd_provider_->QueryAvailable(
 | 
| -        base::Bind(&CupsPrintersHandler::QueryAvailableModelsDone,
 | 
| -                   weak_factory_.GetWeakPtr(), js_callback, manufacturer));
 | 
| +    base::DictionaryValue response;
 | 
| +    response.SetBoolean("success", true);
 | 
| +    response.Set("models", base::MakeUnique<base::ListValue>());
 | 
| +    ResolveJavascriptCallback(base::StringValue(js_callback), response);
 | 
| +    return;
 | 
|    }
 | 
| +
 | 
| +  ppd_provider_->ResolvePrinters(
 | 
| +      manufacturer, base::Bind(&CupsPrintersHandler::ResolvePrintersDone,
 | 
| +                               weak_factory_.GetWeakPtr(), js_callback));
 | 
|  }
 | 
|  
 | 
|  void CupsPrintersHandler::HandleSelectPPDFile(const base::ListValue* args) {
 | 
|    CHECK_EQ(1U, args->GetSize());
 | 
|    CHECK(args->GetString(0, &webui_callback_id_));
 | 
|  
 | 
| -  base::FilePath downloads_path = DownloadPrefs::FromDownloadManager(
 | 
| -      content::BrowserContext::GetDownloadManager(profile_))->DownloadPath();
 | 
| +  base::FilePath downloads_path =
 | 
| +      DownloadPrefs::FromDownloadManager(
 | 
| +          content::BrowserContext::GetDownloadManager(profile_))
 | 
| +          ->DownloadPath();
 | 
|  
 | 
|    select_file_dialog_ = ui::SelectFileDialog::Create(
 | 
|        this, new ChromeSelectFilePolicy(web_ui()->GetWebContents()));
 | 
| @@ -306,40 +327,33 @@ void CupsPrintersHandler::HandleSelectPPDFile(const base::ListValue* args) {
 | 
|        nullptr, 0, FILE_PATH_LITERAL(""), owning_window, nullptr);
 | 
|  }
 | 
|  
 | 
| -void CupsPrintersHandler::QueryAvailableManufacturersDone(
 | 
| +void CupsPrintersHandler::ResolveManufacturersDone(
 | 
|      const std::string& js_callback,
 | 
|      chromeos::printing::PpdProvider::CallbackResultCode result_code,
 | 
| -    const chromeos::printing::PpdProvider::AvailablePrintersMap& available) {
 | 
| -  auto manufacturers = base::MakeUnique<base::ListValue>();
 | 
| +    const std::vector<std::string>& manufacturers) {
 | 
| +  auto manufacturers_value = base::MakeUnique<base::ListValue>();
 | 
|    if (result_code == chromeos::printing::PpdProvider::SUCCESS) {
 | 
| -    for (const auto& entry : available) {
 | 
| -      manufacturers->AppendString(entry.first);
 | 
| -    }
 | 
| +    manufacturers_value->AppendStrings(manufacturers);
 | 
|    }
 | 
|    base::DictionaryValue response;
 | 
|    response.SetBoolean("success",
 | 
|                        result_code == chromeos::printing::PpdProvider::SUCCESS);
 | 
| -  response.Set("manufacturers", std::move(manufacturers));
 | 
| +  response.Set("manufacturers", std::move(manufacturers_value));
 | 
|    ResolveJavascriptCallback(base::StringValue(js_callback), response);
 | 
|  }
 | 
|  
 | 
| -void CupsPrintersHandler::QueryAvailableModelsDone(
 | 
| +void CupsPrintersHandler::ResolvePrintersDone(
 | 
|      const std::string& js_callback,
 | 
| -    const std::string& manufacturer,
 | 
|      chromeos::printing::PpdProvider::CallbackResultCode result_code,
 | 
| -    const chromeos::printing::PpdProvider::AvailablePrintersMap& available) {
 | 
| -  auto models = base::MakeUnique<base::ListValue>();
 | 
| +    const std::vector<std::string>& printers) {
 | 
| +  auto printers_value = base::MakeUnique<base::ListValue>();
 | 
|    if (result_code == chromeos::printing::PpdProvider::SUCCESS) {
 | 
| -    const auto it = available.find(manufacturer);
 | 
| -    if (it != available.end()) {
 | 
| -      // Everything looks good.
 | 
| -      models->AppendStrings(it->second);
 | 
| -    }
 | 
| +    printers_value->AppendStrings(printers);
 | 
|    }
 | 
|    base::DictionaryValue response;
 | 
|    response.SetBoolean("success",
 | 
| -                       result_code == chromeos::printing::PpdProvider::SUCCESS);
 | 
| -  response.Set("models", std::move(models));
 | 
| +                      result_code == chromeos::printing::PpdProvider::SUCCESS);
 | 
| +  response.Set("models", std::move(printers_value));
 | 
|    ResolveJavascriptCallback(base::StringValue(js_callback), response);
 | 
|  }
 | 
|  
 | 
| @@ -392,34 +406,30 @@ void CupsPrintersHandler::OnDiscoveryDone() {
 | 
|                           base::StringValue("on-printer-discovery-done"));
 | 
|  }
 | 
|  
 | 
| -void CupsPrintersHandler::AddPrinterToCups(std::unique_ptr<Printer> printer,
 | 
| -                                           const base::FilePath& ppd_path,
 | 
| -                                           bool ipp_everywhere) {
 | 
| +void CupsPrintersHandler::ResolvePpdDone(
 | 
| +    std::unique_ptr<Printer> printer,
 | 
| +    printing::PpdProvider::CallbackResultCode result,
 | 
| +    const std::string& ppd_contents) {
 | 
| +  if (result != printing::PpdProvider::SUCCESS) {
 | 
| +    // TODO(skau): Add appropriate failure modes crbug.com/670068.
 | 
| +    LOG(ERROR) << "Error resolving";
 | 
| +    OnAddPrinterError();
 | 
| +    return;
 | 
| +  }
 | 
| +
 | 
|    std::string printer_id = printer->id();
 | 
|    std::string printer_uri = printer->uri();
 | 
|  
 | 
|    chromeos::DebugDaemonClient* client =
 | 
|        chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
 | 
| -  client->CupsAddPrinter(
 | 
| -      printer_id, printer_uri, ppd_path.value(), ipp_everywhere,
 | 
| +
 | 
| +  client->CupsAddManuallyConfiguredPrinter(
 | 
| +      printer_id, printer_uri, ppd_contents,
 | 
|        base::Bind(&CupsPrintersHandler::OnAddedPrinter,
 | 
|                   weak_factory_.GetWeakPtr(), base::Passed(&printer)),
 | 
|        base::Bind(&CupsPrintersHandler::OnAddPrinterError,
 | 
|                   weak_factory_.GetWeakPtr()));
 | 
|  }
 | 
|  
 | 
| -void CupsPrintersHandler::OnPPDResolved(
 | 
| -    std::unique_ptr<Printer> printer,
 | 
| -    printing::PpdProvider::CallbackResultCode result,
 | 
| -    base::FilePath path) {
 | 
| -  if (result != printing::PpdProvider::SUCCESS) {
 | 
| -    // TODO(skau): Add appropriate failure modes crbug.com/670068.
 | 
| -    OnAddPrinterError();
 | 
| -    return;
 | 
| -  }
 | 
| -
 | 
| -  AddPrinterToCups(std::move(printer), path, false /* never ipp everywhere */);
 | 
| -}
 | 
| -
 | 
|  }  // namespace settings
 | 
|  }  // namespace chromeos
 | 
| 
 |