Commit e41aab5f authored by Darin Fisher's avatar Darin Fisher Committed by Commit Bot

Cleanup plumbing of chrome::mojom::PrerenderCanceler

Three changes:

1- Avoid returning a raw pointer to chrome::mojom::PrerenderCanceler
   from GetPrerenderCanceller helper functions in favor returning a
   mojo::PendingRemote<chrome::mojom::PrerenderCanceler>. This avoids
   the need to schedule a DeleteSoon (in the renderer case) to cleanup
   the memory associated with that object later.

2- By returning a mojo::PendingRemote<..> instead of a raw pointer to
   the interface, it is no longer necessary to manually PostTask before
   accessing that interface. A mojo::PendingRemote<..> can instead be
   bound to a mojo::Remote<..> that implicitly schedules function calls
   on the right thread. The PostTask is implicit.

3- Make PrerenderContents support having multiple bound cancelers. This
   makes the above possible. In the renderer, the canceler is acquired
   immediately instead of lazily, and that is extra cost (an extra IPC)
   in the case where a canceler is not needed. This only happens for a
   page being prerendered, and so that overhead should be relatively
   small and seems worth the benefit of simple code.

Change-Id: If43a1f6fa607f07eded8511639898ea99a023cd6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2023358
Commit-Queue: Darin Fisher <darin@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarRyan Sturm <ryansturm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#736455}
parent a0cfb1d0
...@@ -238,7 +238,7 @@ void BindPrerenderCanceler( ...@@ -238,7 +238,7 @@ void BindPrerenderCanceler(
prerender::PrerenderContents::FromWebContents(web_contents); prerender::PrerenderContents::FromWebContents(web_contents);
if (!prerender_contents) if (!prerender_contents)
return; return;
prerender_contents->OnPrerenderCancelerReceiver(std::move(receiver)); prerender_contents->AddPrerenderCancelerReceiver(std::move(receiver));
} }
void BindDocumentCoordinationUnit( void BindDocumentCoordinationUnit(
......
...@@ -967,14 +967,12 @@ bool URLHasExtensionBackgroundPermission( ...@@ -967,14 +967,12 @@ bool URLHasExtensionBackgroundPermission(
#endif #endif
chrome::mojom::PrerenderCanceler* GetPrerenderCanceller( mojo::PendingRemote<chrome::mojom::PrerenderCanceler> GetPrerenderCanceler(
const base::Callback<content::WebContents*()>& wc_getter) { const base::Callback<content::WebContents*()>& wc_getter) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); mojo::PendingRemote<chrome::mojom::PrerenderCanceler> canceler;
auto* web_contents = wc_getter.Run(); prerender::PrerenderContents::FromWebContents(wc_getter.Run())
if (!web_contents) ->AddPrerenderCancelerReceiver(canceler.InitWithNewPipeAndPassReceiver());
return nullptr; return canceler;
return prerender::PrerenderContents::FromWebContents(web_contents);
} }
void LaunchURL(const GURL& url, void LaunchURL(const GURL& url,
...@@ -4306,8 +4304,7 @@ ChromeContentBrowserClient::CreateURLLoaderThrottles( ...@@ -4306,8 +4304,7 @@ ChromeContentBrowserClient::CreateURLLoaderThrottles(
result.push_back(std::make_unique<prerender::PrerenderURLLoaderThrottle>( result.push_back(std::make_unique<prerender::PrerenderURLLoaderThrottle>(
chrome_navigation_ui_data->prerender_mode(), chrome_navigation_ui_data->prerender_mode(),
chrome_navigation_ui_data->prerender_histogram_prefix(), chrome_navigation_ui_data->prerender_histogram_prefix(),
base::BindOnce(GetPrerenderCanceller, wc_getter), GetPrerenderCanceler(wc_getter)));
base::CreateSingleThreadTaskRunner({BrowserThread::UI})));
} }
signin::IdentityManager* identity_manager = signin::IdentityManager* identity_manager =
......
...@@ -719,10 +719,9 @@ void PrerenderContents::CancelPrerenderForUnsupportedScheme(const GURL& url) { ...@@ -719,10 +719,9 @@ void PrerenderContents::CancelPrerenderForUnsupportedScheme(const GURL& url) {
ReportUnsupportedPrerenderScheme(url); ReportUnsupportedPrerenderScheme(url);
} }
void PrerenderContents::OnPrerenderCancelerReceiver( void PrerenderContents::AddPrerenderCancelerReceiver(
mojo::PendingReceiver<chrome::mojom::PrerenderCanceler> receiver) { mojo::PendingReceiver<chrome::mojom::PrerenderCanceler> receiver) {
if (!prerender_canceler_receiver_.is_bound()) prerender_canceler_receiver_set_.Add(this, std::move(receiver));
prerender_canceler_receiver_.Bind(std::move(receiver));
} }
void PrerenderContents::AddNetworkBytes(int64_t bytes) { void PrerenderContents::AddNetworkBytes(int64_t bytes) {
......
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
#include "content/public/common/referrer.h" #include "content/public/common/referrer.h"
#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "url/origin.h" #include "url/origin.h"
...@@ -233,7 +232,7 @@ class PrerenderContents : public content::NotificationObserver, ...@@ -233,7 +232,7 @@ class PrerenderContents : public content::NotificationObserver,
// Running byte count. Increased when each resource completes loading. // Running byte count. Increased when each resource completes loading.
int64_t network_bytes() { return network_bytes_; } int64_t network_bytes() { return network_bytes_; }
void OnPrerenderCancelerReceiver( void AddPrerenderCancelerReceiver(
mojo::PendingReceiver<chrome::mojom::PrerenderCanceler> receiver); mojo::PendingReceiver<chrome::mojom::PrerenderCanceler> receiver);
protected: protected:
...@@ -295,8 +294,8 @@ class PrerenderContents : public content::NotificationObserver, ...@@ -295,8 +294,8 @@ class PrerenderContents : public content::NotificationObserver,
void CancelPrerenderForUnsupportedMethod() override; void CancelPrerenderForUnsupportedMethod() override;
void CancelPrerenderForUnsupportedScheme(const GURL& url) override; void CancelPrerenderForUnsupportedScheme(const GURL& url) override;
mojo::Receiver<chrome::mojom::PrerenderCanceler> prerender_canceler_receiver_{ mojo::ReceiverSet<chrome::mojom::PrerenderCanceler>
this}; prerender_canceler_receiver_set_;
base::ObserverList<Observer>::Unchecked observer_list_; base::ObserverList<Observer>::Unchecked observer_list_;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/common/prerender_util.h" #include "chrome/common/prerender_util.h"
#include "content/public/common/content_constants.h" #include "content/public/common/content_constants.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/load_flags.h" #include "net/base/load_flags.h"
#include "net/url_request/redirect_info.h" #include "net/url_request/redirect_info.h"
#include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/resource_request.h"
...@@ -20,19 +21,17 @@ namespace { ...@@ -20,19 +21,17 @@ namespace {
const char kPurposeHeaderName[] = "Purpose"; const char kPurposeHeaderName[] = "Purpose";
const char kPurposeHeaderValue[] = "prefetch"; const char kPurposeHeaderValue[] = "prefetch";
void CancelPrerenderForUnsupportedMethod( void CallCancelPrerenderForUnsupportedMethod(
PrerenderURLLoaderThrottle::CancelerGetterCallback callback) { mojo::PendingRemote<chrome::mojom::PrerenderCanceler> canceler) {
chrome::mojom::PrerenderCanceler* canceler = std::move(callback).Run(); mojo::Remote<chrome::mojom::PrerenderCanceler>(std::move(canceler))
if (canceler) ->CancelPrerenderForUnsupportedMethod();
canceler->CancelPrerenderForUnsupportedMethod();
} }
void CancelPrerenderForUnsupportedScheme( void CallCancelPrerenderForUnsupportedScheme(
PrerenderURLLoaderThrottle::CancelerGetterCallback callback, mojo::PendingRemote<chrome::mojom::PrerenderCanceler> canceler,
const GURL& url) { const GURL& url) {
chrome::mojom::PrerenderCanceler* canceler = std::move(callback).Run(); mojo::Remote<chrome::mojom::PrerenderCanceler>(std::move(canceler))
if (canceler) ->CancelPrerenderForUnsupportedScheme(url);
canceler->CancelPrerenderForUnsupportedScheme(url);
} }
// Returns true if the response has a "no-store" cache control header. // Returns true if the response has a "no-store" cache control header.
...@@ -46,12 +45,11 @@ bool IsNoStoreResponse(const network::mojom::URLResponseHead& response_head) { ...@@ -46,12 +45,11 @@ bool IsNoStoreResponse(const network::mojom::URLResponseHead& response_head) {
PrerenderURLLoaderThrottle::PrerenderURLLoaderThrottle( PrerenderURLLoaderThrottle::PrerenderURLLoaderThrottle(
PrerenderMode mode, PrerenderMode mode,
const std::string& histogram_prefix, const std::string& histogram_prefix,
CancelerGetterCallback canceler_getter, mojo::PendingRemote<chrome::mojom::PrerenderCanceler> canceler)
scoped_refptr<base::SequencedTaskRunner> canceler_getter_task_runner)
: mode_(mode), : mode_(mode),
histogram_prefix_(histogram_prefix), histogram_prefix_(histogram_prefix),
canceler_getter_(std::move(canceler_getter)), canceler_(std::move(canceler)) {
canceler_getter_task_runner_(canceler_getter_task_runner) { DCHECK(canceler_);
} }
PrerenderURLLoaderThrottle::~PrerenderURLLoaderThrottle() { PrerenderURLLoaderThrottle::~PrerenderURLLoaderThrottle() {
...@@ -90,9 +88,7 @@ void PrerenderURLLoaderThrottle::WillStartRequest( ...@@ -90,9 +88,7 @@ void PrerenderURLLoaderThrottle::WillStartRequest(
// prefetch going. // prefetch going.
delegate_->CancelWithError(net::ERR_ABORTED); delegate_->CancelWithError(net::ERR_ABORTED);
if (mode_ == DEPRECATED_FULL_PRERENDER) { if (mode_ == DEPRECATED_FULL_PRERENDER) {
canceler_getter_task_runner_->PostTask( CallCancelPrerenderForUnsupportedMethod(std::move(canceler_));
FROM_HERE, base::BindOnce(CancelPrerenderForUnsupportedMethod,
std::move(canceler_getter_)));
return; return;
} }
} }
...@@ -107,9 +103,7 @@ void PrerenderURLLoaderThrottle::WillStartRequest( ...@@ -107,9 +103,7 @@ void PrerenderURLLoaderThrottle::WillStartRequest(
// WillRedirectRequest() and PrerenderContents::CheckURL(). See // WillRedirectRequest() and PrerenderContents::CheckURL(). See
// http://crbug.com/673771. // http://crbug.com/673771.
delegate_->CancelWithError(net::ERR_ABORTED); delegate_->CancelWithError(net::ERR_ABORTED);
canceler_getter_task_runner_->PostTask( CallCancelPrerenderForUnsupportedScheme(std::move(canceler_), request->url);
FROM_HERE, base::BindOnce(CancelPrerenderForUnsupportedScheme,
std::move(canceler_getter_), request->url));
return; return;
} }
...@@ -166,10 +160,8 @@ void PrerenderURLLoaderThrottle::WillRedirectRequest( ...@@ -166,10 +160,8 @@ void PrerenderURLLoaderThrottle::WillRedirectRequest(
// Abort any prerenders with requests which redirect to invalid schemes. // Abort any prerenders with requests which redirect to invalid schemes.
if (!DoesURLHaveValidScheme(redirect_info->new_url)) { if (!DoesURLHaveValidScheme(redirect_info->new_url)) {
delegate_->CancelWithError(net::ERR_ABORTED); delegate_->CancelWithError(net::ERR_ABORTED);
canceler_getter_task_runner_->PostTask( CallCancelPrerenderForUnsupportedScheme(std::move(canceler_),
FROM_HERE, redirect_info->new_url);
base::BindOnce(CancelPrerenderForUnsupportedScheme,
std::move(canceler_getter_), redirect_info->new_url));
} else if (follow_only_when_prerender_shown_header == "1" && } else if (follow_only_when_prerender_shown_header == "1" &&
resource_type_ != content::ResourceType::kMainFrame) { resource_type_ != content::ResourceType::kMainFrame) {
// Only defer redirects with the Follow-Only-When-Prerender-Shown // Only defer redirects with the Follow-Only-When-Prerender-Shown
......
...@@ -22,15 +22,10 @@ class PrerenderURLLoaderThrottle ...@@ -22,15 +22,10 @@ class PrerenderURLLoaderThrottle
: public blink::URLLoaderThrottle, : public blink::URLLoaderThrottle,
public base::SupportsWeakPtr<PrerenderURLLoaderThrottle> { public base::SupportsWeakPtr<PrerenderURLLoaderThrottle> {
public: public:
// If the throttle needs to cancel the prerender, it will run
// |canceler_getter| on |canceler_getter_task_runner| to do so.
using CancelerGetterCallback =
base::OnceCallback<chrome::mojom::PrerenderCanceler*()>;
PrerenderURLLoaderThrottle( PrerenderURLLoaderThrottle(
PrerenderMode mode, PrerenderMode mode,
const std::string& histogram_prefix, const std::string& histogram_prefix,
CancelerGetterCallback canceler_getter, mojo::PendingRemote<chrome::mojom::PrerenderCanceler> canceler);
scoped_refptr<base::SequencedTaskRunner> canceler_getter_task_runner);
~PrerenderURLLoaderThrottle() override; ~PrerenderURLLoaderThrottle() override;
// Called when the prerender is used. This will unpaused requests and set the // Called when the prerender is used. This will unpaused requests and set the
...@@ -64,8 +59,7 @@ class PrerenderURLLoaderThrottle ...@@ -64,8 +59,7 @@ class PrerenderURLLoaderThrottle
int redirect_count_ = 0; int redirect_count_ = 0;
content::ResourceType resource_type_; content::ResourceType resource_type_;
CancelerGetterCallback canceler_getter_; mojo::PendingRemote<chrome::mojom::PrerenderCanceler> canceler_;
scoped_refptr<base::SequencedTaskRunner> canceler_getter_task_runner_;
// The throttle changes most request priorities to IDLE during prerendering. // The throttle changes most request priorities to IDLE during prerendering.
// The priority is reset back to the original priority when prerendering is // The priority is reset back to the original priority when prerendering is
......
...@@ -44,21 +44,12 @@ ...@@ -44,21 +44,12 @@
namespace { namespace {
chrome::mojom::PrerenderCanceler* GetPrerenderCanceller(int render_frame_id) { mojo::PendingRemote<chrome::mojom::PrerenderCanceler> GetPrerenderCanceler(
content::RenderFrame* render_frame = content::RenderFrame* render_frame) {
content::RenderFrame::FromRoutingID(render_frame_id); mojo::PendingRemote<chrome::mojom::PrerenderCanceler> canceler;
if (!render_frame)
return nullptr;
prerender::PrerenderHelper* helper =
prerender::PrerenderHelper::Get(render_frame);
if (!helper)
return nullptr;
auto* canceler = new mojo::Remote<chrome::mojom::PrerenderCanceler>;
render_frame->GetBrowserInterfaceBroker()->GetInterface( render_frame->GetBrowserInterfaceBroker()->GetInterface(
canceler->BindNewPipeAndPassReceiver()); canceler.InitWithNewPipeAndPassReceiver());
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, canceler); return canceler;
return canceler->get();
} }
#if BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_EXTENSIONS)
...@@ -200,8 +191,7 @@ URLLoaderThrottleProviderImpl::CreateThrottles( ...@@ -200,8 +191,7 @@ URLLoaderThrottleProviderImpl::CreateThrottles(
auto throttle = std::make_unique<prerender::PrerenderURLLoaderThrottle>( auto throttle = std::make_unique<prerender::PrerenderURLLoaderThrottle>(
prerender_helper->prerender_mode(), prerender_helper->prerender_mode(),
prerender_helper->histogram_prefix(), prerender_helper->histogram_prefix(),
base::BindOnce(GetPrerenderCanceller, render_frame_id), GetPrerenderCanceler(render_frame));
base::ThreadTaskRunnerHandle::Get());
prerender_helper->AddThrottle(throttle->AsWeakPtr()); prerender_helper->AddThrottle(throttle->AsWeakPtr());
if (prerender_helper->prerender_mode() == prerender::PREFETCH_ONLY) { if (prerender_helper->prerender_mode() == prerender::PREFETCH_ONLY) {
auto* prerender_dispatcher = auto* prerender_dispatcher =
......
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