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..d9b6442fd17fce647a0c4282cefa46ab1dcb90a2 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 { |
@@ -82,11 +99,37 @@ ExtensionPrinterHandler::~ExtensionPrinterHandler() { |
void ExtensionPrinterHandler::Reset() { |
// TODO(tbarzic): Keep track of pending request ids issued by |this| and |
// cancel them from here. |
+ printer_enumeration_complete_ = false; |
+ wait_for_usb_enumeration_ = false; |
weak_ptr_factory_.InvalidateWeakPtrs(); |
} |
void ExtensionPrinterHandler::StartGetPrinters( |
const PrinterHandler::GetPrintersCallback& callback) { |
+ // Assume that there can only be one printer enumeration occuring at once. |
+ DCHECK(!printer_enumeration_complete_); |
+ DCHECK(!wait_for_usb_enumeration_); |
+ |
+ ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); |
+ for (const auto& extension : registry->enabled_extensions()) { |
+ if (UsbPrinterManifestData::Get(extension.get()) && |
+ extension->permissions_data() && |
+ extension->permissions_data()->HasAPIPermission( |
+ extensions::APIPermission::kPrinterProvider) && |
+ extension->permissions_data()->HasAPIPermission( |
+ extensions::APIPermission::kUsb)) { |
+ wait_for_usb_enumeration_ = true; |
tbarzic
2015/05/28 00:20:00
break;
Reilly Grant (use Gerrit)
2015/05/28 21:45:00
Done.
|
+ } |
+ } |
+ |
+ if (wait_for_usb_enumeration_) { |
+ device::UsbService* service = device::DeviceClient::Get()->GetUsbService(); |
+ DCHECK(service); |
+ service->GetDevices( |
+ base::Bind(&ExtensionPrinterHandler::OnUsbDevicesEnumerated, |
+ weak_ptr_factory_.GetWeakPtr(), callback)); |
+ } |
+ |
extensions::PrinterProviderAPIFactory::GetInstance() |
->GetForBrowserContext(browser_context_) |
->DispatchGetPrintersRequested( |
@@ -192,6 +235,12 @@ void ExtensionPrinterHandler::WrapGetPrintersCallback( |
const PrinterHandler::GetPrintersCallback& callback, |
const base::ListValue& printers, |
bool done) { |
+ if (done) { |
Vitaly Buka (NO REVIEWS)
2015/05/28 16:34:12
maybe simpler is just to have integer counters:
i
Reilly Grant (use Gerrit)
2015/05/28 21:45:00
Done.
|
+ printer_enumeration_complete_ = true; |
tbarzic
2015/05/28 00:20:00
nit: no {}
|
+ } |
+ if (wait_for_usb_enumeration_) { |
tbarzic
2015/05/28 00:19:59
remove this and invoke callback as
callback.Run(p
Reilly Grant (use Gerrit)
2015/05/28 21:45:00
Done.
|
+ done = false; |
+ } |
callback.Run(printers, done); |
} |
@@ -208,3 +257,58 @@ 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()); |
+ |
+ if (!manifest_data || !extension->permissions_data() || |
+ !extension->permissions_data()->HasAPIPermission( |
+ extensions::APIPermission::kPrinterProvider) || |
tbarzic
2015/05/28 00:20:00
extract to a separate method (you have the same co
Reilly Grant (use Gerrit)
2015/05/28 21:45:00
Done.
|
+ !extension->permissions_data()->HasAPIPermission( |
+ extensions::APIPermission::kUsb)) { |
+ 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())); |
tbarzic
2015/05/28 00:20:00
set a flag "isProvisional" (so it can be distingui
Reilly Grant (use Gerrit)
2015/05/28 21:45:00
Done.
|
+ } |
+ } |
+ } |
+ |
+ wait_for_usb_enumeration_ = false; |
+ callback.Run(*printer_list.Build().get(), printer_enumeration_complete_); |
+} |