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> |
| 8 #include <set> |
7 #include <utility> | 9 #include <utility> |
8 #include <vector> | 10 #include <vector> |
9 | 11 |
10 #include "base/bind.h" | 12 #include "base/bind.h" |
11 #include "base/json/json_string_value_serializer.h" | 13 #include "base/json/json_string_value_serializer.h" |
12 #include "base/lazy_instance.h" | 14 #include "base/macros.h" |
| 15 #include "base/memory/ref_counted_memory.h" |
| 16 #include "base/scoped_observer.h" |
13 #include "base/values.h" | 17 #include "base/values.h" |
| 18 #include "extensions/browser/api/printer_provider/printer_provider_print_job.h" |
14 #include "extensions/browser/api/printer_provider_internal/printer_provider_inte
rnal_api.h" | 19 #include "extensions/browser/api/printer_provider_internal/printer_provider_inte
rnal_api.h" |
| 20 #include "extensions/browser/api/printer_provider_internal/printer_provider_inte
rnal_api_observer.h" |
15 #include "extensions/browser/event_router.h" | 21 #include "extensions/browser/event_router.h" |
16 #include "extensions/browser/extension_registry.h" | 22 #include "extensions/browser/extension_registry.h" |
17 #include "extensions/browser/extension_registry_factory.h" | 23 #include "extensions/browser/extension_registry_observer.h" |
18 #include "extensions/common/api/printer_provider.h" | 24 #include "extensions/common/api/printer_provider.h" |
19 #include "extensions/common/api/printer_provider_internal.h" | 25 #include "extensions/common/api/printer_provider_internal.h" |
20 #include "extensions/common/extension.h" | 26 #include "extensions/common/extension.h" |
21 | 27 |
22 namespace extensions { | 28 namespace extensions { |
23 | 29 |
24 namespace { | 30 namespace { |
25 | 31 |
26 static base::LazyInstance<BrowserContextKeyedAPIFactory<PrinterProviderAPI>> | |
27 g_api_factory = LAZY_INSTANCE_INITIALIZER; | |
28 | |
29 // The separator between extension id and the extension's internal printer id | 32 // The separator between extension id and the extension's internal printer id |
30 // used when generating a printer id unique across extensions. | 33 // used when generating a printer id unique across extensions. |
31 const char kPrinterIdSeparator = ':'; | 34 const char kPrinterIdSeparator = ':'; |
32 | 35 |
33 // Given an extension ID and an ID of a printer reported by the extension, it | 36 // Given an extension ID and an ID of a printer reported by the extension, it |
34 // generates a ID for the printer unique across extensions (assuming that the | 37 // generates a ID for the printer unique across extensions (assuming that the |
35 // printer id is unique in the extension's space). | 38 // printer id is unique in the extension's space). |
36 std::string GeneratePrinterId(const std::string& extension_id, | 39 std::string GeneratePrinterId(const std::string& extension_id, |
37 const std::string& internal_printer_id) { | 40 const std::string& internal_printer_id) { |
38 std::string result = extension_id; | 41 std::string result = extension_id; |
39 result.append(1, kPrinterIdSeparator); | 42 result.append(1, kPrinterIdSeparator); |
40 result.append(internal_printer_id); | 43 result.append(internal_printer_id); |
41 return result; | 44 return result; |
42 } | 45 } |
43 | 46 |
44 // Parses an ID created using |GeneratePrinterId| to it's components: | 47 // Parses an ID created using |GeneratePrinterId| to it's components: |
45 // the extension ID and the printer ID internal to the extension. | 48 // the extension ID and the printer ID internal to the extension. |
46 // Returns whenter the ID was succesfully parsed. | 49 // Returns whenter the ID was succesfully parsed. |
47 bool ParsePrinterId(const std::string& printer_id, | 50 bool ParsePrinterId(const std::string& printer_id, |
48 std::string* extension_id, | 51 std::string* extension_id, |
49 std::string* internal_printer_id) { | 52 std::string* internal_printer_id) { |
50 size_t separator = printer_id.find_first_of(kPrinterIdSeparator); | 53 size_t separator = printer_id.find_first_of(kPrinterIdSeparator); |
51 if (separator == std::string::npos) | 54 if (separator == std::string::npos) |
52 return false; | 55 return false; |
53 *extension_id = printer_id.substr(0, separator); | 56 *extension_id = printer_id.substr(0, separator); |
54 *internal_printer_id = printer_id.substr(separator + 1); | 57 *internal_printer_id = printer_id.substr(separator + 1); |
55 return true; | 58 return true; |
56 } | 59 } |
57 | 60 |
58 } // namespace | 61 // Holds information about a pending onGetPrintersRequested request; |
59 | 62 // in particular, the list of extensions to which the event was dispatched but |
60 PrinterProviderAPI::PrintJob::PrintJob() { | 63 // which haven't yet responded, and the |GetPrinters| callback associated with |
61 } | 64 // the event. |
62 | 65 class GetPrintersRequest { |
63 PrinterProviderAPI::PrintJob::~PrintJob() { | 66 public: |
64 } | 67 explicit GetPrintersRequest( |
65 | 68 const PrinterProviderAPI::GetPrintersCallback& callback); |
66 // static | 69 ~GetPrintersRequest(); |
67 BrowserContextKeyedAPIFactory<PrinterProviderAPI>* | 70 |
68 PrinterProviderAPI::GetFactoryInstance() { | 71 // Adds an extension id to the list of the extensions that need to respond |
69 return g_api_factory.Pointer(); | 72 // to the event. |
70 } | 73 void AddSource(const std::string& extension_id); |
71 | 74 |
72 // static | 75 // Whether all extensions have responded to the event. |
73 std::string PrinterProviderAPI::GetDefaultPrintError() { | 76 bool IsDone() const; |
74 return core_api::printer_provider_internal::ToString( | 77 |
75 core_api::printer_provider_internal::PRINT_ERROR_FAILED); | 78 // Runs the callback for an extension and removes the extension from the |
76 } | 79 // list of extensions that still have to respond to the event. |
77 | 80 void ReportForExtension(const std::string& extension_id, |
78 PrinterProviderAPI::PrinterProviderAPI(content::BrowserContext* browser_context) | 81 const base::ListValue& printers); |
| 82 |
| 83 private: |
| 84 // Callback reporting event result for an extension. Called once for each |
| 85 // extension. |
| 86 PrinterProviderAPI::GetPrintersCallback callback_; |
| 87 |
| 88 // The list of extensions that still have to respond to the event. |
| 89 std::set<std::string> extensions_; |
| 90 }; |
| 91 |
| 92 // Keeps track of pending chrome.printerProvider.onGetPrintersRequested |
| 93 // requests. |
| 94 class PendingGetPrintersRequests { |
| 95 public: |
| 96 PendingGetPrintersRequests(); |
| 97 ~PendingGetPrintersRequests(); |
| 98 |
| 99 // Adds a new request to the set of pending requests. Returns the id |
| 100 // assigned to the request. |
| 101 int Add(const PrinterProviderAPI::GetPrintersCallback& callback); |
| 102 |
| 103 // Completes a request for an extension. It runs the request callback with |
| 104 // values reported by the extension. |
| 105 bool CompleteForExtension(const std::string& extension_id, |
| 106 int request_id, |
| 107 const base::ListValue& result); |
| 108 |
| 109 // Runs callbacks for the extension for all requests that are waiting for a |
| 110 // response from the extension with the provided extension id. Callbacks are |
| 111 // called as if the extension reported empty set of printers. |
| 112 void FailAllForExtension(const std::string& extension_id); |
| 113 |
| 114 // Adds an extension id to the list of the extensions that need to respond |
| 115 // to the event. |
| 116 bool AddSource(int request_id, const std::string& extension_id); |
| 117 |
| 118 private: |
| 119 int last_request_id_; |
| 120 std::map<int, GetPrintersRequest> pending_requests_; |
| 121 |
| 122 DISALLOW_COPY_AND_ASSIGN(PendingGetPrintersRequests); |
| 123 }; |
| 124 |
| 125 // Keeps track of pending chrome.printerProvider.onGetCapabilityRequested |
| 126 // requests for an extension. |
| 127 class PendingGetCapabilityRequests { |
| 128 public: |
| 129 PendingGetCapabilityRequests(); |
| 130 ~PendingGetCapabilityRequests(); |
| 131 |
| 132 // Adds a new request to the set. Only information needed is the callback |
| 133 // associated with the request. Returns the id assigned to the request. |
| 134 int Add(const PrinterProviderAPI::GetCapabilityCallback& callback); |
| 135 |
| 136 // Completes the request with the provided request id. It runs the request |
| 137 // callback and removes the request from the set. |
| 138 bool Complete(int request_id, const base::DictionaryValue& result); |
| 139 |
| 140 // Runs all pending callbacks with empty capability value and clears the |
| 141 // set of pending requests. |
| 142 void FailAll(); |
| 143 |
| 144 private: |
| 145 int last_request_id_; |
| 146 std::map<int, PrinterProviderAPI::GetCapabilityCallback> pending_requests_; |
| 147 }; |
| 148 |
| 149 // Keeps track of pending chrome.printerProvider.ontPrintRequested requests |
| 150 // for an extension. |
| 151 class PendingPrintRequests { |
| 152 public: |
| 153 PendingPrintRequests(); |
| 154 ~PendingPrintRequests(); |
| 155 |
| 156 // Adds a new request to the set. Only information needed is the callback |
| 157 // associated with the request. Returns the id assigned to the request. |
| 158 int Add(const PrinterProviderAPI::PrintCallback& callback); |
| 159 |
| 160 // Completes the request with the provided request id. It runs the request |
| 161 // callback and removes the request from the set. |
| 162 bool Complete(int request_id, bool success, const std::string& result); |
| 163 |
| 164 // Runs all pending callbacks with ERROR_FAILED and clears the set of |
| 165 // pending requests. |
| 166 void FailAll(); |
| 167 |
| 168 private: |
| 169 int last_request_id_; |
| 170 std::map<int, PrinterProviderAPI::PrintCallback> pending_requests_; |
| 171 }; |
| 172 |
| 173 // Implements chrome.printerProvider API events. |
| 174 class PrinterProviderAPIImpl : public PrinterProviderAPI, |
| 175 public PrinterProviderInternalAPIObserver, |
| 176 public ExtensionRegistryObserver { |
| 177 public: |
| 178 explicit PrinterProviderAPIImpl(content::BrowserContext* browser_context); |
| 179 ~PrinterProviderAPIImpl() override; |
| 180 |
| 181 private: |
| 182 // PrinterProviderAPI implementation: |
| 183 void DispatchGetPrintersRequested( |
| 184 const PrinterProviderAPI::GetPrintersCallback& callback) override; |
| 185 void DispatchGetCapabilityRequested( |
| 186 const std::string& printer_id, |
| 187 const PrinterProviderAPI::GetCapabilityCallback& callback) override; |
| 188 void DispatchPrintRequested( |
| 189 const PrinterProviderPrintJob& job, |
| 190 const PrinterProviderAPI::PrintCallback& callback) override; |
| 191 |
| 192 // PrinterProviderInternalAPIObserver implementation: |
| 193 void OnGetPrintersResult( |
| 194 const Extension* extension, |
| 195 int request_id, |
| 196 const PrinterProviderInternalAPIObserver::PrinterInfoVector& result) |
| 197 override; |
| 198 void OnGetCapabilityResult(const Extension* extension, |
| 199 int request_id, |
| 200 const base::DictionaryValue& result) override; |
| 201 void OnPrintResult( |
| 202 const Extension* extension, |
| 203 int request_id, |
| 204 core_api::printer_provider_internal::PrintError error) override; |
| 205 |
| 206 // ExtensionRegistryObserver implementation: |
| 207 void OnExtensionUnloaded(content::BrowserContext* browser_context, |
| 208 const Extension* extension, |
| 209 UnloadedExtensionInfo::Reason reason) override; |
| 210 |
| 211 // Called before chrome.printerProvider.onGetPrintersRequested event is |
| 212 // dispatched to an extension. It returns whether the extension is interested |
| 213 // in the event. If the extension listens to the event, it's added to the set |
| 214 // of |request| sources. |request| is |GetPrintersRequest| object associated |
| 215 // with the event. |
| 216 bool WillRequestPrinters(int request_id, |
| 217 content::BrowserContext* browser_context, |
| 218 const Extension* extension, |
| 219 base::ListValue* args); |
| 220 |
| 221 content::BrowserContext* browser_context_; |
| 222 |
| 223 PendingGetPrintersRequests pending_get_printers_requests_; |
| 224 |
| 225 std::map<std::string, PendingPrintRequests> pending_print_requests_; |
| 226 |
| 227 std::map<std::string, PendingGetCapabilityRequests> |
| 228 pending_capability_requests_; |
| 229 |
| 230 ScopedObserver<PrinterProviderInternalAPI, PrinterProviderInternalAPIObserver> |
| 231 internal_api_observer_; |
| 232 |
| 233 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> |
| 234 extension_registry_observer_; |
| 235 |
| 236 DISALLOW_COPY_AND_ASSIGN(PrinterProviderAPIImpl); |
| 237 }; |
| 238 |
| 239 GetPrintersRequest::GetPrintersRequest( |
| 240 const PrinterProviderAPI::GetPrintersCallback& callback) |
| 241 : callback_(callback) { |
| 242 } |
| 243 |
| 244 GetPrintersRequest::~GetPrintersRequest() { |
| 245 } |
| 246 |
| 247 void GetPrintersRequest::AddSource(const std::string& extension_id) { |
| 248 extensions_.insert(extension_id); |
| 249 } |
| 250 |
| 251 bool GetPrintersRequest::IsDone() const { |
| 252 return extensions_.empty(); |
| 253 } |
| 254 |
| 255 void GetPrintersRequest::ReportForExtension(const std::string& extension_id, |
| 256 const base::ListValue& printers) { |
| 257 if (extensions_.erase(extension_id) > 0) |
| 258 callback_.Run(printers, IsDone()); |
| 259 } |
| 260 |
| 261 PendingGetPrintersRequests::PendingGetPrintersRequests() : last_request_id_(0) { |
| 262 } |
| 263 |
| 264 PendingGetPrintersRequests::~PendingGetPrintersRequests() { |
| 265 } |
| 266 |
| 267 int PendingGetPrintersRequests::Add( |
| 268 const PrinterProviderAPI::GetPrintersCallback& callback) { |
| 269 pending_requests_.insert( |
| 270 std::make_pair(++last_request_id_, GetPrintersRequest(callback))); |
| 271 return last_request_id_; |
| 272 } |
| 273 |
| 274 bool PendingGetPrintersRequests::CompleteForExtension( |
| 275 const std::string& extension_id, |
| 276 int request_id, |
| 277 const base::ListValue& result) { |
| 278 auto it = pending_requests_.find(request_id); |
| 279 if (it == pending_requests_.end()) |
| 280 return false; |
| 281 |
| 282 it->second.ReportForExtension(extension_id, result); |
| 283 if (it->second.IsDone()) { |
| 284 pending_requests_.erase(it); |
| 285 } |
| 286 return true; |
| 287 } |
| 288 |
| 289 void PendingGetPrintersRequests::FailAllForExtension( |
| 290 const std::string& extension_id) { |
| 291 auto it = pending_requests_.begin(); |
| 292 while (it != pending_requests_.end()) { |
| 293 int request_id = it->first; |
| 294 // |it| may get deleted during |CompleteForExtension|, so progress it to the |
| 295 // next item before calling the method. |
| 296 ++it; |
| 297 CompleteForExtension(extension_id, request_id, base::ListValue()); |
| 298 } |
| 299 } |
| 300 |
| 301 bool PendingGetPrintersRequests::AddSource(int request_id, |
| 302 const std::string& extension_id) { |
| 303 auto it = pending_requests_.find(request_id); |
| 304 if (it == pending_requests_.end()) |
| 305 return false; |
| 306 |
| 307 it->second.AddSource(extension_id); |
| 308 return true; |
| 309 } |
| 310 |
| 311 PendingGetCapabilityRequests::PendingGetCapabilityRequests() |
| 312 : last_request_id_(0) { |
| 313 } |
| 314 |
| 315 PendingGetCapabilityRequests::~PendingGetCapabilityRequests() { |
| 316 } |
| 317 |
| 318 int PendingGetCapabilityRequests::Add( |
| 319 const PrinterProviderAPI::GetCapabilityCallback& callback) { |
| 320 pending_requests_[++last_request_id_] = callback; |
| 321 return last_request_id_; |
| 322 } |
| 323 |
| 324 bool PendingGetCapabilityRequests::Complete( |
| 325 int request_id, |
| 326 const base::DictionaryValue& response) { |
| 327 auto it = pending_requests_.find(request_id); |
| 328 if (it == pending_requests_.end()) |
| 329 return false; |
| 330 |
| 331 PrinterProviderAPI::GetCapabilityCallback callback = it->second; |
| 332 pending_requests_.erase(it); |
| 333 |
| 334 callback.Run(response); |
| 335 return true; |
| 336 } |
| 337 |
| 338 void PendingGetCapabilityRequests::FailAll() { |
| 339 for (auto& request : pending_requests_) |
| 340 request.second.Run(base::DictionaryValue()); |
| 341 pending_requests_.clear(); |
| 342 } |
| 343 |
| 344 PendingPrintRequests::PendingPrintRequests() : last_request_id_(0) { |
| 345 } |
| 346 |
| 347 PendingPrintRequests::~PendingPrintRequests() { |
| 348 } |
| 349 |
| 350 int PendingPrintRequests::Add( |
| 351 const PrinterProviderAPI::PrintCallback& callback) { |
| 352 pending_requests_[++last_request_id_] = callback; |
| 353 return last_request_id_; |
| 354 } |
| 355 |
| 356 bool PendingPrintRequests::Complete(int request_id, |
| 357 bool success, |
| 358 const std::string& response) { |
| 359 auto it = pending_requests_.find(request_id); |
| 360 if (it == pending_requests_.end()) |
| 361 return false; |
| 362 |
| 363 PrinterProviderAPI::PrintCallback callback = it->second; |
| 364 pending_requests_.erase(it); |
| 365 |
| 366 callback.Run(success, response); |
| 367 return true; |
| 368 } |
| 369 |
| 370 void PendingPrintRequests::FailAll() { |
| 371 for (auto& request : pending_requests_) |
| 372 request.second.Run(false, PrinterProviderAPI::GetDefaultPrintError()); |
| 373 pending_requests_.clear(); |
| 374 } |
| 375 |
| 376 PrinterProviderAPIImpl::PrinterProviderAPIImpl( |
| 377 content::BrowserContext* browser_context) |
79 : browser_context_(browser_context), | 378 : browser_context_(browser_context), |
80 internal_api_observer_(this), | 379 internal_api_observer_(this), |
81 extension_registry_observer_(this) { | 380 extension_registry_observer_(this) { |
82 internal_api_observer_.Add( | 381 internal_api_observer_.Add( |
83 PrinterProviderInternalAPI::GetFactoryInstance()->Get(browser_context)); | 382 PrinterProviderInternalAPI::GetFactoryInstance()->Get(browser_context)); |
84 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context)); | 383 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context)); |
85 } | 384 } |
86 | 385 |
87 PrinterProviderAPI::~PrinterProviderAPI() { | 386 PrinterProviderAPIImpl::~PrinterProviderAPIImpl() { |
88 } | 387 } |
89 | 388 |
90 void PrinterProviderAPI::DispatchGetPrintersRequested( | 389 void PrinterProviderAPIImpl::DispatchGetPrintersRequested( |
91 const GetPrintersCallback& callback) { | 390 const GetPrintersCallback& callback) { |
92 EventRouter* event_router = EventRouter::Get(browser_context_); | 391 EventRouter* event_router = EventRouter::Get(browser_context_); |
93 if (!event_router->HasEventListener( | 392 if (!event_router->HasEventListener( |
94 core_api::printer_provider::OnGetPrintersRequested::kEventName)) { | 393 core_api::printer_provider::OnGetPrintersRequested::kEventName)) { |
95 callback.Run(base::ListValue(), true /* done */); | 394 callback.Run(base::ListValue(), true /* done */); |
96 return; | 395 return; |
97 } | 396 } |
98 | 397 |
99 // |pending_get_printers_requests_| take ownership of |request| which gets | 398 // |pending_get_printers_requests_| take ownership of |request| which gets |
100 // NULLed out. Save the pointer before passing it to the requests, as it will | 399 // NULLed out. Save the pointer before passing it to the requests, as it will |
101 // be needed later on. | 400 // be needed later on. |
102 int request_id = pending_get_printers_requests_.Add(callback); | 401 int request_id = pending_get_printers_requests_.Add(callback); |
103 | 402 |
104 scoped_ptr<base::ListValue> internal_args(new base::ListValue); | 403 scoped_ptr<base::ListValue> internal_args(new base::ListValue); |
105 // Request id is not part of the public API, but it will be massaged out in | 404 // Request id is not part of the public API, but it will be massaged out in |
106 // custom bindings. | 405 // custom bindings. |
107 internal_args->AppendInteger(request_id); | 406 internal_args->AppendInteger(request_id); |
108 | 407 |
109 scoped_ptr<Event> event( | 408 scoped_ptr<Event> event( |
110 new Event(core_api::printer_provider::OnGetPrintersRequested::kEventName, | 409 new Event(core_api::printer_provider::OnGetPrintersRequested::kEventName, |
111 internal_args.Pass())); | 410 internal_args.Pass())); |
112 // This callback is called synchronously during |BroadcastEvent|, so | 411 // This callback is called synchronously during |BroadcastEvent|, so |
113 // Unretained is safe. Also, |raw_request_ptr| will stay valid at least until | 412 // Unretained is safe. |
114 // |BroadcastEvent| finishes. | |
115 event->will_dispatch_callback = | 413 event->will_dispatch_callback = |
116 base::Bind(&PrinterProviderAPI::WillRequestPrinters, | 414 base::Bind(&PrinterProviderAPIImpl::WillRequestPrinters, |
117 base::Unretained(this), request_id); | 415 base::Unretained(this), request_id); |
118 | 416 |
119 event_router->BroadcastEvent(event.Pass()); | 417 event_router->BroadcastEvent(event.Pass()); |
120 } | 418 } |
121 | 419 |
122 void PrinterProviderAPI::DispatchGetCapabilityRequested( | 420 void PrinterProviderAPIImpl::DispatchGetCapabilityRequested( |
123 const std::string& printer_id, | 421 const std::string& printer_id, |
124 const PrinterProviderAPI::GetCapabilityCallback& callback) { | 422 const PrinterProviderAPI::GetCapabilityCallback& callback) { |
125 std::string extension_id; | 423 std::string extension_id; |
126 std::string internal_printer_id; | 424 std::string internal_printer_id; |
127 if (!ParsePrinterId(printer_id, &extension_id, &internal_printer_id)) { | 425 if (!ParsePrinterId(printer_id, &extension_id, &internal_printer_id)) { |
128 callback.Run(base::DictionaryValue()); | 426 callback.Run(base::DictionaryValue()); |
129 return; | 427 return; |
130 } | 428 } |
131 | 429 |
132 EventRouter* event_router = EventRouter::Get(browser_context_); | 430 EventRouter* event_router = EventRouter::Get(browser_context_); |
(...skipping 12 matching lines...) Expand all Loading... |
145 internal_args->AppendInteger(request_id); | 443 internal_args->AppendInteger(request_id); |
146 internal_args->AppendString(internal_printer_id); | 444 internal_args->AppendString(internal_printer_id); |
147 | 445 |
148 scoped_ptr<Event> event(new Event( | 446 scoped_ptr<Event> event(new Event( |
149 core_api::printer_provider::OnGetCapabilityRequested::kEventName, | 447 core_api::printer_provider::OnGetCapabilityRequested::kEventName, |
150 internal_args.Pass())); | 448 internal_args.Pass())); |
151 | 449 |
152 event_router->DispatchEventToExtension(extension_id, event.Pass()); | 450 event_router->DispatchEventToExtension(extension_id, event.Pass()); |
153 } | 451 } |
154 | 452 |
155 void PrinterProviderAPI::DispatchPrintRequested( | 453 void PrinterProviderAPIImpl::DispatchPrintRequested( |
156 const PrinterProviderAPI::PrintJob& job, | 454 const PrinterProviderPrintJob& job, |
157 const PrinterProviderAPI::PrintCallback& callback) { | 455 const PrinterProviderAPI::PrintCallback& callback) { |
158 std::string extension_id; | 456 std::string extension_id; |
159 std::string internal_printer_id; | 457 std::string internal_printer_id; |
160 if (!ParsePrinterId(job.printer_id, &extension_id, &internal_printer_id)) { | 458 if (!ParsePrinterId(job.printer_id, &extension_id, &internal_printer_id)) { |
161 callback.Run(false, GetDefaultPrintError()); | 459 callback.Run(false, PrinterProviderAPI::GetDefaultPrintError()); |
162 return; | 460 return; |
163 } | 461 } |
164 | 462 |
165 EventRouter* event_router = EventRouter::Get(browser_context_); | 463 EventRouter* event_router = EventRouter::Get(browser_context_); |
166 if (!event_router->ExtensionHasEventListener( | 464 if (!event_router->ExtensionHasEventListener( |
167 extension_id, | 465 extension_id, |
168 core_api::printer_provider::OnPrintRequested::kEventName)) { | 466 core_api::printer_provider::OnPrintRequested::kEventName)) { |
169 callback.Run(false, GetDefaultPrintError()); | 467 callback.Run(false, PrinterProviderAPI::GetDefaultPrintError()); |
170 return; | 468 return; |
171 } | 469 } |
172 | 470 |
173 core_api::printer_provider::PrintJob print_job; | 471 core_api::printer_provider::PrintJob print_job; |
174 print_job.printer_id = internal_printer_id; | 472 print_job.printer_id = internal_printer_id; |
175 | 473 |
176 JSONStringValueSerializer serializer(job.ticket_json); | 474 JSONStringValueSerializer serializer(job.ticket_json); |
177 scoped_ptr<base::Value> ticket_value(serializer.Deserialize(NULL, NULL)); | 475 scoped_ptr<base::Value> ticket_value(serializer.Deserialize(NULL, NULL)); |
178 if (!ticket_value || | 476 if (!ticket_value || |
179 !core_api::printer_provider::PrintJob::Ticket::Populate( | 477 !core_api::printer_provider::PrintJob::Ticket::Populate( |
(...skipping 24 matching lines...) Expand all Loading... |
204 // custom bindings. | 502 // custom bindings. |
205 internal_args->AppendInteger(request_id); | 503 internal_args->AppendInteger(request_id); |
206 internal_args->Append(print_job.ToValue().release()); | 504 internal_args->Append(print_job.ToValue().release()); |
207 scoped_ptr<Event> event( | 505 scoped_ptr<Event> event( |
208 new Event(core_api::printer_provider::OnPrintRequested::kEventName, | 506 new Event(core_api::printer_provider::OnPrintRequested::kEventName, |
209 internal_args.Pass())); | 507 internal_args.Pass())); |
210 | 508 |
211 event_router->DispatchEventToExtension(extension_id, event.Pass()); | 509 event_router->DispatchEventToExtension(extension_id, event.Pass()); |
212 } | 510 } |
213 | 511 |
214 PrinterProviderAPI::GetPrintersRequest::GetPrintersRequest( | 512 void PrinterProviderAPIImpl::OnGetPrintersResult( |
215 const GetPrintersCallback& callback) | |
216 : callback_(callback) { | |
217 } | |
218 | |
219 PrinterProviderAPI::GetPrintersRequest::~GetPrintersRequest() { | |
220 } | |
221 | |
222 void PrinterProviderAPI::GetPrintersRequest::AddSource( | |
223 const std::string& extension_id) { | |
224 extensions_.insert(extension_id); | |
225 } | |
226 | |
227 bool PrinterProviderAPI::GetPrintersRequest::IsDone() const { | |
228 return extensions_.empty(); | |
229 } | |
230 | |
231 void PrinterProviderAPI::GetPrintersRequest::ReportForExtension( | |
232 const std::string& extension_id, | |
233 const base::ListValue& printers) { | |
234 if (extensions_.erase(extension_id) > 0) | |
235 callback_.Run(printers, IsDone()); | |
236 } | |
237 | |
238 PrinterProviderAPI::PendingGetPrintersRequests::PendingGetPrintersRequests() | |
239 : last_request_id_(0) { | |
240 } | |
241 | |
242 PrinterProviderAPI::PendingGetPrintersRequests::~PendingGetPrintersRequests() { | |
243 } | |
244 | |
245 int PrinterProviderAPI::PendingGetPrintersRequests::Add( | |
246 const GetPrintersCallback& callback) { | |
247 pending_requests_.insert( | |
248 std::make_pair(++last_request_id_, GetPrintersRequest(callback))); | |
249 return last_request_id_; | |
250 } | |
251 | |
252 bool PrinterProviderAPI::PendingGetPrintersRequests::CompleteForExtension( | |
253 const std::string& extension_id, | |
254 int request_id, | |
255 const base::ListValue& result) { | |
256 auto it = pending_requests_.find(request_id); | |
257 if (it == pending_requests_.end()) | |
258 return false; | |
259 | |
260 it->second.ReportForExtension(extension_id, result); | |
261 if (it->second.IsDone()) { | |
262 pending_requests_.erase(it); | |
263 } | |
264 return true; | |
265 } | |
266 | |
267 void PrinterProviderAPI::PendingGetPrintersRequests::FailAllForExtension( | |
268 const std::string& extension_id) { | |
269 auto it = pending_requests_.begin(); | |
270 while (it != pending_requests_.end()) { | |
271 int request_id = it->first; | |
272 // |it| may get deleted during |CompleteForExtension|, so progress it to the | |
273 // next item before calling the method. | |
274 ++it; | |
275 CompleteForExtension(extension_id, request_id, base::ListValue()); | |
276 } | |
277 } | |
278 | |
279 bool PrinterProviderAPI::PendingGetPrintersRequests::AddSource( | |
280 int request_id, | |
281 const std::string& extension_id) { | |
282 auto it = pending_requests_.find(request_id); | |
283 if (it == pending_requests_.end()) | |
284 return false; | |
285 | |
286 it->second.AddSource(extension_id); | |
287 return true; | |
288 } | |
289 | |
290 PrinterProviderAPI::PendingGetCapabilityRequests::PendingGetCapabilityRequests() | |
291 : last_request_id_(0) { | |
292 } | |
293 | |
294 PrinterProviderAPI::PendingGetCapabilityRequests:: | |
295 ~PendingGetCapabilityRequests() { | |
296 } | |
297 | |
298 int PrinterProviderAPI::PendingGetCapabilityRequests::Add( | |
299 const PrinterProviderAPI::GetCapabilityCallback& callback) { | |
300 pending_requests_[++last_request_id_] = callback; | |
301 return last_request_id_; | |
302 } | |
303 | |
304 bool PrinterProviderAPI::PendingGetCapabilityRequests::Complete( | |
305 int request_id, | |
306 const base::DictionaryValue& response) { | |
307 auto it = pending_requests_.find(request_id); | |
308 if (it == pending_requests_.end()) | |
309 return false; | |
310 | |
311 GetCapabilityCallback callback = it->second; | |
312 pending_requests_.erase(it); | |
313 | |
314 callback.Run(response); | |
315 return true; | |
316 } | |
317 | |
318 void PrinterProviderAPI::PendingGetCapabilityRequests::FailAll() { | |
319 for (auto& request : pending_requests_) | |
320 request.second.Run(base::DictionaryValue()); | |
321 pending_requests_.clear(); | |
322 } | |
323 | |
324 PrinterProviderAPI::PendingPrintRequests::PendingPrintRequests() | |
325 : last_request_id_(0) { | |
326 } | |
327 | |
328 PrinterProviderAPI::PendingPrintRequests::~PendingPrintRequests() { | |
329 } | |
330 | |
331 int PrinterProviderAPI::PendingPrintRequests::Add( | |
332 const PrinterProviderAPI::PrintCallback& callback) { | |
333 pending_requests_[++last_request_id_] = callback; | |
334 return last_request_id_; | |
335 } | |
336 | |
337 bool PrinterProviderAPI::PendingPrintRequests::Complete( | |
338 int request_id, | |
339 bool success, | |
340 const std::string& response) { | |
341 auto it = pending_requests_.find(request_id); | |
342 if (it == pending_requests_.end()) | |
343 return false; | |
344 | |
345 PrintCallback callback = it->second; | |
346 pending_requests_.erase(it); | |
347 | |
348 callback.Run(success, response); | |
349 return true; | |
350 } | |
351 | |
352 void PrinterProviderAPI::PendingPrintRequests::FailAll() { | |
353 for (auto& request : pending_requests_) | |
354 request.second.Run(false, GetDefaultPrintError()); | |
355 pending_requests_.clear(); | |
356 } | |
357 | |
358 void PrinterProviderAPI::OnGetPrintersResult( | |
359 const Extension* extension, | 513 const Extension* extension, |
360 int request_id, | 514 int request_id, |
361 const PrinterProviderInternalAPIObserver::PrinterInfoVector& result) { | 515 const PrinterProviderInternalAPIObserver::PrinterInfoVector& result) { |
362 base::ListValue printer_list; | 516 base::ListValue printer_list; |
363 | 517 |
364 // Update some printer description properties to better identify the extension | 518 // Update some printer description properties to better identify the extension |
365 // managing the printer. | 519 // managing the printer. |
366 for (size_t i = 0; i < result.size(); ++i) { | 520 for (size_t i = 0; i < result.size(); ++i) { |
367 scoped_ptr<base::DictionaryValue> printer(result[i]->ToValue()); | 521 scoped_ptr<base::DictionaryValue> printer(result[i]->ToValue()); |
368 std::string internal_printer_id; | 522 std::string internal_printer_id; |
369 CHECK(printer->GetString("id", &internal_printer_id)); | 523 CHECK(printer->GetString("id", &internal_printer_id)); |
370 printer->SetString("id", | 524 printer->SetString("id", |
371 GeneratePrinterId(extension->id(), internal_printer_id)); | 525 GeneratePrinterId(extension->id(), internal_printer_id)); |
372 printer->SetString("extensionId", extension->id()); | 526 printer->SetString("extensionId", extension->id()); |
373 printer_list.Append(printer.release()); | 527 printer_list.Append(printer.release()); |
374 } | 528 } |
375 | 529 |
376 pending_get_printers_requests_.CompleteForExtension(extension->id(), | 530 pending_get_printers_requests_.CompleteForExtension(extension->id(), |
377 request_id, printer_list); | 531 request_id, printer_list); |
378 } | 532 } |
379 | 533 |
380 void PrinterProviderAPI::OnGetCapabilityResult( | 534 void PrinterProviderAPIImpl::OnGetCapabilityResult( |
381 const Extension* extension, | 535 const Extension* extension, |
382 int request_id, | 536 int request_id, |
383 const base::DictionaryValue& result) { | 537 const base::DictionaryValue& result) { |
384 pending_capability_requests_[extension->id()].Complete(request_id, result); | 538 pending_capability_requests_[extension->id()].Complete(request_id, result); |
385 } | 539 } |
386 | 540 |
387 void PrinterProviderAPI::OnPrintResult( | 541 void PrinterProviderAPIImpl::OnPrintResult( |
388 const Extension* extension, | 542 const Extension* extension, |
389 int request_id, | 543 int request_id, |
390 core_api::printer_provider_internal::PrintError error) { | 544 core_api::printer_provider_internal::PrintError error) { |
391 const std::string error_str = | 545 const std::string error_str = |
392 error == core_api::printer_provider_internal::PRINT_ERROR_NONE | 546 error == core_api::printer_provider_internal::PRINT_ERROR_NONE |
393 ? GetDefaultPrintError() | 547 ? PrinterProviderAPI::GetDefaultPrintError() |
394 : core_api::printer_provider_internal::ToString(error); | 548 : core_api::printer_provider_internal::ToString(error); |
395 pending_print_requests_[extension->id()].Complete( | 549 pending_print_requests_[extension->id()].Complete( |
396 request_id, error == core_api::printer_provider_internal::PRINT_ERROR_OK, | 550 request_id, error == core_api::printer_provider_internal::PRINT_ERROR_OK, |
397 error_str); | 551 error_str); |
398 } | 552 } |
399 | 553 |
400 void PrinterProviderAPI::OnExtensionUnloaded( | 554 void PrinterProviderAPIImpl::OnExtensionUnloaded( |
401 content::BrowserContext* browser_context, | 555 content::BrowserContext* browser_context, |
402 const Extension* extension, | 556 const Extension* extension, |
403 UnloadedExtensionInfo::Reason reason) { | 557 UnloadedExtensionInfo::Reason reason) { |
404 pending_get_printers_requests_.FailAllForExtension(extension->id()); | 558 pending_get_printers_requests_.FailAllForExtension(extension->id()); |
405 | 559 |
406 auto print_it = pending_print_requests_.find(extension->id()); | 560 auto print_it = pending_print_requests_.find(extension->id()); |
407 if (print_it != pending_print_requests_.end()) { | 561 if (print_it != pending_print_requests_.end()) { |
408 print_it->second.FailAll(); | 562 print_it->second.FailAll(); |
409 pending_print_requests_.erase(print_it); | 563 pending_print_requests_.erase(print_it); |
410 } | 564 } |
411 | 565 |
412 auto capability_it = pending_capability_requests_.find(extension->id()); | 566 auto capability_it = pending_capability_requests_.find(extension->id()); |
413 if (capability_it != pending_capability_requests_.end()) { | 567 if (capability_it != pending_capability_requests_.end()) { |
414 capability_it->second.FailAll(); | 568 capability_it->second.FailAll(); |
415 pending_capability_requests_.erase(capability_it); | 569 pending_capability_requests_.erase(capability_it); |
416 } | 570 } |
417 } | 571 } |
418 | 572 |
419 bool PrinterProviderAPI::WillRequestPrinters( | 573 bool PrinterProviderAPIImpl::WillRequestPrinters( |
420 int request_id, | 574 int request_id, |
421 content::BrowserContext* browser_context, | 575 content::BrowserContext* browser_context, |
422 const Extension* extension, | 576 const Extension* extension, |
423 base::ListValue* args) { | 577 base::ListValue* args) { |
424 if (!extension) | 578 if (!extension) |
425 return false; | 579 return false; |
426 EventRouter* event_router = EventRouter::Get(browser_context_); | 580 EventRouter* event_router = EventRouter::Get(browser_context_); |
427 if (!event_router->ExtensionHasEventListener( | 581 if (!event_router->ExtensionHasEventListener( |
428 extension->id(), | 582 extension->id(), |
429 core_api::printer_provider::OnGetPrintersRequested::kEventName)) { | 583 core_api::printer_provider::OnGetPrintersRequested::kEventName)) { |
430 return false; | 584 return false; |
431 } | 585 } |
432 | 586 |
433 return pending_get_printers_requests_.AddSource(request_id, extension->id()); | 587 return pending_get_printers_requests_.AddSource(request_id, extension->id()); |
434 } | 588 } |
435 | 589 |
436 template <> | 590 } // namespace |
437 void BrowserContextKeyedAPIFactory< | 591 |
438 PrinterProviderAPI>::DeclareFactoryDependencies() { | 592 // static |
439 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); | 593 PrinterProviderAPI* PrinterProviderAPI::Create( |
440 DependsOn(PrinterProviderInternalAPI::GetFactoryInstance()); | 594 content::BrowserContext* context) { |
441 DependsOn(ExtensionRegistryFactory::GetInstance()); | 595 return new PrinterProviderAPIImpl(context); |
| 596 } |
| 597 |
| 598 // static |
| 599 std::string PrinterProviderAPI::GetDefaultPrintError() { |
| 600 return core_api::printer_provider_internal::ToString( |
| 601 core_api::printer_provider_internal::PRINT_ERROR_FAILED); |
442 } | 602 } |
443 | 603 |
444 } // namespace extensions | 604 } // namespace extensions |
OLD | NEW |