Commit 5fdbf6eb authored by Tommy C. Li's avatar Tommy C. Li Committed by Commit Bot

Click to Open PDF: Improve first-time IFRAME throttle behavior

Currently, the IFRAME throttle doesn't always work on first-time use,
when the Chrome process is first started. This is because the IFRAME
throttle itself doesn't trigger the plugin list load.

This CL updates the throttle to also trigger the plugin list load
itself (only if it hasn't been loaded already), and should make the
behavior less flaky.

Bug: 924823
Change-Id: If51e85bf2d7005af1a5a825279388dd6d9324409
Reviewed-on: https://chromium-review.googlesource.com/c/1452771
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Reviewed-by: default avatarCamille Lamy <clamy@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#629878}
parent 925b15c3
......@@ -387,7 +387,7 @@ TEST_F(DataReductionProxyChromeSettingsTest, CreateDataBasic) {
scoped_refptr<net::HttpResponseHeaders> headers =
new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
raw_headers.c_str(), raw_headers.size()));
handle.set_response_headers(headers.get());
handle.set_response_headers(headers);
auto data = drp_chrome_settings_->CreateDataFromNavigationHandle(
&handle, headers.get());
......@@ -406,7 +406,7 @@ TEST_F(DataReductionProxyChromeSettingsTest, CreateDataUsedDataReductionProxy) {
scoped_refptr<net::HttpResponseHeaders> headers =
new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
raw_headers.c_str(), raw_headers.size()));
handle.set_response_headers(headers.get());
handle.set_response_headers(headers);
auto data = drp_chrome_settings_->CreateDataFromNavigationHandle(
&handle, headers.get());
......@@ -421,7 +421,7 @@ TEST_F(DataReductionProxyChromeSettingsTest, CreateDataCachedResponse) {
scoped_refptr<net::HttpResponseHeaders> headers =
new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
raw_headers.c_str(), raw_headers.size()));
handle.set_response_headers(headers.get());
handle.set_response_headers(headers);
handle.set_was_response_cached(true);
auto data = drp_chrome_settings_->CreateDataFromNavigationHandle(
&handle, headers.get());
......@@ -435,7 +435,7 @@ TEST_F(DataReductionProxyChromeSettingsTest, CreateHTTPSDataCachedResponse) {
scoped_refptr<net::HttpResponseHeaders> headers =
new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
raw_headers.c_str(), raw_headers.size()));
handle.set_response_headers(headers.get());
handle.set_response_headers(headers);
handle.set_was_response_cached(true);
auto data = drp_chrome_settings_->CreateDataFromNavigationHandle(
&handle, headers.get());
......@@ -452,7 +452,7 @@ TEST_F(DataReductionProxyChromeSettingsTest,
scoped_refptr<net::HttpResponseHeaders> headers =
new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
raw_headers.c_str(), raw_headers.size()));
handle.set_response_headers(headers.get());
handle.set_response_headers(headers);
handle.set_was_response_cached(true);
auto data = drp_chrome_settings_->CreateDataFromNavigationHandle(
&handle, headers.get());
......@@ -468,7 +468,7 @@ TEST_F(DataReductionProxyChromeSettingsTest, CreateDataWithLitePage) {
scoped_refptr<net::HttpResponseHeaders> headers =
new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
raw_headers.c_str(), raw_headers.size()));
handle.set_response_headers(headers.get());
handle.set_response_headers(headers);
auto data = drp_chrome_settings_->CreateDataFromNavigationHandle(
&handle, headers.get());
......@@ -485,7 +485,7 @@ TEST_F(DataReductionProxyChromeSettingsTest, CreateDataWithLofiPolicyReceived) {
scoped_refptr<net::HttpResponseHeaders> headers =
new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
raw_headers.c_str(), raw_headers.size()));
handle.set_response_headers(headers.get());
handle.set_response_headers(headers);
auto data = drp_chrome_settings_->CreateDataFromNavigationHandle(
&handle, headers.get());
......@@ -502,7 +502,7 @@ TEST_F(DataReductionProxyChromeSettingsTest, CreateDataWithLofiReceived) {
scoped_refptr<net::HttpResponseHeaders> headers =
new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
raw_headers.c_str(), raw_headers.size()));
handle.set_response_headers(headers.get());
handle.set_response_headers(headers);
auto data = drp_chrome_settings_->CreateDataFromNavigationHandle(
&handle, headers.get());
......
......@@ -487,20 +487,6 @@ class PDFPluginDisabledTest : public PDFExtensionTest {
content::BrowserContext::GetDownloadManager(browser_context);
download_awaiter_ = std::make_unique<DownloadAwaiter>();
download_manager->AddObserver(download_awaiter_.get());
// TODO(tommycli): PDFIFrameNavigationThrottle currently doesn't wait for
// the plugin list to be loaded, and this causes some unpredictable (but not
// catastrophic) behavior on startup. Remove this after we fix that.
base::RunLoop run_loop;
content::PluginService::GetInstance()->GetPlugins(base::BindOnce(
&PDFPluginDisabledTest::PluginsLoadedCallback, run_loop.QuitClosure()));
run_loop.Run();
}
static void PluginsLoadedCallback(
base::OnceClosure callback,
const std::vector<content::WebPluginInfo>& plugins) {
std::move(callback).Run();
}
void TearDownOnMainThread() override {
......
......@@ -9,7 +9,6 @@
#include "base/feature_list.h"
#include "base/memory/weak_ptr.h"
#include "base/task/post_task.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pdf_util.h"
#include "content/public/browser/browser_context.h"
......@@ -23,7 +22,6 @@
#include "content/public/browser/web_contents_user_data.h"
#include "net/base/escape.h"
#include "net/http/http_response_headers.h"
#include "ppapi/buildflags/buildflags.h"
#if BUILDFLAG(ENABLE_PLUGINS)
#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
......@@ -58,6 +56,26 @@ class PdfWebContentsLifetimeHelper
WEB_CONTENTS_USER_DATA_KEY_IMPL(PdfWebContentsLifetimeHelper)
#if BUILDFLAG(ENABLE_PLUGINS)
// Returns true if the PDF plugin for |navigation_handle| is enabled. Optionally
// also sets |is_stale| to true if the plugin list needs a reload.
bool IsPDFPluginEnabled(content::NavigationHandle* navigation_handle,
bool* is_stale) {
content::WebContents* web_contents = navigation_handle->GetWebContents();
int process_id = web_contents->GetMainFrame()->GetProcess()->GetID();
int routing_id = web_contents->GetMainFrame()->GetRoutingID();
content::ResourceContext* resource_context =
web_contents->GetBrowserContext()->GetResourceContext();
content::WebPluginInfo plugin_info;
return content::PluginService::GetInstance()->GetPluginInfo(
process_id, routing_id, resource_context, navigation_handle->GetURL(),
web_contents->GetMainFrame()->GetLastCommittedOrigin(), kPDFMimeType,
false /* allow_wildcard */, is_stale, &plugin_info,
nullptr /* actual_mime_type */);
}
#endif
} // namespace
PDFIFrameNavigationThrottle::PDFIFrameNavigationThrottle(
......@@ -77,28 +95,6 @@ PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(
if (handle->IsInMainFrame())
return nullptr;
#if BUILDFLAG(ENABLE_PLUGINS)
content::WebPluginInfo pdf_plugin_info;
static const base::FilePath pdf_plugin_path(
ChromeContentClient::kPDFPluginPath);
content::PluginService::GetInstance()->GetPluginInfoByPath(pdf_plugin_path,
&pdf_plugin_info);
ChromePluginServiceFilter* filter = ChromePluginServiceFilter::GetInstance();
int process_id =
handle->GetWebContents()->GetMainFrame()->GetProcess()->GetID();
int routing_id = handle->GetWebContents()->GetMainFrame()->GetRoutingID();
content::ResourceContext* resource_context =
handle->GetWebContents()->GetBrowserContext()->GetResourceContext();
if (filter->IsPluginAvailable(process_id, routing_id, resource_context,
handle->GetURL(), url::Origin(),
&pdf_plugin_info)) {
return nullptr;
}
#endif
// If ENABLE_PLUGINS is false, the PDF plugin is not available, so we should
// always intercept PDF iframe navigations.
return std::make_unique<PDFIFrameNavigationThrottle>(handle);
}
......@@ -126,6 +122,41 @@ PDFIFrameNavigationThrottle::WillProcessResponse() {
if (!base::FeatureList::IsEnabled(features::kClickToOpenPDFPlaceholder))
return content::NavigationThrottle::PROCEED;
#if BUILDFLAG(ENABLE_PLUGINS)
bool is_stale = false;
bool pdf_plugin_enabled = IsPDFPluginEnabled(navigation_handle(), &is_stale);
if (is_stale) {
// On browser start, the plugin list may not be ready yet.
content::PluginService::GetInstance()->GetPlugins(
base::BindOnce(&PDFIFrameNavigationThrottle::OnPluginsLoaded,
weak_factory_.GetWeakPtr()));
return content::NavigationThrottle::DEFER;
}
// If the plugin was found, proceed on the navigation. Otherwise fall through
// to the placeholder case.
if (pdf_plugin_enabled)
return content::NavigationThrottle::PROCEED;
#endif
LoadPlaceholderHTML();
return content::NavigationThrottle::CANCEL_AND_IGNORE;
}
#if BUILDFLAG(ENABLE_PLUGINS)
void PDFIFrameNavigationThrottle::OnPluginsLoaded(
const std::vector<content::WebPluginInfo>& plugins) {
if (IsPDFPluginEnabled(navigation_handle(), nullptr /* is_stale */)) {
Resume();
} else {
LoadPlaceholderHTML();
CancelDeferredNavigation(content::NavigationThrottle::CANCEL_AND_IGNORE);
}
}
#endif
void PDFIFrameNavigationThrottle::LoadPlaceholderHTML() {
// Prepare the params to navigate to the placeholder.
std::string html = GetPDFPlaceholderHTML(navigation_handle()->GetURL());
GURL data_url("data:text/html," + net::EscapePath(html));
......@@ -148,6 +179,4 @@ PDFIFrameNavigationThrottle::WillProcessResponse() {
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&PdfWebContentsLifetimeHelper::NavigateIFrameToPlaceholder,
helper->GetWeakPtr(), params));
return content::NavigationThrottle::CANCEL_AND_IGNORE;
}
......@@ -6,12 +6,16 @@
#define CHROME_BROWSER_PLUGINS_PDF_IFRAME_NAVIGATION_THROTTLE_H_
#include <memory>
#include <vector>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/navigation_throttle.h"
#include "ppapi/buildflags/buildflags.h"
namespace content {
class NavigationHandle;
struct WebPluginInfo;
} // namespace content
class PDFIFrameNavigationThrottle : public content::NavigationThrottle {
......@@ -25,6 +29,17 @@ class PDFIFrameNavigationThrottle : public content::NavigationThrottle {
// content::NavigationThrottle:
ThrottleCheckResult WillProcessResponse() override;
const char* GetNameForLogging() override;
private:
#if BUILDFLAG(ENABLE_PLUGINS)
// Callback to check on the PDF plugin status after loading the plugin list.
void OnPluginsLoaded(const std::vector<content::WebPluginInfo>& plugins);
#endif
// Loads the placeholder HTML into the IFRAME.
void LoadPlaceholderHTML();
base::WeakPtrFactory<PDFIFrameNavigationThrottle> weak_factory_{this};
};
#endif // CHROME_BROWSER_PLUGINS_PDF_IFRAME_NAVIGATION_THROTTLE_H_
......@@ -6,8 +6,12 @@
#include "base/bind.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pdf_util.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/mock_navigation_handle.h"
......@@ -21,16 +25,8 @@
namespace {
const char kHeader[] = "HTTP/1.1 200 OK\r\n";
const char kExampleURL[] = "http://example.com";
#if BUILDFLAG(ENABLE_PLUGINS)
void PluginsLoadedCallback(base::OnceClosure callback,
const std::vector<content::WebPluginInfo>& plugins) {
std::move(callback).Run();
}
#endif
} // namespace
class PDFIFrameNavigationThrottleTest : public ChromeRenderViewHostTestHarness {
......@@ -45,10 +41,15 @@ class PDFIFrameNavigationThrottleTest : public ChromeRenderViewHostTestHarness {
#endif
}
std::string GetHeaderWithMimeType(const std::string& mime_type) {
return "HTTP/1.1 200 OK\r\n"
"content-type: " +
mime_type + "\r\n";
scoped_refptr<net::HttpResponseHeaders> GetHeaderWithMimeType(
const std::string& mime_type) {
std::string raw_response_headers =
"HTTP/1.1 200 OK\r\n"
"content-type: " +
mime_type + "\r\n";
return base::MakeRefCounted<net::HttpResponseHeaders>(
net::HttpUtil::AssembleRawHeaders(raw_response_headers.c_str(),
raw_response_headers.size()));
}
content::RenderFrameHost* subframe() { return subframe_; }
......@@ -58,13 +59,21 @@ class PDFIFrameNavigationThrottleTest : public ChromeRenderViewHostTestHarness {
ChromeRenderViewHostTestHarness::SetUp();
#if BUILDFLAG(ENABLE_PLUGINS)
content::PluginService::GetInstance()->Init();
// Load plugins.
base::RunLoop run_loop;
content::PluginService::GetInstance()->GetPlugins(
base::BindOnce(&PluginsLoadedCallback, run_loop.QuitClosure()));
run_loop.Run();
content::PluginService* plugin_service =
content::PluginService::GetInstance();
plugin_service->Init();
plugin_service->SetFilter(ChromePluginServiceFilter::GetInstance());
// Register a fake PDF Viewer plugin into our plugin service.
content::WebPluginInfo info;
info.name =
base::ASCIIToUTF16(ChromeContentClient::kPDFExtensionPluginName);
info.mime_types.push_back(content::WebPluginMimeType(
kPDFMimeType, "pdf", "Fake PDF description"));
plugin_service->RegisterInternalPlugin(info, true);
// Set the plugin list as dirty, like when the browser first starts.
plugin_service->RefreshPlugins();
#endif
content::RenderFrameHostTester::For(main_rfh())
......@@ -84,62 +93,56 @@ TEST_F(PDFIFrameNavigationThrottleTest, OnlyCreateThrottleForSubframes) {
SetAlwaysOpenPdfExternallyForTests(true);
// Never create throttle for main frames.
std::string raw_response_headers =
net::HttpUtil::AssembleRawHeaders(kHeader, strlen(kHeader));
scoped_refptr<net::HttpResponseHeaders> headers =
new net::HttpResponseHeaders(raw_response_headers);
content::MockNavigationHandle handle(GURL(kExampleURL), main_rfh());
handle.set_response_headers(headers.get());
std::unique_ptr<content::NavigationThrottle> throttle =
PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(&handle);
ASSERT_EQ(nullptr, throttle);
handle.set_response_headers(GetHeaderWithMimeType(""));
ASSERT_EQ(nullptr,
PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(&handle));
// Create a throttle for subframes.
handle.set_render_frame_host(subframe());
throttle = PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(&handle);
ASSERT_NE(nullptr, throttle);
ASSERT_NE(nullptr,
PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(&handle));
}
TEST_F(PDFIFrameNavigationThrottleTest, InterceptPDFOnly) {
// Setup
SetAlwaysOpenPdfExternallyForTests(true);
std::string raw_response_headers = GetHeaderWithMimeType("application/pdf");
raw_response_headers = net::HttpUtil::AssembleRawHeaders(
raw_response_headers.c_str(), raw_response_headers.size());
scoped_refptr<net::HttpResponseHeaders> headers =
new net::HttpResponseHeaders(raw_response_headers);
// Load plugins to keep this test synchronous.
#if BUILDFLAG(ENABLE_PLUGINS)
base::RunLoop run_loop;
content::PluginService::GetInstance()->GetPlugins(base::BindRepeating(
[](base::RunLoop* run_loop,
const std::vector<content::WebPluginInfo>& plugins) {
run_loop->Quit();
},
base::Unretained(&run_loop)));
run_loop.Run();
#endif
content::MockNavigationHandle handle(GURL(kExampleURL), subframe());
handle.set_response_headers(headers.get());
handle.set_response_headers(GetHeaderWithMimeType("application/pdf"));
// Verify that we CANCEL for PDF mime type.
std::unique_ptr<content::NavigationThrottle> throttle =
PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(&handle);
ASSERT_NE(nullptr, throttle);
ASSERT_EQ(content::NavigationThrottle::CANCEL_AND_IGNORE,
throttle->WillProcessResponse().action());
// Verify that we PROCEED for other mime types.
// Blank mime type
raw_response_headers =
net::HttpUtil::AssembleRawHeaders(kHeader, strlen(kHeader));
headers = new net::HttpResponseHeaders(raw_response_headers);
handle.set_response_headers(headers.get());
handle.set_response_headers(GetHeaderWithMimeType(""));
ASSERT_EQ(content::NavigationThrottle::PROCEED,
throttle->WillProcessResponse().action());
// HTML
raw_response_headers = GetHeaderWithMimeType("text/html");
headers = new net::HttpResponseHeaders(raw_response_headers);
handle.set_response_headers(headers.get());
handle.set_response_headers(GetHeaderWithMimeType("text/html"));
ASSERT_EQ(content::NavigationThrottle::PROCEED,
throttle->WillProcessResponse().action());
// PNG
raw_response_headers = GetHeaderWithMimeType("image/png");
headers = new net::HttpResponseHeaders(raw_response_headers);
handle.set_response_headers(headers.get());
handle.set_response_headers(GetHeaderWithMimeType("image/png"));
ASSERT_EQ(content::NavigationThrottle::PROCEED,
throttle->WillProcessResponse().action());
}
......@@ -167,26 +170,54 @@ TEST_F(PDFIFrameNavigationThrottleTest, AllowPDFAttachments) {
}
#if BUILDFLAG(ENABLE_PLUGINS)
TEST_F(PDFIFrameNavigationThrottleTest, CancelOnlyIfPDFViewerIsDisabled) {
// Setup
std::string raw_response_headers = GetHeaderWithMimeType("application/pdf");
raw_response_headers = net::HttpUtil::AssembleRawHeaders(
raw_response_headers.c_str(), raw_response_headers.size());
scoped_refptr<net::HttpResponseHeaders> headers =
new net::HttpResponseHeaders(raw_response_headers);
TEST_F(PDFIFrameNavigationThrottleTest, ProceedIfPDFViewerIsEnabled) {
content::MockNavigationHandle handle(GURL(kExampleURL), subframe());
handle.set_response_headers(headers.get());
handle.set_response_headers(GetHeaderWithMimeType("application/pdf"));
// Test PDF Viewer enabled.
SetAlwaysOpenPdfExternallyForTests(false);
// First time should asynchronously Resume the navigation.
std::unique_ptr<content::NavigationThrottle> throttle =
PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(&handle);
ASSERT_EQ(nullptr, throttle);
ASSERT_NE(nullptr, throttle);
ASSERT_EQ(content::NavigationThrottle::DEFER,
throttle->WillProcessResponse().action());
base::RunLoop run_loop;
throttle->set_resume_callback_for_testing(run_loop.QuitClosure());
run_loop.Run();
// Test PDF Viewer disabled.
SetAlwaysOpenPdfExternallyForTests(true);
// Subsequent times should synchronously PROCEED the navigation.
throttle = PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(&handle);
ASSERT_NE(nullptr, throttle);
ASSERT_EQ(content::NavigationThrottle::PROCEED,
throttle->WillProcessResponse().action());
}
TEST_F(PDFIFrameNavigationThrottleTest, CancelIfPDFViewerIsDisabled) {
content::MockNavigationHandle handle(GURL(kExampleURL), subframe());
handle.set_response_headers(GetHeaderWithMimeType("application/pdf"));
SetAlwaysOpenPdfExternallyForTests(true);
// First time should asynchronously Cancel the navigation.
std::unique_ptr<content::NavigationThrottle> throttle =
PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(&handle);
ASSERT_NE(nullptr, throttle);
ASSERT_EQ(content::NavigationThrottle::DEFER,
throttle->WillProcessResponse().action());
base::RunLoop run_loop;
throttle->set_cancel_deferred_navigation_callback_for_testing(
base::BindRepeating(
[](base::RunLoop* run_loop,
content::NavigationThrottle::ThrottleCheckResult result) {
ASSERT_EQ(content::NavigationThrottle::CANCEL_AND_IGNORE, result);
run_loop->Quit();
},
base::Unretained(&run_loop)));
run_loop.Run();
// Subsequent times should synchronously CANCEL the navigation.
throttle = PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(&handle);
ASSERT_NE(nullptr, throttle);
ASSERT_EQ(content::NavigationThrottle::CANCEL_AND_IGNORE,
throttle->WillProcessResponse().action());
......
......@@ -99,8 +99,6 @@ PluginServiceImpl* PluginServiceImpl::GetInstance() {
}
PluginServiceImpl::PluginServiceImpl() : filter_(nullptr) {
plugin_list_sequence_checker_.DetachFromSequence();
// Collect the total number of browser processes (which create
// PluginServiceImpl objects, to be precise). The number is used to normalize
// the number of processes which start at least one NPAPI/PPAPI Flash process.
......@@ -119,6 +117,9 @@ void PluginServiceImpl::Init() {
plugin_list_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
// Setup the sequence checker right after setting up the task runner.
plugin_list_sequence_checker_.DetachFromSequence();
PluginList::Singleton()->set_will_load_plugins_callback(base::BindRepeating(
&WillLoadPluginsCallback, &plugin_list_sequence_checker_));
......
......@@ -81,7 +81,7 @@ NavigationThrottle::WillProcessResponse() {
}
void NavigationThrottle::Resume() {
if (!resume_callback_.is_null()) {
if (resume_callback_) {
resume_callback_.Run();
return;
}
......@@ -90,6 +90,10 @@ void NavigationThrottle::Resume() {
void NavigationThrottle::CancelDeferredNavigation(
NavigationThrottle::ThrottleCheckResult result) {
if (cancel_deferred_navigation_callback_) {
cancel_deferred_navigation_callback_.Run(result);
return;
}
static_cast<NavigationHandleImpl*>(navigation_handle_)
->CancelDeferredNavigation(this, result);
}
......
......@@ -180,6 +180,13 @@ class CONTENT_EXPORT NavigationThrottle {
resume_callback_ = callback;
}
// Overrides the default CancelDeferredNavigation method and replaces it by
// |callback|. This should only be used in tests.
void set_cancel_deferred_navigation_callback_for_testing(
const base::RepeatingCallback<void(ThrottleCheckResult)> callback) {
cancel_deferred_navigation_callback_ = callback;
}
protected:
// Resumes a navigation that was previously deferred by this
// NavigationThrottle.
......@@ -201,6 +208,8 @@ class CONTENT_EXPORT NavigationThrottle {
// Used in tests.
base::RepeatingClosure resume_callback_;
base::RepeatingCallback<void(ThrottleCheckResult)>
cancel_deferred_navigation_callback_;
};
#if defined(UNIT_TEST)
......
......@@ -5,6 +5,7 @@
#ifndef CONTENT_PUBLIC_TEST_MOCK_NAVIGATION_HANDLE_H_
#define CONTENT_PUBLIC_TEST_MOCK_NAVIGATION_HANDLE_H_
#include "base/memory/ref_counted.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
......@@ -72,7 +73,7 @@ class MockNavigationHandle : public NavigationHandle {
MOCK_METHOD1(RemoveRequestHeader, void(const std::string&));
MOCK_METHOD2(SetRequestHeader, void(const std::string&, const std::string&));
const net::HttpResponseHeaders* GetResponseHeaders() override {
return response_headers_;
return response_headers_.get();
}
MOCK_METHOD0(GetConnectionInfo, net::HttpResponseInfo::ConnectionInfo());
const net::SSLInfo& GetSSLInfo() override { return ssl_info_; }
......@@ -117,8 +118,9 @@ class MockNavigationHandle : public NavigationHandle {
void set_request_headers(const net::HttpRequestHeaders& request_headers) {
request_headers_ = request_headers;
}
void set_response_headers(net::HttpResponseHeaders* reponse_headers) {
response_headers_ = reponse_headers;
void set_response_headers(
scoped_refptr<net::HttpResponseHeaders> response_headers) {
response_headers_ = response_headers;
}
void set_ssl_info(const net::SSLInfo& ssl_info) { ssl_info_ = ssl_info; }
void set_is_form_submission(bool is_form_submission) {
......@@ -146,7 +148,7 @@ class MockNavigationHandle : public NavigationHandle {
bool has_committed_ = false;
bool is_error_page_ = false;
net::HttpRequestHeaders request_headers_;
net::HttpResponseHeaders* response_headers_ = nullptr;
scoped_refptr<net::HttpResponseHeaders> response_headers_;
net::SSLInfo ssl_info_;
bool is_form_submission_ = false;
bool was_response_cached_ = false;
......
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