| 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()) { |
| 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 |