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
3 // found in the LICENSE file.
5 #include "extensions/browser/api/printer_provider/printer_provider_api.h"
12 #include "base/bind.h"
13 #include "base/i18n/rtl.h"
14 #include "base/json/json_string_value_serializer.h"
15 #include "base/macros.h"
16 #include "base/scoped_observer.h"
17 #include "base/strings/string16.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/values.h"
20 #include "device/usb/usb_device.h"
21 #include "extensions/browser/api/printer_provider/printer_provider_print_job.h"
22 #include "extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h"
23 #include "extensions/browser/api/printer_provider_internal/printer_provider_internal_api_observer.h"
24 #include "extensions/browser/api/usb/usb_guid_map.h"
25 #include "extensions/browser/event_router.h"
26 #include "extensions/browser/extension_registry.h"
27 #include "extensions/browser/extension_registry_observer.h"
28 #include "extensions/common/api/printer_provider.h"
29 #include "extensions/common/api/printer_provider_internal.h"
30 #include "extensions/common/api/usb.h"
31 #include "extensions/common/extension.h"
33 using device::UsbDevice
;
35 namespace extensions
{
39 // The separator between extension id and the extension's internal printer id
40 // used when generating a printer id unique across extensions.
41 const char kPrinterIdSeparator
= ':';
43 // Given an extension ID and an ID of a printer reported by the extension, it
44 // generates a ID for the printer unique across extensions (assuming that the
45 // printer id is unique in the extension's space).
46 std::string
GeneratePrinterId(const std::string
& extension_id
,
47 const std::string
& internal_printer_id
) {
48 std::string result
= extension_id
;
49 result
.append(1, kPrinterIdSeparator
);
50 result
.append(internal_printer_id
);
54 // Parses an ID created using |GeneratePrinterId| to it's components:
55 // the extension ID and the printer ID internal to the extension.
56 // Returns whenter the ID was succesfully parsed.
57 bool ParsePrinterId(const std::string
& printer_id
,
58 std::string
* extension_id
,
59 std::string
* internal_printer_id
) {
60 size_t separator
= printer_id
.find_first_of(kPrinterIdSeparator
);
61 if (separator
== std::string::npos
)
63 *extension_id
= printer_id
.substr(0, separator
);
64 *internal_printer_id
= printer_id
.substr(separator
+ 1);
68 void UpdatePrinterWithExtensionInfo(base::DictionaryValue
* printer
,
69 const Extension
* extension
) {
70 std::string internal_printer_id
;
71 CHECK(printer
->GetString("id", &internal_printer_id
));
72 printer
->SetString("id",
73 GeneratePrinterId(extension
->id(), internal_printer_id
));
74 printer
->SetString("extensionId", extension
->id());
75 printer
->SetString("extensionName", extension
->name());
77 base::string16 printer_name
;
78 if (printer
->GetString("name", &printer_name
) &&
79 base::i18n::AdjustStringForLocaleDirection(&printer_name
)) {
80 printer
->SetString("name", printer_name
);
83 base::string16 printer_description
;
84 if (printer
->GetString("description", &printer_description
) &&
85 base::i18n::AdjustStringForLocaleDirection(&printer_description
)) {
86 printer
->SetString("description", printer_description
);
90 // Holds information about a pending onGetPrintersRequested request;
91 // in particular, the list of extensions to which the event was dispatched but
92 // which haven't yet responded, and the |GetPrinters| callback associated with
94 class GetPrintersRequest
{
96 explicit GetPrintersRequest(
97 const PrinterProviderAPI::GetPrintersCallback
& callback
);
98 ~GetPrintersRequest();
100 // Adds an extension id to the list of the extensions that need to respond
102 void AddSource(const std::string
& extension_id
);
104 // Whether all extensions have responded to the event.
107 // Runs the callback for an extension and removes the extension from the
108 // list of extensions that still have to respond to the event.
109 void ReportForExtension(const std::string
& extension_id
,
110 const base::ListValue
& printers
);
113 // Callback reporting event result for an extension. Called once for each
115 PrinterProviderAPI::GetPrintersCallback callback_
;
117 // The list of extensions that still have to respond to the event.
118 std::set
<std::string
> extensions_
;
121 // Keeps track of pending chrome.printerProvider.onGetPrintersRequested
123 class PendingGetPrintersRequests
{
125 PendingGetPrintersRequests();
126 ~PendingGetPrintersRequests();
128 // Adds a new request to the set of pending requests. Returns the id
129 // assigned to the request.
130 int Add(const PrinterProviderAPI::GetPrintersCallback
& callback
);
132 // Completes a request for an extension. It runs the request callback with
133 // values reported by the extension.
134 bool CompleteForExtension(const std::string
& extension_id
,
136 const base::ListValue
& result
);
138 // Runs callbacks for the extension for all requests that are waiting for a
139 // response from the extension with the provided extension id. Callbacks are
140 // called as if the extension reported empty set of printers.
141 void FailAllForExtension(const std::string
& extension_id
);
143 // Adds an extension id to the list of the extensions that need to respond to
145 bool AddSource(int request_id
, const std::string
& extension_id
);
148 int last_request_id_
;
149 std::map
<int, GetPrintersRequest
> pending_requests_
;
151 DISALLOW_COPY_AND_ASSIGN(PendingGetPrintersRequests
);
154 // Keeps track of pending chrome.printerProvider.onGetCapabilityRequested
155 // requests for an extension.
156 class PendingGetCapabilityRequests
{
158 PendingGetCapabilityRequests();
159 ~PendingGetCapabilityRequests();
161 // Adds a new request to the set. Only information needed is the callback
162 // associated with the request. Returns the id assigned to the request.
163 int Add(const PrinterProviderAPI::GetCapabilityCallback
& callback
);
165 // Completes the request with the provided request id. It runs the request
166 // callback and removes the request from the set.
167 bool Complete(int request_id
, const base::DictionaryValue
& result
);
169 // Runs all pending callbacks with empty capability value and clears the
170 // set of pending requests.
174 int last_request_id_
;
175 std::map
<int, PrinterProviderAPI::GetCapabilityCallback
> pending_requests_
;
178 // Keeps track of pending chrome.printerProvider.onPrintRequested requests
180 class PendingPrintRequests
{
182 PendingPrintRequests();
183 ~PendingPrintRequests();
185 // Adds a new request to the set. Only information needed is the callback
186 // associated with the request. Returns the id assigned to the request.
187 int Add(const PrinterProviderPrintJob
& job
,
188 const PrinterProviderAPI::PrintCallback
& callback
);
190 // Gets print job associated with a request.
191 const PrinterProviderPrintJob
* GetPrintJob(int request_id
) const;
193 // Completes the request with the provided request id. It runs the request
194 // callback and removes the request from the set.
195 bool Complete(int request_id
, bool success
, const std::string
& result
);
197 // Runs all pending callbacks with ERROR_FAILED and clears the set of
202 struct PrintRequest
{
203 PrinterProviderAPI::PrintCallback callback
;
204 PrinterProviderPrintJob job
;
207 int last_request_id_
;
208 std::map
<int, PrintRequest
> pending_requests_
;
211 // Keeps track of pending chrome.printerProvider.onGetUsbPrinterInfoRequested
212 // requests for an extension.
213 class PendingUsbPrinterInfoRequests
{
215 PendingUsbPrinterInfoRequests();
216 ~PendingUsbPrinterInfoRequests();
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::GetPrinterInfoCallback
& callback
);
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
, const base::DictionaryValue
& printer_info
);
226 // Runs all pending callbacks with empty capability value and clears the
227 // set of pending requests.
231 int last_request_id_
= 0;
232 std::map
<int, PrinterProviderAPI::GetPrinterInfoCallback
> pending_requests_
;
235 // Implements chrome.printerProvider API events.
236 class PrinterProviderAPIImpl
: public PrinterProviderAPI
,
237 public PrinterProviderInternalAPIObserver
,
238 public ExtensionRegistryObserver
{
240 explicit PrinterProviderAPIImpl(content::BrowserContext
* browser_context
);
241 ~PrinterProviderAPIImpl() override
;
244 // PrinterProviderAPI implementation:
245 void DispatchGetPrintersRequested(
246 const PrinterProviderAPI::GetPrintersCallback
& callback
) override
;
247 void DispatchGetCapabilityRequested(
248 const std::string
& printer_id
,
249 const PrinterProviderAPI::GetCapabilityCallback
& callback
) override
;
250 void DispatchPrintRequested(
251 const PrinterProviderPrintJob
& job
,
252 const PrinterProviderAPI::PrintCallback
& callback
) override
;
253 const PrinterProviderPrintJob
* GetPrintJob(const Extension
* extension
,
254 int request_id
) const override
;
255 void DispatchGetUsbPrinterInfoRequested(
256 const std::string
& extension_id
,
257 scoped_refptr
<UsbDevice
> device
,
258 const PrinterProviderAPI::GetPrinterInfoCallback
& callback
) override
;
260 // PrinterProviderInternalAPIObserver implementation:
261 void OnGetPrintersResult(
262 const Extension
* extension
,
264 const PrinterProviderInternalAPIObserver::PrinterInfoVector
& result
)
266 void OnGetCapabilityResult(const Extension
* extension
,
268 const base::DictionaryValue
& result
) override
;
270 const Extension
* extension
,
272 core_api::printer_provider_internal::PrintError error
) override
;
273 void OnGetUsbPrinterInfoResult(
274 const Extension
* extension
,
276 const core_api::printer_provider::PrinterInfo
* printer_info
) override
;
278 // ExtensionRegistryObserver implementation:
279 void OnExtensionUnloaded(content::BrowserContext
* browser_context
,
280 const Extension
* extension
,
281 UnloadedExtensionInfo::Reason reason
) override
;
283 // Called before chrome.printerProvider.onGetPrintersRequested event is
284 // dispatched to an extension. It returns whether the extension is interested
285 // in the event. If the extension listens to the event, it's added to the set
286 // of |request| sources. |request| is |GetPrintersRequest| object associated
288 bool WillRequestPrinters(int request_id
,
289 content::BrowserContext
* browser_context
,
290 const Extension
* extension
,
291 base::ListValue
* args
);
293 content::BrowserContext
* browser_context_
;
295 PendingGetPrintersRequests pending_get_printers_requests_
;
297 std::map
<std::string
, PendingPrintRequests
> pending_print_requests_
;
299 std::map
<std::string
, PendingGetCapabilityRequests
>
300 pending_capability_requests_
;
302 std::map
<std::string
, PendingUsbPrinterInfoRequests
>
303 pending_usb_printer_info_requests_
;
305 ScopedObserver
<PrinterProviderInternalAPI
, PrinterProviderInternalAPIObserver
>
306 internal_api_observer_
;
308 ScopedObserver
<ExtensionRegistry
, ExtensionRegistryObserver
>
309 extension_registry_observer_
;
311 DISALLOW_COPY_AND_ASSIGN(PrinterProviderAPIImpl
);
314 GetPrintersRequest::GetPrintersRequest(
315 const PrinterProviderAPI::GetPrintersCallback
& callback
)
316 : callback_(callback
) {
319 GetPrintersRequest::~GetPrintersRequest() {
322 void GetPrintersRequest::AddSource(const std::string
& extension_id
) {
323 extensions_
.insert(extension_id
);
326 bool GetPrintersRequest::IsDone() const {
327 return extensions_
.empty();
330 void GetPrintersRequest::ReportForExtension(const std::string
& extension_id
,
331 const base::ListValue
& printers
) {
332 if (extensions_
.erase(extension_id
) > 0)
333 callback_
.Run(printers
, IsDone());
336 PendingGetPrintersRequests::PendingGetPrintersRequests() : last_request_id_(0) {
339 PendingGetPrintersRequests::~PendingGetPrintersRequests() {
342 int PendingGetPrintersRequests::Add(
343 const PrinterProviderAPI::GetPrintersCallback
& callback
) {
344 pending_requests_
.insert(
345 std::make_pair(++last_request_id_
, GetPrintersRequest(callback
)));
346 return last_request_id_
;
349 bool PendingGetPrintersRequests::CompleteForExtension(
350 const std::string
& extension_id
,
352 const base::ListValue
& result
) {
353 auto it
= pending_requests_
.find(request_id
);
354 if (it
== pending_requests_
.end())
357 it
->second
.ReportForExtension(extension_id
, result
);
358 if (it
->second
.IsDone()) {
359 pending_requests_
.erase(it
);
364 void PendingGetPrintersRequests::FailAllForExtension(
365 const std::string
& extension_id
) {
366 auto it
= pending_requests_
.begin();
367 while (it
!= pending_requests_
.end()) {
368 int request_id
= it
->first
;
369 // |it| may get deleted during |CompleteForExtension|, so progress it to the
370 // next item before calling the method.
372 CompleteForExtension(extension_id
, request_id
, base::ListValue());
376 bool PendingGetPrintersRequests::AddSource(int request_id
,
377 const std::string
& extension_id
) {
378 auto it
= pending_requests_
.find(request_id
);
379 if (it
== pending_requests_
.end())
382 it
->second
.AddSource(extension_id
);
386 PendingGetCapabilityRequests::PendingGetCapabilityRequests()
387 : last_request_id_(0) {
390 PendingGetCapabilityRequests::~PendingGetCapabilityRequests() {
393 int PendingGetCapabilityRequests::Add(
394 const PrinterProviderAPI::GetCapabilityCallback
& callback
) {
395 pending_requests_
[++last_request_id_
] = callback
;
396 return last_request_id_
;
399 bool PendingGetCapabilityRequests::Complete(
401 const base::DictionaryValue
& response
) {
402 auto it
= pending_requests_
.find(request_id
);
403 if (it
== pending_requests_
.end())
406 PrinterProviderAPI::GetCapabilityCallback callback
= it
->second
;
407 pending_requests_
.erase(it
);
409 callback
.Run(response
);
413 void PendingGetCapabilityRequests::FailAll() {
414 for (auto& request
: pending_requests_
)
415 request
.second
.Run(base::DictionaryValue());
416 pending_requests_
.clear();
419 PendingPrintRequests::PendingPrintRequests() : last_request_id_(0) {
422 PendingPrintRequests::~PendingPrintRequests() {
425 int PendingPrintRequests::Add(
426 const PrinterProviderPrintJob
& job
,
427 const PrinterProviderAPI::PrintCallback
& callback
) {
428 PrintRequest request
;
429 request
.callback
= callback
;
431 pending_requests_
[++last_request_id_
] = request
;
432 return last_request_id_
;
435 bool PendingPrintRequests::Complete(int request_id
,
437 const std::string
& response
) {
438 auto it
= pending_requests_
.find(request_id
);
439 if (it
== pending_requests_
.end())
442 PrinterProviderAPI::PrintCallback callback
= it
->second
.callback
;
443 pending_requests_
.erase(it
);
445 callback
.Run(success
, response
);
449 const PrinterProviderPrintJob
* PendingPrintRequests::GetPrintJob(
450 int request_id
) const {
451 auto it
= pending_requests_
.find(request_id
);
452 if (it
== pending_requests_
.end())
455 return &it
->second
.job
;
458 void PendingPrintRequests::FailAll() {
459 for (auto& request
: pending_requests_
)
460 request
.second
.callback
.Run(false,
461 PrinterProviderAPI::GetDefaultPrintError());
462 pending_requests_
.clear();
465 PendingUsbPrinterInfoRequests::PendingUsbPrinterInfoRequests() {
468 PendingUsbPrinterInfoRequests::~PendingUsbPrinterInfoRequests() {
471 int PendingUsbPrinterInfoRequests::Add(
472 const PrinterProviderAPI::GetPrinterInfoCallback
& callback
) {
473 pending_requests_
[++last_request_id_
] = callback
;
474 return last_request_id_
;
477 void PendingUsbPrinterInfoRequests::Complete(
479 const base::DictionaryValue
& printer_info
) {
480 auto it
= pending_requests_
.find(request_id
);
481 if (it
== pending_requests_
.end())
484 PrinterProviderAPI::GetPrinterInfoCallback callback
= it
->second
;
485 pending_requests_
.erase(it
);
487 callback
.Run(printer_info
);
490 void PendingUsbPrinterInfoRequests::FailAll() {
491 for (auto& request
: pending_requests_
) {
492 request
.second
.Run(base::DictionaryValue());
494 pending_requests_
.clear();
497 PrinterProviderAPIImpl::PrinterProviderAPIImpl(
498 content::BrowserContext
* browser_context
)
499 : browser_context_(browser_context
),
500 internal_api_observer_(this),
501 extension_registry_observer_(this) {
502 internal_api_observer_
.Add(
503 PrinterProviderInternalAPI::GetFactoryInstance()->Get(browser_context
));
504 extension_registry_observer_
.Add(ExtensionRegistry::Get(browser_context
));
507 PrinterProviderAPIImpl::~PrinterProviderAPIImpl() {
510 void PrinterProviderAPIImpl::DispatchGetPrintersRequested(
511 const GetPrintersCallback
& callback
) {
512 EventRouter
* event_router
= EventRouter::Get(browser_context_
);
513 if (!event_router
->HasEventListener(
514 core_api::printer_provider::OnGetPrintersRequested::kEventName
)) {
515 callback
.Run(base::ListValue(), true /* done */);
519 // |pending_get_printers_requests_| take ownership of |request| which gets
520 // NULLed out. Save the pointer before passing it to the requests, as it will
521 // be needed later on.
522 int request_id
= pending_get_printers_requests_
.Add(callback
);
524 scoped_ptr
<base::ListValue
> internal_args(new base::ListValue
);
525 // Request id is not part of the public API, but it will be massaged out in
527 internal_args
->AppendInteger(request_id
);
529 scoped_ptr
<Event
> event(
530 new Event(events::PRINTER_PROVIDER_ON_GET_PRINTERS_REQUESTED
,
531 core_api::printer_provider::OnGetPrintersRequested::kEventName
,
532 internal_args
.Pass()));
533 // This callback is called synchronously during |BroadcastEvent|, so
534 // Unretained is safe.
535 event
->will_dispatch_callback
=
536 base::Bind(&PrinterProviderAPIImpl::WillRequestPrinters
,
537 base::Unretained(this), request_id
);
539 event_router
->BroadcastEvent(event
.Pass());
542 void PrinterProviderAPIImpl::DispatchGetCapabilityRequested(
543 const std::string
& printer_id
,
544 const PrinterProviderAPI::GetCapabilityCallback
& callback
) {
545 std::string extension_id
;
546 std::string internal_printer_id
;
547 if (!ParsePrinterId(printer_id
, &extension_id
, &internal_printer_id
)) {
548 callback
.Run(base::DictionaryValue());
552 EventRouter
* event_router
= EventRouter::Get(browser_context_
);
553 if (!event_router
->ExtensionHasEventListener(
555 core_api::printer_provider::OnGetCapabilityRequested::kEventName
)) {
556 callback
.Run(base::DictionaryValue());
560 int request_id
= pending_capability_requests_
[extension_id
].Add(callback
);
562 scoped_ptr
<base::ListValue
> internal_args(new base::ListValue
);
563 // Request id is not part of the public API, but it will be massaged out in
565 internal_args
->AppendInteger(request_id
);
566 internal_args
->AppendString(internal_printer_id
);
568 scoped_ptr
<Event
> event(new Event(
569 events::PRINTER_PROVIDER_ON_GET_CAPABILITY_REQUESTED
,
570 core_api::printer_provider::OnGetCapabilityRequested::kEventName
,
571 internal_args
.Pass()));
573 event_router
->DispatchEventToExtension(extension_id
, event
.Pass());
576 void PrinterProviderAPIImpl::DispatchPrintRequested(
577 const PrinterProviderPrintJob
& job
,
578 const PrinterProviderAPI::PrintCallback
& callback
) {
579 std::string extension_id
;
580 std::string internal_printer_id
;
581 if (!ParsePrinterId(job
.printer_id
, &extension_id
, &internal_printer_id
)) {
582 callback
.Run(false, PrinterProviderAPI::GetDefaultPrintError());
586 EventRouter
* event_router
= EventRouter::Get(browser_context_
);
587 if (!event_router
->ExtensionHasEventListener(
589 core_api::printer_provider::OnPrintRequested::kEventName
)) {
590 callback
.Run(false, PrinterProviderAPI::GetDefaultPrintError());
594 core_api::printer_provider::PrintJob print_job
;
595 print_job
.printer_id
= internal_printer_id
;
597 JSONStringValueDeserializer
deserializer(job
.ticket_json
);
598 scoped_ptr
<base::Value
> ticket_value(deserializer
.Deserialize(NULL
, NULL
));
600 !core_api::printer_provider::PrintJob::Ticket::Populate(
601 *ticket_value
, &print_job
.ticket
)) {
603 core_api::printer_provider::ToString(
604 core_api::printer_provider::PRINT_ERROR_INVALID_TICKET
));
608 print_job
.content_type
= job
.content_type
;
609 print_job
.title
= base::UTF16ToUTF8(job
.job_title
);
610 int request_id
= pending_print_requests_
[extension_id
].Add(job
, callback
);
612 scoped_ptr
<base::ListValue
> internal_args(new base::ListValue
);
613 // Request id is not part of the public API and it will be massaged out in
615 internal_args
->AppendInteger(request_id
);
616 internal_args
->Append(print_job
.ToValue().release());
617 scoped_ptr
<Event
> event(
618 new Event(events::PRINTER_PROVIDER_ON_PRINT_REQUESTED
,
619 core_api::printer_provider::OnPrintRequested::kEventName
,
620 internal_args
.Pass()));
621 event_router
->DispatchEventToExtension(extension_id
, event
.Pass());
624 const PrinterProviderPrintJob
* PrinterProviderAPIImpl::GetPrintJob(
625 const Extension
* extension
,
626 int request_id
) const {
627 auto it
= pending_print_requests_
.find(extension
->id());
628 if (it
== pending_print_requests_
.end())
630 return it
->second
.GetPrintJob(request_id
);
633 void PrinterProviderAPIImpl::DispatchGetUsbPrinterInfoRequested(
634 const std::string
& extension_id
,
635 scoped_refptr
<UsbDevice
> device
,
636 const PrinterProviderAPI::GetPrinterInfoCallback
& callback
) {
637 EventRouter
* event_router
= EventRouter::Get(browser_context_
);
638 if (!event_router
->ExtensionHasEventListener(
639 extension_id
, core_api::printer_provider::
640 OnGetUsbPrinterInfoRequested::kEventName
)) {
641 callback
.Run(base::DictionaryValue());
646 pending_usb_printer_info_requests_
[extension_id
].Add(callback
);
647 core_api::usb::Device usb_device
;
649 UsbGuidMap::Get(browser_context_
)->GetIdFromGuid(device
->guid());
650 usb_device
.vendor_id
= device
->vendor_id();
651 usb_device
.product_id
= device
->product_id();
653 scoped_ptr
<base::ListValue
> internal_args(new base::ListValue
);
654 // Request id is not part of the public API and it will be massaged out in
656 internal_args
->AppendInteger(request_id
);
657 internal_args
->Append(usb_device
.ToValue().release());
658 scoped_ptr
<Event
> event(new Event(
659 events::PRINTER_PROVIDER_ON_GET_USB_PRINTER_INFO_REQUESTED
,
660 core_api::printer_provider::OnGetUsbPrinterInfoRequested::kEventName
,
661 internal_args
.Pass()));
662 event_router
->DispatchEventToExtension(extension_id
, event
.Pass());
665 void PrinterProviderAPIImpl::OnGetPrintersResult(
666 const Extension
* extension
,
668 const PrinterProviderInternalAPIObserver::PrinterInfoVector
& result
) {
669 base::ListValue printer_list
;
671 // Update some printer description properties to better identify the extension
672 // managing the printer.
673 for (size_t i
= 0; i
< result
.size(); ++i
) {
674 scoped_ptr
<base::DictionaryValue
> printer(result
[i
]->ToValue());
675 UpdatePrinterWithExtensionInfo(printer
.get(), extension
);
676 printer_list
.Append(printer
.Pass());
679 pending_get_printers_requests_
.CompleteForExtension(extension
->id(),
680 request_id
, printer_list
);
683 void PrinterProviderAPIImpl::OnGetCapabilityResult(
684 const Extension
* extension
,
686 const base::DictionaryValue
& result
) {
687 pending_capability_requests_
[extension
->id()].Complete(request_id
, result
);
690 void PrinterProviderAPIImpl::OnPrintResult(
691 const Extension
* extension
,
693 core_api::printer_provider_internal::PrintError error
) {
694 const std::string error_str
=
695 error
== core_api::printer_provider_internal::PRINT_ERROR_NONE
696 ? PrinterProviderAPI::GetDefaultPrintError()
697 : core_api::printer_provider_internal::ToString(error
);
698 pending_print_requests_
[extension
->id()].Complete(
699 request_id
, error
== core_api::printer_provider_internal::PRINT_ERROR_OK
,
703 void PrinterProviderAPIImpl::OnGetUsbPrinterInfoResult(
704 const Extension
* extension
,
706 const core_api::printer_provider::PrinterInfo
* result
) {
708 scoped_ptr
<base::DictionaryValue
> printer(result
->ToValue());
709 UpdatePrinterWithExtensionInfo(printer
.get(), extension
);
710 pending_usb_printer_info_requests_
[extension
->id()].Complete(request_id
,
713 pending_usb_printer_info_requests_
[extension
->id()].Complete(
714 request_id
, base::DictionaryValue());
718 void PrinterProviderAPIImpl::OnExtensionUnloaded(
719 content::BrowserContext
* browser_context
,
720 const Extension
* extension
,
721 UnloadedExtensionInfo::Reason reason
) {
722 pending_get_printers_requests_
.FailAllForExtension(extension
->id());
724 auto print_it
= pending_print_requests_
.find(extension
->id());
725 if (print_it
!= pending_print_requests_
.end()) {
726 print_it
->second
.FailAll();
727 pending_print_requests_
.erase(print_it
);
730 auto capability_it
= pending_capability_requests_
.find(extension
->id());
731 if (capability_it
!= pending_capability_requests_
.end()) {
732 capability_it
->second
.FailAll();
733 pending_capability_requests_
.erase(capability_it
);
736 auto usb_it
= pending_usb_printer_info_requests_
.find(extension
->id());
737 if (usb_it
!= pending_usb_printer_info_requests_
.end()) {
738 usb_it
->second
.FailAll();
739 pending_usb_printer_info_requests_
.erase(usb_it
);
743 bool PrinterProviderAPIImpl::WillRequestPrinters(
745 content::BrowserContext
* browser_context
,
746 const Extension
* extension
,
747 base::ListValue
* args
) {
750 EventRouter
* event_router
= EventRouter::Get(browser_context_
);
751 if (!event_router
->ExtensionHasEventListener(
753 core_api::printer_provider::OnGetPrintersRequested::kEventName
)) {
757 return pending_get_printers_requests_
.AddSource(request_id
, extension
->id());
763 PrinterProviderAPI
* PrinterProviderAPI::Create(
764 content::BrowserContext
* context
) {
765 return new PrinterProviderAPIImpl(context
);
769 std::string
PrinterProviderAPI::GetDefaultPrintError() {
770 return core_api::printer_provider_internal::ToString(
771 core_api::printer_provider_internal::PRINT_ERROR_FAILED
);
774 } // namespace extensions