Commit 5c0b4d1a authored by Wei Li's avatar Wei Li Committed by Commit Bot

Use OOPIF printing for extension/app pages

Some extension/app pages are hosted by guest views, which means they
have nested web contents. This CL checks nested web contents and always
use the outer contents to handle print requests so the entire content
can be printed correctly.

BUG=819583, 447941

Change-Id: I6b45f4867d13cf5141476a7e748e8c0e5d3b0996
Reviewed-on: https://chromium-review.googlesource.com/969949
Commit-Queue: Wei Li <weili@chromium.org>
Reviewed-by: default avatarAlex Moshchuk <alexmos@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#545077}
parent dd2d3501
......@@ -5,13 +5,19 @@
#include <memory>
#include "base/auto_reset.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/printing/print_view_manager_common.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/webui_url_constants.cc"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/prefs/pref_service.h"
......@@ -23,9 +29,14 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "extensions/common/extension.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#if defined(OS_CHROMEOS)
#include "ui/aura/env.h"
#endif
namespace printing {
namespace {
......@@ -231,6 +242,51 @@ class IsolateOriginsPrintBrowserTest : public PrintBrowserTest {
constexpr char IsolateOriginsPrintBrowserTest::kIsolatedSite[];
class PrintExtensionBrowserTest : public ExtensionBrowserTest {
public:
PrintExtensionBrowserTest() {}
~PrintExtensionBrowserTest() override {}
void PrintAndWaitUntilPreviewIsReady(bool print_only_selection) {
PrintPreviewObserver print_preview_observer;
printing::StartPrint(browser()->tab_strip_model()->GetActiveWebContents(),
/*print_preview_disabled=*/false,
print_only_selection);
print_preview_observer.WaitUntilPreviewIsReady();
}
void LoadExtensionAndNavigateToOptionPage() {
const extensions::Extension* extension = nullptr;
{
base::ScopedAllowBlockingForTesting allow_blocking;
base::FilePath test_data_dir;
PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
extension = LoadExtension(
test_data_dir.AppendASCII("printing").AppendASCII("test_extension"));
ASSERT_TRUE(extension);
}
GURL url(chrome::kChromeUIExtensionsURL);
std::string query =
base::StringPrintf("options=%s", extension->id().c_str());
GURL::Replacements replacements;
replacements.SetQueryStr(query);
url = url.ReplaceComponents(replacements);
ui_test_utils::NavigateToURL(browser(), url);
}
};
class SitePerProcessPrintExtensionBrowserTest
: public PrintExtensionBrowserTest {
public:
// content::BrowserTestBase
void SetUpCommandLine(base::CommandLine* command_line) override {
content::IsolateAllSitesForTesting(command_line);
}
};
// Printing only a selection containing iframes is partially supported.
// Iframes aren't currently displayed. This test passes whenever the print
// preview is rendered (i.e. no timeout in the test).
......@@ -493,4 +549,31 @@ IN_PROC_BROWSER_TEST_F(IsolateOriginsPrintBrowserTest, OopifPrinting) {
EXPECT_TRUE(IsOopifEnabled());
}
// Printing an extension option page.
// The test should not crash or timeout.
IN_PROC_BROWSER_TEST_F(PrintExtensionBrowserTest, PrintOptionPage) {
#if defined(OS_CHROMEOS)
// Mus can not support this test now https://crbug.com/823782.
if (aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS)
return;
#endif
LoadExtensionAndNavigateToOptionPage();
PrintAndWaitUntilPreviewIsReady(/*print_only_selection=*/false);
}
// Printing an extension option page with site per process is enabled.
// The test should not crash or timeout.
IN_PROC_BROWSER_TEST_F(SitePerProcessPrintExtensionBrowserTest,
PrintOptionPage) {
#if defined(OS_CHROMEOS)
// Mus can not support this test now https://crbug.com/823782.
if (aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS)
return;
#endif
LoadExtensionAndNavigateToOptionPage();
PrintAndWaitUntilPreviewIsReady(/*print_only_selection=*/false);
}
} // namespace printing
{
"name": "Test Extensions",
"description" : "Base Level Extension",
"version": "1.0",
"manifest_version": 2,
"browser_action": {
"default_popup": "test_extension.html"
},
"options_ui": {
"page": "options.html",
"chrome_style": true
}
}
<html>
<body>
<h2>Test Extension's Option Page</h2>
<p>No content here, for test only.</p>
</body>
</html>
<html>
<body>
<h1>Test Extensions</h1>
</body>
</html>
......@@ -68,6 +68,21 @@ void PrintCompositeClient::OnDidPrintFrameContent(
content::RenderFrameHost* render_frame_host,
int document_cookie,
const PrintHostMsg_DidPrintContent_Params& params) {
auto* outer_contents = web_contents()->GetOuterWebContents();
if (outer_contents) {
// When the printed content belongs to an extension or app page, the print
// composition needs to be handled by its outer content.
// TODO(weili): so far, we don't have printable web contents nested in more
// than one level. In the future, especially after PDF plugin is moved to
// OOPIF-based webview, we should check whether we need to handle web
// contents nested in multiple layers.
auto* outer_client = PrintCompositeClient::FromWebContents(outer_contents);
DCHECK(outer_client);
outer_client->OnDidPrintFrameContent(render_frame_host, document_cookie,
params);
return;
}
// Content in |params| is sent from untrusted source; only minimal processing
// is done here. Most of it will be directly forwarded to pdf compositor
// service.
......
......@@ -4068,6 +4068,16 @@ void WebContentsImpl::PrintCrossProcessSubframe(
const gfx::Rect& rect,
int document_cookie,
RenderFrameHost* subframe_host) {
auto* outer_contents = GetOuterWebContents();
if (outer_contents) {
// When an extension or app page is printed, the content should be
// composited with outer content, so the outer contents should handle the
// print request.
outer_contents->PrintCrossProcessSubframe(rect, document_cookie,
subframe_host);
return;
}
// If there is no delegate such as in tests or during deletion, do nothing.
if (!delegate_)
return;
......
......@@ -170,11 +170,6 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// TODO(creis): Remove this now that we can get to it via FrameTreeNode.
RenderFrameHostManager* GetRenderManagerForTesting();
// Returns the outer WebContents of this WebContents if any.
// Note that without --site-per-process, this will return the WebContents
// of the BrowserPluginEmbedder, if |this| is a guest.
WebContentsImpl* GetOuterWebContents();
// Returns guest browser plugin object, or NULL if this WebContents is not a
// guest.
BrowserPluginGuest* GetBrowserPluginGuest() const;
......@@ -373,7 +368,9 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void AttachToOuterWebContentsFrame(
WebContents* outer_web_contents,
RenderFrameHost* outer_contents_frame) override;
WebContentsImpl* GetOuterWebContents() override;
void DidChangeVisibleSecurityState() override;
void Stop() override;
void FreezePage() override;
WebContents* Clone() override;
......
......@@ -474,6 +474,10 @@ class WebContents : public PageNavigator,
WebContents* outer_web_contents,
RenderFrameHost* outer_contents_frame) = 0;
// Returns the outer WebContents of this WebContents if any.
// Otherwise, return nullptr.
virtual WebContents* GetOuterWebContents() = 0;
// Invoked when visible security state changes.
virtual void DidChangeVisibleSecurityState() = 0;
......
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