Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(722)

Unified Diff: content/browser/media/capture/web_contents_video_capture_device.cc

Issue 2602923002: Tab capture: Tracking continues after renderer crash. (Closed)
Patch Set: nits Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/media/capture/web_contents_tracker.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/media/capture/web_contents_video_capture_device.cc
diff --git a/content/browser/media/capture/web_contents_video_capture_device.cc b/content/browser/media/capture/web_contents_video_capture_device.cc
index d258238ef7e97762740a5c88a48ce5dbab96c9b2..aae4ed1de690b7d6c0d94d6dca7dbe580873eec1 100644
--- a/content/browser/media/capture/web_contents_video_capture_device.cc
+++ b/content/browser/media/capture/web_contents_video_capture_device.cc
@@ -155,7 +155,7 @@ class FrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
base::WeakPtrFactory<FrameSubscriber> weak_ptr_factory_;
};
-// ContentCaptureSubscription is the relationship between a RenderWidgetHost
+// ContentCaptureSubscription is the relationship between a RenderWidgetHostView
// whose content is updating, a subscriber that is deciding which of these
// updates to capture (and where to deliver them to), and a callback that
// knows how to do the capture and prepare the result for delivery.
@@ -180,7 +180,7 @@ class ContentCaptureSubscription {
// subscription will invoke |capture_callback| on the UI thread to do the
// work.
ContentCaptureSubscription(
- const RenderWidgetHost& source,
+ base::WeakPtr<RenderWidgetHostViewBase> source_view,
const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy,
const CaptureCallback& capture_callback);
~ContentCaptureSubscription();
@@ -191,11 +191,7 @@ class ContentCaptureSubscription {
// Called for active frame refresh requests, or mouse activity events.
void OnEvent(FrameSubscriber* subscriber);
- // Maintain a weak reference to the RenderWidgetHost (via its routing ID),
- // since the instance could be destroyed externally during the lifetime of
- // |this|.
- const int render_process_id_;
- const int render_widget_id_;
+ const base::WeakPtr<RenderWidgetHostViewBase> source_view_;
std::unique_ptr<FrameSubscriber> refresh_subscriber_;
std::unique_ptr<FrameSubscriber> mouse_activity_subscriber_;
@@ -288,9 +284,10 @@ class WebContentsCaptureMachine : public media::VideoCaptureMachine {
const gfx::Rect& region_in_frame,
bool success);
- // Remove the old subscription, and attempt to start a new one if |had_target|
- // is true.
- void RenewFrameSubscription(bool had_target);
+ // Remove the old subscription, and attempt to start a new one. If
+ // |is_still_tracking| is false, emit an error rather than attempt to start a
+ // new subscription.
+ void RenewFrameSubscription(bool is_still_tracking);
// Called whenever the render widget is resized.
void UpdateCaptureSize();
@@ -300,7 +297,7 @@ class WebContentsCaptureMachine : public media::VideoCaptureMachine {
const int initial_main_render_frame_id_;
// Tracks events and calls back to RenewFrameSubscription() to maintain
- // capture on the correct RenderWidgetHost.
+ // capture on the correct RenderWidgetHostView.
const scoped_refptr<WebContentsTracker> tracker_;
// Set to false to prevent the capture size from automatically adjusting in
@@ -404,21 +401,17 @@ bool FrameSubscriber::IsUserInteractingWithContent() {
}
ContentCaptureSubscription::ContentCaptureSubscription(
- const RenderWidgetHost& source,
+ base::WeakPtr<RenderWidgetHostViewBase> source_view,
const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy,
const CaptureCallback& capture_callback)
- : render_process_id_(source.GetProcess()->GetID()),
- render_widget_id_(source.GetRoutingID()),
- capture_callback_(capture_callback) {
+ : source_view_(source_view), capture_callback_(capture_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(source_view_);
- RenderWidgetHostView* const view = source.GetView();
#if defined(USE_AURA) || defined(OS_MACOSX)
- if (view) {
- cursor_renderer_ = CursorRenderer::Create(view->GetNativeView());
- window_activity_tracker_ =
- WindowActivityTracker::Create(view->GetNativeView());
- }
+ cursor_renderer_ = CursorRenderer::Create(source_view_->GetNativeView());
+ window_activity_tracker_ =
+ WindowActivityTracker::Create(source_view_->GetNativeView());
#endif
refresh_subscriber_.reset(new FrameSubscriber(
media::VideoCaptureOracle::kActiveRefreshRequest, oracle_proxy,
@@ -435,16 +428,14 @@ ContentCaptureSubscription::ContentCaptureSubscription(
// Subscribe to compositor updates. These will be serviced directly by the
// oracle.
- if (view) {
- std::unique_ptr<RenderWidgetHostViewFrameSubscriber> subscriber(
- new FrameSubscriber(
- media::VideoCaptureOracle::kCompositorUpdate, oracle_proxy,
- cursor_renderer_ ? cursor_renderer_->GetWeakPtr()
- : base::WeakPtr<CursorRenderer>(),
- window_activity_tracker_ ? window_activity_tracker_->GetWeakPtr()
- : base::WeakPtr<WindowActivityTracker>()));
- view->BeginFrameSubscription(std::move(subscriber));
- }
+ std::unique_ptr<RenderWidgetHostViewFrameSubscriber> subscriber(
+ new FrameSubscriber(
+ media::VideoCaptureOracle::kCompositorUpdate, oracle_proxy,
+ cursor_renderer_ ? cursor_renderer_->GetWeakPtr()
+ : base::WeakPtr<CursorRenderer>(),
+ window_activity_tracker_ ? window_activity_tracker_->GetWeakPtr()
+ : base::WeakPtr<WindowActivityTracker>()));
+ source_view_->BeginFrameSubscription(std::move(subscriber));
// Subscribe to mouse movement and mouse cursor update events.
if (window_activity_tracker_) {
@@ -462,11 +453,13 @@ ContentCaptureSubscription::~ContentCaptureSubscription() {
return;
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- RenderWidgetHost* const source =
- RenderWidgetHost::FromID(render_process_id_, render_widget_id_);
- RenderWidgetHostView* const view = source ? source->GetView() : NULL;
- if (view)
- view->EndFrameSubscription();
+ // If the RWHV weak pointer is still valid, make sure the view is still
+ // associated with a RWH before attempting to end the frame subscription. This
+ // is because a null RWH indicates the RWHV has had its Destroy() method
+ // called, which makes it invalid to call any of its methods that assume the
+ // compositor is present.
+ if (source_view_ && source_view_->GetRenderWidgetHost())
+ source_view_->EndFrameSubscription();
}
void ContentCaptureSubscription::MaybeCaptureForRefresh() {
@@ -641,7 +634,7 @@ void WebContentsCaptureMachine::InternalSuspend() {
return;
frame_capture_active_ = false;
if (IsStarted())
- RenewFrameSubscription(true);
+ RenewFrameSubscription(tracker_->is_still_tracking());
}
void WebContentsCaptureMachine::Resume() {
@@ -656,7 +649,7 @@ void WebContentsCaptureMachine::InternalResume() {
return;
frame_capture_active_ = true;
if (IsStarted())
- RenewFrameSubscription(true);
+ RenewFrameSubscription(tracker_->is_still_tracking());
}
void WebContentsCaptureMachine::Stop(const base::Closure& callback) {
@@ -714,9 +707,8 @@ void WebContentsCaptureMachine::Capture(
deliver_frame_cb) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- RenderWidgetHost* rwh = tracker_->GetTargetRenderWidgetHost();
- RenderWidgetHostViewBase* view =
- rwh ? static_cast<RenderWidgetHostViewBase*>(rwh->GetView()) : NULL;
+ auto* const view =
+ static_cast<RenderWidgetHostViewBase*>(tracker_->GetTargetView());
if (!view) {
deliver_frame_cb.Run(base::TimeTicks(), gfx::Rect(), false);
return;
@@ -736,13 +728,15 @@ void WebContentsCaptureMachine::Capture(
? gfx::Size()
: media::ComputeLetterboxRegion(target->visible_rect(), view_size)
.size();
- rwh->CopyFromBackingStore(
- gfx::Rect(),
- fitted_size, // Size here is a request not always honored.
- base::Bind(&WebContentsCaptureMachine::DidCopyFromBackingStore,
- weak_ptr_factory_.GetWeakPtr(), start_time, target,
- deliver_frame_cb),
- kN32_SkColorType);
+ if (auto* rwh = view->GetRenderWidgetHost()) {
+ rwh->CopyFromBackingStore(
+ gfx::Rect(),
+ fitted_size, // Size here is a request not always honored.
+ base::Bind(&WebContentsCaptureMachine::DidCopyFromBackingStore,
+ weak_ptr_factory_.GetWeakPtr(), start_time, target,
+ deliver_frame_cb),
+ kN32_SkColorType);
+ }
}
}
@@ -795,9 +789,7 @@ gfx::Size WebContentsCaptureMachine::ComputeOptimalViewSize() const {
// render widget to the "preferred size," the widget will be physically
// rendered at the exact capture size, thereby eliminating unnecessary scaling
// operations in the graphics pipeline.
- RenderWidgetHost* const rwh = tracker_->GetTargetRenderWidgetHost();
- RenderWidgetHostView* const rwhv = rwh ? rwh->GetView() : NULL;
- if (rwhv) {
+ if (auto* rwhv = tracker_->GetTargetView()) {
const gfx::NativeView view = rwhv->GetNativeView();
const float scale = ui::GetScaleFactorForNativeView(view);
if (scale > 1.0f) {
@@ -849,20 +841,16 @@ void WebContentsCaptureMachine::DidCopyFromCompositingSurfaceToVideoFrame(
deliver_frame_cb.Run(start_time, region_in_frame, success);
}
-void WebContentsCaptureMachine::RenewFrameSubscription(bool had_target) {
+void WebContentsCaptureMachine::RenewFrameSubscription(bool is_still_tracking) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- RenderWidgetHost* const rwh =
- had_target ? tracker_->GetTargetRenderWidgetHost() : nullptr;
-
// Always destroy the old subscription before creating a new one.
if (subscription_) {
- DVLOG(1) << "Cancelling existing ContentCaptureSubscription.";
+ DVLOG(1) << "Cancelling existing subscription.";
subscription_.reset();
}
- if (!rwh) {
- DVLOG(1) << "Cannot renew ContentCaptureSubscription: no RWH target.";
+ if (!is_still_tracking) {
if (IsStarted()) {
// Tracking of WebContents and/or its main frame has failed before Stop()
// was called, so report this as an error:
@@ -872,12 +860,23 @@ void WebContentsCaptureMachine::RenewFrameSubscription(bool had_target) {
return;
}
- if (frame_capture_active_) {
- DVLOG(1) << "Renewing ContentCaptureSubscription to RWH@" << rwh;
- subscription_.reset(new ContentCaptureSubscription(
- *rwh, oracle_proxy_, base::Bind(&WebContentsCaptureMachine::Capture,
- weak_ptr_factory_.GetWeakPtr())));
+ if (!frame_capture_active_) {
+ DVLOG(1) << "Not renewing subscription: Frame capture is suspended.";
+ return;
+ }
+
+ auto* const view =
+ static_cast<RenderWidgetHostViewBase*>(tracker_->GetTargetView());
+ if (!view) {
+ DVLOG(1) << "Cannot renew subscription: No view to capture.";
+ return;
}
+
+ DVLOG(1) << "Renewing subscription to RenderWidgetHostView@" << view;
+ subscription_.reset(new ContentCaptureSubscription(
+ view->GetWeakPtr(), oracle_proxy_,
+ base::Bind(&WebContentsCaptureMachine::Capture,
+ weak_ptr_factory_.GetWeakPtr())));
}
void WebContentsCaptureMachine::UpdateCaptureSize() {
@@ -885,8 +884,7 @@ void WebContentsCaptureMachine::UpdateCaptureSize() {
if (!oracle_proxy_)
return;
- RenderWidgetHost* const rwh = tracker_->GetTargetRenderWidgetHost();
- RenderWidgetHostView* const view = rwh ? rwh->GetView() : nullptr;
+ RenderWidgetHostView* const view = tracker_->GetTargetView();
if (!view)
return;
« no previous file with comments | « content/browser/media/capture/web_contents_tracker.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698