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_internal/printer_provider_internal_api.h"
10 #include "base/bind.h"
11 #include "base/guid.h"
12 #include "base/lazy_instance.h"
13 #include "base/location.h"
14 #include "base/memory/ref_counted_memory.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/values.h"
17 #include "content/public/browser/blob_handle.h"
18 #include "content/public/browser/browser_context.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/render_process_host.h"
21 #include "content/public/browser/render_view_host.h"
22 #include "content/public/browser/web_contents.h"
23 #include "extensions/browser/api/printer_provider/printer_provider_api.h"
24 #include "extensions/browser/api/printer_provider/printer_provider_api_factory.h"
25 #include "extensions/browser/api/printer_provider/printer_provider_print_job.h"
26 #include "extensions/browser/blob_holder.h"
27 #include "extensions/common/api/printer_provider.h"
28 #include "extensions/common/api/printer_provider_internal.h"
30 namespace internal_api
= extensions::core_api::printer_provider_internal
;
32 namespace extensions
{
36 static base::LazyInstance
<
37 BrowserContextKeyedAPIFactory
<PrinterProviderInternalAPI
>> g_api_factory
=
38 LAZY_INSTANCE_INITIALIZER
;
43 BrowserContextKeyedAPIFactory
<PrinterProviderInternalAPI
>*
44 PrinterProviderInternalAPI::GetFactoryInstance() {
45 return g_api_factory
.Pointer();
48 PrinterProviderInternalAPI::PrinterProviderInternalAPI(
49 content::BrowserContext
* browser_context
) {
52 PrinterProviderInternalAPI::~PrinterProviderInternalAPI() {
55 void PrinterProviderInternalAPI::AddObserver(
56 PrinterProviderInternalAPIObserver
* observer
) {
57 observers_
.AddObserver(observer
);
60 void PrinterProviderInternalAPI::RemoveObserver(
61 PrinterProviderInternalAPIObserver
* observer
) {
62 observers_
.RemoveObserver(observer
);
65 void PrinterProviderInternalAPI::NotifyGetPrintersResult(
66 const Extension
* extension
,
68 const PrinterProviderInternalAPIObserver::PrinterInfoVector
& printers
) {
69 FOR_EACH_OBSERVER(PrinterProviderInternalAPIObserver
, observers_
,
70 OnGetPrintersResult(extension
, request_id
, printers
));
73 void PrinterProviderInternalAPI::NotifyGetCapabilityResult(
74 const Extension
* extension
,
76 const base::DictionaryValue
& capability
) {
77 FOR_EACH_OBSERVER(PrinterProviderInternalAPIObserver
, observers_
,
78 OnGetCapabilityResult(extension
, request_id
, capability
));
81 void PrinterProviderInternalAPI::NotifyPrintResult(
82 const Extension
* extension
,
84 core_api::printer_provider_internal::PrintError error
) {
85 FOR_EACH_OBSERVER(PrinterProviderInternalAPIObserver
, observers_
,
86 OnPrintResult(extension
, request_id
, error
));
89 PrinterProviderInternalReportPrintResultFunction::
90 PrinterProviderInternalReportPrintResultFunction() {
93 PrinterProviderInternalReportPrintResultFunction::
94 ~PrinterProviderInternalReportPrintResultFunction() {
97 ExtensionFunction::ResponseAction
98 PrinterProviderInternalReportPrintResultFunction::Run() {
99 scoped_ptr
<internal_api::ReportPrintResult::Params
> params(
100 internal_api::ReportPrintResult::Params::Create(*args_
));
101 EXTENSION_FUNCTION_VALIDATE(params
.get());
103 PrinterProviderInternalAPI::GetFactoryInstance()
104 ->Get(browser_context())
105 ->NotifyPrintResult(extension(), params
->request_id
, params
->error
);
106 return RespondNow(NoArguments());
109 PrinterProviderInternalReportPrinterCapabilityFunction::
110 PrinterProviderInternalReportPrinterCapabilityFunction() {
113 PrinterProviderInternalReportPrinterCapabilityFunction::
114 ~PrinterProviderInternalReportPrinterCapabilityFunction() {
117 ExtensionFunction::ResponseAction
118 PrinterProviderInternalReportPrinterCapabilityFunction::Run() {
119 scoped_ptr
<internal_api::ReportPrinterCapability::Params
> params(
120 internal_api::ReportPrinterCapability::Params::Create(*args_
));
121 EXTENSION_FUNCTION_VALIDATE(params
.get());
123 if (params
->capability
) {
124 PrinterProviderInternalAPI::GetFactoryInstance()
125 ->Get(browser_context())
126 ->NotifyGetCapabilityResult(extension(), params
->request_id
,
127 params
->capability
->additional_properties
);
129 PrinterProviderInternalAPI::GetFactoryInstance()
130 ->Get(browser_context())
131 ->NotifyGetCapabilityResult(extension(), params
->request_id
,
132 base::DictionaryValue());
134 return RespondNow(NoArguments());
137 PrinterProviderInternalReportPrintersFunction::
138 PrinterProviderInternalReportPrintersFunction() {
141 PrinterProviderInternalReportPrintersFunction::
142 ~PrinterProviderInternalReportPrintersFunction() {
145 ExtensionFunction::ResponseAction
146 PrinterProviderInternalReportPrintersFunction::Run() {
147 scoped_ptr
<internal_api::ReportPrinters::Params
> params(
148 internal_api::ReportPrinters::Params::Create(*args_
));
149 EXTENSION_FUNCTION_VALIDATE(params
.get());
151 base::ListValue printers
;
152 if (params
->printers
) {
153 PrinterProviderInternalAPI::GetFactoryInstance()
154 ->Get(browser_context())
155 ->NotifyGetPrintersResult(extension(), params
->request_id
,
158 PrinterProviderInternalAPI::GetFactoryInstance()
159 ->Get(browser_context())
160 ->NotifyGetPrintersResult(
161 extension(), params
->request_id
,
162 PrinterProviderInternalAPIObserver::PrinterInfoVector());
164 return RespondNow(NoArguments());
167 PrinterProviderInternalGetPrintDataFunction::
168 PrinterProviderInternalGetPrintDataFunction() {
171 PrinterProviderInternalGetPrintDataFunction::
172 ~PrinterProviderInternalGetPrintDataFunction() {
175 ExtensionFunction::ResponseAction
176 PrinterProviderInternalGetPrintDataFunction::Run() {
177 scoped_ptr
<internal_api::GetPrintData::Params
> params(
178 internal_api::GetPrintData::Params::Create(*args_
));
179 EXTENSION_FUNCTION_VALIDATE(params
.get());
181 const PrinterProviderPrintJob
* job
=
182 PrinterProviderAPIFactory::GetInstance()
183 ->GetForBrowserContext(browser_context())
184 ->GetPrintJob(extension(), params
->request_id
);
186 return RespondNow(Error("Print request not found."));
188 if (job
->document_bytes
.get()) {
189 // |job->document_bytes| are passed to the callback to make sure the ref
190 // counted memory does not go away before the memory backed blob is created.
191 content::BrowserContext::CreateMemoryBackedBlob(
192 browser_context(), job
->document_bytes
->front_as
<char>(),
193 job
->document_bytes
->size(),
194 base::Bind(&PrinterProviderInternalGetPrintDataFunction::OnBlob
, this,
195 job
->content_type
, job
->document_bytes
->size(),
196 job
->document_bytes
));
197 } else if (!job
->document_path
.empty()) {
198 content::BrowserContext::CreateFileBackedBlob(
199 browser_context(), job
->document_path
, 0 /* offset */,
200 job
->file_info
.size
, job
->file_info
.last_modified
,
201 base::Bind(&PrinterProviderInternalGetPrintDataFunction::OnBlob
, this,
202 job
->content_type
, job
->file_info
.size
,
203 scoped_refptr
<base::RefCountedMemory
>()));
205 return RespondNow(Error("Job data not set"));
207 return RespondLater();
210 void PrinterProviderInternalGetPrintDataFunction::OnBlob(
211 const std::string
& type
,
213 const scoped_refptr
<base::RefCountedMemory
>& data
,
214 scoped_ptr
<content::BlobHandle
> blob
) {
216 SetError("Unable to create the blob.");
221 internal_api::BlobInfo info
;
222 info
.blob_uuid
= blob
->GetUUID();
226 std::vector
<std::string
> uuids
;
227 uuids
.push_back(blob
->GetUUID());
229 content::WebContents
* contents
=
230 content::WebContents::FromRenderViewHost(render_view_host());
231 extensions::BlobHolder
* holder
=
232 extensions::BlobHolder::FromRenderProcessHost(
233 contents
->GetRenderProcessHost());
234 holder
->HoldBlobReference(blob
.Pass());
236 results_
= internal_api::GetPrintData::Results::Create(info
);
237 SetTransferredBlobUUIDs(uuids
);
241 } // namespace extensions