Commit 87a3217a authored by thestig's avatar thestig Committed by Commit bot

Enable PDF plugin for iframes within the print preview dialog.

BUG=465495

Review URL: https://codereview.chromium.org/1022673002

Cr-Commit-Position: refs/heads/master@{#321295}
parent 1ebbc90c
......@@ -14,7 +14,6 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
#include "chrome/browser/printing/print_view_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
......@@ -24,7 +23,6 @@
#include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
#include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/url_constants.h"
#include "components/web_modal/web_contents_modal_dialog_host.h"
......@@ -34,13 +32,9 @@
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/webplugininfo.h"
#include "extensions/browser/guest_view/guest_view_base.h"
#include "ui/web_dialogs/web_dialog_delegate.h"
......@@ -50,22 +44,6 @@ using content::WebUIMessageHandler;
namespace {
void EnableInternalPDFPluginForContents(WebContents* preview_dialog) {
// Always enable the internal PDF plugin for the print preview page.
base::FilePath pdf_plugin_path = base::FilePath::FromUTF8Unsafe(
ChromeContentClient::kPDFPluginPath);
content::WebPluginInfo pdf_plugin;
if (!content::PluginService::GetInstance()->GetPluginInfoByPath(
pdf_plugin_path, &pdf_plugin))
return;
ChromePluginServiceFilter::GetInstance()->OverridePluginForFrame(
preview_dialog->GetRenderProcessHost()->GetID(),
preview_dialog->GetMainFrame()->GetRoutingID(),
GURL(), pdf_plugin);
}
// A ui::WebDialogDelegate that specifies the print preview dialog appearance.
class PrintPreviewDialogDelegate : public ui::WebDialogDelegate {
public:
......@@ -391,7 +369,6 @@ WebContents* PrintPreviewDialogController::CreatePrintPreviewDialog(
GURL print_url(chrome::kChromeUIPrintURL);
content::HostZoomMap::Get(preview_dialog->GetSiteInstance())
->SetZoomLevelForHostAndScheme(print_url.scheme(), print_url.host(), 0);
EnableInternalPDFPluginForContents(preview_dialog);
PrintViewManager::CreateForWebContents(preview_dialog);
extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
preview_dialog);
......
......@@ -2,16 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/bind_helpers.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
#include "chrome/browser/plugins/plugin_prefs.h"
#include "chrome/browser/printing/print_preview_dialog_controller.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/printing/common/print_messages.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/test/browser_test_utils.h"
#include "ipc/ipc_message_macros.h"
......@@ -20,6 +28,8 @@
using content::WebContents;
using content::WebContentsObserver;
namespace {
class RequestPrintPreviewObserver : public WebContentsObserver {
public:
explicit RequestPrintPreviewObserver(WebContents* dialog)
......@@ -95,6 +105,42 @@ class PrintPreviewDialogDestroyedObserver : public WebContentsObserver {
DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogDestroyedObserver);
};
void PluginsLoadedCallback(
const base::Closure& quit_closure,
const std::vector<content::WebPluginInfo>& /* info */) {
quit_closure.Run();
}
bool GetPdfPluginInfo(content::WebPluginInfo* info) {
base::FilePath pdf_plugin_path = base::FilePath::FromUTF8Unsafe(
ChromeContentClient::kPDFPluginPath);
return content::PluginService::GetInstance()->GetPluginInfoByPath(
pdf_plugin_path, info);
}
const char kDummyPrintUrl[] = "chrome://print/dummy.pdf";
void CountFrames(int* frame_count,
content::RenderFrameHost* frame) {
++(*frame_count);
}
void CheckPdfPluginForRenderFrame(content::RenderFrameHost* frame) {
content::WebPluginInfo pdf_plugin_info;
ASSERT_TRUE(GetPdfPluginInfo(&pdf_plugin_info));
ChromePluginServiceFilter* filter = ChromePluginServiceFilter::GetInstance();
EXPECT_TRUE(filter->IsPluginAvailable(
frame->GetProcess()->GetID(),
frame->GetRoutingID(),
nullptr,
GURL(kDummyPrintUrl),
GURL(),
&pdf_plugin_info));
}
} // namespace
class PrintPreviewDialogControllerBrowserTest : public InProcessBrowserTest {
public:
PrintPreviewDialogControllerBrowserTest() : initiator_(NULL) {}
......@@ -134,6 +180,9 @@ class PrintPreviewDialogControllerBrowserTest : public InProcessBrowserTest {
initiator_ = browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(initiator_);
ASSERT_NE(first_tab, initiator_);
content::PluginService::GetInstance()->Init();
content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
}
void TearDownOnMainThread() override {
......@@ -161,7 +210,7 @@ class PrintPreviewDialogControllerBrowserTest : public InProcessBrowserTest {
#endif
IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest,
MAYBE_NavigateFromInitiatorTab) {
// print for the first time.
// Print for the first time.
PrintPreview();
// Get the preview dialog for the initiator tab.
......@@ -197,7 +246,7 @@ IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest,
#endif
IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest,
MAYBE_ReloadInitiatorTab) {
// print for the first time.
// Print for the first time.
PrintPreview();
WebContents* preview_dialog = GetPrintPreviewDialog();
......@@ -221,3 +270,60 @@ IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest,
WebContents* new_preview_dialog = GetPrintPreviewDialog();
EXPECT_TRUE(new_preview_dialog);
}
// Test to verify that after print preview works even when the PDF plugin is
// disabled for webpages.
IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest,
PdfPluginDisabled) {
// Make sure plugins are loaded.
{
base::RunLoop run_loop;
content::PluginService::GetInstance()->GetPlugins(
base::Bind(&PluginsLoadedCallback, run_loop.QuitClosure()));
run_loop.Run();
}
// Get the PDF plugin info.
content::WebPluginInfo pdf_plugin_info;
ASSERT_TRUE(GetPdfPluginInfo(&pdf_plugin_info));
// Disable the PDF plugin.
PluginPrefs::GetForProfile(browser()->profile())->EnablePluginGroup(
false, base::ASCIIToUTF16(ChromeContentClient::kPDFPluginName));
// Make sure it is actually disabled for webpages.
ChromePluginServiceFilter* filter = ChromePluginServiceFilter::GetInstance();
content::WebPluginInfo dummy_pdf_plugin_info = pdf_plugin_info;
EXPECT_FALSE(filter->IsPluginAvailable(
initiator()->GetRenderProcessHost()->GetID(),
initiator()->GetMainFrame()->GetRoutingID(),
nullptr,
GURL("http://google.com"),
GURL(),
&dummy_pdf_plugin_info));
PrintPreview();
// Check a new print preview dialog got created.
WebContents* preview_dialog = GetPrintPreviewDialog();
ASSERT_TRUE(preview_dialog);
ASSERT_NE(initiator(), preview_dialog);
// Wait until the <iframe> in the print preview renderer has loaded.
// |frame_count| should be 2. The other frame is the main frame.
const int kExpectedFrameCount = 2;
int frame_count;
do {
base::RunLoop run_loop;
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromSeconds(1));
run_loop.Run();
frame_count = 0;
preview_dialog->ForEachFrame(
base::Bind(&CountFrames, base::Unretained(&frame_count)));
} while (frame_count < kExpectedFrameCount);
ASSERT_EQ(kExpectedFrameCount, frame_count);
// Make sure all the frames in the dialog has access to the PDF plugin.
preview_dialog->ForEachFrame(base::Bind(&CheckPdfPluginForRenderFrame));
}
......@@ -10,13 +10,19 @@
#include "base/lazy_instance.h"
#include "base/metrics/histogram.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/print_preview_dialog_controller.h"
#include "chrome/browser/printing/print_view_manager_observer.h"
#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
#include "chrome/common/chrome_content_client.h"
#include "components/printing/common/print_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/webplugininfo.h"
using content::BrowserThread;
......@@ -31,6 +37,22 @@ typedef std::map<content::RenderProcessHost*, base::Closure>
static base::LazyInstance<ScriptedPrintPreviewClosureMap>
g_scripted_print_preview_closure_map = LAZY_INSTANCE_INITIALIZER;
void EnableInternalPDFPluginForContents(int render_process_id,
int render_frame_id) {
// Always enable the internal PDF plugin for the print preview page.
base::FilePath pdf_plugin_path = base::FilePath::FromUTF8Unsafe(
ChromeContentClient::kPDFPluginPath);
content::WebPluginInfo pdf_plugin;
if (!content::PluginService::GetInstance()->GetPluginInfoByPath(
pdf_plugin_path, &pdf_plugin)) {
return;
}
ChromePluginServiceFilter::GetInstance()->OverridePluginForFrame(
render_process_id, render_frame_id, GURL(), pdf_plugin);
}
} // namespace
namespace printing {
......@@ -40,6 +62,11 @@ PrintViewManager::PrintViewManager(content::WebContents* web_contents)
observer_(NULL),
print_preview_state_(NOT_PREVIEWING),
scripted_print_preview_rph_(NULL) {
if (PrintPreviewDialogController::IsPrintPreviewDialog(web_contents)) {
EnableInternalPDFPluginForContents(
web_contents->GetRenderProcessHost()->GetID(),
web_contents->GetMainFrame()->GetRoutingID());
}
}
PrintViewManager::~PrintViewManager() {
......@@ -70,6 +97,7 @@ bool PrintViewManager::BasicPrint() {
}
}
#endif // ENABLE_BASIC_PRINTING
bool PrintViewManager::PrintPreviewNow(bool selection_only) {
// Users can send print commands all they want and it is beyond
// PrintViewManager's control. Just ignore the extra commands.
......@@ -114,6 +142,14 @@ void PrintViewManager::set_observer(PrintViewManagerObserver* observer) {
observer_ = observer;
}
void PrintViewManager::RenderFrameCreated(
content::RenderFrameHost* render_frame_host) {
if (PrintPreviewDialogController::IsPrintPreviewDialog(web_contents())) {
EnableInternalPDFPluginForContents(render_frame_host->GetProcess()->GetID(),
render_frame_host->GetRoutingID());
}
}
void PrintViewManager::RenderProcessGone(base::TerminationStatus status) {
print_preview_state_ = NOT_PREVIEWING;
PrintViewManagerBase::RenderProcessGone(status);
......
......@@ -55,6 +55,9 @@ class PrintViewManager : public PrintViewManagerBase,
// content::WebContentsObserver implementation.
bool OnMessageReceived(const IPC::Message& message) override;
// content::WebContentsObserver implementation.
void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
// content::WebContentsObserver implementation.
// Terminates or cancels the print job if one was pending.
void RenderProcessGone(base::TerminationStatus status) override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment