diff options
author | Sadrul Habib Chowdhury <sadrul@chromium.org> | 2014-08-27 23:50:36 -0400 |
---|---|---|
committer | Sadrul Habib Chowdhury <sadrul@chromium.org> | 2014-08-28 03:51:28 +0000 |
commit | 2f8807f697e2c043c857ec37c43d45573d239d8f (patch) | |
tree | 3e067a88970845d20d703c94d8ca7afbdc1445e9 /components/pdf | |
parent | 99492bedc3bd5ac3a26b12fbf7599a55086a998e (diff) | |
download | chromium_src-2f8807f697e2c043c857ec37c43d45573d239d8f.zip chromium_src-2f8807f697e2c043c857ec37c43d45573d239d8f.tar.gz chromium_src-2f8807f697e2c043c857ec37c43d45573d239d8f.tar.bz2 |
pdf: Create a separate component for using the pdf pepper plugin.
Create a component necessary for showing PDF in a content-based client. Much of
the relevant code currently lives in //chrome/, and is usable by chrome. Moving
this code into a separate component in //components/pdf/ allows it to be easily
used by other content-clients (e.g. app-shell, athena, etc.). This patch moves
PPB_PDF_Impl (implementation for the PPB_PDF interface in ppapi) and the
relevant IPC messages in the pdf component.
A short summary of the changes in this patch:
. Move ppb_pdf_impl.cc|h into //components/pdf from //chrome/renderer/pepper
. Put this code in the 'pdf' namespace. This code lives in 'pdf_renderer'
target. 'chrome_renderer' depends on this target.
. Move the following IPC messages from render_messages.h to pdf_messages.h:
- PDFUpdateContentRestrictions
- PDFHasUnsupportedFeature
- PDFSaveURLAs
- PDFModalPromptForPassword
Change the prefix of these messages from ChromeViewHostMsg_ to PDFHostMsg_
. Move PDFTabHelper into //components/pdf from //chrome/browser/ui/pdf.
Put this code in the 'pdf' namespace. This code lives in 'pdf_browser'
target. 'chrome_browser' depends on this target.
BUG=401242
R=blundell@chromium.org, raymes@chromium.org, thestig@chromium.org, tsepez@chromium.org
TBR=darin@chromium.org for DEPS
Review URL: https://codereview.chromium.org/477263003
Cr-Commit-Position: refs/heads/master@{#292313}
Diffstat (limited to 'components/pdf')
-rw-r--r-- | components/pdf/DEPS | 10 | ||||
-rw-r--r-- | components/pdf/OWNERS | 4 | ||||
-rw-r--r-- | components/pdf/README | 4 | ||||
-rw-r--r-- | components/pdf/browser/BUILD.gn | 19 | ||||
-rw-r--r-- | components/pdf/browser/open_pdf_in_reader_prompt_client.h | 36 | ||||
-rw-r--r-- | components/pdf/browser/pdf_web_contents_helper.cc | 107 | ||||
-rw-r--r-- | components/pdf/browser/pdf_web_contents_helper.h | 74 | ||||
-rw-r--r-- | components/pdf/browser/pdf_web_contents_helper_client.h | 43 | ||||
-rw-r--r-- | components/pdf/common/BUILD.gn | 20 | ||||
-rw-r--r-- | components/pdf/common/OWNERS | 11 | ||||
-rw-r--r-- | components/pdf/common/pdf_message_generator.cc | 33 | ||||
-rw-r--r-- | components/pdf/common/pdf_message_generator.h | 7 | ||||
-rw-r--r-- | components/pdf/common/pdf_messages.h | 31 | ||||
-rw-r--r-- | components/pdf/renderer/BUILD.gn | 28 | ||||
-rw-r--r-- | components/pdf/renderer/OWNERS | 5 | ||||
-rw-r--r-- | components/pdf/renderer/ppb_pdf_impl.cc | 446 | ||||
-rw-r--r-- | components/pdf/renderer/ppb_pdf_impl.h | 45 |
17 files changed, 923 insertions, 0 deletions
diff --git a/components/pdf/DEPS b/components/pdf/DEPS new file mode 100644 index 0000000..745ee50 --- /dev/null +++ b/components/pdf/DEPS @@ -0,0 +1,10 @@ +include_rules = [ + "+content/app", + "+content/public", + "+grit/webkit_resources.h", + "+ipc", + "+ppapi", + "+third_party/skia/include", + "+third_party/WebKit/public", + "+ui/base", +] diff --git a/components/pdf/OWNERS b/components/pdf/OWNERS new file mode 100644 index 0000000..fb5f2d2 --- /dev/null +++ b/components/pdf/OWNERS @@ -0,0 +1,4 @@ +gene@chromium.org +jam@chromium.org +raymes@chromium.org +thestig@chromium.org diff --git a/components/pdf/README b/components/pdf/README new file mode 100644 index 0000000..da0b817 --- /dev/null +++ b/components/pdf/README @@ -0,0 +1,4 @@ +The PDF component contains code necessary for using the PDF plugin in +content-based clients. It provides an implementation for the PPB_PDF ppapi +interface, and the necessary browser and renderer-side code for processing the +relevant IPC mesages. diff --git a/components/pdf/browser/BUILD.gn b/components/pdf/browser/BUILD.gn new file mode 100644 index 0000000..7434a8f --- /dev/null +++ b/components/pdf/browser/BUILD.gn @@ -0,0 +1,19 @@ +# 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. + +import("//build/config/features.gni") + +static_library("browser") { + sources = [ + "open_pdf_in_reader_prompt_client.h", + "pdf_web_contents_helper.cc", + "pdf_web_contents_helper.h", + "pdf_web_contents_helper_client.h", + ] + + deps = [ + "//components/pdf/common", + "//content/public/browser", + ] +} diff --git a/components/pdf/browser/open_pdf_in_reader_prompt_client.h b/components/pdf/browser/open_pdf_in_reader_prompt_client.h new file mode 100644 index 0000000..854e6f4 --- /dev/null +++ b/components/pdf/browser/open_pdf_in_reader_prompt_client.h @@ -0,0 +1,36 @@ +// Copyright (c) 2012 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. + +#ifndef COMPONENTS_PDF_BROWSER_OPEN_PDF_IN_READER_PROMPT_CLIENT_H_ +#define COMPONENTS_PDF_BROWSER_OPEN_PDF_IN_READER_PROMPT_CLIENT_H_ + +#include "base/strings/string16.h" + +namespace content { +struct LoadCommittedDetails; +} + +namespace pdf { + +class OpenPDFInReaderPromptClient { + public: + virtual ~OpenPDFInReaderPromptClient() {} + + virtual base::string16 GetMessageText() const = 0; + + virtual base::string16 GetAcceptButtonText() const = 0; + + virtual base::string16 GetCancelButtonText() const = 0; + + virtual bool ShouldExpire( + const content::LoadCommittedDetails& details) const = 0; + + virtual void Accept() = 0; + + virtual void Cancel() = 0; +}; + +} // namespace pdf + +#endif // COMPONENTS_PDF_BROWSER_OPEN_PDF_IN_READER_PROMPT_CLIENT_H_ diff --git a/components/pdf/browser/pdf_web_contents_helper.cc b/components/pdf/browser/pdf_web_contents_helper.cc new file mode 100644 index 0000000..59a17a8 --- /dev/null +++ b/components/pdf/browser/pdf_web_contents_helper.cc @@ -0,0 +1,107 @@ +// Copyright (c) 2012 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/browser/pdf_web_contents_helper.h" + +#include "base/bind.h" +#include "base/strings/utf_string_conversions.h" +#include "components/pdf/browser/open_pdf_in_reader_prompt_client.h" +#include "components/pdf/browser/pdf_web_contents_helper_client.h" +#include "components/pdf/common/pdf_messages.h" +#include "content/public/browser/navigation_details.h" + +DEFINE_WEB_CONTENTS_USER_DATA_KEY(pdf::PDFWebContentsHelper); + +namespace pdf { + +// static +void PDFWebContentsHelper::CreateForWebContentsWithClient( + content::WebContents* contents, + scoped_ptr<PDFWebContentsHelperClient> client) { + if (FromWebContents(contents)) + return; + contents->SetUserData(UserDataKey(), + new PDFWebContentsHelper(contents, client.Pass())); +} + +PDFWebContentsHelper::PDFWebContentsHelper( + content::WebContents* web_contents, + scoped_ptr<PDFWebContentsHelperClient> client) + : content::WebContentsObserver(web_contents), client_(client.Pass()) { +} + +PDFWebContentsHelper::~PDFWebContentsHelper() { +} + +void PDFWebContentsHelper::ShowOpenInReaderPrompt( + scoped_ptr<OpenPDFInReaderPromptClient> prompt) { + open_in_reader_prompt_ = prompt.Pass(); + UpdateLocationBar(); +} + +bool PDFWebContentsHelper::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PDFWebContentsHelper, message) + IPC_MESSAGE_HANDLER(PDFHostMsg_PDFHasUnsupportedFeature, + OnHasUnsupportedFeature) + IPC_MESSAGE_HANDLER(PDFHostMsg_PDFSaveURLAs, OnSaveURLAs) + IPC_MESSAGE_HANDLER(PDFHostMsg_PDFUpdateContentRestrictions, + OnUpdateContentRestrictions) + IPC_MESSAGE_HANDLER_DELAY_REPLY(PDFHostMsg_PDFModalPromptForPassword, + OnModalPromptForPassword) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void PDFWebContentsHelper::DidNavigateMainFrame( + const content::LoadCommittedDetails& details, + const content::FrameNavigateParams& params) { + if (open_in_reader_prompt_.get() && + open_in_reader_prompt_->ShouldExpire(details)) { + open_in_reader_prompt_.reset(); + UpdateLocationBar(); + } +} + +void PDFWebContentsHelper::UpdateLocationBar() { + client_->UpdateLocationBar(web_contents()); +} + +void PDFWebContentsHelper::OnHasUnsupportedFeature() { + client_->OnPDFHasUnsupportedFeature(web_contents()); +} + +void PDFWebContentsHelper::OnSaveURLAs(const GURL& url, + const content::Referrer& referrer) { + client_->OnSaveURL(web_contents()); + web_contents()->SaveFrame(url, referrer); +} + +void PDFWebContentsHelper::OnUpdateContentRestrictions( + int content_restrictions) { + client_->UpdateContentRestrictions(web_contents(), content_restrictions); +} + +void PDFWebContentsHelper::OnModalPromptForPasswordClosed( + IPC::Message* reply_message, + bool success, + const base::string16& actual_value) { + PDFHostMsg_PDFModalPromptForPassword::WriteReplyParams( + reply_message, base::UTF16ToUTF8(actual_value)); + Send(reply_message); +} + +void PDFWebContentsHelper::OnModalPromptForPassword( + const std::string& prompt, + IPC::Message* reply_message) { + base::Callback<void(bool, const base::string16&)> callback = + base::Bind(&PDFWebContentsHelper::OnModalPromptForPasswordClosed, + base::Unretained(this), + reply_message); + client_->OnShowPDFPasswordDialog( + web_contents(), base::UTF8ToUTF16(prompt), callback); +} + +} // namespace pdf diff --git a/components/pdf/browser/pdf_web_contents_helper.h b/components/pdf/browser/pdf_web_contents_helper.h new file mode 100644 index 0000000..d37b57f --- /dev/null +++ b/components/pdf/browser/pdf_web_contents_helper.h @@ -0,0 +1,74 @@ +// Copyright (c) 2012 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. + +#ifndef COMPONENTS_PDF_BROWSER_PDF_WEB_CONTENTS_HELPER_H_ +#define COMPONENTS_PDF_BROWSER_PDF_WEB_CONTENTS_HELPER_H_ + +#include <string> + +#include "base/callback.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" +#include "ipc/ipc_message.h" + +namespace content { +class WebContents; +} + +namespace pdf { + +class OpenPDFInReaderPromptClient; +class PDFWebContentsHelperClient; + +// Per-WebContents class to handle PDF messages. +class PDFWebContentsHelper + : public content::WebContentsObserver, + public content::WebContentsUserData<PDFWebContentsHelper> { + public: + static void CreateForWebContentsWithClient( + content::WebContents* contents, + scoped_ptr<PDFWebContentsHelperClient> client); + + OpenPDFInReaderPromptClient* open_in_reader_prompt() const { + return open_in_reader_prompt_.get(); + } + + void ShowOpenInReaderPrompt(scoped_ptr<OpenPDFInReaderPromptClient> prompt); + + private: + PDFWebContentsHelper(content::WebContents* web_contents, + scoped_ptr<PDFWebContentsHelperClient> client); + virtual ~PDFWebContentsHelper(); + + // content::WebContentsObserver overrides: + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + virtual void DidNavigateMainFrame( + const content::LoadCommittedDetails& details, + const content::FrameNavigateParams& params) OVERRIDE; + + // Internal helpers ---------------------------------------------------------- + + void UpdateLocationBar(); + void OnModalPromptForPasswordClosed(IPC::Message* reply_message, + bool success, + const base::string16& actual_value); + + // Message handlers. + void OnHasUnsupportedFeature(); + void OnSaveURLAs(const GURL& url, const content::Referrer& referrer); + void OnUpdateContentRestrictions(int content_restrictions); + void OnModalPromptForPassword(const std::string& prompt, + IPC::Message* reply_message); + + // The model for the confirmation prompt to open a PDF in Adobe Reader. + scoped_ptr<OpenPDFInReaderPromptClient> open_in_reader_prompt_; + scoped_ptr<PDFWebContentsHelperClient> client_; + + DISALLOW_COPY_AND_ASSIGN(PDFWebContentsHelper); +}; + +} // namespace pdf + +#endif // COMPONENTS_PDF_BROWSER_PDF_WEB_CONTENTS_HELPER_H_ diff --git a/components/pdf/browser/pdf_web_contents_helper_client.h b/components/pdf/browser/pdf_web_contents_helper_client.h new file mode 100644 index 0000000..17dfb4e --- /dev/null +++ b/components/pdf/browser/pdf_web_contents_helper_client.h @@ -0,0 +1,43 @@ +// 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. + +#ifndef COMPONENTS_PDF_BROWSER_PDF_WEB_CONTENTS_HELPER_CLIENT_H_ +#define COMPONENTS_PDF_BROWSER_PDF_WEB_CONTENTS_HELPER_CLIENT_H_ + +#include "base/callback.h" +#include "base/strings/string16.h" +#include "ipc/ipc_message.h" + +namespace content { +class WebContents; +} + +namespace pdf { + +typedef base::Callback< + void(bool /* success */, const base::string16& /* password */)> + PasswordDialogClosedCallback; + +class PDFWebContentsHelperClient { + public: + virtual ~PDFWebContentsHelperClient() {} + + virtual void UpdateLocationBar(content::WebContents* contents) = 0; + + virtual void UpdateContentRestrictions(content::WebContents* contents, + int content_restrictions) = 0; + + virtual void OnPDFHasUnsupportedFeature(content::WebContents* contents) = 0; + + virtual void OnSaveURL(content::WebContents* contents) = 0; + + virtual void OnShowPDFPasswordDialog( + content::WebContents* contents, + const base::string16& prompt, + const PasswordDialogClosedCallback& callback) = 0; +}; + +} // namespace pdf + +#endif // COMPONENTS_PDF_BROWSER_PDF_WEB_CONTENTS_HELPER_CLIENT_H_ diff --git a/components/pdf/common/BUILD.gn b/components/pdf/common/BUILD.gn new file mode 100644 index 0000000..adff35e --- /dev/null +++ b/components/pdf/common/BUILD.gn @@ -0,0 +1,20 @@ +# 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. + +import("//build/config/features.gni") + +static_library("common") { + sources = [ + "pdf_message_generator.cc", + "pdf_message_generator.h", + "pdf_messages.h", + ] + + deps = [ + "//base", + "//content/public/common", + "//ipc", + "//url", + ] +} diff --git a/components/pdf/common/OWNERS b/components/pdf/common/OWNERS new file mode 100644 index 0000000..faa1757 --- /dev/null +++ b/components/pdf/common/OWNERS @@ -0,0 +1,11 @@ +# Changes to IPC messages require a security review to avoid introducing +# new sandbox escapes. +per-file *_messages*.h=set noparent +per-file *_messages*.h=cevans@chromium.org +per-file *_messages*.h=dcheng@chromium.org +per-file *_messages*.h=inferno@chromium.org +per-file *_messages*.h=jln@chromium.org +per-file *_messages*.h=jschuh@chromium.org +per-file *_messages*.h=kenrb@chromium.org +per-file *_messages*.h=nasko@chromium.org +per-file *_messages*.h=tsepez@chromium.org diff --git a/components/pdf/common/pdf_message_generator.cc b/components/pdf/common/pdf_message_generator.cc new file mode 100644 index 0000000..025d94c --- /dev/null +++ b/components/pdf/common/pdf_message_generator.cc @@ -0,0 +1,33 @@ +// 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. + +// Get basic type definitions. +#define IPC_MESSAGE_IMPL +#include "components/pdf/common/pdf_message_generator.h" + +// Generate constructors. +#include "ipc/struct_constructor_macros.h" +#include "components/pdf/common/pdf_message_generator.h" + +// Generate destructors. +#include "ipc/struct_destructor_macros.h" +#include "components/pdf/common/pdf_message_generator.h" + +// Generate param traits write methods. +#include "ipc/param_traits_write_macros.h" +namespace IPC { +#include "components/pdf/common/pdf_message_generator.h" +} // namespace IPC + +// Generate param traits read methods. +#include "ipc/param_traits_read_macros.h" +namespace IPC { +#include "components/pdf/common/pdf_message_generator.h" +} // namespace IPC + +// Generate param traits log methods. +#include "ipc/param_traits_log_macros.h" +namespace IPC { +#include "components/pdf/common/pdf_message_generator.h" +} // namespace IPC diff --git a/components/pdf/common/pdf_message_generator.h b/components/pdf/common/pdf_message_generator.h new file mode 100644 index 0000000..c55d672 --- /dev/null +++ b/components/pdf/common/pdf_message_generator.h @@ -0,0 +1,7 @@ +// 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. + +// Multiply-included file, no traditional include guard. + +#include "components/pdf/common/pdf_messages.h" diff --git a/components/pdf/common/pdf_messages.h b/components/pdf/common/pdf_messages.h new file mode 100644 index 0000000..0973923 --- /dev/null +++ b/components/pdf/common/pdf_messages.h @@ -0,0 +1,31 @@ +// 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. + +// Multiply-included file, no traditional include guard. +#include <string.h> + +#include "content/public/common/common_param_traits.h" +#include "content/public/common/common_param_traits_macros.h" +#include "content/public/common/referrer.h" +#include "ipc/ipc_message_macros.h" +#include "url/gurl.h" + +#define IPC_MESSAGE_START PDFMsgStart + +// Updates the content restrictions, i.e. to disable print/copy. +IPC_MESSAGE_ROUTED1(PDFHostMsg_PDFUpdateContentRestrictions, + int /* restrictions */) + +// The currently displayed PDF has an unsupported feature. +IPC_MESSAGE_ROUTED0(PDFHostMsg_PDFHasUnsupportedFeature) + +// Brings up SaveAs... dialog to save specified URL. +IPC_MESSAGE_ROUTED2(PDFHostMsg_PDFSaveURLAs, + GURL /* url */, + content::Referrer /* referrer */) + +// Brings up a Password... dialog for protected documents. +IPC_SYNC_MESSAGE_ROUTED1_1(PDFHostMsg_PDFModalPromptForPassword, + std::string /* prompt */, + std::string /* actual_value */) diff --git a/components/pdf/renderer/BUILD.gn b/components/pdf/renderer/BUILD.gn new file mode 100644 index 0000000..e2cfaeb --- /dev/null +++ b/components/pdf/renderer/BUILD.gn @@ -0,0 +1,28 @@ +# 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. + +import("//build/config/features.gni") + +static_library("renderer") { + sources = [ + "ppb_pdf_impl.cc", + "ppb_pdf_impl.h", + ] + + deps = [ + "//base", + "//components/pdf/common", + "//content/public/renderer", + "//ppapi:ppapi_shared", + "//third_party/icu", + "//v8", + "//third_party/WebKit/public:blink_minimal", + ] + + if (is_win) { + cflags += [ + "/wd4267" # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. + ] + } +} diff --git a/components/pdf/renderer/OWNERS b/components/pdf/renderer/OWNERS new file mode 100644 index 0000000..d998f46 --- /dev/null +++ b/components/pdf/renderer/OWNERS @@ -0,0 +1,5 @@ +per-file ppb_pdf_impl.*=bbudge@chromium.org +per-file ppb_pdf_impl.*=dmichael@chromium.org +per-file ppb_pdf_impl.*=raymes@chromium.org +per-file ppb_pdf_impl.*=teravest@chromium.org +per-file ppb_pdf_impl.*=yzshen@chromium.org diff --git a/components/pdf/renderer/ppb_pdf_impl.cc b/components/pdf/renderer/ppb_pdf_impl.cc new file mode 100644 index 0000000..716ff9a --- /dev/null +++ b/components/pdf/renderer/ppb_pdf_impl.cc @@ -0,0 +1,446 @@ +// Copyright (c) 2012 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/ppb_pdf_impl.h" + +#include "base/files/scoped_file.h" +#include "base/metrics/histogram.h" +#include "base/numerics/safe_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" +#include "components/pdf/common/pdf_messages.h" +#include "content/app/resources/grit/content_resources.h" +#include "content/app/strings/grit/content_strings.h" +#include "content/public/common/child_process_sandbox_support_linux.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 "ppapi/c/pp_resource.h" +#include "ppapi/c/private/ppb_pdf.h" +#include "ppapi/c/trusted/ppb_browser_font_trusted.h" +#include "ppapi/shared_impl/ppapi_globals.h" +#include "ppapi/shared_impl/resource.h" +#include "ppapi/shared_impl/resource_tracker.h" +#include "ppapi/shared_impl/var.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 "third_party/icu/source/i18n/unicode/usearch.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" + +namespace pdf { +namespace { + +PPB_PDF_Impl::PrintClient* g_print_client = NULL; + +#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) +class PrivateFontFile : public ppapi::Resource { + public: + PrivateFontFile(PP_Instance instance, int fd) + : Resource(ppapi::OBJECT_IS_IMPL, instance), fd_(fd) {} + + bool GetFontTable(uint32_t table, void* output, uint32_t* output_length) { + size_t temp_size = static_cast<size_t>(*output_length); + bool rv = content::GetFontTable(fd_.get(), + table, + 0 /* offset */, + static_cast<uint8_t*>(output), + &temp_size); + *output_length = base::checked_cast<uint32_t>(temp_size); + return rv; + } + + protected: + virtual ~PrivateFontFile() {} + + private: + base::ScopedFD fd_; +}; +#endif + +struct ResourceImageInfo { + PP_ResourceImage pp_id; + int res_id; +}; + +static const ResourceImageInfo kResourceImageMap[] = { + {PP_RESOURCEIMAGE_PDF_BUTTON_FTP, IDR_PDF_BUTTON_FTP}, + {PP_RESOURCEIMAGE_PDF_BUTTON_FTP_HOVER, IDR_PDF_BUTTON_FTP_HOVER}, + {PP_RESOURCEIMAGE_PDF_BUTTON_FTP_PRESSED, IDR_PDF_BUTTON_FTP_PRESSED}, + {PP_RESOURCEIMAGE_PDF_BUTTON_FTW, IDR_PDF_BUTTON_FTW}, + {PP_RESOURCEIMAGE_PDF_BUTTON_FTW_HOVER, IDR_PDF_BUTTON_FTW_HOVER}, + {PP_RESOURCEIMAGE_PDF_BUTTON_FTW_PRESSED, IDR_PDF_BUTTON_FTW_PRESSED}, + {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END, IDR_PDF_BUTTON_ZOOMIN_END}, + {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END_HOVER, + IDR_PDF_BUTTON_ZOOMIN_END_HOVER}, + {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END_PRESSED, + IDR_PDF_BUTTON_ZOOMIN_END_PRESSED}, + {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN, IDR_PDF_BUTTON_ZOOMIN}, + {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_HOVER, IDR_PDF_BUTTON_ZOOMIN_HOVER}, + {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_PRESSED, IDR_PDF_BUTTON_ZOOMIN_PRESSED}, + {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT, IDR_PDF_BUTTON_ZOOMOUT}, + {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_HOVER, IDR_PDF_BUTTON_ZOOMOUT_HOVER}, + {PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_PRESSED, + IDR_PDF_BUTTON_ZOOMOUT_PRESSED}, + {PP_RESOURCEIMAGE_PDF_BUTTON_SAVE, IDR_PDF_BUTTON_SAVE}, + {PP_RESOURCEIMAGE_PDF_BUTTON_SAVE_HOVER, IDR_PDF_BUTTON_SAVE_HOVER}, + {PP_RESOURCEIMAGE_PDF_BUTTON_SAVE_PRESSED, IDR_PDF_BUTTON_SAVE_PRESSED}, + {PP_RESOURCEIMAGE_PDF_BUTTON_PRINT, IDR_PDF_BUTTON_PRINT}, + {PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_HOVER, IDR_PDF_BUTTON_PRINT_HOVER}, + {PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_PRESSED, IDR_PDF_BUTTON_PRINT_PRESSED}, + {PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_DISABLED, IDR_PDF_BUTTON_PRINT_DISABLED}, + {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_0, IDR_PDF_THUMBNAIL_0}, + {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_1, IDR_PDF_THUMBNAIL_1}, + {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_2, IDR_PDF_THUMBNAIL_2}, + {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_3, IDR_PDF_THUMBNAIL_3}, + {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_4, IDR_PDF_THUMBNAIL_4}, + {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_5, IDR_PDF_THUMBNAIL_5}, + {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_6, IDR_PDF_THUMBNAIL_6}, + {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_7, IDR_PDF_THUMBNAIL_7}, + {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_8, IDR_PDF_THUMBNAIL_8}, + {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_9, IDR_PDF_THUMBNAIL_9}, + {PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_NUM_BACKGROUND, + IDR_PDF_THUMBNAIL_NUM_BACKGROUND}, + {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_0, IDR_PDF_PROGRESS_BAR_0}, + {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_1, IDR_PDF_PROGRESS_BAR_1}, + {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_2, IDR_PDF_PROGRESS_BAR_2}, + {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_3, IDR_PDF_PROGRESS_BAR_3}, + {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_4, IDR_PDF_PROGRESS_BAR_4}, + {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_5, IDR_PDF_PROGRESS_BAR_5}, + {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_6, IDR_PDF_PROGRESS_BAR_6}, + {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_7, IDR_PDF_PROGRESS_BAR_7}, + {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_8, IDR_PDF_PROGRESS_BAR_8}, + {PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_BACKGROUND, + IDR_PDF_PROGRESS_BAR_BACKGROUND}, + {PP_RESOURCEIMAGE_PDF_PAGE_INDICATOR_BACKGROUND, + IDR_PDF_PAGE_INDICATOR_BACKGROUND}, + {PP_RESOURCEIMAGE_PDF_PAGE_DROPSHADOW, IDR_PDF_PAGE_DROPSHADOW}, + {PP_RESOURCEIMAGE_PDF_PAN_SCROLL_ICON, IDR_PAN_SCROLL_ICON}, +}; + +PP_Var GetLocalizedString(PP_Instance instance_id, + PP_ResourceString string_id) { + content::PepperPluginInstance* instance = + content::PepperPluginInstance::Get(instance_id); + if (!instance) + return PP_MakeUndefined(); + + std::string rv; + if (string_id == PP_RESOURCESTRING_PDFGETPASSWORD) { + rv = base::UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_NEED_PASSWORD)); + } else if (string_id == PP_RESOURCESTRING_PDFLOADING) { + rv = base::UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PAGE_LOADING)); + } else if (string_id == PP_RESOURCESTRING_PDFLOAD_FAILED) { + rv = base::UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PAGE_LOAD_FAILED)); + } else if (string_id == PP_RESOURCESTRING_PDFPROGRESSLOADING) { + rv = base::UTF16ToUTF8(l10n_util::GetStringUTF16(IDS_PDF_PROGRESS_LOADING)); + } else { + NOTREACHED(); + } + + return ppapi::StringVar::StringToPPVar(rv); +} + +PP_Resource GetFontFileWithFallback( + PP_Instance instance_id, + const PP_BrowserFont_Trusted_Description* description, + PP_PrivateFontCharset charset) { +#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) + // Validate the instance before using it below. + if (!content::PepperPluginInstance::Get(instance_id)) + return 0; + + scoped_refptr<ppapi::StringVar> face_name( + ppapi::StringVar::FromPPVar(description->face)); + if (!face_name) + return 0; + + int fd = content::MatchFontWithFallback( + face_name->value().c_str(), + description->weight >= PP_BROWSERFONT_TRUSTED_WEIGHT_BOLD, + description->italic, + charset, + description->family); + if (fd == -1) + return 0; + + scoped_refptr<PrivateFontFile> font(new PrivateFontFile(instance_id, fd)); + + return font->GetReference(); +#else + // For trusted PPAPI plugins, this is only needed in Linux since font loading + // on Windows and Mac works through the renderer sandbox. + return 0; +#endif +} + +bool GetFontTableForPrivateFontFile(PP_Resource font_file, + uint32_t table, + void* output, + uint32_t* output_length) { +#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) + ppapi::Resource* resource = + ppapi::PpapiGlobals::Get()->GetResourceTracker()->GetResource(font_file); + if (!resource) + return false; + + PrivateFontFile* font = static_cast<PrivateFontFile*>(resource); + return font->GetFontTable(table, output, output_length); +#else + return false; +#endif +} + +void SearchString(PP_Instance instance, + const unsigned short* input_string, + const unsigned short* input_term, + bool case_sensitive, + PP_PrivateFindResult** results, + int* count) { + const base::char16* string = + reinterpret_cast<const base::char16*>(input_string); + const base::char16* term = reinterpret_cast<const base::char16*>(input_term); + + UErrorCode status = U_ZERO_ERROR; + UStringSearch* searcher = + usearch_open(term, + -1, + string, + -1, + content::RenderThread::Get()->GetLocale().c_str(), + 0, + &status); + DCHECK(status == U_ZERO_ERROR || status == U_USING_FALLBACK_WARNING || + status == U_USING_DEFAULT_WARNING); + UCollationStrength strength = case_sensitive ? UCOL_TERTIARY : UCOL_PRIMARY; + + UCollator* collator = usearch_getCollator(searcher); + if (ucol_getStrength(collator) != strength) { + ucol_setStrength(collator, strength); + usearch_reset(searcher); + } + + status = U_ZERO_ERROR; + int match_start = usearch_first(searcher, &status); + DCHECK(status == U_ZERO_ERROR); + + std::vector<PP_PrivateFindResult> pp_results; + while (match_start != USEARCH_DONE) { + size_t matched_length = usearch_getMatchedLength(searcher); + PP_PrivateFindResult result; + result.start_index = match_start; + result.length = matched_length; + pp_results.push_back(result); + match_start = usearch_next(searcher, &status); + DCHECK(status == U_ZERO_ERROR); + } + + *count = pp_results.size(); + if (*count) { + *results = reinterpret_cast<PP_PrivateFindResult*>( + malloc(*count * sizeof(PP_PrivateFindResult))); + memcpy(*results, &pp_results[0], *count * sizeof(PP_PrivateFindResult)); + } else { + *results = NULL; + } + + usearch_close(searcher); +} + +void DidStartLoading(PP_Instance instance_id) { + content::PepperPluginInstance* instance = + content::PepperPluginInstance::Get(instance_id); + if (!instance) + return; + instance->GetRenderView()->DidStartLoading(); +} + +void DidStopLoading(PP_Instance instance_id) { + content::PepperPluginInstance* instance = + content::PepperPluginInstance::Get(instance_id); + if (!instance) + return; + instance->GetRenderView()->DidStopLoading(); +} + +void SetContentRestriction(PP_Instance instance_id, int restrictions) { + content::PepperPluginInstance* instance = + content::PepperPluginInstance::Get(instance_id); + if (!instance) + return; + instance->GetRenderView()->Send(new PDFHostMsg_PDFUpdateContentRestrictions( + instance->GetRenderView()->GetRoutingID(), restrictions)); +} + +void HistogramPDFPageCount(PP_Instance instance, int count) { + UMA_HISTOGRAM_COUNTS_10000("PDF.PageCount", count); +} + +void UserMetricsRecordAction(PP_Instance instance, PP_Var action) { + scoped_refptr<ppapi::StringVar> action_str( + ppapi::StringVar::FromPPVar(action)); + if (action_str) + content::RenderThread::Get()->RecordComputedAction(action_str->value()); +} + +void HasUnsupportedFeature(PP_Instance instance_id) { + content::PepperPluginInstance* instance = + content::PepperPluginInstance::Get(instance_id); + if (!instance) + return; + + // Only want to show an info bar if the pdf is the whole tab. + if (!instance->IsFullPagePlugin()) + return; + + 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())); +} + +void SaveAs(PP_Instance instance_id) { + content::PepperPluginInstance* instance = + content::PepperPluginInstance::Get(instance_id); + if (!instance) + return; + GURL url = instance->GetPluginURL(); + + content::RenderView* render_view = instance->GetRenderView(); + blink::WebLocalFrame* frame = + render_view->GetWebView()->mainFrame()->toWebLocalFrame(); + content::Referrer referrer(frame->document().url(), + frame->document().referrerPolicy()); + render_view->Send( + new PDFHostMsg_PDFSaveURLAs(render_view->GetRoutingID(), url, referrer)); +} + +PP_Bool IsFeatureEnabled(PP_Instance instance, PP_PDFFeature feature) { + switch (feature) { + case PP_PDFFEATURE_HIDPI: + return PP_TRUE; + case PP_PDFFEATURE_PRINTING: + return (g_print_client && g_print_client->IsPrintingEnabled(instance)) + ? PP_TRUE + : PP_FALSE; + } + return PP_FALSE; +} + +PP_Resource GetResourceImageForScale(PP_Instance instance_id, + PP_ResourceImage image_id, + float scale) { + int res_id = 0; + for (size_t i = 0; i < arraysize(kResourceImageMap); ++i) { + if (kResourceImageMap[i].pp_id == image_id) { + res_id = kResourceImageMap[i].res_id; + break; + } + } + if (res_id == 0) + return 0; + + // Validate the instance. + content::PepperPluginInstance* instance = + content::PepperPluginInstance::Get(instance_id); + if (!instance) + return 0; + + gfx::ImageSkia* res_image_skia = + ResourceBundle::GetSharedInstance().GetImageSkiaNamed(res_id); + + if (!res_image_skia) + return 0; + + return instance->CreateImage(res_image_skia, scale); +} + +PP_Resource GetResourceImage(PP_Instance instance_id, + PP_ResourceImage image_id) { + return GetResourceImageForScale(instance_id, image_id, 1.0f); +} + +PP_Var ModalPromptForPassword(PP_Instance instance_id, PP_Var message) { + content::PepperPluginInstance* instance = + content::PepperPluginInstance::Get(instance_id); + if (!instance) + return PP_MakeUndefined(); + + std::string actual_value; + scoped_refptr<ppapi::StringVar> message_string( + ppapi::StringVar::FromPPVar(message)); + + IPC::SyncMessage* msg = new PDFHostMsg_PDFModalPromptForPassword( + instance->GetRenderView()->GetRoutingID(), + message_string->value(), + &actual_value); + msg->EnableMessagePumping(); + instance->GetRenderView()->Send(msg); + + return ppapi::StringVar::StringToPPVar(actual_value); +} + +PP_Bool IsOutOfProcess(PP_Instance instance_id) { + return PP_FALSE; +} + +void SetSelectedText(PP_Instance instance_id, const char* selected_text) { + // This function is intended for out of process PDF plugin. +} + +void SetLinkUnderCursor(PP_Instance instance_id, const char* url) { + content::PepperPluginInstance* instance = + content::PepperPluginInstance::Get(instance_id); + if (!instance) + return; + instance->SetLinkUnderCursor(url); +} + +const PPB_PDF ppb_pdf = { // + &GetLocalizedString, // + &GetResourceImage, // + &GetFontFileWithFallback, // + &GetFontTableForPrivateFontFile, // + &SearchString, // + &DidStartLoading, // + &DidStopLoading, // + &SetContentRestriction, // + &HistogramPDFPageCount, // + &UserMetricsRecordAction, // + &HasUnsupportedFeature, // + &SaveAs, // + &PPB_PDF_Impl::InvokePrintingForInstance, // + &IsFeatureEnabled, // + &GetResourceImageForScale, // + &ModalPromptForPassword, // + &IsOutOfProcess, // + &SetSelectedText, // + &SetLinkUnderCursor, // +}; + +} // namespace + +// static +const PPB_PDF* PPB_PDF_Impl::GetInterface() { + return &ppb_pdf; +} + +// static +void PPB_PDF_Impl::InvokePrintingForInstance(PP_Instance instance_id) { + if (g_print_client) + g_print_client->Print(instance_id); +} + +void PPB_PDF_Impl::SetPrintClient(PPB_PDF_Impl::PrintClient* client) { + CHECK(!g_print_client) << "There should only be a single PrintClient."; + g_print_client = client; +} + +} // namespace pdf diff --git a/components/pdf/renderer/ppb_pdf_impl.h b/components/pdf/renderer/ppb_pdf_impl.h new file mode 100644 index 0000000..2cd5a44 --- /dev/null +++ b/components/pdf/renderer/ppb_pdf_impl.h @@ -0,0 +1,45 @@ +// 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. + +#ifndef COMPONENT_PDF_RENDERER_PPB_PDF_IMPL_H_ +#define COMPONENT_PDF_RENDERER_PPB_PDF_IMPL_H_ + +#include "ppapi/c/pp_instance.h" + +struct PPB_PDF; + +namespace pdf { + +class PPB_PDF_Impl { + public: + class PrintClient { + public: + virtual ~PrintClient() {} + + // Returns whether printing is enabled for the plugin instance identified by + // |instance_id|. + virtual bool IsPrintingEnabled(PP_Instance instance_id) = 0; + + // Invokes the "Print" command for the plugin instance identified by + // |instance_id|. + virtual void Print(PP_Instance instance_id) = 0; + }; + + // Returns a pointer to the interface implementing PPB_PDF that is exposed + // to the plugin. + static const PPB_PDF* GetInterface(); + + // Invokes the "Print" command for the given instance as if the user right + // clicked on it and selected "Print". + static void InvokePrintingForInstance(PP_Instance instance); + + // The caller retains the ownership of |print_client|. The client is + // allowed to be set only once, and when set, the client must outlive the + // PPB_PDF_Impl instance. + static void SetPrintClient(PrintClient* print_client); +}; + +} // namespace pdf + +#endif // COMPONENT_PDF_RENDERER_PPB_PDF_IMPL_H_ |