Explicitly add python-numpy dependency to install-build-deps.
[chromium-blink-merge.git] / components / pdf / renderer / pepper_pdf_host.cc
blob30599320a35b11535ab1f265afb67e6526be717b
1 // Copyright 2014 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 "components/pdf/renderer/pepper_pdf_host.h"
7 #include "components/pdf/common/pdf_messages.h"
8 #include "components/pdf/renderer/pdf_resource_util.h"
9 #include "components/pdf/renderer/ppb_pdf_impl.h"
10 #include "content/public/common/referrer.h"
11 #include "content/public/renderer/pepper_plugin_instance.h"
12 #include "content/public/renderer/render_thread.h"
13 #include "content/public/renderer/render_view.h"
14 #include "content/public/renderer/renderer_ppapi_host.h"
15 #include "ppapi/host/dispatch_host_message.h"
16 #include "ppapi/host/host_message_context.h"
17 #include "ppapi/host/ppapi_host.h"
18 #include "ppapi/proxy/host_dispatcher.h"
19 #include "ppapi/proxy/ppapi_messages.h"
20 #include "ppapi/proxy/ppb_image_data_proxy.h"
21 #include "ppapi/shared_impl/ppb_image_data_shared.h"
22 #include "ppapi/shared_impl/scoped_pp_resource.h"
23 #include "ppapi/thunk/enter.h"
24 #include "ppapi/thunk/ppb_image_data_api.h"
25 #include "skia/ext/platform_canvas.h"
26 #include "third_party/WebKit/public/web/WebDocument.h"
27 #include "third_party/WebKit/public/web/WebElement.h"
28 #include "third_party/WebKit/public/web/WebLocalFrame.h"
29 #include "third_party/WebKit/public/web/WebPluginContainer.h"
30 #include "third_party/WebKit/public/web/WebView.h"
31 #include "third_party/skia/include/core/SkBitmap.h"
32 #include "ui/base/layout.h"
33 #include "ui/gfx/image/image_skia.h"
34 #include "ui/gfx/image/image_skia_rep.h"
35 #include "ui/gfx/point.h"
37 namespace pdf {
39 PepperPDFHost::PepperPDFHost(content::RendererPpapiHost* host,
40 PP_Instance instance,
41 PP_Resource resource)
42 : ppapi::host::ResourceHost(host->GetPpapiHost(), instance, resource),
43 host_(host) {}
45 PepperPDFHost::~PepperPDFHost() {}
47 int32_t PepperPDFHost::OnResourceMessageReceived(
48 const IPC::Message& msg,
49 ppapi::host::HostMessageContext* context) {
50 PPAPI_BEGIN_MESSAGE_MAP(PepperPDFHost, msg)
51 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_GetLocalizedString,
52 OnHostMsgGetLocalizedString)
53 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_DidStartLoading,
54 OnHostMsgDidStartLoading)
55 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_DidStopLoading,
56 OnHostMsgDidStopLoading)
57 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_UserMetricsRecordAction,
58 OnHostMsgUserMetricsRecordAction)
59 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_HasUnsupportedFeature,
60 OnHostMsgHasUnsupportedFeature)
61 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_Print, OnHostMsgPrint)
62 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_SaveAs,
63 OnHostMsgSaveAs)
64 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_GetResourceImage,
65 OnHostMsgGetResourceImage)
66 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SetSelectedText,
67 OnHostMsgSetSelectedText)
68 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SetLinkUnderCursor,
69 OnHostMsgSetLinkUnderCursor)
70 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SetContentRestriction,
71 OnHostMsgSetContentRestriction)
72 PPAPI_END_MESSAGE_MAP()
73 return PP_ERROR_FAILED;
76 int32_t PepperPDFHost::OnHostMsgGetLocalizedString(
77 ppapi::host::HostMessageContext* context,
78 PP_ResourceString string_id) {
79 std::string rv = GetStringResource(string_id);
80 context->reply_msg = PpapiPluginMsg_PDF_GetLocalizedStringReply(rv);
81 return PP_OK;
84 int32_t PepperPDFHost::OnHostMsgDidStartLoading(
85 ppapi::host::HostMessageContext* context) {
86 content::PepperPluginInstance* instance =
87 host_->GetPluginInstance(pp_instance());
88 if (!instance)
89 return PP_ERROR_FAILED;
90 instance->GetRenderView()->DidStartLoading();
91 return PP_OK;
94 int32_t PepperPDFHost::OnHostMsgDidStopLoading(
95 ppapi::host::HostMessageContext* context) {
96 content::PepperPluginInstance* instance =
97 host_->GetPluginInstance(pp_instance());
98 if (!instance)
99 return PP_ERROR_FAILED;
100 instance->GetRenderView()->DidStopLoading();
101 return PP_OK;
104 int32_t PepperPDFHost::OnHostMsgSetContentRestriction(
105 ppapi::host::HostMessageContext* context,
106 int restrictions) {
107 content::PepperPluginInstance* instance =
108 host_->GetPluginInstance(pp_instance());
109 if (!instance)
110 return PP_ERROR_FAILED;
111 instance->GetRenderView()->Send(new PDFHostMsg_PDFUpdateContentRestrictions(
112 instance->GetRenderView()->GetRoutingID(), restrictions));
113 return PP_OK;
116 int32_t PepperPDFHost::OnHostMsgUserMetricsRecordAction(
117 ppapi::host::HostMessageContext* context,
118 const std::string& action) {
119 if (action.empty())
120 return PP_ERROR_FAILED;
121 content::RenderThread::Get()->RecordComputedAction(action);
122 return PP_OK;
125 int32_t PepperPDFHost::OnHostMsgHasUnsupportedFeature(
126 ppapi::host::HostMessageContext* context) {
127 content::PepperPluginInstance* instance =
128 host_->GetPluginInstance(pp_instance());
129 if (!instance)
130 return PP_ERROR_FAILED;
132 blink::WebView* view =
133 instance->GetContainer()->element().document().frame()->view();
134 content::RenderView* render_view = content::RenderView::FromWebView(view);
135 render_view->Send(
136 new PDFHostMsg_PDFHasUnsupportedFeature(render_view->GetRoutingID()));
137 return PP_OK;
140 int32_t PepperPDFHost::OnHostMsgPrint(
141 ppapi::host::HostMessageContext* context) {
142 return PPB_PDF_Impl::InvokePrintingForInstance(pp_instance()) ? PP_OK :
143 PP_ERROR_FAILED;
146 int32_t PepperPDFHost::OnHostMsgSaveAs(
147 ppapi::host::HostMessageContext* context) {
148 content::PepperPluginInstance* instance =
149 host_->GetPluginInstance(pp_instance());
150 if (!instance)
151 return PP_ERROR_FAILED;
152 GURL url = instance->GetPluginURL();
153 content::RenderView* render_view = instance->GetRenderView();
154 blink::WebLocalFrame* frame =
155 render_view->GetWebView()->mainFrame()->toWebLocalFrame();
156 content::Referrer referrer(frame->document().url(),
157 frame->document().referrerPolicy());
158 render_view->Send(
159 new PDFHostMsg_PDFSaveURLAs(render_view->GetRoutingID(), url, referrer));
160 return PP_OK;
163 int32_t PepperPDFHost::OnHostMsgGetResourceImage(
164 ppapi::host::HostMessageContext* context,
165 PP_ResourceImage image_id,
166 float scale) {
167 gfx::ImageSkia* res_image_skia = GetImageResource(image_id);
169 if (!res_image_skia)
170 return PP_ERROR_FAILED;
172 gfx::ImageSkiaRep image_skia_rep = res_image_skia->GetRepresentation(scale);
174 if (image_skia_rep.is_null() || image_skia_rep.scale() != scale)
175 return PP_ERROR_FAILED;
177 PP_Size pp_size;
178 pp_size.width = image_skia_rep.pixel_width();
179 pp_size.height = image_skia_rep.pixel_height();
181 ppapi::HostResource host_resource;
182 PP_ImageDataDesc image_data_desc;
183 IPC::PlatformFileForTransit image_handle;
184 uint32_t byte_count = 0;
185 bool success =
186 CreateImageData(pp_instance(),
187 ppapi::PPB_ImageData_Shared::GetNativeImageDataFormat(),
188 pp_size,
189 image_skia_rep.sk_bitmap(),
190 &host_resource,
191 &image_data_desc,
192 &image_handle,
193 &byte_count);
194 ppapi::ScopedPPResource image_data_resource(
195 ppapi::ScopedPPResource::PassRef(), host_resource.host_resource());
196 if (!success)
197 return PP_ERROR_FAILED;
199 ppapi::host::ReplyMessageContext reply_context =
200 context->MakeReplyMessageContext();
201 ppapi::proxy::SerializedHandle serialized_handle;
202 serialized_handle.set_shmem(image_handle, byte_count);
203 reply_context.params.AppendHandle(serialized_handle);
204 SendReply(
205 reply_context,
206 PpapiPluginMsg_PDF_GetResourceImageReply(host_resource, image_data_desc));
208 // Keep a reference to the resource only if the function succeeds.
209 image_data_resource.Release();
211 return PP_OK_COMPLETIONPENDING;
214 int32_t PepperPDFHost::OnHostMsgSetSelectedText(
215 ppapi::host::HostMessageContext* context,
216 const base::string16& selected_text) {
217 content::PepperPluginInstance* instance =
218 host_->GetPluginInstance(pp_instance());
219 if (!instance)
220 return PP_ERROR_FAILED;
221 instance->SetSelectedText(selected_text);
222 return PP_OK;
225 int32_t PepperPDFHost::OnHostMsgSetLinkUnderCursor(
226 ppapi::host::HostMessageContext* context,
227 const std::string& url) {
228 content::PepperPluginInstance* instance =
229 host_->GetPluginInstance(pp_instance());
230 if (!instance)
231 return PP_ERROR_FAILED;
232 instance->SetLinkUnderCursor(url);
233 return PP_OK;
236 // TODO(raymes): This function is mainly copied from ppb_image_data_proxy.cc.
237 // It's a mess and needs to be fixed in several ways but this is better done
238 // when we refactor PPB_ImageData. On success, the image handle will be
239 // non-null.
240 bool PepperPDFHost::CreateImageData(
241 PP_Instance instance,
242 PP_ImageDataFormat format,
243 const PP_Size& size,
244 const SkBitmap& pixels_to_write,
245 ppapi::HostResource* result,
246 PP_ImageDataDesc* out_image_data_desc,
247 IPC::PlatformFileForTransit* out_image_handle,
248 uint32_t* out_byte_count) {
249 PP_Resource resource = ppapi::proxy::PPB_ImageData_Proxy::CreateImageData(
250 instance,
251 ppapi::PPB_ImageData_Shared::SIMPLE,
252 format,
253 size,
254 false /* init_to_zero */,
255 out_image_data_desc,
256 out_image_handle,
257 out_byte_count);
258 if (!resource)
259 return false;
261 result->SetHostResource(instance, resource);
263 // Write the image to the resource shared memory.
264 ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API>
265 enter_resource(resource, false);
266 if (enter_resource.failed())
267 return false;
269 ppapi::thunk::PPB_ImageData_API* image_data =
270 static_cast<ppapi::thunk::PPB_ImageData_API*>(enter_resource.object());
271 SkCanvas* canvas = image_data->GetCanvas();
272 bool needs_unmapping = false;
273 if (!canvas) {
274 needs_unmapping = true;
275 image_data->Map();
276 canvas = image_data->GetCanvas();
277 if (!canvas)
278 return false; // Failure mapping.
281 const SkBitmap* bitmap = &skia::GetTopDevice(*canvas)->accessBitmap(false);
282 pixels_to_write.copyPixelsTo(
283 bitmap->getPixels(), bitmap->getSize(), bitmap->rowBytes());
285 if (needs_unmapping)
286 image_data->Unmap();
288 return true;
291 } // namespace pdf