Commit 19a1b541 authored by Hiroki Nakagawa's avatar Hiroki Nakagawa Committed by Commit Bot

Prerender: Remove unused mojom::PrerenderProcessor::Abandon()

mojom::PrerenderProcessor::Abandon() is a mojo call from a renderer
process to the browser process in order to abandon a running prerender,
but this is never called. This CL removes the mojo function and relevant
functions (e.g., pre-finalizer).

> Why is this never called?

Abandon() is supposed to be called when a page that has
<link rel=prerender> navigates away, etc, and apparently
blink::PrerenderHandle::Dispose() calls it. However, actually Dispose()
never calls Abandon(). See the following code snippet.

  void PrerenderHandle::Dispose() {
    if (remote_processor_.is_bound() &&
        !GetExecutionContext()->IsContextDestroyed())
      remote_processor_->Abandon();
    Detach();
  }

Dispose() is called by ContextLifecycleObserver during the context
destruction. |remote_processor_| can be unbound at this point because
the remote processor is retained with MojoHeapRemote that is supposed
to be reset by ContextLifecycleObserver. There is an ordering issue
here. Also, even if the remote processor is still bound,
IsContextDestroyed() always returns true because Dispose() is called
during the context destruction.

In another case, Dispose() is called on the pre-finalizer, but this
doesn't work as well because PrerenderHandle::Cancel() that resets
|remote_processor_| or ContextDestroyed() that calls Dispose() are
already called before the pre-finalizer.

In summary, both Abandon() and the pre-finalizer are not necessary.
This CL removes them.

> Mojo connections are managed by MojoHeap variants. Does
> PrerenderHandle have to explicitly reset them on the context
> destruction?

That's not necessary. MojoHeap variants automatically reset the
connections on the context destruction. This CL removes
ContextLifecycleObserver implementation used for resetting the
connections from PrerenderHandle.

> Is the browser-side abandon code also never used?

No, it's used. Instead of waiting for Abandon() call from a renderer
process, PrerenderLinkManager::LinkPrerender in the browser process
monitors the connection of mojom::PrerenderProcessorClient and abandons
the running prerender on connection destruction. Therefore, this CL
doesn't remove the browser-side code.

Bug: 1130360
Change-Id: I14555530f98d1fb191b04f387636f58a52484c95
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2462987
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarRobert Ogden <robertogden@chromium.org>
Cr-Commit-Position: refs/heads/master@{#816897}
parent 828c2a43
...@@ -125,9 +125,8 @@ base::Optional<int> PrerenderLinkManager::OnStartPrerender( ...@@ -125,9 +125,8 @@ base::Optional<int> PrerenderLinkManager::OnStartPrerender(
std::move(attributes), initiator_origin, std::move(processor_client), std::move(attributes), initiator_origin, std::move(processor_client),
manager_->GetCurrentTimeTicks(), prerender_contents); manager_->GetCurrentTimeTicks(), prerender_contents);
// Observe disconnect of the client and treat as equivalent to explicit // Observe disconnect of the client to abandon the running prerender. The raw
// abandonment. Similar to above, the raw pointer to |this| is safe because // pointer to |this| is safe because |prerender| is owned by |this|.
// |prerender| is owned by |this|.
prerender->remote_processor_client.set_disconnect_handler( prerender->remote_processor_client.set_disconnect_handler(
base::BindOnce(&PrerenderLinkManager::OnAbandonPrerender, base::BindOnce(&PrerenderLinkManager::OnAbandonPrerender,
base::Unretained(this), prerender->prerender_id)); base::Unretained(this), prerender->prerender_id));
......
...@@ -79,14 +79,6 @@ void PrerenderProcessorImpl::Cancel() { ...@@ -79,14 +79,6 @@ void PrerenderProcessorImpl::Cancel() {
link_manager->OnCancelPrerender(*prerender_id_); 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() { PrerenderLinkManager* PrerenderProcessorImpl::GetPrerenderLinkManager() {
auto* render_frame_host = auto* render_frame_host =
content::RenderFrameHost::FromID(render_process_id_, render_frame_id_); content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
......
...@@ -34,7 +34,6 @@ class PrerenderProcessorImpl : public blink::mojom::PrerenderProcessor { ...@@ -34,7 +34,6 @@ class PrerenderProcessorImpl : public blink::mojom::PrerenderProcessor {
mojo::PendingRemote<blink::mojom::PrerenderProcessorClient> client) mojo::PendingRemote<blink::mojom::PrerenderProcessorClient> client)
override; override;
void Cancel() override; void Cancel() override;
void Abandon() override;
private: private:
PrerenderLinkManager* GetPrerenderLinkManager(); PrerenderLinkManager* GetPrerenderLinkManager();
......
...@@ -58,14 +58,4 @@ interface PrerenderProcessor { ...@@ -58,14 +58,4 @@ interface PrerenderProcessor {
// etc. This must be called after Start(). This does not trigger // etc. This must be called after Start(). This does not trigger
// OnPrerenderStop() on PrerenderProcessorClient. // OnPrerenderStop() on PrerenderProcessorClient.
Cancel(); 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();
}; };
...@@ -83,14 +83,10 @@ class MockPrerenderProcessor : public mojom::blink::PrerenderProcessor { ...@@ -83,14 +83,10 @@ class MockPrerenderProcessor : public mojom::blink::PrerenderProcessor {
client_.Bind(std::move(client)); client_.Bind(std::move(client));
} }
void Cancel() override { cancel_count_++; } void Cancel() override { cancel_count_++; }
void Abandon() override { abandon_count_++; }
// Returns the number of times |Cancel| was called. // Returns the number of times |Cancel| was called.
size_t CancelCount() const { return cancel_count_; } size_t CancelCount() const { return cancel_count_; }
// Returns the number of times |Abandon| was called.
size_t AbandonCount() const { return abandon_count_; }
const KURL& Url() const { return attributes_->url; } const KURL& Url() const { return attributes_->url; }
mojom::blink::PrerenderRelType RelType() const { mojom::blink::PrerenderRelType RelType() const {
return attributes_->rel_type; return attributes_->rel_type;
...@@ -122,7 +118,6 @@ class MockPrerenderProcessor : public mojom::blink::PrerenderProcessor { ...@@ -122,7 +118,6 @@ class MockPrerenderProcessor : public mojom::blink::PrerenderProcessor {
mojo::Receiver<mojom::blink::PrerenderProcessor> receiver_{this}; mojo::Receiver<mojom::blink::PrerenderProcessor> receiver_{this};
size_t cancel_count_ = 0; size_t cancel_count_ = 0;
size_t abandon_count_ = 0;
}; };
class PrerenderTest : public testing::Test { class PrerenderTest : public testing::Test {
...@@ -242,7 +237,6 @@ TEST_F(PrerenderTest, SinglePrerender) { ...@@ -242,7 +237,6 @@ TEST_F(PrerenderTest, SinglePrerender) {
EXPECT_EQ(mojom::blink::PrerenderRelType::kPrerender, processor.RelType()); EXPECT_EQ(mojom::blink::PrerenderRelType::kPrerender, processor.RelType());
EXPECT_EQ(0u, processor.CancelCount()); EXPECT_EQ(0u, processor.CancelCount());
EXPECT_EQ(0u, processor.AbandonCount());
EXPECT_FALSE(IsUseCounted(WebFeature::kWebkitPrerenderStartEventFired)); EXPECT_FALSE(IsUseCounted(WebFeature::kWebkitPrerenderStartEventFired));
processor.NotifyDidStartPrerender(); processor.NotifyDidStartPrerender();
...@@ -277,33 +271,10 @@ TEST_F(PrerenderTest, CancelPrerender) { ...@@ -277,33 +271,10 @@ TEST_F(PrerenderTest, CancelPrerender) {
MockPrerenderProcessor& processor = *processors()[0]; MockPrerenderProcessor& processor = *processors()[0];
EXPECT_EQ(0u, processor.CancelCount()); EXPECT_EQ(0u, processor.CancelCount());
EXPECT_EQ(0u, processor.AbandonCount());
ExecuteScript("removePrerender()"); ExecuteScript("removePrerender()");
EXPECT_EQ(1u, processor.CancelCount()); EXPECT_EQ(1u, processor.CancelCount());
EXPECT_EQ(0u, processor.AbandonCount());
}
TEST_F(PrerenderTest, AbandonPrerender) {
Initialize("http://www.foo.com/", "prerender/single_prerender.html");
ASSERT_EQ(processors().size(), 1u);
MockPrerenderProcessor& processor = *processors()[0];
EXPECT_EQ(0u, processor.CancelCount());
EXPECT_EQ(0u, processor.AbandonCount());
NavigateAway();
EXPECT_EQ(0u, processor.CancelCount());
EXPECT_EQ(0u, processor.AbandonCount());
// Check that the prerender does not emit an extra cancel when
// garbage-collecting everything.
Close();
EXPECT_EQ(0u, processor.CancelCount());
EXPECT_EQ(0u, processor.AbandonCount());
} }
TEST_F(PrerenderTest, TwoPrerenders) { TEST_F(PrerenderTest, TwoPrerenders) {
...@@ -316,9 +287,7 @@ TEST_F(PrerenderTest, TwoPrerenders) { ...@@ -316,9 +287,7 @@ TEST_F(PrerenderTest, TwoPrerenders) {
EXPECT_EQ(KURL("http://second-prerender.com/"), second_processor.Url()); EXPECT_EQ(KURL("http://second-prerender.com/"), second_processor.Url());
EXPECT_EQ(0u, first_processor.CancelCount()); EXPECT_EQ(0u, first_processor.CancelCount());
EXPECT_EQ(0u, first_processor.AbandonCount());
EXPECT_EQ(0u, second_processor.CancelCount()); EXPECT_EQ(0u, second_processor.CancelCount());
EXPECT_EQ(0u, second_processor.AbandonCount());
first_processor.NotifyDidStartPrerender(); first_processor.NotifyDidStartPrerender();
EXPECT_EQ(1u, ConsoleLength()); EXPECT_EQ(1u, ConsoleLength());
...@@ -337,23 +306,17 @@ TEST_F(PrerenderTest, TwoPrerendersRemovingFirstThenNavigating) { ...@@ -337,23 +306,17 @@ TEST_F(PrerenderTest, TwoPrerendersRemovingFirstThenNavigating) {
MockPrerenderProcessor& second_processor = *processors()[1]; MockPrerenderProcessor& second_processor = *processors()[1];
EXPECT_EQ(0u, first_processor.CancelCount()); EXPECT_EQ(0u, first_processor.CancelCount());
EXPECT_EQ(0u, first_processor.AbandonCount());
EXPECT_EQ(0u, second_processor.CancelCount()); EXPECT_EQ(0u, second_processor.CancelCount());
EXPECT_EQ(0u, second_processor.AbandonCount());
ExecuteScript("removeFirstPrerender()"); ExecuteScript("removeFirstPrerender()");
EXPECT_EQ(1u, first_processor.CancelCount()); EXPECT_EQ(1u, first_processor.CancelCount());
EXPECT_EQ(0u, first_processor.AbandonCount());
EXPECT_EQ(0u, second_processor.CancelCount()); EXPECT_EQ(0u, second_processor.CancelCount());
EXPECT_EQ(0u, second_processor.AbandonCount());
NavigateAway(); NavigateAway();
EXPECT_EQ(1u, first_processor.CancelCount()); EXPECT_EQ(1u, first_processor.CancelCount());
EXPECT_EQ(0u, first_processor.AbandonCount());
EXPECT_EQ(0u, second_processor.CancelCount()); EXPECT_EQ(0u, second_processor.CancelCount());
EXPECT_EQ(0u, second_processor.AbandonCount());
} }
TEST_F(PrerenderTest, TwoPrerendersAddingThird) { TEST_F(PrerenderTest, TwoPrerendersAddingThird) {
...@@ -364,9 +327,7 @@ TEST_F(PrerenderTest, TwoPrerendersAddingThird) { ...@@ -364,9 +327,7 @@ TEST_F(PrerenderTest, TwoPrerendersAddingThird) {
MockPrerenderProcessor& second_processor = *processors()[1]; MockPrerenderProcessor& second_processor = *processors()[1];
EXPECT_EQ(0u, first_processor.CancelCount()); EXPECT_EQ(0u, first_processor.CancelCount());
EXPECT_EQ(0u, first_processor.AbandonCount());
EXPECT_EQ(0u, second_processor.CancelCount()); EXPECT_EQ(0u, second_processor.CancelCount());
EXPECT_EQ(0u, second_processor.AbandonCount());
ExecuteScript("addThirdPrerender()"); ExecuteScript("addThirdPrerender()");
...@@ -374,11 +335,8 @@ TEST_F(PrerenderTest, TwoPrerendersAddingThird) { ...@@ -374,11 +335,8 @@ TEST_F(PrerenderTest, TwoPrerendersAddingThird) {
MockPrerenderProcessor& third_processor = *processors()[2]; MockPrerenderProcessor& third_processor = *processors()[2];
EXPECT_EQ(0u, first_processor.CancelCount()); EXPECT_EQ(0u, first_processor.CancelCount());
EXPECT_EQ(0u, first_processor.AbandonCount());
EXPECT_EQ(0u, second_processor.CancelCount()); EXPECT_EQ(0u, second_processor.CancelCount());
EXPECT_EQ(0u, second_processor.AbandonCount());
EXPECT_EQ(0u, third_processor.CancelCount()); EXPECT_EQ(0u, third_processor.CancelCount());
EXPECT_EQ(0u, third_processor.AbandonCount());
} }
TEST_F(PrerenderTest, ShortLivedClient) { TEST_F(PrerenderTest, ShortLivedClient) {
...@@ -387,7 +345,6 @@ TEST_F(PrerenderTest, ShortLivedClient) { ...@@ -387,7 +345,6 @@ TEST_F(PrerenderTest, ShortLivedClient) {
MockPrerenderProcessor& processor = *processors()[0]; MockPrerenderProcessor& processor = *processors()[0];
EXPECT_EQ(0u, processor.CancelCount()); EXPECT_EQ(0u, processor.CancelCount());
EXPECT_EQ(0u, processor.AbandonCount());
NavigateAway(); NavigateAway();
Close(); Close();
...@@ -402,7 +359,6 @@ TEST_F(PrerenderTest, FastRemoveElement) { ...@@ -402,7 +359,6 @@ TEST_F(PrerenderTest, FastRemoveElement) {
MockPrerenderProcessor& processor = *processors()[0]; MockPrerenderProcessor& processor = *processors()[0];
EXPECT_EQ(0u, processor.CancelCount()); EXPECT_EQ(0u, processor.CancelCount());
EXPECT_EQ(0u, processor.AbandonCount());
// Race removing & starting the prerender against each other, as if the // Race removing & starting the prerender against each other, as if the
// element was removed very quickly. // element was removed very quickly.
...@@ -411,7 +367,6 @@ TEST_F(PrerenderTest, FastRemoveElement) { ...@@ -411,7 +367,6 @@ TEST_F(PrerenderTest, FastRemoveElement) {
// Removing the element should cancel prerendering. // Removing the element should cancel prerendering.
EXPECT_EQ(1u, processor.CancelCount()); EXPECT_EQ(1u, processor.CancelCount());
EXPECT_EQ(0u, processor.AbandonCount());
// The page should be totally disconnected from the Prerender at this point, // The page should be totally disconnected from the Prerender at this point,
// so the console should not have updated. // so the console should not have updated.
...@@ -426,7 +381,6 @@ TEST_F(PrerenderTest, MutateTarget) { ...@@ -426,7 +381,6 @@ TEST_F(PrerenderTest, MutateTarget) {
EXPECT_EQ(KURL("http://prerender.com/"), processor.Url()); EXPECT_EQ(KURL("http://prerender.com/"), processor.Url());
EXPECT_EQ(0u, processor.CancelCount()); EXPECT_EQ(0u, processor.CancelCount());
EXPECT_EQ(0u, processor.AbandonCount());
// Change the href of this prerender, make sure this is treated as a remove // Change the href of this prerender, make sure this is treated as a remove
// and add. // and add.
...@@ -437,9 +391,7 @@ TEST_F(PrerenderTest, MutateTarget) { ...@@ -437,9 +391,7 @@ TEST_F(PrerenderTest, MutateTarget) {
EXPECT_EQ(KURL("http://mutated.com/"), mutated_processor.Url()); EXPECT_EQ(KURL("http://mutated.com/"), mutated_processor.Url());
EXPECT_EQ(1u, processor.CancelCount()); EXPECT_EQ(1u, processor.CancelCount());
EXPECT_EQ(0u, processor.AbandonCount());
EXPECT_EQ(0u, mutated_processor.CancelCount()); EXPECT_EQ(0u, mutated_processor.CancelCount());
EXPECT_EQ(0u, mutated_processor.AbandonCount());
} }
TEST_F(PrerenderTest, MutateRel) { TEST_F(PrerenderTest, MutateRel) {
...@@ -450,13 +402,11 @@ TEST_F(PrerenderTest, MutateRel) { ...@@ -450,13 +402,11 @@ TEST_F(PrerenderTest, MutateRel) {
EXPECT_EQ(KURL("http://prerender.com/"), processor.Url()); EXPECT_EQ(KURL("http://prerender.com/"), processor.Url());
EXPECT_EQ(0u, processor.CancelCount()); EXPECT_EQ(0u, processor.CancelCount());
EXPECT_EQ(0u, processor.AbandonCount());
// Change the rel of this prerender, make sure this is treated as a remove. // Change the rel of this prerender, make sure this is treated as a remove.
ExecuteScript("mutateRel()"); ExecuteScript("mutateRel()");
EXPECT_EQ(1u, processor.CancelCount()); EXPECT_EQ(1u, processor.CancelCount());
EXPECT_EQ(0u, processor.AbandonCount());
} }
} // namespace blink } // namespace blink
...@@ -89,8 +89,7 @@ PrerenderHandle::PrerenderHandle( ...@@ -89,8 +89,7 @@ PrerenderHandle::PrerenderHandle(
const KURL& url, const KURL& url,
HeapMojoRemote<mojom::blink::PrerenderProcessor> remote_processor, HeapMojoRemote<mojom::blink::PrerenderProcessor> remote_processor,
mojo::PendingReceiver<mojom::blink::PrerenderProcessorClient> receiver) mojo::PendingReceiver<mojom::blink::PrerenderProcessorClient> receiver)
: ExecutionContextLifecycleObserver(context), : url_(url),
url_(url),
client_(client), client_(client),
remote_processor_(std::move(remote_processor)), remote_processor_(std::move(remote_processor)),
receiver_(this, context) { receiver_(this, context) {
...@@ -100,37 +99,17 @@ PrerenderHandle::PrerenderHandle( ...@@ -100,37 +99,17 @@ PrerenderHandle::PrerenderHandle(
PrerenderHandle::~PrerenderHandle() = default; PrerenderHandle::~PrerenderHandle() = default;
void PrerenderHandle::Dispose() {
// 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();
}
void PrerenderHandle::Cancel() { void PrerenderHandle::Cancel() {
// Avoid both abandoning and canceling the same prerender. In the abandon
// case, the LinkLoader cancels the PrerenderHandle as the Document is
// destroyed, even through the ExecutionContextLifecycleObserver has already
// abandoned it.
if (remote_processor_.is_bound()) if (remote_processor_.is_bound())
remote_processor_->Cancel(); remote_processor_->Cancel();
Detach(); remote_processor_.reset();
receiver_.reset();
} }
const KURL& PrerenderHandle::Url() const { const KURL& PrerenderHandle::Url() const {
return url_; return url_;
} }
void PrerenderHandle::ContextDestroyed() {
// A PrerenderHandle is not removed from LifecycleNotifier::m_observers until
// the next GC runs. Thus contextDestroyed() can be called for a
// PrerenderHandle that is already cancelled (and thus detached). In that
// case, we should not detach the PrerenderHandle again.
Dispose();
}
void PrerenderHandle::OnPrerenderStart() { void PrerenderHandle::OnPrerenderStart() {
if (client_) if (client_)
client_->DidStartPrerender(); client_->DidStartPrerender();
...@@ -155,12 +134,6 @@ void PrerenderHandle::Trace(Visitor* visitor) const { ...@@ -155,12 +134,6 @@ void PrerenderHandle::Trace(Visitor* visitor) const {
visitor->Trace(client_); visitor->Trace(client_);
visitor->Trace(remote_processor_); visitor->Trace(remote_processor_);
visitor->Trace(receiver_); visitor->Trace(receiver_);
ExecutionContextLifecycleObserver::Trace(visitor);
}
void PrerenderHandle::Detach() {
remote_processor_.reset();
receiver_.reset();
} }
} // namespace blink } // namespace blink
...@@ -53,12 +53,16 @@ class PrerenderClient; ...@@ -53,12 +53,16 @@ class PrerenderClient;
// instantiated per prerender request, for example, when a new <link // instantiated per prerender request, for example, when a new <link
// rel=prerender> element is added, when the element's href is changed etc. // rel=prerender> element is added, when the element's href is changed etc.
// //
// TODO(https://crbug.com/1126305): Rename this to PrerenderProcessorHandle. // When you no longer need the prerendering page (e.g., when the
// <link rel=prerender> element is removed), you can ask the browser process to
// cancel the running prerender by Cancel(). If mojo connections are reset
// without Cancel() call, the browser process considers this prerendering
// request to be abandoned and may still use the prerendered page if a
// navigation occurs to that URL shortly after.
//
// TODO(https://crbug.com/1126305): Rename this to PrerenderProcessorClient.
class PrerenderHandle final : public GarbageCollected<PrerenderHandle>, class PrerenderHandle final : public GarbageCollected<PrerenderHandle>,
public ExecutionContextLifecycleObserver,
public mojom::blink::PrerenderProcessorClient { public mojom::blink::PrerenderProcessorClient {
USING_PRE_FINALIZER(PrerenderHandle, Dispose);
public: public:
static PrerenderHandle* Create( static PrerenderHandle* Create(
Document&, Document&,
...@@ -75,13 +79,11 @@ class PrerenderHandle final : public GarbageCollected<PrerenderHandle>, ...@@ -75,13 +79,11 @@ class PrerenderHandle final : public GarbageCollected<PrerenderHandle>,
HeapMojoRemote<mojom::blink::PrerenderProcessor>, HeapMojoRemote<mojom::blink::PrerenderProcessor>,
mojo::PendingReceiver<mojom::blink::PrerenderProcessorClient>); mojo::PendingReceiver<mojom::blink::PrerenderProcessorClient>);
~PrerenderHandle() override; ~PrerenderHandle() override;
void Dispose();
// Asks the browser process to cancel the running prerender.
void Cancel(); void Cancel();
const KURL& Url() const;
// ExecutionContextLifecycleObserver: const KURL& Url() const;
void ContextDestroyed() override;
// mojom::blink::PrerenderProcessorClient: // mojom::blink::PrerenderProcessorClient:
void OnPrerenderStart() override; void OnPrerenderStart() override;
...@@ -89,13 +91,11 @@ class PrerenderHandle final : public GarbageCollected<PrerenderHandle>, ...@@ -89,13 +91,11 @@ class PrerenderHandle final : public GarbageCollected<PrerenderHandle>,
void OnPrerenderDomContentLoaded() override; void OnPrerenderDomContentLoaded() override;
void OnPrerenderStop() override; void OnPrerenderStop() override;
void Trace(Visitor*) const override; virtual void Trace(Visitor*) const;
private: private:
void Detach(); const KURL url_;
const WeakMember<PrerenderClient> client_;
KURL url_;
WeakMember<PrerenderClient> client_;
HeapMojoRemote<mojom::blink::PrerenderProcessor> remote_processor_; HeapMojoRemote<mojom::blink::PrerenderProcessor> remote_processor_;
HeapMojoReceiver<mojom::blink::PrerenderProcessorClient, PrerenderHandle> HeapMojoReceiver<mojom::blink::PrerenderProcessorClient, PrerenderHandle>
receiver_; 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