summaryrefslogtreecommitdiffstats
path: root/components/pdf
diff options
context:
space:
mode:
authorSadrul Habib Chowdhury <sadrul@chromium.org>2014-08-27 23:50:36 -0400
committerSadrul Habib Chowdhury <sadrul@chromium.org>2014-08-28 03:51:28 +0000
commit2f8807f697e2c043c857ec37c43d45573d239d8f (patch)
tree3e067a88970845d20d703c94d8ca7afbdc1445e9 /components/pdf
parent99492bedc3bd5ac3a26b12fbf7599a55086a998e (diff)
downloadchromium_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/DEPS10
-rw-r--r--components/pdf/OWNERS4
-rw-r--r--components/pdf/README4
-rw-r--r--components/pdf/browser/BUILD.gn19
-rw-r--r--components/pdf/browser/open_pdf_in_reader_prompt_client.h36
-rw-r--r--components/pdf/browser/pdf_web_contents_helper.cc107
-rw-r--r--components/pdf/browser/pdf_web_contents_helper.h74
-rw-r--r--components/pdf/browser/pdf_web_contents_helper_client.h43
-rw-r--r--components/pdf/common/BUILD.gn20
-rw-r--r--components/pdf/common/OWNERS11
-rw-r--r--components/pdf/common/pdf_message_generator.cc33
-rw-r--r--components/pdf/common/pdf_message_generator.h7
-rw-r--r--components/pdf/common/pdf_messages.h31
-rw-r--r--components/pdf/renderer/BUILD.gn28
-rw-r--r--components/pdf/renderer/OWNERS5
-rw-r--r--components/pdf/renderer/ppb_pdf_impl.cc446
-rw-r--r--components/pdf/renderer/ppb_pdf_impl.h45
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_