Commit cc50c0ec authored by Hiroki Nakagawa's avatar Hiroki Nakagawa Committed by Commit Bot

Prerender: Merge mojom::PrerenderHandle into mojom::PrerenderProcessor

For code simplification, this CL merges mojom::PrerenderHandle into
mojom::PrerenerProcessor. These interfaces were very similar: These were
materialized per <link rel=prerender> element, and used for sending
messages from a renderer process to the browser process.

To merge them, this CL...

- assigns unique identifier per LinkPreload instance. This is used for
  canceling or abandoning prerendering from PrerenderProcessorImpl.
- removes PrerenderHandleProxy that implemented mojom::PrerenderHandle.

Bonus: This cleanup will make it easier to reuse the mojom interfaces
for the prerender V2 implementation we are now planning (see the issue).

Change-Id: If731c50408c4e125b3e71a70bef9bbf680eb073f
Bug: 1126305
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2413830Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarRobert Ogden <robertogden@chromium.org>
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Cr-Commit-Position: refs/heads/master@{#810968}
parent d798762c
......@@ -410,18 +410,14 @@ class PrerenderTest : public testing::Test {
clients_.Add(std::make_unique<DummyPrerenderHandleClient>(),
handle_client.InitWithNewPipeAndPassReceiver());
mojo::PendingRemote<blink::mojom::PrerenderHandle> handle;
// This could delete an existing prerender as a side-effect.
bool added = prerender_link_manager()->OnAddPrerender(
render_process_id, render_view_id, std::move(attributes),
std::move(handle_client), handle.InitWithNewPipeAndPassReceiver());
// We don't care about retaining the |handle|, so just let it be discarded.
// The PrerenderLinkManager won't care.
base::Optional<int> prerender_id =
prerender_link_manager()->OnStartPrerender(
render_process_id, render_view_id, std::move(attributes),
std::move(handle_client));
// Check if the new prerender request was added and running.
return added && LastPrerenderIsRunning();
return prerender_id && LastPrerenderIsRunning();
}
// Shorthand to add a simple prerender with a reasonable source. Returns
......@@ -444,25 +440,25 @@ class PrerenderTest : public testing::Test {
void AbandonFirstPrerender() {
CHECK(!prerender_link_manager()->prerenders_.empty());
prerender_link_manager()->OnAbandonPrerender(
prerender_link_manager()->prerenders_.front().get());
prerender_link_manager()->prerenders_.front()->prerender_id);
}
void AbandonLastPrerender() {
CHECK(!prerender_link_manager()->prerenders_.empty());
prerender_link_manager()->OnAbandonPrerender(
prerender_link_manager()->prerenders_.back().get());
prerender_link_manager()->prerenders_.back()->prerender_id);
}
void CancelFirstPrerender() {
CHECK(!prerender_link_manager()->prerenders_.empty());
prerender_link_manager()->OnCancelPrerender(
prerender_link_manager()->prerenders_.front().get());
prerender_link_manager()->prerenders_.front()->prerender_id);
}
void CancelLastPrerender() {
CHECK(!prerender_link_manager()->prerenders_.empty());
prerender_link_manager()->OnCancelPrerender(
prerender_link_manager()->prerenders_.back().get());
prerender_link_manager()->prerenders_.back()->prerender_id);
}
void DisablePrerender() {
......
......@@ -39,79 +39,14 @@ using content::SessionStorageNamespace;
namespace prerender {
// Implementation of the interface used to control a requested prerender.
class PrerenderLinkManager::PrerenderHandleProxy
: public blink::mojom::PrerenderHandle {
public:
PrerenderHandleProxy(
PrerenderLinkManager* prerender_link_manager,
PrerenderLinkManager::LinkPrerender* link_prerender,
mojo::PendingReceiver<blink::mojom::PrerenderHandle> handle)
: prerender_link_manager_(prerender_link_manager),
link_prerender_(link_prerender),
receiver_(this, std::move(handle)) {}
~PrerenderHandleProxy() override = default;
// blink::mojom::PrerenderHandle implementation
void Cancel() override {
prerender_link_manager_->OnCancelPrerender(link_prerender_);
}
void Abandon() override {
prerender_link_manager_->OnAbandonPrerender(link_prerender_);
}
namespace {
private:
PrerenderLinkManager* prerender_link_manager_;
LinkPrerender* link_prerender_;
mojo::Receiver<blink::mojom::PrerenderHandle> receiver_;
};
// Used to store state about a requested prerender.
class PrerenderLinkManager::LinkPrerender {
public:
LinkPrerender(
int launcher_render_process_id,
int launcher_render_view_id,
blink::mojom::PrerenderAttributesPtr attributes,
mojo::PendingRemote<blink::mojom::PrerenderHandleClient> handle_client,
base::TimeTicks creation_time,
PrerenderContents* deferred_launcher);
~LinkPrerender();
LinkPrerender(const LinkPrerender& other) = delete;
LinkPrerender& operator=(const LinkPrerender& other) = delete;
// Parameters from PrerenderLinkManager::OnAddPrerender():
int launcher_render_process_id;
int launcher_render_view_id;
GURL url;
blink::mojom::PrerenderRelType rel_type;
content::Referrer referrer;
url::Origin initiator_origin;
gfx::Size size;
// Notification interface back to the requestor of this prerender.
mojo::Remote<blink::mojom::PrerenderHandleClient> remote_handle_client;
// Control interface used by the requestor of this prerender. Owned by this
// class to ensure that it gets destroyed at the same time.
std::unique_ptr<PrerenderHandleProxy> handle_proxy;
// The time at which this Prerender was added to PrerenderLinkManager.
base::TimeTicks creation_time;
// If non-null, this link prerender was launched by an unswapped prerender,
// |deferred_launcher|. When |deferred_launcher| is swapped in, the field is
// set to null.
PrerenderContents* deferred_launcher;
// Initially null, |handle| is set once we start this prerender. It is owned
// by this struct, and must be deleted before destructing this struct.
std::unique_ptr<PrerenderHandle> handle;
// True if this prerender has been abandoned by its launcher.
bool has_been_abandoned;
};
int GetNextPrerenderId() {
static int next_id = 1;
return next_id++;
}
} // namespace
PrerenderLinkManager::LinkPrerender::LinkPrerender(
int launcher_render_process_id,
......@@ -130,7 +65,8 @@ PrerenderLinkManager::LinkPrerender::LinkPrerender(
remote_handle_client(std::move(handle_client)),
creation_time(creation_time),
deferred_launcher(deferred_launcher),
has_been_abandoned(false) {}
has_been_abandoned(false),
prerender_id(GetNextPrerenderId()) {}
PrerenderLinkManager::LinkPrerender::~LinkPrerender() {
DCHECK_EQ(nullptr, handle.get())
......@@ -151,12 +87,11 @@ PrerenderLinkManager::~PrerenderLinkManager() {
}
}
bool PrerenderLinkManager::OnAddPrerender(
base::Optional<int> PrerenderLinkManager::OnStartPrerender(
int launcher_render_process_id,
int launcher_render_view_id,
blink::mojom::PrerenderAttributesPtr attributes,
mojo::PendingRemote<blink::mojom::PrerenderHandleClient> handle_client,
mojo::PendingReceiver<blink::mojom::PrerenderHandle> handle) {
mojo::PendingRemote<blink::mojom::PrerenderHandleClient> handle_client) {
// TODO(crbug.com/722453): Use a dedicated build flag for GuestView.
#if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_FUCHSIA)
content::RenderViewHost* rvh = content::RenderViewHost::FromID(
......@@ -166,7 +101,7 @@ bool PrerenderLinkManager::OnAddPrerender(
// Guests inside <webview> do not support cross-process navigation and so we
// do not allow guests to prerender content.
if (guest_view::GuestViewBase::IsGuest(web_contents))
return false;
return base::nullopt;
#endif
// Check if the launcher is itself an unswapped prerender.
......@@ -178,7 +113,7 @@ bool PrerenderLinkManager::OnAddPrerender(
// The launcher is a prerender about to be destroyed asynchronously, but
// its AddLinkRelPrerender message raced with shutdown. Ignore it.
DCHECK_NE(FINAL_STATUS_USED, prerender_contents->final_status());
return false;
return base::nullopt;
}
auto prerender = std::make_unique<LinkPrerender>(
......@@ -186,18 +121,12 @@ bool PrerenderLinkManager::OnAddPrerender(
std::move(attributes), std::move(handle_client),
manager_->GetCurrentTimeTicks(), prerender_contents);
// Setup implementation of blink::mojom::PrerenderHandle as a proxy to the
// real PrerenderHandle. The first two raw pointers are safe as the proxy is
// owned by |prerender| which is owned by |this|.
prerender->handle_proxy = std::make_unique<PrerenderHandleProxy>(
this, prerender.get(), std::move(handle));
// Observe disconnect of the client and treat as equivalent to explicit
// abandonment. Similar to above, the raw pointer to |this| is safe because
// |prerender| is owned by |this|.
prerender->remote_handle_client.set_disconnect_handler(
base::BindOnce(&PrerenderLinkManager::OnAbandonPrerender,
base::Unretained(this), prerender.get()));
base::Unretained(this), prerender->prerender_id));
// Stash pointer used only for comparison later.
const LinkPrerender* prerender_ptr = prerender.get();
......@@ -209,15 +138,24 @@ bool PrerenderLinkManager::OnAddPrerender(
// Check if the prerender we added is still at the end of the list. It
// may have been discarded by StartPrerenders().
return !prerenders_.empty() && prerenders_.back().get() == prerender_ptr;
if (!prerenders_.empty() && prerenders_.back().get() == prerender_ptr)
return prerender_ptr->prerender_id;
return base::nullopt;
}
void PrerenderLinkManager::OnCancelPrerender(LinkPrerender* prerender) {
void PrerenderLinkManager::OnCancelPrerender(int prerender_id) {
LinkPrerender* prerender = FindByPrerenderId(prerender_id);
if (!prerender)
return;
CancelPrerender(prerender);
StartPrerenders();
}
void PrerenderLinkManager::OnAbandonPrerender(LinkPrerender* prerender) {
void PrerenderLinkManager::OnAbandonPrerender(int prerender_id) {
LinkPrerender* prerender = FindByPrerenderId(prerender_id);
if (!prerender)
return;
if (!prerender->handle) {
RemovePrerender(prerender);
return;
......@@ -368,6 +306,15 @@ PrerenderLinkManager::FindByPrerenderHandle(PrerenderHandle* prerender_handle) {
return nullptr;
}
PrerenderLinkManager::LinkPrerender* PrerenderLinkManager::FindByPrerenderId(
int prerender_id) {
for (auto& prerender : prerenders_) {
if (prerender->prerender_id == prerender_id)
return prerender.get();
}
return nullptr;
}
void PrerenderLinkManager::RemovePrerender(LinkPrerender* prerender) {
for (auto it = prerenders_.begin(); it != prerenders_.end(); ++it) {
LinkPrerender* current_prerender = it->get();
......@@ -400,7 +347,8 @@ void PrerenderLinkManager::Shutdown() {
has_shutdown_ = true;
}
// In practice, this is always called from PrerenderLinkManager::OnAddPrerender.
// In practice, this is always called from
// PrerenderLinkManager::OnStartPrerender().
void PrerenderLinkManager::OnPrerenderStart(PrerenderHandle* prerender_handle) {
LinkPrerender* prerender = FindByPrerenderHandle(prerender_handle);
if (!prerender)
......
......@@ -13,6 +13,7 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/prerender/browser/prerender_handle.h"
......@@ -36,14 +37,24 @@ class PrerenderLinkManager : public KeyedService,
explicit PrerenderLinkManager(PrerenderManager* manager);
~PrerenderLinkManager() override;
// A <link rel=prerender ...> element has been inserted into the document.
// Returns true if a prerender was added.
bool OnAddPrerender(
// Called when a <link rel=prerender ...> element has been inserted into the
// document. Returns the prerender id that is used for canceling or abandoning
// prerendering. Returns base::nullopt if the prerender was not started.
base::Optional<int> OnStartPrerender(
int launcher_render_process_id,
int launcher_render_view_id,
blink::mojom::PrerenderAttributesPtr attributes,
mojo::PendingRemote<blink::mojom::PrerenderHandleClient> handle_client,
mojo::PendingReceiver<blink::mojom::PrerenderHandle> handle);
mojo::PendingRemote<blink::mojom::PrerenderHandleClient> handle_client);
// Called when a <link rel=prerender ...> element has been explicitly removed
// from a document.
void OnCancelPrerender(int prerender_id);
// Called when a renderer launching <link rel=prerender ...> has navigated
// away from the launching page, the launching renderer process has crashed,
// or perhaps the renderer process was fast-closed when the last render view
// in it was closed.
void OnAbandonPrerender(int prerender_id);
private:
friend class PrerenderBrowserTest;
......@@ -51,19 +62,53 @@ class PrerenderLinkManager : public KeyedService,
// WebViewTest.NoPrerenderer needs to access the private IsEmpty() method.
FRIEND_TEST_ALL_PREFIXES(::WebViewTest, NoPrerenderer);
class PrerenderHandleProxy;
class LinkPrerender;
class PendingPrerenderManager;
// A <link rel=prerender ...> element has been explicitly removed from a
// document.
void OnCancelPrerender(LinkPrerender* link_prerender);
// A renderer launching <link rel=prerender ...> has navigated away from the
// launching page, the launching renderer process has crashed, or perhaps the
// renderer process was fast-closed when the last render view in it was
// closed.
void OnAbandonPrerender(LinkPrerender* link_prerender);
// Used to store state about a requested prerender.
struct LinkPrerender {
LinkPrerender(
int launcher_render_process_id,
int launcher_render_view_id,
blink::mojom::PrerenderAttributesPtr attributes,
mojo::PendingRemote<blink::mojom::PrerenderHandleClient> handle_client,
base::TimeTicks creation_time,
PrerenderContents* deferred_launcher);
~LinkPrerender();
LinkPrerender(const LinkPrerender& other) = delete;
LinkPrerender& operator=(const LinkPrerender& other) = delete;
// Parameters from PrerenderLinkManager::OnStartPrerender():
const int launcher_render_process_id;
const int launcher_render_view_id;
const GURL url;
const blink::mojom::PrerenderRelType rel_type;
const content::Referrer referrer;
const url::Origin initiator_origin;
const gfx::Size size;
// Notification interface back to the requestor of this prerender.
mojo::Remote<blink::mojom::PrerenderHandleClient> remote_handle_client;
// The time at which this Prerender was added to PrerenderLinkManager.
const base::TimeTicks creation_time;
// If non-null, this link prerender was launched by an unswapped prerender,
// |deferred_launcher|. When |deferred_launcher| is swapped in, the field is
// set to null.
const PrerenderContents* deferred_launcher;
// Initially null, |handle| is set once we start this prerender. It is owned
// by this struct, and must be deleted before destructing this struct.
std::unique_ptr<PrerenderHandle> handle;
// True if this prerender has been abandoned by its launcher.
bool has_been_abandoned;
// The unique ID of this prerender. Used for canceling or abandoning
// prerendering.
const int prerender_id;
};
bool IsEmpty() const;
......@@ -77,6 +122,7 @@ class PrerenderLinkManager : public KeyedService,
void StartPrerenders();
LinkPrerender* FindByPrerenderHandle(PrerenderHandle* prerender_handle);
LinkPrerender* FindByPrerenderId(int prerender_id);
// Removes |prerender| from the the prerender link manager. Deletes the
// PrerenderHandle as needed.
......
......@@ -36,32 +36,62 @@ void PrerenderProcessorImpl::Create(
std::move(receiver));
}
void PrerenderProcessorImpl::AddPrerender(
void PrerenderProcessorImpl::Start(
blink::mojom::PrerenderAttributesPtr attributes,
mojo::PendingRemote<blink::mojom::PrerenderHandleClient> handle_client,
mojo::PendingReceiver<blink::mojom::PrerenderHandle> handle) {
mojo::PendingRemote<blink::mojom::PrerenderHandleClient> handle_client) {
if (!attributes->initiator_origin.opaque() &&
!content::ChildProcessSecurityPolicy::GetInstance()
->CanAccessDataForOrigin(render_process_id_,
attributes->initiator_origin.GetURL())) {
mojo::ReportBadMessage("PMF_INVALID_INITIATOR_ORIGIN");
mojo::ReportBadMessage("PPI_INVALID_INITIATOR_ORIGIN");
return;
}
content::RenderFrameHost* render_frame_host =
// Start() must be called only one time.
if (prerender_id_) {
mojo::ReportBadMessage("PPI_START_TWICE");
return;
}
auto* render_frame_host =
content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
if (!render_frame_host)
return;
PrerenderLinkManager* link_manager = delegate_->GetPrerenderLinkManager(
render_frame_host->GetProcess()->GetBrowserContext());
auto* link_manager = GetPrerenderLinkManager();
if (!link_manager)
return;
link_manager->OnAddPrerender(
DCHECK(!prerender_id_);
prerender_id_ = link_manager->OnStartPrerender(
render_process_id_,
render_frame_host->GetRenderViewHost()->GetRoutingID(),
std::move(attributes), std::move(handle_client), std::move(handle));
std::move(attributes), std::move(handle_client));
}
void PrerenderProcessorImpl::Cancel() {
if (!prerender_id_)
return;
auto* link_manager = GetPrerenderLinkManager();
if (link_manager)
link_manager->OnCancelPrerender(*prerender_id_);
}
void PrerenderProcessorImpl::Abandon() {
if (!prerender_id_)
return;
auto* link_manager = GetPrerenderLinkManager();
if (link_manager)
link_manager->OnAbandonPrerender(*prerender_id_);
}
PrerenderLinkManager* PrerenderProcessorImpl::GetPrerenderLinkManager() {
auto* render_frame_host =
content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
if (!render_frame_host)
return nullptr;
return delegate_->GetPrerenderLinkManager(
render_frame_host->GetProcess()->GetBrowserContext());
}
} // namespace prerender
......@@ -28,15 +28,22 @@ class PrerenderProcessorImpl : public blink::mojom::PrerenderProcessor {
std::unique_ptr<PrerenderProcessorImplDelegate> delegate);
// blink::mojom::PrerenderProcessor implementation
void AddPrerender(
void Start(
blink::mojom::PrerenderAttributesPtr attributes,
mojo::PendingRemote<blink::mojom::PrerenderHandleClient> client,
mojo::PendingReceiver<blink::mojom::PrerenderHandle> handle) override;
mojo::PendingRemote<blink::mojom::PrerenderHandleClient> client) override;
void Cancel() override;
void Abandon() override;
private:
int render_process_id_;
int render_frame_id_;
std::unique_ptr<PrerenderProcessorImplDelegate> delegate_;
PrerenderLinkManager* GetPrerenderLinkManager();
const int render_process_id_;
const int render_frame_id_;
const std::unique_ptr<PrerenderProcessorImplDelegate> delegate_;
// The ID of PrerenderLinkManager::LinkPrerender. Used for canceling or
// abandoning prerendering.
base::Optional<int> prerender_id_;
};
} // namespace prerender
......
......@@ -9,37 +9,27 @@ import "ui/gfx/geometry/mojom/geometry.mojom";
import "url/mojom/origin.mojom";
import "url/mojom/url.mojom";
// These are messages sent from the browser to the renderer in relation to
// running prerenders.
// This interface is used to notify of events on prerendering from the browser
// process to a renderer process that requested prerendering. This is created
// per prerender request, for example, when a new <link rel=prerender> element
// is added, when the element's href is changed, etc.
//
// TODO(https://crbug.com/1126305): Rename this interface to
// PrerenderProcessorClient.
interface PrerenderHandleClient {
// Signals to launcher that a prerender is running.
// Notifies that a prerender started.
OnPrerenderStart();
// Signals to launcher that a prerender has stopped loading.
// Notifies that a prerender has stopped loading.
OnPrerenderStopLoading();
// Signals to launcher that a prerender has had it's 'domcontentloaded' event.
// Notifies that a prerender has had it's 'domcontentloaded' event.
OnPrerenderDomContentLoaded();
// Signals to a launcher that a prerender is no longer running.
// Notifies that a prerender is no longer running.
OnPrerenderStop();
};
// The renderer sends messages to the browser process over this interface. A
// handle to a requested prerender. Dropping a connection to the handle is
// treated equivalently to calling the Abandon method.
interface PrerenderHandle {
// Notifies on removal of a <link rel=prerender> element from the document.
// This method does not trigger an OnPrerenderStop() call.
Cancel();
// A prerender is abandoned when it's navigated away from or suspended in the
// page cache. This is a weaker signal than Cancel(), since the launcher
// hasn't indicated that the prerender isn't wanted, and we may end up using
// it after, for instance, a short redirect chain.
Abandon();
};
enum PrerenderRelType {
// https://html.spec.whatwg.org/C/#link-type-prerender
kPrerender,
......@@ -56,16 +46,31 @@ struct PrerenderAttributes {
gfx.mojom.Size view_size;
};
// The renderer sends messages to the browser process over this interface. Used
// by a renderer loading a web page to process prerender / prefetch requests,
// that are generally in the form of <link rel> tags that the web page author
// provided as hints.
// This interface is used to request prerendering from a renderer process to the
// browser process. This is created per prerender request, for example, when a
// new <link rel=prerender> element is added, when the element's href is
// changed, etc.
interface PrerenderProcessor {
// Called to add a prerender request to the queue for processing. The
// |prerender_handle_client| will be notified as the prerendering makes
// progress, and |prerender_handle| provides the caller with the ability to
// further control the prerender.
AddPrerender(PrerenderAttributes prerender_attribute,
pending_remote<PrerenderHandleClient> prerender_handle_client,
pending_receiver<PrerenderHandle> prerender_handle);
// Requests the browesr process to start prerendering with
// |prerender_attribute|. |prerender_handle_client| will be notified as the
// prerendering makes progress. This must be called only one time before any
// other functions.
Start(PrerenderAttributes prerender_attribute,
pending_remote<PrerenderHandleClient> prerender_handle_client);
// Cancels the ongoing prerendering. This is supposed to be called when the
// <link rel=prerender> element is removed, the element's href is changed,
// etc. This must be called after Start(). This does not trigger
// OnPrerenderStop() on PrerenderHandleClient.
Cancel();
// Abandons the ongoing prerendering. This is supposed to be called when the
// page navigates away or gets suspended. This is a weaker signal than
// Cancel(), since the requester hasn't indicated that the prerender isn't
// wanted, and we may end up using it after, for example, a short redirect
// chain. This must be called after Start().
//
// TODO(https://crbug.com/1130360): The actual behavior doesn't match this
// comment due to the issue. Fix the behavior or update this comment.
Abandon();
};
......@@ -66,22 +66,20 @@ PrerenderHandle* PrerenderHandle::Create(
attributes->view_size =
gfx::Size(document.GetFrame()->GetMainFrameViewportSize());
mojo::Remote<mojom::blink::PrerenderProcessor> prerender_processor;
HeapMojoRemote<mojom::blink::PrerenderProcessor> prerender_processor(context);
context->GetBrowserInterfaceBroker().GetInterface(
prerender_processor.BindNewPipeAndPassReceiver());
prerender_processor.BindNewPipeAndPassReceiver(
context->GetTaskRunner(TaskType::kMiscPlatformAPI)));
mojo::PendingRemote<mojom::blink::PrerenderHandleClient>
prerender_handle_client;
auto receiver = prerender_handle_client.InitWithNewPipeAndPassReceiver();
HeapMojoRemote<mojom::blink::PrerenderHandle> remote_handle(context);
prerender_processor->AddPrerender(
std::move(attributes), std::move(prerender_handle_client),
remote_handle.BindNewPipeAndPassReceiver(
context->GetTaskRunner(TaskType::kMiscPlatformAPI)));
prerender_processor->Start(std::move(attributes),
std::move(prerender_handle_client));
return MakeGarbageCollected<PrerenderHandle>(PassKey(), context, client, url,
std::move(remote_handle),
std::move(prerender_processor),
std::move(receiver));
}
......@@ -90,12 +88,12 @@ PrerenderHandle::PrerenderHandle(
ExecutionContext* context,
PrerenderClient* client,
const KURL& url,
HeapMojoRemote<mojom::blink::PrerenderHandle> remote_handle,
HeapMojoRemote<mojom::blink::PrerenderProcessor> remote_processor,
mojo::PendingReceiver<mojom::blink::PrerenderHandleClient> receiver)
: ExecutionContextLifecycleObserver(context),
url_(url),
client_(client),
remote_handle_(std::move(remote_handle)),
remote_processor_(std::move(remote_processor)),
receiver_(this, context) {
receiver_.Bind(std::move(receiver),
context->GetTaskRunner(TaskType::kMiscPlatformAPI));
......@@ -104,8 +102,11 @@ PrerenderHandle::PrerenderHandle(
PrerenderHandle::~PrerenderHandle() = default;
void PrerenderHandle::Dispose() {
if (remote_handle_.is_bound() && !GetExecutionContext()->IsContextDestroyed())
remote_handle_->Abandon();
// TODO(https://crbug.com/1130360): This condition is never satisfied and
// Abandon() is not called. See the issue for details. We should fix this.
if (remote_processor_.is_bound() &&
!GetExecutionContext()->IsContextDestroyed())
remote_processor_->Abandon();
Detach();
}
......@@ -114,8 +115,8 @@ void PrerenderHandle::Cancel() {
// case, the LinkLoader cancels the PrerenderHandle as the Document is
// destroyed, even through the ExecutionContextLifecycleObserver has already
// abandoned it.
if (remote_handle_.is_bound())
remote_handle_->Cancel();
if (remote_processor_.is_bound())
remote_processor_->Cancel();
Detach();
}
......@@ -153,13 +154,13 @@ void PrerenderHandle::OnPrerenderStop() {
void PrerenderHandle::Trace(Visitor* visitor) const {
visitor->Trace(client_);
visitor->Trace(remote_handle_);
visitor->Trace(remote_processor_);
visitor->Trace(receiver_);
ExecutionContextLifecycleObserver::Trace(visitor);
}
void PrerenderHandle::Detach() {
remote_handle_.reset();
remote_processor_.reset();
receiver_.reset();
}
......
......@@ -64,7 +64,7 @@ class PrerenderHandle final : public GarbageCollected<PrerenderHandle>,
ExecutionContext*,
PrerenderClient*,
const KURL&,
HeapMojoRemote<mojom::blink::PrerenderHandle>,
HeapMojoRemote<mojom::blink::PrerenderProcessor>,
mojo::PendingReceiver<mojom::blink::PrerenderHandleClient>);
~PrerenderHandle() override;
void Dispose();
......@@ -88,7 +88,7 @@ class PrerenderHandle final : public GarbageCollected<PrerenderHandle>,
KURL url_;
WeakMember<PrerenderClient> client_;
HeapMojoRemote<mojom::blink::PrerenderHandle> remote_handle_;
HeapMojoRemote<mojom::blink::PrerenderProcessor> remote_processor_;
HeapMojoReceiver<mojom::blink::PrerenderHandleClient, PrerenderHandle>
receiver_;
......
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