Index: content/browser/renderer_host/render_widget_host_view_android.cc |
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc |
index 2da5ad962dfed375abda9c138e1ef5a92d183fbd..39f467ad7625a9894902e9625cea13ff146090b6 100644 |
--- a/content/browser/renderer_host/render_widget_host_view_android.cc |
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc |
@@ -565,6 +565,12 @@ void RenderWidgetHostViewAndroid::WasResized() { |
host_->WasResized(); |
} |
+void RenderWidgetHostViewAndroid::OnFullscreenStateChanged( |
+ bool entered_fullscreen) { |
+ web_contents_is_fullscreen_ = entered_fullscreen; |
+ UpdateFullscreenStateAndEvictFrameIfNeeded(); |
+} |
+ |
void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) { |
// Ignore the given size as only the Java code has the power to |
// resize the view on Android. |
@@ -1184,6 +1190,65 @@ void RenderWidgetHostViewAndroid::DidCreateNewRendererCompositorFrameSink( |
surface_returned_resources_.clear(); |
} |
+void RenderWidgetHostViewAndroid::UpdateFullscreenStateAndEvictFrameIfNeeded() { |
+ UpdateFullscreenState(); |
+ if (IsInFullscreenTransition()) { |
+ // When we're in a fullscreen transition, we don't want to show a frame |
+ // since it will look janky, so instead we show black. |
+ EvictDelegatedFrame(); |
+ UpdateBackgroundColor(SK_ColorBLACK); |
+ ClearThumbnailPlaceholder(); |
+ } |
+} |
+ |
+void RenderWidgetHostViewAndroid::UpdateFullscreenState() { |
+ bool mismatched_fullscreen_states = |
+ web_contents_is_fullscreen_ != current_frame_is_fullscreen_; |
+ bool mismatched_sizes = |
+ view_.GetPhysicalBackingSize() != current_surface_size_; |
+ |
+ switch (fullscreen_state_) { |
+ // From kNotFullscreen, we transition to kEnteringFullscreen whenever the |
+ // fullscreen state changes. |
+ case FullscreenState::kNotFullscreen: |
+ if (mismatched_fullscreen_states) { |
+ DCHECK(web_contents_is_fullscreen_); |
+ fullscreen_state_ = FullscreenState::kEnteringFullscreen; |
+ fullscreen_transition_awaiting_resize_ = true; |
+ } |
+ break; |
+ // From kFullscreen, we transition to kExitingFullscreen on a fullscreen |
+ // state change, or to kFullscreenRotation if we get a new size. |
+ case FullscreenState::kFullscreen: |
+ if (mismatched_fullscreen_states) { |
+ DCHECK(!web_contents_is_fullscreen_); |
+ fullscreen_state_ = FullscreenState::kExitingFullscreen; |
+ fullscreen_transition_awaiting_resize_ = true; |
+ } else if (mismatched_sizes) { |
+ fullscreen_state_ = FullscreenState::kFullscreenRotation; |
+ } |
+ break; |
+ // From any transition state, once we receive a "good" frame we transition |
+ // to the proper "good" state. |
+ case FullscreenState::kExitingFullscreen: |
+ case FullscreenState::kEnteringFullscreen: |
+ case FullscreenState::kFullscreenRotation: |
+ if (!mismatched_fullscreen_states && !mismatched_sizes && |
+ !fullscreen_transition_awaiting_resize_) { |
+ fullscreen_state_ = web_contents_is_fullscreen_ |
+ ? FullscreenState::kFullscreen |
+ : FullscreenState::kNotFullscreen; |
+ } |
+ break; |
+ } |
+} |
+ |
+bool RenderWidgetHostViewAndroid::IsInFullscreenTransition() const { |
+ return (fullscreen_state_ == FullscreenState::kEnteringFullscreen || |
+ fullscreen_state_ == FullscreenState::kExitingFullscreen || |
+ fullscreen_state_ == FullscreenState::kFullscreenRotation); |
+} |
+ |
void RenderWidgetHostViewAndroid::SubmitCompositorFrame( |
const cc::LocalSurfaceId& local_surface_id, |
cc::CompositorFrame frame) { |
@@ -1243,6 +1308,7 @@ void RenderWidgetHostViewAndroid::DestroyDelegatedContent() { |
frame_evictor_->DiscardedFrame(); |
delegated_frame_host_->DestroyDelegatedContent(); |
+ current_surface_size_.SetSize(0, 0); |
} |
void RenderWidgetHostViewAndroid::OnDidNotProduceFrame( |
@@ -1455,6 +1521,7 @@ void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated( |
touch_selection_controller_->OnViewportChanged(viewport_rect); |
} |
+ current_frame_is_fullscreen_ = frame_metadata.is_fullscreen; |
UpdateBackgroundColor(is_transparent ? SK_ColorTRANSPARENT |
: frame_metadata.root_background_color); |
@@ -1488,6 +1555,8 @@ void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated( |
frame_metadata.top_controls_height * |
frame_metadata.top_controls_shown_ratio, |
top_shown_pix, top_changed, is_mobile_optimized); |
+ |
+ UpdateFullscreenStateAndEvictFrameIfNeeded(); |
} |
void RenderWidgetHostViewAndroid::ShowInternal() { |
@@ -1930,6 +1999,10 @@ SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const { |
return cached_background_color_; |
} |
+void RenderWidgetHostViewAndroid::ClearThumbnailPlaceholder() { |
+ view_.ClearThumbnailPlaceholder(); |
+} |
+ |
void RenderWidgetHostViewAndroid::SetIsInVR(bool is_in_vr) { |
is_in_vr_ = is_in_vr; |
} |
@@ -2059,6 +2132,8 @@ void RenderWidgetHostViewAndroid::OnGestureEvent( |
} |
void RenderWidgetHostViewAndroid::OnPhysicalBackingSizeChanged() { |
+ fullscreen_transition_awaiting_resize_ = false; |
+ UpdateFullscreenStateAndEvictFrameIfNeeded(); |
WasResized(); |
} |