OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/print_preview/extension_printer_handler.h" | 5 #include "chrome/browser/ui/webui/print_preview/extension_printer_handler.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "base/files/file.h" | 11 #include "base/files/file.h" |
12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
13 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
14 #include "base/location.h" | 14 #include "base/location.h" |
15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
16 #include "base/memory/ref_counted_memory.h" | 16 #include "base/memory/ref_counted_memory.h" |
17 #include "base/task_runner_util.h" | 17 #include "base/task_runner_util.h" |
18 #include "chrome/browser/local_discovery/pwg_raster_converter.h" | 18 #include "chrome/browser/local_discovery/pwg_raster_converter.h" |
19 #include "components/cloud_devices/common/cloud_device_description.h" | 19 #include "components/cloud_devices/common/cloud_device_description.h" |
20 #include "components/cloud_devices/common/printer_description.h" | 20 #include "components/cloud_devices/common/printer_description.h" |
| 21 #include "device/core/device_client.h" |
| 22 #include "device/usb/usb_device.h" |
| 23 #include "device/usb/usb_service.h" |
| 24 #include "extensions/browser/api/device_permissions_manager.h" |
21 #include "extensions/browser/api/printer_provider/printer_provider_api.h" | 25 #include "extensions/browser/api/printer_provider/printer_provider_api.h" |
22 #include "extensions/browser/api/printer_provider/printer_provider_api_factory.h
" | 26 #include "extensions/browser/api/printer_provider/printer_provider_api_factory.h
" |
23 #include "extensions/browser/api/printer_provider/printer_provider_print_job.h" | 27 #include "extensions/browser/api/printer_provider/printer_provider_print_job.h" |
| 28 #include "extensions/browser/extension_registry.h" |
| 29 #include "extensions/common/api/printer_provider/usb_printer_manifest_data.h" |
| 30 #include "extensions/common/permissions/permissions_data.h" |
| 31 #include "extensions/common/permissions/usb_device_permission.h" |
| 32 #include "extensions/common/permissions/usb_device_permission_data.h" |
| 33 #include "extensions/common/value_builder.h" |
24 #include "printing/pdf_render_settings.h" | 34 #include "printing/pdf_render_settings.h" |
25 #include "printing/pwg_raster_settings.h" | 35 #include "printing/pwg_raster_settings.h" |
26 | 36 |
| 37 using device::UsbDevice; |
| 38 using extensions::DevicePermissionsManager; |
| 39 using extensions::DictionaryBuilder; |
| 40 using extensions::Extension; |
| 41 using extensions::ExtensionRegistry; |
| 42 using extensions::ListBuilder; |
| 43 using extensions::UsbPrinterManifestData; |
27 using local_discovery::PWGRasterConverter; | 44 using local_discovery::PWGRasterConverter; |
28 | 45 |
29 namespace { | 46 namespace { |
30 | 47 |
31 const char kContentTypePdf[] = "application/pdf"; | 48 const char kContentTypePdf[] = "application/pdf"; |
32 const char kContentTypePWGRaster[] = "image/pwg-raster"; | 49 const char kContentTypePWGRaster[] = "image/pwg-raster"; |
33 const char kContentTypeAll[] = "*/*"; | 50 const char kContentTypeAll[] = "*/*"; |
34 | 51 |
35 const char kInvalidDataPrintError[] = "INVALID_DATA"; | 52 const char kInvalidDataPrintError[] = "INVALID_DATA"; |
36 const char kInvalidTicketPrintError[] = "INVALID_TICKET"; | 53 const char kInvalidTicketPrintError[] = "INVALID_TICKET"; |
(...skipping 22 matching lines...) Expand all Loading... |
59 return; | 76 return; |
60 } | 77 } |
61 | 78 |
62 base::PostTaskAndReplyWithResult( | 79 base::PostTaskAndReplyWithResult( |
63 slow_task_runner.get(), FROM_HERE, | 80 slow_task_runner.get(), FROM_HERE, |
64 base::Bind(&UpdateJobFileInfoOnWorkerThread, pwg_file_path, | 81 base::Bind(&UpdateJobFileInfoOnWorkerThread, pwg_file_path, |
65 base::Passed(&job)), | 82 base::Passed(&job)), |
66 callback); | 83 callback); |
67 } | 84 } |
68 | 85 |
| 86 bool HasUsbPrinterProviderPermissions(const Extension* extension) { |
| 87 return extension->permissions_data() && |
| 88 extension->permissions_data()->HasAPIPermission( |
| 89 extensions::APIPermission::kPrinterProvider) && |
| 90 extension->permissions_data()->HasAPIPermission( |
| 91 extensions::APIPermission::kUsb); |
| 92 } |
| 93 |
69 } // namespace | 94 } // namespace |
70 | 95 |
71 ExtensionPrinterHandler::ExtensionPrinterHandler( | 96 ExtensionPrinterHandler::ExtensionPrinterHandler( |
72 content::BrowserContext* browser_context, | 97 content::BrowserContext* browser_context, |
73 const scoped_refptr<base::TaskRunner>& slow_task_runner) | 98 const scoped_refptr<base::TaskRunner>& slow_task_runner) |
74 : browser_context_(browser_context), | 99 : browser_context_(browser_context), |
75 slow_task_runner_(slow_task_runner), | 100 slow_task_runner_(slow_task_runner), |
76 weak_ptr_factory_(this) { | 101 weak_ptr_factory_(this) { |
77 } | 102 } |
78 | 103 |
79 ExtensionPrinterHandler::~ExtensionPrinterHandler() { | 104 ExtensionPrinterHandler::~ExtensionPrinterHandler() { |
80 } | 105 } |
81 | 106 |
82 void ExtensionPrinterHandler::Reset() { | 107 void ExtensionPrinterHandler::Reset() { |
83 // TODO(tbarzic): Keep track of pending request ids issued by |this| and | 108 // TODO(tbarzic): Keep track of pending request ids issued by |this| and |
84 // cancel them from here. | 109 // cancel them from here. |
| 110 pending_enumeration_count_ = 0; |
85 weak_ptr_factory_.InvalidateWeakPtrs(); | 111 weak_ptr_factory_.InvalidateWeakPtrs(); |
86 } | 112 } |
87 | 113 |
88 void ExtensionPrinterHandler::StartGetPrinters( | 114 void ExtensionPrinterHandler::StartGetPrinters( |
89 const PrinterHandler::GetPrintersCallback& callback) { | 115 const PrinterHandler::GetPrintersCallback& callback) { |
| 116 // Assume that there can only be one printer enumeration occuring at once. |
| 117 DCHECK_EQ(pending_enumeration_count_, 0); |
| 118 pending_enumeration_count_ = 1; |
| 119 |
| 120 bool extension_supports_usb_printers = false; |
| 121 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); |
| 122 for (const auto& extension : registry->enabled_extensions()) { |
| 123 if (UsbPrinterManifestData::Get(extension.get()) && |
| 124 HasUsbPrinterProviderPermissions(extension.get())) { |
| 125 extension_supports_usb_printers = true; |
| 126 break; |
| 127 } |
| 128 } |
| 129 |
| 130 if (extension_supports_usb_printers) { |
| 131 device::UsbService* service = device::DeviceClient::Get()->GetUsbService(); |
| 132 pending_enumeration_count_++; |
| 133 service->GetDevices( |
| 134 base::Bind(&ExtensionPrinterHandler::OnUsbDevicesEnumerated, |
| 135 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 136 } |
| 137 |
90 extensions::PrinterProviderAPIFactory::GetInstance() | 138 extensions::PrinterProviderAPIFactory::GetInstance() |
91 ->GetForBrowserContext(browser_context_) | 139 ->GetForBrowserContext(browser_context_) |
92 ->DispatchGetPrintersRequested( | 140 ->DispatchGetPrintersRequested( |
93 base::Bind(&ExtensionPrinterHandler::WrapGetPrintersCallback, | 141 base::Bind(&ExtensionPrinterHandler::WrapGetPrintersCallback, |
94 weak_ptr_factory_.GetWeakPtr(), callback)); | 142 weak_ptr_factory_.GetWeakPtr(), callback)); |
95 } | 143 } |
96 | 144 |
97 void ExtensionPrinterHandler::StartGetCapability( | 145 void ExtensionPrinterHandler::StartGetCapability( |
98 const std::string& destination_id, | 146 const std::string& destination_id, |
99 const PrinterHandler::GetCapabilityCallback& callback) { | 147 const PrinterHandler::GetCapabilityCallback& callback) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 ->GetForBrowserContext(browser_context_) | 233 ->GetForBrowserContext(browser_context_) |
186 ->DispatchPrintRequested( | 234 ->DispatchPrintRequested( |
187 *print_job, base::Bind(&ExtensionPrinterHandler::WrapPrintCallback, | 235 *print_job, base::Bind(&ExtensionPrinterHandler::WrapPrintCallback, |
188 weak_ptr_factory_.GetWeakPtr(), callback)); | 236 weak_ptr_factory_.GetWeakPtr(), callback)); |
189 } | 237 } |
190 | 238 |
191 void ExtensionPrinterHandler::WrapGetPrintersCallback( | 239 void ExtensionPrinterHandler::WrapGetPrintersCallback( |
192 const PrinterHandler::GetPrintersCallback& callback, | 240 const PrinterHandler::GetPrintersCallback& callback, |
193 const base::ListValue& printers, | 241 const base::ListValue& printers, |
194 bool done) { | 242 bool done) { |
195 callback.Run(printers, done); | 243 DCHECK_GT(pending_enumeration_count_, 0); |
| 244 if (done) |
| 245 pending_enumeration_count_--; |
| 246 |
| 247 callback.Run(printers, pending_enumeration_count_ == 0); |
196 } | 248 } |
197 | 249 |
198 void ExtensionPrinterHandler::WrapGetCapabilityCallback( | 250 void ExtensionPrinterHandler::WrapGetCapabilityCallback( |
199 const PrinterHandler::GetCapabilityCallback& callback, | 251 const PrinterHandler::GetCapabilityCallback& callback, |
200 const std::string& destination_id, | 252 const std::string& destination_id, |
201 const base::DictionaryValue& capability) { | 253 const base::DictionaryValue& capability) { |
202 callback.Run(destination_id, capability); | 254 callback.Run(destination_id, capability); |
203 } | 255 } |
204 | 256 |
205 void ExtensionPrinterHandler::WrapPrintCallback( | 257 void ExtensionPrinterHandler::WrapPrintCallback( |
206 const PrinterHandler::PrintCallback& callback, | 258 const PrinterHandler::PrintCallback& callback, |
207 bool success, | 259 bool success, |
208 const std::string& status) { | 260 const std::string& status) { |
209 callback.Run(success, status); | 261 callback.Run(success, status); |
210 } | 262 } |
| 263 |
| 264 void ExtensionPrinterHandler::OnUsbDevicesEnumerated( |
| 265 const PrinterHandler::GetPrintersCallback& callback, |
| 266 const std::vector<scoped_refptr<UsbDevice>>& devices) { |
| 267 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); |
| 268 DevicePermissionsManager* permissions_manager = |
| 269 DevicePermissionsManager::Get(browser_context_); |
| 270 |
| 271 ListBuilder printer_list; |
| 272 |
| 273 for (const auto& extension : registry->enabled_extensions()) { |
| 274 const UsbPrinterManifestData* manifest_data = |
| 275 UsbPrinterManifestData::Get(extension.get()); |
| 276 if (!manifest_data || !HasUsbPrinterProviderPermissions(extension.get())) |
| 277 continue; |
| 278 |
| 279 const extensions::DevicePermissions* device_permissions = |
| 280 permissions_manager->GetForExtension(extension->id()); |
| 281 for (const auto& device : devices) { |
| 282 if (manifest_data->SupportsDevice(device)) { |
| 283 extensions::UsbDevicePermission::CheckParam param( |
| 284 device->vendor_id(), device->product_id(), |
| 285 extensions::UsbDevicePermissionData::UNSPECIFIED_INTERFACE); |
| 286 if (device_permissions->FindUsbDeviceEntry(device) || |
| 287 extension->permissions_data()->CheckAPIPermissionWithParam( |
| 288 extensions::APIPermission::kUsbDevice, ¶m)) { |
| 289 // Skip devices the extension already has permission to access. |
| 290 continue; |
| 291 } |
| 292 |
| 293 printer_list.Append( |
| 294 DictionaryBuilder() |
| 295 .Set("id", base::StringPrintf("provisional-usb:%s:%u", |
| 296 extension->id().c_str(), |
| 297 device->unique_id())) |
| 298 .Set("name", |
| 299 DevicePermissionsManager::GetPermissionMessage( |
| 300 device->vendor_id(), device->product_id(), |
| 301 device->manufacturer_string(), |
| 302 device->product_string(), base::string16(), false)) |
| 303 .Set("extensionId", extension->id()) |
| 304 .Set("extensionName", extension->name()) |
| 305 .Set("provisional", true)); |
| 306 } |
| 307 } |
| 308 } |
| 309 |
| 310 DCHECK_GT(pending_enumeration_count_, 0); |
| 311 pending_enumeration_count_--; |
| 312 callback.Run(*printer_list.Build().get(), pending_enumeration_count_ == 0); |
| 313 } |
OLD | NEW |