// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/pdf/renderer/pepper_pdf_host.h" #include "components/pdf/common/pdf_messages.h" #include "components/strings/grit/components_strings.h" #include "content/public/common/referrer.h" #include "content/public/renderer/pepper_plugin_instance.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/renderer_ppapi_host.h" #include "ppapi/host/dispatch_host_message.h" #include "ppapi/host/host_message_context.h" #include "ppapi/host/ppapi_host.h" #include "ppapi/proxy/host_dispatcher.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppb_image_data_proxy.h" #include "ppapi/shared_impl/ppb_image_data_shared.h" #include "ppapi/shared_impl/scoped_pp_resource.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/ppb_image_data_api.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebElement.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebPluginContainer.h" #include "third_party/WebKit/public/web/WebView.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/layout.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/geometry/point.h" namespace pdf { namespace { // --single-process model may fail in CHECK(!g_print_client) if there exist // more than two RenderThreads, so here we use TLS for g_print_client. // See http://crbug.com/457580. base::LazyInstance>::Leaky g_print_client_tls = LAZY_INSTANCE_INITIALIZER; std::string GetStringResource(PP_ResourceString string_id) { int resource_id = 0; switch (string_id) { case PP_RESOURCESTRING_PDFGETPASSWORD: resource_id = IDS_PDF_NEED_PASSWORD; break; case PP_RESOURCESTRING_PDFLOADING: resource_id = IDS_PDF_PAGE_LOADING; break; case PP_RESOURCESTRING_PDFLOAD_FAILED: resource_id = IDS_PDF_PAGE_LOAD_FAILED; break; case PP_RESOURCESTRING_PDFPROGRESSLOADING: resource_id = IDS_PDF_PROGRESS_LOADING; break; } return l10n_util::GetStringUTF8(resource_id); } } // namespace PepperPDFHost::PepperPDFHost(content::RendererPpapiHost* host, PP_Instance instance, PP_Resource resource) : ppapi::host::ResourceHost(host->GetPpapiHost(), instance, resource), host_(host) {} PepperPDFHost::~PepperPDFHost() {} // static bool PepperPDFHost::InvokePrintingForInstance(PP_Instance instance_id) { return g_print_client_tls.Pointer()->Get() ? g_print_client_tls.Pointer()->Get()->Print(instance_id) : false; } // static void PepperPDFHost::SetPrintClient(PepperPDFHost::PrintClient* client) { CHECK(!g_print_client_tls.Pointer()->Get()) << "There should only be a single PrintClient for one RenderThread."; g_print_client_tls.Pointer()->Set(client); } int32_t PepperPDFHost::OnResourceMessageReceived( const IPC::Message& msg, ppapi::host::HostMessageContext* context) { PPAPI_BEGIN_MESSAGE_MAP(PepperPDFHost, msg) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_GetLocalizedString, OnHostMsgGetLocalizedString) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_DidStartLoading, OnHostMsgDidStartLoading) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_DidStopLoading, OnHostMsgDidStopLoading) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_UserMetricsRecordAction, OnHostMsgUserMetricsRecordAction) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_HasUnsupportedFeature, OnHostMsgHasUnsupportedFeature) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_Print, OnHostMsgPrint) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_PDF_SaveAs, OnHostMsgSaveAs) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SetSelectedText, OnHostMsgSetSelectedText) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SetLinkUnderCursor, OnHostMsgSetLinkUnderCursor) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SetContentRestriction, OnHostMsgSetContentRestriction) PPAPI_END_MESSAGE_MAP() return PP_ERROR_FAILED; } int32_t PepperPDFHost::OnHostMsgGetLocalizedString( ppapi::host::HostMessageContext* context, PP_ResourceString string_id) { std::string rv = GetStringResource(string_id); context->reply_msg = PpapiPluginMsg_PDF_GetLocalizedStringReply(rv); return PP_OK; } int32_t PepperPDFHost::OnHostMsgDidStartLoading( ppapi::host::HostMessageContext* context) { content::PepperPluginInstance* instance = host_->GetPluginInstance(pp_instance()); if (!instance) return PP_ERROR_FAILED; instance->GetRenderView()->DidStartLoading(); return PP_OK; } int32_t PepperPDFHost::OnHostMsgDidStopLoading( ppapi::host::HostMessageContext* context) { content::PepperPluginInstance* instance = host_->GetPluginInstance(pp_instance()); if (!instance) return PP_ERROR_FAILED; instance->GetRenderView()->DidStopLoading(); return PP_OK; } int32_t PepperPDFHost::OnHostMsgSetContentRestriction( ppapi::host::HostMessageContext* context, int restrictions) { content::PepperPluginInstance* instance = host_->GetPluginInstance(pp_instance()); if (!instance) return PP_ERROR_FAILED; instance->GetRenderView()->Send(new PDFHostMsg_PDFUpdateContentRestrictions( instance->GetRenderView()->GetRoutingID(), restrictions)); return PP_OK; } int32_t PepperPDFHost::OnHostMsgUserMetricsRecordAction( ppapi::host::HostMessageContext* context, const std::string& action) { if (action.empty()) return PP_ERROR_FAILED; content::RenderThread::Get()->RecordComputedAction(action); return PP_OK; } int32_t PepperPDFHost::OnHostMsgHasUnsupportedFeature( ppapi::host::HostMessageContext* context) { content::PepperPluginInstance* instance = host_->GetPluginInstance(pp_instance()); if (!instance) return PP_ERROR_FAILED; blink::WebView* view = instance->GetContainer()->element().document().frame()->view(); content::RenderView* render_view = content::RenderView::FromWebView(view); render_view->Send( new PDFHostMsg_PDFHasUnsupportedFeature(render_view->GetRoutingID())); return PP_OK; } int32_t PepperPDFHost::OnHostMsgPrint( ppapi::host::HostMessageContext* context) { return InvokePrintingForInstance(pp_instance()) ? PP_OK : PP_ERROR_FAILED; } int32_t PepperPDFHost::OnHostMsgSaveAs( ppapi::host::HostMessageContext* context) { content::PepperPluginInstance* instance = host_->GetPluginInstance(pp_instance()); if (!instance) return PP_ERROR_FAILED; GURL url = instance->GetPluginURL(); content::RenderView* render_view = instance->GetRenderView(); blink::WebLocalFrame* frame = render_view->GetWebView()->mainFrame()->toWebLocalFrame(); content::Referrer referrer = content::Referrer::SanitizeForRequest( url, content::Referrer(frame->document().url(), frame->document().referrerPolicy())); render_view->Send( new PDFHostMsg_PDFSaveURLAs(render_view->GetRoutingID(), url, referrer)); return PP_OK; } int32_t PepperPDFHost::OnHostMsgSetSelectedText( ppapi::host::HostMessageContext* context, const base::string16& selected_text) { content::PepperPluginInstance* instance = host_->GetPluginInstance(pp_instance()); if (!instance) return PP_ERROR_FAILED; instance->SetSelectedText(selected_text); return PP_OK; } int32_t PepperPDFHost::OnHostMsgSetLinkUnderCursor( ppapi::host::HostMessageContext* context, const std::string& url) { content::PepperPluginInstance* instance = host_->GetPluginInstance(pp_instance()); if (!instance) return PP_ERROR_FAILED; instance->SetLinkUnderCursor(url); return PP_OK; } } // namespace pdf