Chromium Code Reviews| Index: chrome/browser/ui/webui/print_preview/extension_printer_handler.cc |
| diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc |
| index 3236e3ecda46426e5261994ef313b501b8fbc0f7..598eb83accee8b417e218a6fa7bd344792219a81 100644 |
| --- a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc |
| +++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc |
| @@ -18,12 +18,29 @@ |
| #include "chrome/browser/local_discovery/pwg_raster_converter.h" |
| #include "components/cloud_devices/common/cloud_device_description.h" |
| #include "components/cloud_devices/common/printer_description.h" |
| +#include "device/core/device_client.h" |
| +#include "device/usb/usb_device.h" |
| +#include "device/usb/usb_service.h" |
| +#include "extensions/browser/api/device_permissions_manager.h" |
| #include "extensions/browser/api/printer_provider/printer_provider_api.h" |
| #include "extensions/browser/api/printer_provider/printer_provider_api_factory.h" |
| #include "extensions/browser/api/printer_provider/printer_provider_print_job.h" |
| +#include "extensions/browser/extension_registry.h" |
| +#include "extensions/common/api/printer_provider/usb_printer_manifest_data.h" |
| +#include "extensions/common/permissions/permissions_data.h" |
| +#include "extensions/common/permissions/usb_device_permission.h" |
| +#include "extensions/common/permissions/usb_device_permission_data.h" |
| +#include "extensions/common/value_builder.h" |
| #include "printing/pdf_render_settings.h" |
| #include "printing/pwg_raster_settings.h" |
| +using device::UsbDevice; |
| +using extensions::DevicePermissionsManager; |
| +using extensions::DictionaryBuilder; |
| +using extensions::Extension; |
| +using extensions::ExtensionRegistry; |
| +using extensions::ListBuilder; |
| +using extensions::UsbPrinterManifestData; |
| using local_discovery::PWGRasterConverter; |
| namespace { |
| @@ -66,6 +83,14 @@ void UpdateJobFileInfo( |
| callback); |
| } |
| +bool HasUsbPrinterProviderPermissions(const Extension* extension) { |
| + return extension->permissions_data() && |
| + extension->permissions_data()->HasAPIPermission( |
| + extensions::APIPermission::kPrinterProvider) && |
| + extension->permissions_data()->HasAPIPermission( |
| + extensions::APIPermission::kUsb); |
| +} |
| + |
| } // namespace |
| ExtensionPrinterHandler::ExtensionPrinterHandler( |
| @@ -82,11 +107,35 @@ ExtensionPrinterHandler::~ExtensionPrinterHandler() { |
| void ExtensionPrinterHandler::Reset() { |
| // TODO(tbarzic): Keep track of pending request ids issued by |this| and |
| // cancel them from here. |
| + pending_enumeration_count_ = 0; |
| weak_ptr_factory_.InvalidateWeakPtrs(); |
| } |
| void ExtensionPrinterHandler::StartGetPrinters( |
| const PrinterHandler::GetPrintersCallback& callback) { |
| + // Assume that there can only be one printer enumeration occuring at once. |
|
Vitaly Buka (NO REVIEWS)
2015/05/28 22:50:55
Do we have code outside that guaranty that this wi
Reilly Grant (use Gerrit)
2015/05/28 23:04:50
At the PrinterProviderAPI layer we support multipl
|
| + DCHECK(pending_enumeration_count_ == 0); |
|
Vitaly Buka (NO REVIEWS)
2015/05/28 22:50:55
DCHECK_EQ
Reilly Grant (use Gerrit)
2015/05/28 23:04:50
Done.
|
| + pending_enumeration_count_ = 1; |
|
tbarzic
2015/05/28 21:57:43
nit: Put this next to call to DispatchGetPrintersR
Reilly Grant (use Gerrit)
2015/05/28 22:16:48
This has to happen before we start the USB enumera
|
| + |
| + bool extension_supports_usb_printers = false; |
| + ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); |
| + for (const auto& extension : registry->enabled_extensions()) { |
| + if (UsbPrinterManifestData::Get(extension.get()) && |
| + HasUsbPrinterProviderPermissions(extension.get())) { |
| + extension_supports_usb_printers = true; |
| + break; |
| + } |
| + } |
| + |
| + if (extension_supports_usb_printers) { |
| + device::UsbService* service = device::DeviceClient::Get()->GetUsbService(); |
| + DCHECK(service); |
|
Vitaly Buka (NO REVIEWS)
2015/05/28 22:50:54
We don't set DCHECKs before deference
It will cras
Reilly Grant (use Gerrit)
2015/05/28 23:04:50
Done.
|
| + pending_enumeration_count_++; |
| + service->GetDevices( |
| + base::Bind(&ExtensionPrinterHandler::OnUsbDevicesEnumerated, |
| + weak_ptr_factory_.GetWeakPtr(), callback)); |
| + } |
| + |
| extensions::PrinterProviderAPIFactory::GetInstance() |
| ->GetForBrowserContext(browser_context_) |
| ->DispatchGetPrintersRequested( |
| @@ -192,7 +241,11 @@ void ExtensionPrinterHandler::WrapGetPrintersCallback( |
| const PrinterHandler::GetPrintersCallback& callback, |
| const base::ListValue& printers, |
| bool done) { |
| - callback.Run(printers, done); |
| + DCHECK(pending_enumeration_count_ > 0); |
|
Vitaly Buka (NO REVIEWS)
2015/05/28 22:50:54
DCHECK_GT
Reilly Grant (use Gerrit)
2015/05/28 23:04:50
Done.
|
| + if (done) { |
|
tbarzic
2015/05/28 21:57:43
no {}
Reilly Grant (use Gerrit)
2015/05/28 22:16:49
Done.
|
| + pending_enumeration_count_--; |
| + } |
| + callback.Run(printers, pending_enumeration_count_ == 0); |
| } |
| void ExtensionPrinterHandler::WrapGetCapabilityCallback( |
| @@ -208,3 +261,56 @@ void ExtensionPrinterHandler::WrapPrintCallback( |
| const std::string& status) { |
| callback.Run(success, status); |
| } |
| + |
| +void ExtensionPrinterHandler::OnUsbDevicesEnumerated( |
| + const PrinterHandler::GetPrintersCallback& callback, |
| + const std::vector<scoped_refptr<UsbDevice>>& devices) { |
| + ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); |
| + DevicePermissionsManager* permissions_manager = |
| + DevicePermissionsManager::Get(browser_context_); |
| + |
| + ListBuilder printer_list; |
| + |
| + for (const auto& extension : registry->enabled_extensions()) { |
| + const UsbPrinterManifestData* manifest_data = |
| + UsbPrinterManifestData::Get(extension.get()); |
| + const extensions::DevicePermissions* device_permissions = |
| + permissions_manager->GetForExtension(extension->id()); |
|
Vitaly Buka (NO REVIEWS)
2015/05/28 22:50:55
You can put device_permissions declaration after !
Reilly Grant (use Gerrit)
2015/05/28 23:04:49
Done.
|
| + |
| + if (!manifest_data || !HasUsbPrinterProviderPermissions(extension.get())) { |
|
tbarzic
2015/05/28 21:57:43
no { }
Reilly Grant (use Gerrit)
2015/05/28 22:16:49
Done.
|
| + continue; |
| + } |
| + |
| + for (const auto& device : devices) { |
| + if (manifest_data->SupportsDevice(device)) { |
| + extensions::UsbDevicePermission::CheckParam param( |
| + device->vendor_id(), device->product_id(), |
| + extensions::UsbDevicePermissionData::UNSPECIFIED_INTERFACE); |
| + if (device_permissions->FindUsbDeviceEntry(device) || |
| + extension->permissions_data()->CheckAPIPermissionWithParam( |
| + extensions::APIPermission::kUsbDevice, ¶m)) { |
| + // Skip devices the extension already has permission to access. |
| + continue; |
| + } |
| + |
| + printer_list.Append( |
| + DictionaryBuilder() |
| + .Set("id", base::StringPrintf("provisional-usb:%s:%u", |
| + extension->id().c_str(), |
| + device->unique_id())) |
| + .Set("name", |
| + DevicePermissionsManager::GetPermissionMessage( |
| + device->vendor_id(), device->product_id(), |
| + device->manufacturer_string(), |
| + device->product_string(), base::string16(), false)) |
| + .Set("extensionId", extension->id()) |
| + .Set("extensionName", extension->name()) |
| + .Set("provisional", true)); |
| + } |
| + } |
| + } |
| + |
| + DCHECK(pending_enumeration_count_ > 0); |
|
Vitaly Buka (NO REVIEWS)
2015/05/28 22:50:55
DCHECK_GT
Reilly Grant (use Gerrit)
2015/05/28 23:04:50
Done.
|
| + pending_enumeration_count_--; |
| + callback.Run(*printer_list.Build().get(), pending_enumeration_count_ == 0); |
|
Vitaly Buka (NO REVIEWS)
2015/05/28 22:50:55
do you need get() here?
Reilly Grant (use Gerrit)
2015/05/28 23:04:50
Yes, to turn a scoped_ptr<base::ListValue> into a
|
| +} |