Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / renderer / pepper / pepper_pdf_host.cc
blob25a518b70581162ddca8c3e9fe259ab493d5a64c
1 // Copyright (c) 2013 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 "chrome/renderer/pepper/pepper_pdf_host.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/common/render_messages.h"
9 #include "chrome/renderer/printing/print_web_view_helper.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 "grit/webkit_resources.h"
16 #include "grit/webkit_strings.h"
17 #include "ppapi/host/dispatch_host_message.h"
18 #include "ppapi/host/host_message_context.h"
19 #include "ppapi/host/ppapi_host.h"
20 #include "ppapi/proxy/host_dispatcher.h"
21 #include "ppapi/proxy/ppapi_messages.h"
22 #include "ppapi/proxy/ppb_image_data_proxy.h"
23 #include "ppapi/shared_impl/ppb_image_data_shared.h"
24 #include "ppapi/shared_impl/scoped_pp_resource.h"
25 #include "ppapi/thunk/enter.h"
26 #include "ppapi/thunk/ppb_image_data_api.h"
27 #include "skia/ext/platform_canvas.h"
28 #include "third_party/WebKit/public/web/WebDocument.h"
29 #include "third_party/WebKit/public/web/WebElement.h"
30 #include "third_party/WebKit/public/web/WebLocalFrame.h"
31 #include "third_party/WebKit/public/web/WebPluginContainer.h"
32 #include "third_party/WebKit/public/web/WebView.h"
33 #include "third_party/skia/include/core/SkBitmap.h"
34 #include "ui/base/l10n/l10n_util.h"
35 #include "ui/base/layout.h"
36 #include "ui/base/resource/resource_bundle.h"
37 #include "ui/gfx/image/image_skia.h"
38 #include "ui/gfx/image/image_skia_rep.h"
39 #include "ui/gfx/point.h"
41 namespace {
43 struct ResourceImageInfo {
44 PP_ResourceImage pp_id;
45 int res_id;
48 const ResourceImageInfo kResourceImageMap[] = {
49 {PP_RESOURCEIMAGE_PDF_BUTTON_FTP, IDR_PDF_BUTTON_FTP},
50 {PP_RESOURCEIMAGE_PDF_BUTTON_FTP_HOVER, IDR_PDF_BUTTON_FTP_HOVER},
51 {PP_RESOURCEIMAGE_PDF_BUTTON_FTP_PRESSED, IDR_PDF_BUTTON_FTP_PRESSED},
52 {PP_RESOURCEIMAGE_PDF_BUTTON_FTW, IDR_PDF_BUTTON_FTW},
53 {PP_RESOURCEIMAGE_PDF_BUTTON_FTW_HOVER, IDR_PDF_BUTTON_FTW_HOVER},
54 {PP_RESOURCEIMAGE_PDF_BUTTON_FTW_PRESSED, IDR_PDF_BUTTON_FTW_PRESSED},
55 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END, IDR_PDF_BUTTON_ZOOMIN_END},
56 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END_HOVER,
57 IDR_PDF_BUTTON_ZOOMIN_END_HOVER},
58 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END_PRESSED,
59 IDR_PDF_BUTTON_ZOOMIN_END_PRESSED},
60 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN, IDR_PDF_BUTTON_ZOOMIN},
61 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_HOVER, IDR_PDF_BUTTON_ZOOMIN_HOVER},
62 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_PRESSED, IDR_PDF_BUTTON_ZOOMIN_PRESSED},
63 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT, IDR_PDF_BUTTON_ZOOMOUT},
64 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_HOVER, IDR_PDF_BUTTON_ZOOMOUT_HOVER},
65 {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_PRESSED,
66 IDR_PDF_BUTTON_ZOOMOUT_PRESSED},
67 {PP_RESOURCEIMAGE_PDF_BUTTON_SAVE, IDR_PDF_BUTTON_SAVE},
68 {PP_RESOURCEIMAGE_PDF_BUTTON_SAVE_HOVER, IDR_PDF_BUTTON_SAVE_HOVER},
69 {PP_RESOURCEIMAGE_PDF_BUTTON_SAVE_PRESSED, IDR_PDF_BUTTON_SAVE_PRESSED},
70 {PP_RESOURCEIMAGE_PDF_BUTTON_PRINT, IDR_PDF_BUTTON_PRINT},
71 {PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_HOVER, IDR_PDF_BUTTON_PRINT_HOVER},
72 {PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_PRESSED, IDR_PDF_BUTTON_PRINT_PRESSED},
73 {PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_DISABLED, IDR_PDF_BUTTON_PRINT_DISABLED},
74 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_0, IDR_PDF_THUMBNAIL_0},
75 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_1, IDR_PDF_THUMBNAIL_1},
76 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_2, IDR_PDF_THUMBNAIL_2},
77 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_3, IDR_PDF_THUMBNAIL_3},
78 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_4, IDR_PDF_THUMBNAIL_4},
79 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_5, IDR_PDF_THUMBNAIL_5},
80 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_6, IDR_PDF_THUMBNAIL_6},
81 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_7, IDR_PDF_THUMBNAIL_7},
82 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_8, IDR_PDF_THUMBNAIL_8},
83 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_9, IDR_PDF_THUMBNAIL_9},
84 {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_NUM_BACKGROUND,
85 IDR_PDF_THUMBNAIL_NUM_BACKGROUND},
86 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_0, IDR_PDF_PROGRESS_BAR_0},
87 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_1, IDR_PDF_PROGRESS_BAR_1},
88 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_2, IDR_PDF_PROGRESS_BAR_2},
89 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_3, IDR_PDF_PROGRESS_BAR_3},
90 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_4, IDR_PDF_PROGRESS_BAR_4},
91 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_5, IDR_PDF_PROGRESS_BAR_5},
92 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_6, IDR_PDF_PROGRESS_BAR_6},
93 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_7, IDR_PDF_PROGRESS_BAR_7},
94 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_8, IDR_PDF_PROGRESS_BAR_8},
95 {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_BACKGROUND,
96 IDR_PDF_PROGRESS_BAR_BACKGROUND},
97 {PP_RESOURCEIMAGE_PDF_PAGE_INDICATOR_BACKGROUND,
98 IDR_PDF_PAGE_INDICATOR_BACKGROUND},
99 {PP_RESOURCEIMAGE_PDF_PAGE_DROPSHADOW, IDR_PDF_PAGE_DROPSHADOW},
100 {PP_RESOURCEIMAGE_PDF_PAN_SCROLL_ICON, IDR_PAN_SCROLL_ICON}, };
102 } // namespace
104 PepperPDFHost::PepperPDFHost(content::RendererPpapiHost* host,
105 PP_Instance instance,
106 PP_Resource resource)
107 : ppapi::host::ResourceHost(host->GetPpapiHost(), instance, resource),
108 host_(host) {}
110 PepperPDFHost::~PepperPDFHost() {}
112 int32_t PepperPDFHost::OnResourceMessageReceived(
113 const IPC::Message& msg,
114 ppapi::host::HostMessageContext* context) {
115 IPC_BEGIN_MESSAGE_MAP(PepperPDFHost, msg)
116 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_GetLocalizedString,
117 OnHostMsgGetLocalizedString)
118 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_DidStartLoading,
119 OnHostMsgDidStartLoading)
120 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_DidStopLoading,
121 OnHostMsgDidStopLoading)
122 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_UserMetricsRecordAction,
123 OnHostMsgUserMetricsRecordAction)
124 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_HasUnsupportedFeature,
125 OnHostMsgHasUnsupportedFeature)
126 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_Print, OnHostMsgPrint)
127 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_SaveAs, OnHostMsgSaveAs)
128 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_GetResourceImage,
129 OnHostMsgGetResourceImage)
130 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SetSelectedText,
131 OnHostMsgSetSelectedText)
132 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SetLinkUnderCursor,
133 OnHostMsgSetLinkUnderCursor)
134 IPC_END_MESSAGE_MAP()
135 return PP_ERROR_FAILED;
138 int32_t PepperPDFHost::OnHostMsgGetLocalizedString(
139 ppapi::host::HostMessageContext* context,
140 PP_ResourceString string_id) {
141 std::string rv;
142 if (string_id == PP_RESOURCESTRING_PDFGETPASSWORD) {
143 rv = base::UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_NEED_PASSWORD));
144 } else if (string_id == PP_RESOURCESTRING_PDFLOADING) {
145 rv = base::UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PAGE_LOADING));
146 } else if (string_id == PP_RESOURCESTRING_PDFLOAD_FAILED) {
147 rv = base::UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PAGE_LOAD_FAILED));
148 } else if (string_id == PP_RESOURCESTRING_PDFPROGRESSLOADING) {
149 rv = base::UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PROGRESS_LOADING));
150 } else {
151 NOTREACHED();
152 return PP_ERROR_FAILED;
155 context->reply_msg = PpapiPluginMsg_PDF_GetLocalizedStringReply(rv);
156 return PP_OK;
159 int32_t PepperPDFHost::OnHostMsgDidStartLoading(
160 ppapi::host::HostMessageContext* context) {
161 content::PepperPluginInstance* instance =
162 host_->GetPluginInstance(pp_instance());
163 if (!instance)
164 return PP_ERROR_FAILED;
165 instance->GetRenderView()->DidStartLoading();
166 return PP_OK;
169 int32_t PepperPDFHost::OnHostMsgDidStopLoading(
170 ppapi::host::HostMessageContext* context) {
171 content::PepperPluginInstance* instance =
172 host_->GetPluginInstance(pp_instance());
173 if (!instance)
174 return PP_ERROR_FAILED;
175 instance->GetRenderView()->DidStopLoading();
176 return PP_OK;
179 int32_t PepperPDFHost::OnHostMsgSetContentRestriction(
180 ppapi::host::HostMessageContext* context,
181 int restrictions) {
182 content::PepperPluginInstance* instance =
183 host_->GetPluginInstance(pp_instance());
184 if (!instance)
185 return PP_ERROR_FAILED;
186 instance->GetRenderView()->Send(
187 new ChromeViewHostMsg_PDFUpdateContentRestrictions(
188 instance->GetRenderView()->GetRoutingID(), restrictions));
189 return PP_OK;
192 int32_t PepperPDFHost::OnHostMsgUserMetricsRecordAction(
193 ppapi::host::HostMessageContext* context,
194 const std::string& action) {
195 if (action.empty())
196 return PP_ERROR_FAILED;
197 content::RenderThread::Get()->RecordComputedAction(action);
198 return PP_OK;
201 int32_t PepperPDFHost::OnHostMsgHasUnsupportedFeature(
202 ppapi::host::HostMessageContext* context) {
203 content::PepperPluginInstance* instance =
204 host_->GetPluginInstance(pp_instance());
205 if (!instance)
206 return PP_ERROR_FAILED;
208 // Only want to show an info bar if the pdf is the whole tab.
209 if (!instance->IsFullPagePlugin())
210 return PP_OK;
212 blink::WebView* view =
213 instance->GetContainer()->element().document().frame()->view();
214 content::RenderView* render_view = content::RenderView::FromWebView(view);
215 render_view->Send(new ChromeViewHostMsg_PDFHasUnsupportedFeature(
216 render_view->GetRoutingID()));
217 return PP_OK;
220 int32_t PepperPDFHost::OnHostMsgPrint(
221 ppapi::host::HostMessageContext* context) {
222 #if defined(ENABLE_FULL_PRINTING)
223 content::PepperPluginInstance* instance =
224 host_->GetPluginInstance(pp_instance());
225 if (!instance)
226 return PP_ERROR_FAILED;
228 blink::WebElement element = instance->GetContainer()->element();
229 blink::WebView* view = element.document().frame()->view();
230 content::RenderView* render_view = content::RenderView::FromWebView(view);
232 using printing::PrintWebViewHelper;
233 PrintWebViewHelper* print_view_helper = PrintWebViewHelper::Get(render_view);
234 if (print_view_helper) {
235 print_view_helper->PrintNode(element);
236 return PP_OK;
238 #endif
239 return PP_ERROR_FAILED;
242 int32_t PepperPDFHost::OnHostMsgSaveAs(
243 ppapi::host::HostMessageContext* context) {
244 content::PepperPluginInstance* instance =
245 host_->GetPluginInstance(pp_instance());
246 if (!instance)
247 return PP_ERROR_FAILED;
248 GURL url = instance->GetPluginURL();
249 content::RenderView* render_view = instance->GetRenderView();
250 blink::WebLocalFrame* frame =
251 render_view->GetWebView()->mainFrame()->toWebLocalFrame();
252 content::Referrer referrer(frame->document().url(),
253 frame->document().referrerPolicy());
254 render_view->Send(new ChromeViewHostMsg_PDFSaveURLAs(
255 render_view->GetRoutingID(), url, referrer));
256 return PP_OK;
259 int32_t PepperPDFHost::OnHostMsgGetResourceImage(
260 ppapi::host::HostMessageContext* context,
261 PP_ResourceImage image_id,
262 float scale) {
263 int res_id = 0;
264 for (size_t i = 0; i < arraysize(kResourceImageMap); ++i) {
265 if (kResourceImageMap[i].pp_id == image_id) {
266 res_id = kResourceImageMap[i].res_id;
267 break;
270 if (res_id == 0)
271 return PP_ERROR_FAILED;
273 gfx::ImageSkia* res_image_skia =
274 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(res_id);
276 if (!res_image_skia)
277 return PP_ERROR_FAILED;
279 gfx::ImageSkiaRep image_skia_rep = res_image_skia->GetRepresentation(scale);
281 if (image_skia_rep.is_null() || image_skia_rep.scale() != scale)
282 return PP_ERROR_FAILED;
284 PP_Size pp_size;
285 pp_size.width = image_skia_rep.pixel_width();
286 pp_size.height = image_skia_rep.pixel_height();
288 ppapi::HostResource host_resource;
289 PP_ImageDataDesc image_data_desc;
290 IPC::PlatformFileForTransit image_handle;
291 uint32_t byte_count = 0;
292 bool success =
293 CreateImageData(pp_instance(),
294 ppapi::PPB_ImageData_Shared::GetNativeImageDataFormat(),
295 pp_size,
296 image_skia_rep.sk_bitmap(),
297 &host_resource,
298 &image_data_desc,
299 &image_handle,
300 &byte_count);
301 ppapi::ScopedPPResource image_data_resource(
302 ppapi::ScopedPPResource::PassRef(), host_resource.host_resource());
303 if (!success)
304 return PP_ERROR_FAILED;
306 ppapi::host::ReplyMessageContext reply_context =
307 context->MakeReplyMessageContext();
308 ppapi::proxy::SerializedHandle serialized_handle;
309 serialized_handle.set_shmem(image_handle, byte_count);
310 reply_context.params.AppendHandle(serialized_handle);
311 SendReply(
312 reply_context,
313 PpapiPluginMsg_PDF_GetResourceImageReply(host_resource, image_data_desc));
315 // Keep a reference to the resource only if the function succeeds.
316 image_data_resource.Release();
318 return PP_OK_COMPLETIONPENDING;
321 int32_t PepperPDFHost::OnHostMsgSetSelectedText(
322 ppapi::host::HostMessageContext* context,
323 const base::string16& selected_text) {
324 content::PepperPluginInstance* instance =
325 host_->GetPluginInstance(pp_instance());
326 if (!instance)
327 return PP_ERROR_FAILED;
328 instance->SetSelectedText(selected_text);
329 return PP_OK;
332 int32_t PepperPDFHost::OnHostMsgSetLinkUnderCursor(
333 ppapi::host::HostMessageContext* context,
334 const std::string& url) {
335 content::PepperPluginInstance* instance =
336 host_->GetPluginInstance(pp_instance());
337 if (!instance)
338 return PP_ERROR_FAILED;
339 instance->SetLinkUnderCursor(url);
340 return PP_OK;
343 // TODO(raymes): This function is mainly copied from ppb_image_data_proxy.cc.
344 // It's a mess and needs to be fixed in several ways but this is better done
345 // when we refactor PPB_ImageData. On success, the image handle will be
346 // non-null.
347 bool PepperPDFHost::CreateImageData(
348 PP_Instance instance,
349 PP_ImageDataFormat format,
350 const PP_Size& size,
351 const SkBitmap& pixels_to_write,
352 ppapi::HostResource* result,
353 PP_ImageDataDesc* out_image_data_desc,
354 IPC::PlatformFileForTransit* out_image_handle,
355 uint32_t* out_byte_count) {
356 PP_Resource resource = ppapi::proxy::PPB_ImageData_Proxy::CreateImageData(
357 instance,
358 ppapi::PPB_ImageData_Shared::SIMPLE,
359 format,
360 size,
361 false /* init_to_zero */,
362 out_image_data_desc,
363 out_image_handle,
364 out_byte_count);
365 if (!resource)
366 return false;
368 result->SetHostResource(instance, resource);
370 // Write the image to the resource shared memory.
371 ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API>
372 enter_resource(resource, false);
373 if (enter_resource.failed())
374 return false;
376 ppapi::thunk::PPB_ImageData_API* image_data =
377 static_cast<ppapi::thunk::PPB_ImageData_API*>(enter_resource.object());
378 SkCanvas* canvas = image_data->GetCanvas();
379 bool needs_unmapping = false;
380 if (!canvas) {
381 needs_unmapping = true;
382 image_data->Map();
383 canvas = image_data->GetCanvas();
384 if (!canvas)
385 return false; // Failure mapping.
388 const SkBitmap* bitmap = &skia::GetTopDevice(*canvas)->accessBitmap(false);
389 pixels_to_write.copyPixelsTo(
390 bitmap->getPixels(), bitmap->getSize(), bitmap->rowBytes());
392 if (needs_unmapping)
393 image_data->Unmap();
395 return true;