Finish refactoring of DomCodeToUsLayoutKeyboardCode().
[chromium-blink-merge.git] / extensions / browser / api / printer_provider / printer_provider_api.cc
blob82e3f31e8483ddff46ca693694489dd306fe5ed3
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"
7 #include <map>
8 #include <set>
9 #include <utility>
10 #include <vector>
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 {
37 namespace {
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);
51 return result;
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)
62 return false;
63 *extension_id = printer_id.substr(0, separator);
64 *internal_printer_id = printer_id.substr(separator + 1);
65 return true;
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
93 // the event.
94 class GetPrintersRequest {
95 public:
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
101 // to the event.
102 void AddSource(const std::string& extension_id);
104 // Whether all extensions have responded to the event.
105 bool IsDone() const;
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);
112 private:
113 // Callback reporting event result for an extension. Called once for each
114 // extension.
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
122 // requests.
123 class PendingGetPrintersRequests {
124 public:
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,
135 int request_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
144 // the event.
145 bool AddSource(int request_id, const std::string& extension_id);
147 private:
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 {
157 public:
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.
171 void FailAll();
173 private:
174 int last_request_id_;
175 std::map<int, PrinterProviderAPI::GetCapabilityCallback> pending_requests_;
178 // Keeps track of pending chrome.printerProvider.onPrintRequested requests
179 // for an extension.
180 class PendingPrintRequests {
181 public:
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
198 // pending requests.
199 void FailAll();
201 private:
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 {
214 public:
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.
228 void FailAll();
230 private:
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 {
239 public:
240 explicit PrinterProviderAPIImpl(content::BrowserContext* browser_context);
241 ~PrinterProviderAPIImpl() override;
243 private:
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,
263 int request_id,
264 const PrinterProviderInternalAPIObserver::PrinterInfoVector& result)
265 override;
266 void OnGetCapabilityResult(const Extension* extension,
267 int request_id,
268 const base::DictionaryValue& result) override;
269 void OnPrintResult(
270 const Extension* extension,
271 int request_id,
272 core_api::printer_provider_internal::PrintError error) override;
273 void OnGetUsbPrinterInfoResult(
274 const Extension* extension,
275 int request_id,
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
287 // with the event.
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,
351 int request_id,
352 const base::ListValue& result) {
353 auto it = pending_requests_.find(request_id);
354 if (it == pending_requests_.end())
355 return false;
357 it->second.ReportForExtension(extension_id, result);
358 if (it->second.IsDone()) {
359 pending_requests_.erase(it);
361 return true;
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.
371 ++it;
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())
380 return false;
382 it->second.AddSource(extension_id);
383 return true;
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(
400 int request_id,
401 const base::DictionaryValue& response) {
402 auto it = pending_requests_.find(request_id);
403 if (it == pending_requests_.end())
404 return false;
406 PrinterProviderAPI::GetCapabilityCallback callback = it->second;
407 pending_requests_.erase(it);
409 callback.Run(response);
410 return true;
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;
430 request.job = job;
431 pending_requests_[++last_request_id_] = request;
432 return last_request_id_;
435 bool PendingPrintRequests::Complete(int request_id,
436 bool success,
437 const std::string& response) {
438 auto it = pending_requests_.find(request_id);
439 if (it == pending_requests_.end())
440 return false;
442 PrinterProviderAPI::PrintCallback callback = it->second.callback;
443 pending_requests_.erase(it);
445 callback.Run(success, response);
446 return true;
449 const PrinterProviderPrintJob* PendingPrintRequests::GetPrintJob(
450 int request_id) const {
451 auto it = pending_requests_.find(request_id);
452 if (it == pending_requests_.end())
453 return nullptr;
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(
478 int request_id,
479 const base::DictionaryValue& printer_info) {
480 auto it = pending_requests_.find(request_id);
481 if (it == pending_requests_.end())
482 return;
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 */);
516 return;
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
526 // custom bindings.
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());
549 return;
552 EventRouter* event_router = EventRouter::Get(browser_context_);
553 if (!event_router->ExtensionHasEventListener(
554 extension_id,
555 core_api::printer_provider::OnGetCapabilityRequested::kEventName)) {
556 callback.Run(base::DictionaryValue());
557 return;
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
564 // custom bindings.
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());
583 return;
586 EventRouter* event_router = EventRouter::Get(browser_context_);
587 if (!event_router->ExtensionHasEventListener(
588 extension_id,
589 core_api::printer_provider::OnPrintRequested::kEventName)) {
590 callback.Run(false, PrinterProviderAPI::GetDefaultPrintError());
591 return;
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));
599 if (!ticket_value ||
600 !core_api::printer_provider::PrintJob::Ticket::Populate(
601 *ticket_value, &print_job.ticket)) {
602 callback.Run(false,
603 core_api::printer_provider::ToString(
604 core_api::printer_provider::PRINT_ERROR_INVALID_TICKET));
605 return;
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
614 // custom bindings.
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())
629 return nullptr;
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());
642 return;
645 int request_id =
646 pending_usb_printer_info_requests_[extension_id].Add(callback);
647 core_api::usb::Device usb_device;
648 usb_device.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
655 // custom bindings.
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,
667 int request_id,
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,
685 int request_id,
686 const base::DictionaryValue& result) {
687 pending_capability_requests_[extension->id()].Complete(request_id, result);
690 void PrinterProviderAPIImpl::OnPrintResult(
691 const Extension* extension,
692 int request_id,
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,
700 error_str);
703 void PrinterProviderAPIImpl::OnGetUsbPrinterInfoResult(
704 const Extension* extension,
705 int request_id,
706 const core_api::printer_provider::PrinterInfo* result) {
707 if (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,
711 *printer);
712 } else {
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(
744 int request_id,
745 content::BrowserContext* browser_context,
746 const Extension* extension,
747 base::ListValue* args) {
748 if (!extension)
749 return false;
750 EventRouter* event_router = EventRouter::Get(browser_context_);
751 if (!event_router->ExtensionHasEventListener(
752 extension->id(),
753 core_api::printer_provider::OnGetPrintersRequested::kEventName)) {
754 return false;
757 return pending_get_printers_requests_.AddSource(request_id, extension->id());
760 } // namespace
762 // static
763 PrinterProviderAPI* PrinterProviderAPI::Create(
764 content::BrowserContext* context) {
765 return new PrinterProviderAPIImpl(context);
768 // static
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