Skip to content

Commit 77e751d

Browse files
author
Derek Cheng
committed
[Presentation API] Fix race condition where Mojo pipes aren't closed.
Race condition introduced in: https://chromium-review.googlesource.com/c/chromium/src/+/724724 The crash is caused by a race condition, where the the renderer attempted to register another PresentationController to PresentationServiceImpl while there is still a (soon-to-be invalid) one already. When we moved the PresentationController implementation from PresentationDispatcher to blink::PresentationController, we are now creating/destoying the PresentationController across navigation (instead of having it long-lived in the PresentationDispatcher / RenderFrameImpl). The fix is to close all message pipes / Reset() in PresentationServiceImpl when a Mojo connection error is detected. This way, the PresentationServiceImpl will be in a clean state when the renderer connects to it again. This also fixes PresentationReceiver's behavior of obtaining a connection to PresentationService and immediately dropping it after calling SetReceiver(), which would let to Reset() getting called with this patch. To merge back to 66 (if possible) and 67. Bug: 832176 Change-Id: Ic7cd2601a107024143936fa9e1ae197505e4cf64 Reviewed-on: https://chromium-review.googlesource.com/1011289 Reviewed-by: mark a. foltz <[email protected]> Reviewed-by: Derek Cheng <[email protected]> Commit-Queue: Derek Cheng <[email protected]> Cr-Original-Commit-Position: refs/heads/master@{#551057}(cherry picked from commit 1ad7724) Reviewed-on: https://chromium-review.googlesource.com/1017319 Cr-Commit-Position: refs/branch-heads/3396@{#85} Cr-Branched-From: 9ef2aa8-refs/heads/master@{#550428}
1 parent 3f2a541 commit 77e751d

File tree

4 files changed

+18
-3
lines changed

4 files changed

+18
-3
lines changed

content/browser/presentation/presentation_service_impl.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ PresentationServiceImpl::PresentationServiceImpl(
6868

6969
if (auto* delegate = GetPresentationServiceDelegate())
7070
delegate->AddObserver(render_process_id_, render_frame_id_, this);
71+
72+
bindings_.set_connection_error_handler(base::BindRepeating(
73+
&PresentationServiceImpl::OnConnectionError, base::Unretained(this)));
7174
}
7275

7376
PresentationServiceImpl::~PresentationServiceImpl() {
@@ -118,6 +121,8 @@ void PresentationServiceImpl::SetController(
118121
return;
119122
}
120123
controller_ = std::move(controller);
124+
controller_.set_connection_error_handler(base::BindOnce(
125+
&PresentationServiceImpl::OnConnectionError, base::Unretained(this)));
121126
}
122127

123128
void PresentationServiceImpl::SetReceiver(
@@ -138,6 +143,8 @@ void PresentationServiceImpl::SetReceiver(
138143
}
139144

140145
receiver_ = std::move(receiver);
146+
receiver_.set_connection_error_handler(base::BindOnce(
147+
&PresentationServiceImpl::OnConnectionError, base::Unretained(this)));
141148
receiver_delegate_->RegisterReceiverConnectionAvailableCallback(
142149
base::Bind(&PresentationServiceImpl::OnReceiverConnectionAvailable,
143150
weak_factory_.GetWeakPtr()));
@@ -387,6 +394,10 @@ bool PresentationServiceImpl::FrameMatches(
387394
render_frame_host->GetRoutingID() == render_frame_id_;
388395
}
389396

397+
void PresentationServiceImpl::OnConnectionError() {
398+
Reset();
399+
}
400+
390401
PresentationServiceDelegate*
391402
PresentationServiceImpl::GetPresentationServiceDelegate() {
392403
return receiver_delegate_

content/browser/presentation/presentation_service_impl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ class CONTENT_EXPORT PresentationServiceImpl
239239
// Returns true if this object is associated with |render_frame_host|.
240240
bool FrameMatches(content::RenderFrameHost* render_frame_host) const;
241241

242+
// Invoked on Mojo connection error. Closes all Mojo message pipes held by
243+
// |this|.
244+
void OnConnectionError();
245+
242246
// Returns |controller_delegate| if current frame is controller frame; Returns
243247
// |receiver_delegate| if current frame is receiver frame.
244248
PresentationServiceDelegate* GetPresentationServiceDelegate();

third_party/blink/renderer/modules/presentation/presentation_receiver.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,12 @@ ScriptPromise PresentationReceiver::connectionList(ScriptState* script_state) {
6666
void PresentationReceiver::Init() {
6767
DCHECK(!receiver_binding_.is_bound());
6868

69-
mojom::blink::PresentationServicePtr presentation_service;
7069
auto* interface_provider = GetFrame()->Client()->GetInterfaceProvider();
71-
interface_provider->GetInterface(mojo::MakeRequest(&presentation_service));
70+
interface_provider->GetInterface(mojo::MakeRequest(&presentation_service_));
7271

7372
mojom::blink::PresentationReceiverPtr receiver_ptr;
7473
receiver_binding_.Bind(mojo::MakeRequest(&receiver_ptr));
75-
presentation_service->SetReceiver(std::move(receiver_ptr));
74+
presentation_service_->SetReceiver(std::move(receiver_ptr));
7675
}
7776

7877
void PresentationReceiver::OnReceiverTerminated() {

third_party/blink/renderer/modules/presentation/presentation_receiver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class MODULES_EXPORT PresentationReceiver final
7979
Member<PresentationConnectionList> connection_list_;
8080

8181
mojo::Binding<mojom::blink::PresentationReceiver> receiver_binding_;
82+
mojom::blink::PresentationServicePtr presentation_service_;
8283
WebPresentationClient* client_;
8384
};
8485

0 commit comments

Comments
 (0)