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 "content/public/common/referrer.h"
9 #include "content/public/renderer/pepper_plugin_instance.h"
10 #include "content/public/renderer/render_thread.h"
11 #include "content/public/renderer/render_view.h"
12 #include "content/public/renderer/renderer_ppapi_host.h"
13 #include "ppapi/host/dispatch_host_message.h"
14 #include "ppapi/host/host_message_context.h"
15 #include "ppapi/host/ppapi_host.h"
16 #include "ppapi/proxy/host_dispatcher.h"
17 #include "ppapi/proxy/ppapi_messages.h"
18 #include "ppapi/proxy/ppb_image_data_proxy.h"
19 #include "ppapi/shared_impl/ppb_image_data_shared.h"
20 #include "ppapi/shared_impl/scoped_pp_resource.h"
21 #include "ppapi/thunk/enter.h"
22 #include "ppapi/thunk/ppb_image_data_api.h"
23 #include "third_party/WebKit/public/web/WebDocument.h"
24 #include "third_party/WebKit/public/web/WebElement.h"
25 #include "third_party/WebKit/public/web/WebLocalFrame.h"
26 #include "third_party/WebKit/public/web/WebPluginContainer.h"
27 #include "third_party/WebKit/public/web/WebView.h"
32 // --single-process model may fail in CHECK(!g_print_client) if there exist
33 // more than two RenderThreads, so here we use TLS for g_print_client.
34 // See http://crbug.com/457580.
35 base::LazyInstance
<base::ThreadLocalPointer
<PepperPDFHost::PrintClient
>>::Leaky
36 g_print_client_tls
= LAZY_INSTANCE_INITIALIZER
;
40 PepperPDFHost::PepperPDFHost(content::RendererPpapiHost
* host
,
43 : ppapi::host::ResourceHost(host
->GetPpapiHost(), instance
, resource
),
46 PepperPDFHost::~PepperPDFHost() {}
49 bool PepperPDFHost::InvokePrintingForInstance(PP_Instance instance_id
) {
50 return g_print_client_tls
.Pointer()->Get()
51 ? g_print_client_tls
.Pointer()->Get()->Print(instance_id
)
56 void PepperPDFHost::SetPrintClient(PepperPDFHost::PrintClient
* client
) {
57 CHECK(!g_print_client_tls
.Pointer()->Get())
58 << "There should only be a single PrintClient for one RenderThread.";
59 g_print_client_tls
.Pointer()->Set(client
);
62 int32_t PepperPDFHost::OnResourceMessageReceived(
63 const IPC::Message
& msg
,
64 ppapi::host::HostMessageContext
* context
) {
65 PPAPI_BEGIN_MESSAGE_MAP(PepperPDFHost
, msg
)
66 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_DidStartLoading
,
67 OnHostMsgDidStartLoading
)
68 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_DidStopLoading
,
69 OnHostMsgDidStopLoading
)
70 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_UserMetricsRecordAction
,
71 OnHostMsgUserMetricsRecordAction
)
72 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_HasUnsupportedFeature
,
73 OnHostMsgHasUnsupportedFeature
)
74 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_Print
, OnHostMsgPrint
)
75 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_SaveAs
,
77 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SetSelectedText
,
78 OnHostMsgSetSelectedText
)
79 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SetLinkUnderCursor
,
80 OnHostMsgSetLinkUnderCursor
)
81 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SetContentRestriction
,
82 OnHostMsgSetContentRestriction
)
83 PPAPI_END_MESSAGE_MAP()
84 return PP_ERROR_FAILED
;
87 int32_t PepperPDFHost::OnHostMsgDidStartLoading(
88 ppapi::host::HostMessageContext
* context
) {
89 content::PepperPluginInstance
* instance
=
90 host_
->GetPluginInstance(pp_instance());
92 return PP_ERROR_FAILED
;
93 instance
->GetRenderView()->DidStartLoading();
97 int32_t PepperPDFHost::OnHostMsgDidStopLoading(
98 ppapi::host::HostMessageContext
* context
) {
99 content::PepperPluginInstance
* instance
=
100 host_
->GetPluginInstance(pp_instance());
102 return PP_ERROR_FAILED
;
103 instance
->GetRenderView()->DidStopLoading();
107 int32_t PepperPDFHost::OnHostMsgSetContentRestriction(
108 ppapi::host::HostMessageContext
* context
,
110 content::PepperPluginInstance
* instance
=
111 host_
->GetPluginInstance(pp_instance());
113 return PP_ERROR_FAILED
;
114 instance
->GetRenderView()->Send(new PDFHostMsg_PDFUpdateContentRestrictions(
115 instance
->GetRenderView()->GetRoutingID(), restrictions
));
119 int32_t PepperPDFHost::OnHostMsgUserMetricsRecordAction(
120 ppapi::host::HostMessageContext
* context
,
121 const std::string
& action
) {
123 return PP_ERROR_FAILED
;
124 content::RenderThread::Get()->RecordComputedAction(action
);
128 int32_t PepperPDFHost::OnHostMsgHasUnsupportedFeature(
129 ppapi::host::HostMessageContext
* context
) {
130 content::PepperPluginInstance
* instance
=
131 host_
->GetPluginInstance(pp_instance());
133 return PP_ERROR_FAILED
;
135 blink::WebView
* view
=
136 instance
->GetContainer()->element().document().frame()->view();
137 content::RenderView
* render_view
= content::RenderView::FromWebView(view
);
139 new PDFHostMsg_PDFHasUnsupportedFeature(render_view
->GetRoutingID()));
143 int32_t PepperPDFHost::OnHostMsgPrint(
144 ppapi::host::HostMessageContext
* context
) {
145 return InvokePrintingForInstance(pp_instance()) ? PP_OK
: PP_ERROR_FAILED
;
148 int32_t PepperPDFHost::OnHostMsgSaveAs(
149 ppapi::host::HostMessageContext
* context
) {
150 content::PepperPluginInstance
* instance
=
151 host_
->GetPluginInstance(pp_instance());
153 return PP_ERROR_FAILED
;
154 GURL url
= instance
->GetPluginURL();
155 content::RenderView
* render_view
= instance
->GetRenderView();
156 blink::WebLocalFrame
* frame
=
157 render_view
->GetWebView()->mainFrame()->toWebLocalFrame();
158 content::Referrer referrer
= content::Referrer::SanitizeForRequest(
159 url
, content::Referrer(frame
->document().url(),
160 frame
->document().referrerPolicy()));
162 new PDFHostMsg_PDFSaveURLAs(render_view
->GetRoutingID(), url
, referrer
));
166 int32_t PepperPDFHost::OnHostMsgSetSelectedText(
167 ppapi::host::HostMessageContext
* context
,
168 const base::string16
& selected_text
) {
169 content::PepperPluginInstance
* instance
=
170 host_
->GetPluginInstance(pp_instance());
172 return PP_ERROR_FAILED
;
173 instance
->SetSelectedText(selected_text
);
177 int32_t PepperPDFHost::OnHostMsgSetLinkUnderCursor(
178 ppapi::host::HostMessageContext
* context
,
179 const std::string
& url
) {
180 content::PepperPluginInstance
* instance
=
181 host_
->GetPluginInstance(pp_instance());
183 return PP_ERROR_FAILED
;
184 instance
->SetLinkUnderCursor(url
);