| 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 "extensions/browser/api/printer_provider/printer_provider_api.h" | 5 #include "extensions/browser/api/printer_provider/printer_provider_api.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/i18n/rtl.h" | 13 #include "base/i18n/rtl.h" |
| 14 #include "base/json/json_string_value_serializer.h" | 14 #include "base/json/json_string_value_serializer.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/memory/ref_counted_memory.h" | 16 #include "base/memory/ref_counted_memory.h" |
| 17 #include "base/scoped_observer.h" | 17 #include "base/scoped_observer.h" |
| 18 #include "base/strings/string16.h" | 18 #include "base/strings/string16.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 20 #include "base/values.h" | 20 #include "base/values.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_print_job.h" | 25 #include "extensions/browser/api/printer_provider/printer_provider_print_job.h" |
| 22 #include "extensions/browser/api/printer_provider_internal/printer_provider_inte
rnal_api.h" | 26 #include "extensions/browser/api/printer_provider_internal/printer_provider_inte
rnal_api.h" |
| 23 #include "extensions/browser/api/printer_provider_internal/printer_provider_inte
rnal_api_observer.h" | 27 #include "extensions/browser/api/printer_provider_internal/printer_provider_inte
rnal_api_observer.h" |
| 24 #include "extensions/browser/event_router.h" | 28 #include "extensions/browser/event_router.h" |
| 25 #include "extensions/browser/extension_registry.h" | 29 #include "extensions/browser/extension_registry.h" |
| 26 #include "extensions/browser/extension_registry_observer.h" | 30 #include "extensions/browser/extension_registry_observer.h" |
| 27 #include "extensions/common/api/printer_provider.h" | 31 #include "extensions/common/api/printer_provider.h" |
| 32 #include "extensions/common/api/printer_provider/usb_printer_manifest_data.h" |
| 28 #include "extensions/common/api/printer_provider_internal.h" | 33 #include "extensions/common/api/printer_provider_internal.h" |
| 34 #include "extensions/common/api/usb.h" |
| 29 #include "extensions/common/extension.h" | 35 #include "extensions/common/extension.h" |
| 36 #include "extensions/common/permissions/permissions_data.h" |
| 37 #include "extensions/common/value_builder.h" |
| 38 |
| 39 using device::UsbDevice; |
| 40 using device::UsbDeviceFilter; |
| 41 using device::UsbService; |
| 30 | 42 |
| 31 namespace extensions { | 43 namespace extensions { |
| 32 | 44 |
| 33 namespace { | 45 namespace { |
| 34 | 46 |
| 35 // The separator between extension id and the extension's internal printer id | 47 // The separator between extension id and the extension's internal printer id |
| 36 // used when generating a printer id unique across extensions. | 48 // used when generating a printer id unique across extensions. |
| 37 const char kPrinterIdSeparator = ':'; | 49 const char kPrinterIdSeparator = ':'; |
| 38 | 50 |
| 39 // Given an extension ID and an ID of a printer reported by the extension, it | 51 // Given an extension ID and an ID of a printer reported by the extension, it |
| (...skipping 21 matching lines...) Expand all Loading... |
| 61 return true; | 73 return true; |
| 62 } | 74 } |
| 63 | 75 |
| 64 // Holds information about a pending onGetPrintersRequested request; | 76 // Holds information about a pending onGetPrintersRequested request; |
| 65 // in particular, the list of extensions to which the event was dispatched but | 77 // in particular, the list of extensions to which the event was dispatched but |
| 66 // which haven't yet responded, and the |GetPrinters| callback associated with | 78 // which haven't yet responded, and the |GetPrinters| callback associated with |
| 67 // the event. | 79 // the event. |
| 68 class GetPrintersRequest { | 80 class GetPrintersRequest { |
| 69 public: | 81 public: |
| 70 explicit GetPrintersRequest( | 82 explicit GetPrintersRequest( |
| 83 bool wait_for_usb_printers, |
| 71 const PrinterProviderAPI::GetPrintersCallback& callback); | 84 const PrinterProviderAPI::GetPrintersCallback& callback); |
| 72 ~GetPrintersRequest(); | 85 ~GetPrintersRequest(); |
| 73 | 86 |
| 74 // Adds an extension id to the list of the extensions that need to respond | 87 // Adds an extension id to the list of the extensions that need to respond |
| 75 // to the event. | 88 // to the event. |
| 76 void AddSource(const std::string& extension_id); | 89 void AddSource(const std::string& extension); |
| 77 | 90 |
| 78 // Whether all extensions have responded to the event. | 91 // Whether all extensions have responded to the event. |
| 79 bool IsDone() const; | 92 bool IsDone() const; |
| 80 | 93 |
| 81 // Runs the callback for an extension and removes the extension from the | 94 // Runs the callback for an extension and removes the extension from the |
| 82 // list of extensions that still have to respond to the event. | 95 // list of extensions that still have to respond to the event. |
| 83 void ReportForExtension(const std::string& extension_id, | 96 void ReportForExtension(const std::string& extension_id, |
| 84 const base::ListValue& printers); | 97 const base::ListValue& printers); |
| 85 | 98 |
| 99 // Runs the callback for USB printers and clears the request for a list of |
| 100 // USB printers. |
| 101 void ReportUsbPrinters(const base::ListValue& printers); |
| 102 |
| 86 private: | 103 private: |
| 87 // Callback reporting event result for an extension. Called once for each | 104 // Callback reporting event result for an extension. Called once for each |
| 88 // extension. | 105 // extension. |
| 89 PrinterProviderAPI::GetPrintersCallback callback_; | 106 PrinterProviderAPI::GetPrintersCallback callback_; |
| 90 | 107 |
| 91 // The list of extensions that still have to respond to the event. | 108 // The list of extensions that still have to respond to the event. |
| 92 std::set<std::string> extensions_; | 109 std::set<std::string> extensions_; |
| 110 |
| 111 // Set when an extension supporting USB printers is detected and the |
| 112 // GetPrintersRequest is not done until those devices are reported. |
| 113 bool wait_for_usb_printers_; |
| 93 }; | 114 }; |
| 94 | 115 |
| 95 // Keeps track of pending chrome.printerProvider.onGetPrintersRequested | 116 // Keeps track of pending chrome.printerProvider.onGetPrintersRequested |
| 96 // requests. | 117 // requests. |
| 97 class PendingGetPrintersRequests { | 118 class PendingGetPrintersRequests { |
| 98 public: | 119 public: |
| 99 PendingGetPrintersRequests(); | 120 PendingGetPrintersRequests(); |
| 100 ~PendingGetPrintersRequests(); | 121 ~PendingGetPrintersRequests(); |
| 101 | 122 |
| 102 // Adds a new request to the set of pending requests. Returns the id | 123 // Adds a new request to the set of pending requests. Returns the id |
| 103 // assigned to the request. | 124 // assigned to the request. |
| 104 int Add(const PrinterProviderAPI::GetPrintersCallback& callback); | 125 int Add(bool wait_for_usb_printers, |
| 126 const PrinterProviderAPI::GetPrintersCallback& callback); |
| 105 | 127 |
| 106 // Completes a request for an extension. It runs the request callback with | 128 // Completes a request for an extension. It runs the request callback with |
| 107 // values reported by the extension. | 129 // values reported by the extension. |
| 108 bool CompleteForExtension(const std::string& extension_id, | 130 bool CompleteForExtension(const std::string& extension_id, |
| 109 int request_id, | 131 int request_id, |
| 110 const base::ListValue& result); | 132 const base::ListValue& result); |
| 111 | 133 |
| 112 // Runs callbacks for the extension for all requests that are waiting for a | 134 // Runs callbacks for the extension for all requests that are waiting for a |
| 113 // response from the extension with the provided extension id. Callbacks are | 135 // response from the extension with the provided extension id. Callbacks are |
| 114 // called as if the extension reported empty set of printers. | 136 // called as if the extension reported empty set of printers. |
| 115 void FailAllForExtension(const std::string& extension_id); | 137 void FailAllForExtension(const std::string& extension_id); |
| 116 | 138 |
| 117 // Adds an extension id to the list of the extensions that need to respond | 139 // Completes a request for all USB printers associated with registered |
| 118 // to the event. | 140 // extensions. |
| 141 void CompleteUsbPrinters(int request_id, const base::ListValue& result); |
| 142 |
| 143 // Adds an extension to the list of the extensions that need to respond to the |
| 144 // event. |
| 119 bool AddSource(int request_id, const std::string& extension_id); | 145 bool AddSource(int request_id, const std::string& extension_id); |
| 120 | 146 |
| 121 private: | 147 private: |
| 122 int last_request_id_; | 148 int last_request_id_; |
| 123 std::map<int, GetPrintersRequest> pending_requests_; | 149 std::map<int, GetPrintersRequest> pending_requests_; |
| 124 | 150 |
| 125 DISALLOW_COPY_AND_ASSIGN(PendingGetPrintersRequests); | 151 DISALLOW_COPY_AND_ASSIGN(PendingGetPrintersRequests); |
| 126 }; | 152 }; |
| 127 | 153 |
| 128 // Keeps track of pending chrome.printerProvider.onGetCapabilityRequested | 154 // Keeps track of pending chrome.printerProvider.onGetCapabilityRequested |
| (...skipping 13 matching lines...) Expand all Loading... |
| 142 | 168 |
| 143 // Runs all pending callbacks with empty capability value and clears the | 169 // Runs all pending callbacks with empty capability value and clears the |
| 144 // set of pending requests. | 170 // set of pending requests. |
| 145 void FailAll(); | 171 void FailAll(); |
| 146 | 172 |
| 147 private: | 173 private: |
| 148 int last_request_id_; | 174 int last_request_id_; |
| 149 std::map<int, PrinterProviderAPI::GetCapabilityCallback> pending_requests_; | 175 std::map<int, PrinterProviderAPI::GetCapabilityCallback> pending_requests_; |
| 150 }; | 176 }; |
| 151 | 177 |
| 152 // Keeps track of pending chrome.printerProvider.ontPrintRequested requests | 178 // Keeps track of pending chrome.printerProvider.onPrintRequested requests |
| 153 // for an extension. | 179 // for an extension. |
| 154 class PendingPrintRequests { | 180 class PendingPrintRequests { |
| 155 public: | 181 public: |
| 156 PendingPrintRequests(); | 182 PendingPrintRequests(); |
| 157 ~PendingPrintRequests(); | 183 ~PendingPrintRequests(); |
| 158 | 184 |
| 159 // Adds a new request to the set. Only information needed is the callback | 185 // Adds a new request to the set. Only information needed is the callback |
| 160 // associated with the request. Returns the id assigned to the request. | 186 // associated with the request. Returns the id assigned to the request. |
| 161 int Add(const PrinterProviderPrintJob& job, | 187 int Add(const PrinterProviderPrintJob& job, |
| 162 const PrinterProviderAPI::PrintCallback& callback); | 188 const PrinterProviderAPI::PrintCallback& callback); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 175 private: | 201 private: |
| 176 struct PrintRequest { | 202 struct PrintRequest { |
| 177 PrinterProviderAPI::PrintCallback callback; | 203 PrinterProviderAPI::PrintCallback callback; |
| 178 PrinterProviderPrintJob job; | 204 PrinterProviderPrintJob job; |
| 179 }; | 205 }; |
| 180 | 206 |
| 181 int last_request_id_; | 207 int last_request_id_; |
| 182 std::map<int, PrintRequest> pending_requests_; | 208 std::map<int, PrintRequest> pending_requests_; |
| 183 }; | 209 }; |
| 184 | 210 |
| 211 // Keeps track of pending chrome.printerProvider.onUsbAccessGranted requests |
| 212 // for an extension. |
| 213 class PendingUsbPrinterInfoRequests { |
| 214 public: |
| 215 PendingUsbPrinterInfoRequests(); |
| 216 ~PendingUsbPrinterInfoRequests(); |
| 217 |
| 218 // Adds a new request to the set. Only information needed is the callback |
| 219 // associated with the request. Returns the id assigned to the request. |
| 220 int Add(const PrinterProviderAPI::UsbAccessGrantedCallback& callback); |
| 221 |
| 222 // Completes the request with the provided request id. It runs the request |
| 223 // callback and removes the request from the set. |
| 224 void Complete(int request_id, |
| 225 const core_api::printer_provider::PrinterInfo* printer_info); |
| 226 |
| 227 // Runs all pending callbacks with empty capability value and clears the |
| 228 // set of pending requests. |
| 229 void FailAll(); |
| 230 |
| 231 private: |
| 232 int last_request_id_ = 0; |
| 233 std::map<int, PrinterProviderAPI::UsbAccessGrantedCallback> pending_requests_; |
| 234 }; |
| 235 |
| 185 // Implements chrome.printerProvider API events. | 236 // Implements chrome.printerProvider API events. |
| 186 class PrinterProviderAPIImpl : public PrinterProviderAPI, | 237 class PrinterProviderAPIImpl : public PrinterProviderAPI, |
| 187 public PrinterProviderInternalAPIObserver, | 238 public PrinterProviderInternalAPIObserver, |
| 188 public ExtensionRegistryObserver { | 239 public ExtensionRegistryObserver { |
| 189 public: | 240 public: |
| 190 explicit PrinterProviderAPIImpl(content::BrowserContext* browser_context); | 241 explicit PrinterProviderAPIImpl(content::BrowserContext* browser_context); |
| 191 ~PrinterProviderAPIImpl() override; | 242 ~PrinterProviderAPIImpl() override; |
| 192 | 243 |
| 193 private: | 244 private: |
| 194 // PrinterProviderAPI implementation: | 245 // PrinterProviderAPI implementation: |
| 195 void DispatchGetPrintersRequested( | 246 void DispatchGetPrintersRequested( |
| 196 const PrinterProviderAPI::GetPrintersCallback& callback) override; | 247 const PrinterProviderAPI::GetPrintersCallback& callback) override; |
| 197 void DispatchGetCapabilityRequested( | 248 void DispatchGetCapabilityRequested( |
| 198 const std::string& printer_id, | 249 const std::string& printer_id, |
| 199 const PrinterProviderAPI::GetCapabilityCallback& callback) override; | 250 const PrinterProviderAPI::GetCapabilityCallback& callback) override; |
| 200 void DispatchPrintRequested( | 251 void DispatchPrintRequested( |
| 201 const PrinterProviderPrintJob& job, | 252 const PrinterProviderPrintJob& job, |
| 202 const PrinterProviderAPI::PrintCallback& callback) override; | 253 const PrinterProviderAPI::PrintCallback& callback) override; |
| 203 const PrinterProviderPrintJob* GetPrintJob(const Extension* extension, | 254 const PrinterProviderPrintJob* GetPrintJob(const Extension* extension, |
| 204 int request_id) const override; | 255 int request_id) const override; |
| 256 void DispatchGrantUsbPrinterAccess( |
| 257 const std::string& extension_id, |
| 258 int device_id, |
| 259 const PrinterProviderAPI::UsbAccessGrantedCallback& callback) override; |
| 205 | 260 |
| 206 // PrinterProviderInternalAPIObserver implementation: | 261 // PrinterProviderInternalAPIObserver implementation: |
| 207 void OnGetPrintersResult( | 262 void OnGetPrintersResult( |
| 208 const Extension* extension, | 263 const Extension* extension, |
| 209 int request_id, | 264 int request_id, |
| 210 const PrinterProviderInternalAPIObserver::PrinterInfoVector& result) | 265 const PrinterProviderInternalAPIObserver::PrinterInfoVector& result) |
| 211 override; | 266 override; |
| 212 void OnGetCapabilityResult(const Extension* extension, | 267 void OnGetCapabilityResult(const Extension* extension, |
| 213 int request_id, | 268 int request_id, |
| 214 const base::DictionaryValue& result) override; | 269 const base::DictionaryValue& result) override; |
| 215 void OnPrintResult( | 270 void OnPrintResult( |
| 216 const Extension* extension, | 271 const Extension* extension, |
| 217 int request_id, | 272 int request_id, |
| 218 core_api::printer_provider_internal::PrintError error) override; | 273 core_api::printer_provider_internal::PrintError error) override; |
| 274 void OnUsbAccessGrantedResult( |
| 275 const Extension* extension, |
| 276 int request_id, |
| 277 const core_api::printer_provider::PrinterInfo* printer_info) override; |
| 219 | 278 |
| 220 // ExtensionRegistryObserver implementation: | 279 // ExtensionRegistryObserver implementation: |
| 221 void OnExtensionUnloaded(content::BrowserContext* browser_context, | 280 void OnExtensionUnloaded(content::BrowserContext* browser_context, |
| 222 const Extension* extension, | 281 const Extension* extension, |
| 223 UnloadedExtensionInfo::Reason reason) override; | 282 UnloadedExtensionInfo::Reason reason) override; |
| 224 | 283 |
| 225 // Called before chrome.printerProvider.onGetPrintersRequested event is | 284 // Called before chrome.printerProvider.onGetPrintersRequested event is |
| 226 // dispatched to an extension. It returns whether the extension is interested | 285 // dispatched to an extension. It returns whether the extension is interested |
| 227 // in the event. If the extension listens to the event, it's added to the set | 286 // in the event. If the extension listens to the event, it's added to the set |
| 228 // of |request| sources. |request| is |GetPrintersRequest| object associated | 287 // of |request| sources. |request| is |GetPrintersRequest| object associated |
| 229 // with the event. | 288 // with the event. |
| 230 bool WillRequestPrinters(int request_id, | 289 bool WillRequestPrinters(int request_id, |
| 231 content::BrowserContext* browser_context, | 290 content::BrowserContext* browser_context, |
| 232 const Extension* extension, | 291 const Extension* extension, |
| 233 base::ListValue* args); | 292 base::ListValue* args); |
| 234 | 293 |
| 294 void OnUsbDevicesEnumerated( |
| 295 int request_id, |
| 296 const std::vector<scoped_refptr<UsbDevice>>& devices); |
| 297 |
| 235 content::BrowserContext* browser_context_; | 298 content::BrowserContext* browser_context_; |
| 236 | 299 |
| 237 PendingGetPrintersRequests pending_get_printers_requests_; | 300 PendingGetPrintersRequests pending_get_printers_requests_; |
| 238 | 301 |
| 239 std::map<std::string, PendingPrintRequests> pending_print_requests_; | 302 std::map<std::string, PendingPrintRequests> pending_print_requests_; |
| 240 | 303 |
| 241 std::map<std::string, PendingGetCapabilityRequests> | 304 std::map<std::string, PendingGetCapabilityRequests> |
| 242 pending_capability_requests_; | 305 pending_capability_requests_; |
| 243 | 306 |
| 307 std::map<std::string, PendingUsbPrinterInfoRequests> |
| 308 pending_usb_printer_info_requests_; |
| 309 |
| 244 ScopedObserver<PrinterProviderInternalAPI, PrinterProviderInternalAPIObserver> | 310 ScopedObserver<PrinterProviderInternalAPI, PrinterProviderInternalAPIObserver> |
| 245 internal_api_observer_; | 311 internal_api_observer_; |
| 246 | 312 |
| 247 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> | 313 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> |
| 248 extension_registry_observer_; | 314 extension_registry_observer_; |
| 249 | 315 |
| 316 base::WeakPtrFactory<PrinterProviderAPIImpl> weak_factory_; |
| 317 |
| 250 DISALLOW_COPY_AND_ASSIGN(PrinterProviderAPIImpl); | 318 DISALLOW_COPY_AND_ASSIGN(PrinterProviderAPIImpl); |
| 251 }; | 319 }; |
| 252 | 320 |
| 253 GetPrintersRequest::GetPrintersRequest( | 321 GetPrintersRequest::GetPrintersRequest( |
| 322 bool wait_for_usb_printers, |
| 254 const PrinterProviderAPI::GetPrintersCallback& callback) | 323 const PrinterProviderAPI::GetPrintersCallback& callback) |
| 255 : callback_(callback) { | 324 : callback_(callback), wait_for_usb_printers_(wait_for_usb_printers) { |
| 256 } | 325 } |
| 257 | 326 |
| 258 GetPrintersRequest::~GetPrintersRequest() { | 327 GetPrintersRequest::~GetPrintersRequest() { |
| 259 } | 328 } |
| 260 | 329 |
| 261 void GetPrintersRequest::AddSource(const std::string& extension_id) { | 330 void GetPrintersRequest::AddSource(const std::string& extension_id) { |
| 262 extensions_.insert(extension_id); | 331 extensions_.insert(extension_id); |
| 263 } | 332 } |
| 264 | 333 |
| 265 bool GetPrintersRequest::IsDone() const { | 334 bool GetPrintersRequest::IsDone() const { |
| 266 return extensions_.empty(); | 335 return extensions_.empty() && !wait_for_usb_printers_; |
| 267 } | 336 } |
| 268 | 337 |
| 269 void GetPrintersRequest::ReportForExtension(const std::string& extension_id, | 338 void GetPrintersRequest::ReportForExtension(const std::string& extension_id, |
| 270 const base::ListValue& printers) { | 339 const base::ListValue& printers) { |
| 271 if (extensions_.erase(extension_id) > 0) | 340 if (extensions_.erase(extension_id) > 0) |
| 272 callback_.Run(printers, IsDone()); | 341 callback_.Run(printers, IsDone()); |
| 273 } | 342 } |
| 274 | 343 |
| 344 void GetPrintersRequest::ReportUsbPrinters(const base::ListValue& printers) { |
| 345 DCHECK(wait_for_usb_printers_); |
| 346 wait_for_usb_printers_ = false; |
| 347 callback_.Run(printers, IsDone()); |
| 348 } |
| 349 |
| 275 PendingGetPrintersRequests::PendingGetPrintersRequests() : last_request_id_(0) { | 350 PendingGetPrintersRequests::PendingGetPrintersRequests() : last_request_id_(0) { |
| 276 } | 351 } |
| 277 | 352 |
| 278 PendingGetPrintersRequests::~PendingGetPrintersRequests() { | 353 PendingGetPrintersRequests::~PendingGetPrintersRequests() { |
| 279 } | 354 } |
| 280 | 355 |
| 281 int PendingGetPrintersRequests::Add( | 356 int PendingGetPrintersRequests::Add( |
| 357 bool wait_for_usb_printers, |
| 282 const PrinterProviderAPI::GetPrintersCallback& callback) { | 358 const PrinterProviderAPI::GetPrintersCallback& callback) { |
| 283 pending_requests_.insert( | 359 pending_requests_.insert(std::make_pair( |
| 284 std::make_pair(++last_request_id_, GetPrintersRequest(callback))); | 360 ++last_request_id_, GetPrintersRequest(wait_for_usb_printers, callback))); |
| 285 return last_request_id_; | 361 return last_request_id_; |
| 286 } | 362 } |
| 287 | 363 |
| 288 bool PendingGetPrintersRequests::CompleteForExtension( | 364 bool PendingGetPrintersRequests::CompleteForExtension( |
| 289 const std::string& extension_id, | 365 const std::string& extension_id, |
| 290 int request_id, | 366 int request_id, |
| 291 const base::ListValue& result) { | 367 const base::ListValue& result) { |
| 292 auto it = pending_requests_.find(request_id); | 368 auto it = pending_requests_.find(request_id); |
| 293 if (it == pending_requests_.end()) | 369 if (it == pending_requests_.end()) |
| 294 return false; | 370 return false; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 305 auto it = pending_requests_.begin(); | 381 auto it = pending_requests_.begin(); |
| 306 while (it != pending_requests_.end()) { | 382 while (it != pending_requests_.end()) { |
| 307 int request_id = it->first; | 383 int request_id = it->first; |
| 308 // |it| may get deleted during |CompleteForExtension|, so progress it to the | 384 // |it| may get deleted during |CompleteForExtension|, so progress it to the |
| 309 // next item before calling the method. | 385 // next item before calling the method. |
| 310 ++it; | 386 ++it; |
| 311 CompleteForExtension(extension_id, request_id, base::ListValue()); | 387 CompleteForExtension(extension_id, request_id, base::ListValue()); |
| 312 } | 388 } |
| 313 } | 389 } |
| 314 | 390 |
| 391 void PendingGetPrintersRequests::CompleteUsbPrinters( |
| 392 int request_id, |
| 393 const base::ListValue& result) { |
| 394 auto it = pending_requests_.find(request_id); |
| 395 if (it == pending_requests_.end()) { |
| 396 return; |
| 397 } |
| 398 |
| 399 it->second.ReportUsbPrinters(result); |
| 400 if (it->second.IsDone()) { |
| 401 pending_requests_.erase(it); |
| 402 } |
| 403 } |
| 404 |
| 315 bool PendingGetPrintersRequests::AddSource(int request_id, | 405 bool PendingGetPrintersRequests::AddSource(int request_id, |
| 316 const std::string& extension_id) { | 406 const std::string& extension_id) { |
| 317 auto it = pending_requests_.find(request_id); | 407 auto it = pending_requests_.find(request_id); |
| 318 if (it == pending_requests_.end()) | 408 if (it == pending_requests_.end()) |
| 319 return false; | 409 return false; |
| 320 | 410 |
| 321 it->second.AddSource(extension_id); | 411 it->second.AddSource(extension_id); |
| 322 return true; | 412 return true; |
| 323 } | 413 } |
| 324 | 414 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 return &it->second.job; | 484 return &it->second.job; |
| 395 } | 485 } |
| 396 | 486 |
| 397 void PendingPrintRequests::FailAll() { | 487 void PendingPrintRequests::FailAll() { |
| 398 for (auto& request : pending_requests_) | 488 for (auto& request : pending_requests_) |
| 399 request.second.callback.Run(false, | 489 request.second.callback.Run(false, |
| 400 PrinterProviderAPI::GetDefaultPrintError()); | 490 PrinterProviderAPI::GetDefaultPrintError()); |
| 401 pending_requests_.clear(); | 491 pending_requests_.clear(); |
| 402 } | 492 } |
| 403 | 493 |
| 494 PendingUsbPrinterInfoRequests::PendingUsbPrinterInfoRequests() { |
| 495 } |
| 496 |
| 497 PendingUsbPrinterInfoRequests::~PendingUsbPrinterInfoRequests() { |
| 498 } |
| 499 |
| 500 int PendingUsbPrinterInfoRequests::Add( |
| 501 const PrinterProviderAPI::UsbAccessGrantedCallback& callback) { |
| 502 pending_requests_[++last_request_id_] = callback; |
| 503 return last_request_id_; |
| 504 } |
| 505 |
| 506 void PendingUsbPrinterInfoRequests::Complete( |
| 507 int request_id, |
| 508 const core_api::printer_provider::PrinterInfo* printer_info) { |
| 509 auto it = pending_requests_.find(request_id); |
| 510 if (it == pending_requests_.end()) { |
| 511 return; |
| 512 } |
| 513 |
| 514 PrinterProviderAPI::UsbAccessGrantedCallback callback = it->second; |
| 515 pending_requests_.erase(it); |
| 516 |
| 517 if (printer_info) { |
| 518 callback.Run(*printer_info->ToValue().get()); |
| 519 } else { |
| 520 callback.Run(base::DictionaryValue()); |
| 521 } |
| 522 } |
| 523 |
| 524 void PendingUsbPrinterInfoRequests::FailAll() { |
| 525 for (auto& request : pending_requests_) { |
| 526 request.second.Run(base::DictionaryValue()); |
| 527 } |
| 528 pending_requests_.clear(); |
| 529 } |
| 530 |
| 404 PrinterProviderAPIImpl::PrinterProviderAPIImpl( | 531 PrinterProviderAPIImpl::PrinterProviderAPIImpl( |
| 405 content::BrowserContext* browser_context) | 532 content::BrowserContext* browser_context) |
| 406 : browser_context_(browser_context), | 533 : browser_context_(browser_context), |
| 407 internal_api_observer_(this), | 534 internal_api_observer_(this), |
| 408 extension_registry_observer_(this) { | 535 extension_registry_observer_(this), |
| 536 weak_factory_(this) { |
| 409 internal_api_observer_.Add( | 537 internal_api_observer_.Add( |
| 410 PrinterProviderInternalAPI::GetFactoryInstance()->Get(browser_context)); | 538 PrinterProviderInternalAPI::GetFactoryInstance()->Get(browser_context)); |
| 411 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context)); | 539 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context)); |
| 412 } | 540 } |
| 413 | 541 |
| 414 PrinterProviderAPIImpl::~PrinterProviderAPIImpl() { | 542 PrinterProviderAPIImpl::~PrinterProviderAPIImpl() { |
| 415 } | 543 } |
| 416 | 544 |
| 417 void PrinterProviderAPIImpl::DispatchGetPrintersRequested( | 545 void PrinterProviderAPIImpl::DispatchGetPrintersRequested( |
| 418 const GetPrintersCallback& callback) { | 546 const GetPrintersCallback& callback) { |
| 419 EventRouter* event_router = EventRouter::Get(browser_context_); | 547 EventRouter* event_router = EventRouter::Get(browser_context_); |
| 420 if (!event_router->HasEventListener( | 548 if (!event_router->HasEventListener( |
| 421 core_api::printer_provider::OnGetPrintersRequested::kEventName)) { | 549 core_api::printer_provider::OnGetPrintersRequested::kEventName)) { |
| 422 callback.Run(base::ListValue(), true /* done */); | 550 callback.Run(base::ListValue(), true /* done */); |
| 423 return; | 551 return; |
| 424 } | 552 } |
| 425 | 553 |
| 426 // |pending_get_printers_requests_| take ownership of |request| which gets | 554 bool extensions_support_usb_devices = false; |
| 427 // NULLed out. Save the pointer before passing it to the requests, as it will | 555 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); |
| 428 // be needed later on. | 556 for (const auto& extension : registry->enabled_extensions()) { |
| 429 int request_id = pending_get_printers_requests_.Add(callback); | 557 if (UsbPrinterManifestData::Get(extension.get()) && |
| 558 extension->permissions_data() && |
| 559 extension->permissions_data()->HasAPIPermission( |
| 560 extensions::APIPermission::kPrinterProvider) && |
| 561 extension->permissions_data()->HasAPIPermission( |
| 562 extensions::APIPermission::kUsb)) { |
| 563 extensions_support_usb_devices = true; |
| 564 } |
| 565 } |
| 566 |
| 567 int request_id = pending_get_printers_requests_.Add( |
| 568 extensions_support_usb_devices, callback); |
| 430 | 569 |
| 431 scoped_ptr<base::ListValue> internal_args(new base::ListValue); | 570 scoped_ptr<base::ListValue> internal_args(new base::ListValue); |
| 432 // Request id is not part of the public API, but it will be massaged out in | 571 // Request id is not part of the public API, but it will be massaged out in |
| 433 // custom bindings. | 572 // custom bindings. |
| 434 internal_args->AppendInteger(request_id); | 573 internal_args->AppendInteger(request_id); |
| 435 | 574 |
| 436 scoped_ptr<Event> event( | 575 scoped_ptr<Event> event( |
| 437 new Event(core_api::printer_provider::OnGetPrintersRequested::kEventName, | 576 new Event(core_api::printer_provider::OnGetPrintersRequested::kEventName, |
| 438 internal_args.Pass())); | 577 internal_args.Pass())); |
| 439 // This callback is called synchronously during |BroadcastEvent|, so | 578 // This callback is called synchronously during |BroadcastEvent|, so |
| 440 // Unretained is safe. | 579 // Unretained is safe. |
| 441 event->will_dispatch_callback = | 580 event->will_dispatch_callback = |
| 442 base::Bind(&PrinterProviderAPIImpl::WillRequestPrinters, | 581 base::Bind(&PrinterProviderAPIImpl::WillRequestPrinters, |
| 443 base::Unretained(this), request_id); | 582 base::Unretained(this), request_id); |
| 444 | 583 |
| 445 event_router->BroadcastEvent(event.Pass()); | 584 event_router->BroadcastEvent(event.Pass()); |
| 585 |
| 586 // Start the USB device enumeration after the event has been broadcast to |
| 587 // extensions as OnUsbDevicesEnumerated may be called synchronously and that |
| 588 // would complete the request before extensions can be Added to it. |
| 589 if (extensions_support_usb_devices) { |
| 590 UsbService* service = device::DeviceClient::Get()->GetUsbService(); |
| 591 DCHECK(service); |
| 592 service->GetDevices( |
| 593 base::Bind(&PrinterProviderAPIImpl::OnUsbDevicesEnumerated, |
| 594 weak_factory_.GetWeakPtr(), request_id)); |
| 595 } |
| 446 } | 596 } |
| 447 | 597 |
| 448 void PrinterProviderAPIImpl::DispatchGetCapabilityRequested( | 598 void PrinterProviderAPIImpl::DispatchGetCapabilityRequested( |
| 449 const std::string& printer_id, | 599 const std::string& printer_id, |
| 450 const PrinterProviderAPI::GetCapabilityCallback& callback) { | 600 const PrinterProviderAPI::GetCapabilityCallback& callback) { |
| 451 std::string extension_id; | 601 std::string extension_id; |
| 452 std::string internal_printer_id; | 602 std::string internal_printer_id; |
| 453 if (!ParsePrinterId(printer_id, &extension_id, &internal_printer_id)) { | 603 if (!ParsePrinterId(printer_id, &extension_id, &internal_printer_id)) { |
| 454 callback.Run(base::DictionaryValue()); | 604 callback.Run(base::DictionaryValue()); |
| 455 return; | 605 return; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 | 677 |
| 528 const PrinterProviderPrintJob* PrinterProviderAPIImpl::GetPrintJob( | 678 const PrinterProviderPrintJob* PrinterProviderAPIImpl::GetPrintJob( |
| 529 const Extension* extension, | 679 const Extension* extension, |
| 530 int request_id) const { | 680 int request_id) const { |
| 531 auto it = pending_print_requests_.find(extension->id()); | 681 auto it = pending_print_requests_.find(extension->id()); |
| 532 if (it == pending_print_requests_.end()) | 682 if (it == pending_print_requests_.end()) |
| 533 return nullptr; | 683 return nullptr; |
| 534 return it->second.GetPrintJob(request_id); | 684 return it->second.GetPrintJob(request_id); |
| 535 } | 685 } |
| 536 | 686 |
| 687 void PrinterProviderAPIImpl::DispatchGrantUsbPrinterAccess( |
| 688 const std::string& extension_id, |
| 689 int device_id, |
| 690 const PrinterProviderAPI::UsbAccessGrantedCallback& callback) { |
| 691 UsbService* service = device::DeviceClient::Get()->GetUsbService(); |
| 692 DCHECK(service); |
| 693 scoped_refptr<UsbDevice> device = service->GetDeviceById(device_id); |
| 694 if (!device) { |
| 695 callback.Run(base::DictionaryValue()); |
| 696 return; |
| 697 } |
| 698 |
| 699 DevicePermissionsManager* permissions_manager = |
| 700 DevicePermissionsManager::Get(browser_context_); |
| 701 DCHECK(permissions_manager); |
| 702 permissions_manager->AllowUsbDevice(extension_id, device); |
| 703 |
| 704 EventRouter* event_router = EventRouter::Get(browser_context_); |
| 705 if (!event_router->ExtensionHasEventListener( |
| 706 extension_id, |
| 707 core_api::printer_provider::OnUsbAccessGranted::kEventName)) { |
| 708 callback.Run(base::DictionaryValue()); |
| 709 return; |
| 710 } |
| 711 |
| 712 int request_id = |
| 713 pending_usb_printer_info_requests_[extension_id].Add(callback); |
| 714 core_api::usb::Device usb_device; |
| 715 usb_device.device = device->unique_id(); |
| 716 usb_device.vendor_id = device->vendor_id(); |
| 717 usb_device.product_id = device->product_id(); |
| 718 |
| 719 scoped_ptr<base::ListValue> internal_args(new base::ListValue); |
| 720 // Request id is not part of the public API and it will be massaged out in |
| 721 // custom bindings. |
| 722 internal_args->AppendInteger(request_id); |
| 723 internal_args->Append(usb_device.ToValue().release()); |
| 724 scoped_ptr<Event> event( |
| 725 new Event(core_api::printer_provider::OnUsbAccessGranted::kEventName, |
| 726 internal_args.Pass())); |
| 727 event_router->DispatchEventToExtension(extension_id, event.Pass()); |
| 728 } |
| 729 |
| 537 void PrinterProviderAPIImpl::OnGetPrintersResult( | 730 void PrinterProviderAPIImpl::OnGetPrintersResult( |
| 538 const Extension* extension, | 731 const Extension* extension, |
| 539 int request_id, | 732 int request_id, |
| 540 const PrinterProviderInternalAPIObserver::PrinterInfoVector& result) { | 733 const PrinterProviderInternalAPIObserver::PrinterInfoVector& result) { |
| 541 base::ListValue printer_list; | 734 base::ListValue printer_list; |
| 542 | 735 |
| 543 // Update some printer description properties to better identify the extension | 736 // Update some printer description properties to better identify the extension |
| 544 // managing the printer. | 737 // managing the printer. |
| 545 for (size_t i = 0; i < result.size(); ++i) { | 738 for (size_t i = 0; i < result.size(); ++i) { |
| 546 scoped_ptr<base::DictionaryValue> printer(result[i]->ToValue()); | 739 scoped_ptr<base::DictionaryValue> printer(result[i]->ToValue()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 core_api::printer_provider_internal::PrintError error) { | 776 core_api::printer_provider_internal::PrintError error) { |
| 584 const std::string error_str = | 777 const std::string error_str = |
| 585 error == core_api::printer_provider_internal::PRINT_ERROR_NONE | 778 error == core_api::printer_provider_internal::PRINT_ERROR_NONE |
| 586 ? PrinterProviderAPI::GetDefaultPrintError() | 779 ? PrinterProviderAPI::GetDefaultPrintError() |
| 587 : core_api::printer_provider_internal::ToString(error); | 780 : core_api::printer_provider_internal::ToString(error); |
| 588 pending_print_requests_[extension->id()].Complete( | 781 pending_print_requests_[extension->id()].Complete( |
| 589 request_id, error == core_api::printer_provider_internal::PRINT_ERROR_OK, | 782 request_id, error == core_api::printer_provider_internal::PRINT_ERROR_OK, |
| 590 error_str); | 783 error_str); |
| 591 } | 784 } |
| 592 | 785 |
| 786 void PrinterProviderAPIImpl::OnUsbAccessGrantedResult( |
| 787 const Extension* extension, |
| 788 int request_id, |
| 789 const core_api::printer_provider::PrinterInfo* printer_info) { |
| 790 pending_usb_printer_info_requests_[extension->id()].Complete(request_id, |
| 791 printer_info); |
| 792 } |
| 793 |
| 593 void PrinterProviderAPIImpl::OnExtensionUnloaded( | 794 void PrinterProviderAPIImpl::OnExtensionUnloaded( |
| 594 content::BrowserContext* browser_context, | 795 content::BrowserContext* browser_context, |
| 595 const Extension* extension, | 796 const Extension* extension, |
| 596 UnloadedExtensionInfo::Reason reason) { | 797 UnloadedExtensionInfo::Reason reason) { |
| 597 pending_get_printers_requests_.FailAllForExtension(extension->id()); | 798 pending_get_printers_requests_.FailAllForExtension(extension->id()); |
| 598 | 799 |
| 599 auto print_it = pending_print_requests_.find(extension->id()); | 800 auto print_it = pending_print_requests_.find(extension->id()); |
| 600 if (print_it != pending_print_requests_.end()) { | 801 if (print_it != pending_print_requests_.end()) { |
| 601 print_it->second.FailAll(); | 802 print_it->second.FailAll(); |
| 602 pending_print_requests_.erase(print_it); | 803 pending_print_requests_.erase(print_it); |
| 603 } | 804 } |
| 604 | 805 |
| 605 auto capability_it = pending_capability_requests_.find(extension->id()); | 806 auto capability_it = pending_capability_requests_.find(extension->id()); |
| 606 if (capability_it != pending_capability_requests_.end()) { | 807 if (capability_it != pending_capability_requests_.end()) { |
| 607 capability_it->second.FailAll(); | 808 capability_it->second.FailAll(); |
| 608 pending_capability_requests_.erase(capability_it); | 809 pending_capability_requests_.erase(capability_it); |
| 609 } | 810 } |
| 811 |
| 812 auto usb_it = pending_usb_printer_info_requests_.find(extension->id()); |
| 813 if (usb_it != pending_usb_printer_info_requests_.end()) { |
| 814 usb_it->second.FailAll(); |
| 815 pending_usb_printer_info_requests_.erase(usb_it); |
| 816 } |
| 610 } | 817 } |
| 611 | 818 |
| 612 bool PrinterProviderAPIImpl::WillRequestPrinters( | 819 bool PrinterProviderAPIImpl::WillRequestPrinters( |
| 613 int request_id, | 820 int request_id, |
| 614 content::BrowserContext* browser_context, | 821 content::BrowserContext* browser_context, |
| 615 const Extension* extension, | 822 const Extension* extension, |
| 616 base::ListValue* args) { | 823 base::ListValue* args) { |
| 617 if (!extension) | 824 if (!extension) |
| 618 return false; | 825 return false; |
| 619 EventRouter* event_router = EventRouter::Get(browser_context_); | 826 EventRouter* event_router = EventRouter::Get(browser_context_); |
| 620 if (!event_router->ExtensionHasEventListener( | 827 if (!event_router->ExtensionHasEventListener( |
| 621 extension->id(), | 828 extension->id(), |
| 622 core_api::printer_provider::OnGetPrintersRequested::kEventName)) { | 829 core_api::printer_provider::OnGetPrintersRequested::kEventName)) { |
| 623 return false; | 830 return false; |
| 624 } | 831 } |
| 625 | 832 |
| 626 return pending_get_printers_requests_.AddSource(request_id, extension->id()); | 833 return pending_get_printers_requests_.AddSource(request_id, extension->id()); |
| 627 } | 834 } |
| 628 | 835 |
| 836 void PrinterProviderAPIImpl::OnUsbDevicesEnumerated( |
| 837 int request_id, |
| 838 const std::vector<scoped_refptr<UsbDevice>>& devices) { |
| 839 std::map<scoped_refptr<UsbDevice>, |
| 840 std::vector<scoped_refptr<const Extension>>> result_map; |
| 841 |
| 842 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); |
| 843 for (const auto& extension : registry->enabled_extensions()) { |
| 844 const UsbPrinterManifestData* manifest_data = |
| 845 UsbPrinterManifestData::Get(extension.get()); |
| 846 |
| 847 if (!manifest_data || !extension->permissions_data() || |
| 848 !extension->permissions_data()->HasAPIPermission( |
| 849 extensions::APIPermission::kPrinterProvider) || |
| 850 !extension->permissions_data()->HasAPIPermission( |
| 851 extensions::APIPermission::kUsb)) { |
| 852 continue; |
| 853 } |
| 854 |
| 855 for (const auto& device : devices) { |
| 856 if (manifest_data->SupportsDevice(device)) { |
| 857 result_map[device].push_back(extension); |
| 858 } |
| 859 } |
| 860 } |
| 861 |
| 862 ListBuilder printer_list; |
| 863 for (const auto& map_entry : result_map) { |
| 864 ListBuilder extension_list; |
| 865 for (const scoped_refptr<const Extension>& extension : map_entry.second) { |
| 866 extension_list.Append(DictionaryBuilder() |
| 867 .Set("extensionId", extension->id()) |
| 868 .Set("extensionName", extension->name())); |
| 869 } |
| 870 |
| 871 const scoped_refptr<UsbDevice>& device = map_entry.first; |
| 872 printer_list.Append( |
| 873 DictionaryBuilder() |
| 874 .Set("name", DevicePermissionsManager::GetPermissionMessage( |
| 875 device->vendor_id(), device->product_id(), |
| 876 device->manufacturer_string(), |
| 877 device->product_string(), base::string16(), false)) |
| 878 .Set("usbDevice", static_cast<int>(device->unique_id())) |
| 879 .Set("extensions", extension_list.Pass())); |
| 880 } |
| 881 |
| 882 pending_get_printers_requests_.CompleteUsbPrinters( |
| 883 request_id, *printer_list.Build().get()); |
| 884 } |
| 885 |
| 629 } // namespace | 886 } // namespace |
| 630 | 887 |
| 631 // static | 888 // static |
| 632 PrinterProviderAPI* PrinterProviderAPI::Create( | 889 PrinterProviderAPI* PrinterProviderAPI::Create( |
| 633 content::BrowserContext* context) { | 890 content::BrowserContext* context) { |
| 634 return new PrinterProviderAPIImpl(context); | 891 return new PrinterProviderAPIImpl(context); |
| 635 } | 892 } |
| 636 | 893 |
| 637 // static | 894 // static |
| 638 std::string PrinterProviderAPI::GetDefaultPrintError() { | 895 std::string PrinterProviderAPI::GetDefaultPrintError() { |
| 639 return core_api::printer_provider_internal::ToString( | 896 return core_api::printer_provider_internal::ToString( |
| 640 core_api::printer_provider_internal::PRINT_ERROR_FAILED); | 897 core_api::printer_provider_internal::PRINT_ERROR_FAILED); |
| 641 } | 898 } |
| 642 | 899 |
| 643 } // namespace extensions | 900 } // namespace extensions |
| OLD | NEW |