Commit c04a9a27 authored by Mounir Lamouri's avatar Mounir Lamouri Committed by Commit Bot

Picture-in-Picture: notifies the controller when window closed via system.

When the internal object is destroyed, notify the controller so it can
reset its internal state. It allows the user to close the window via any
system/window manager UI.

Bug: 863842
Change-Id: Ica84f4ffee2578658a60e0ae708a4e327d293077
Reviewed-on: https://chromium-review.googlesource.com/1147252Reviewed-by: default avatarCamille Lamy <clamy@chromium.org>
Reviewed-by: default avatarapacible <apacible@chromium.org>
Commit-Queue: Mounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577594}
parent 109f9eed
...@@ -916,4 +916,27 @@ IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest, ...@@ -916,4 +916,27 @@ IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS)
// Tests that the Picture-in-Picture state is properly updated when the window
// is closed at a system level.
IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
CloseWindowNotifiesController) {
LoadTabAndEnterPictureInPicture(browser());
content::WebContents* active_web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>(
window_controller()->GetWindowForTesting());
ASSERT_TRUE(overlay_window);
ASSERT_TRUE(overlay_window->IsVisible());
// Simulate closing from the system.
overlay_window->OnNativeWidgetDestroyed();
bool in_picture_in_picture = false;
ASSERT_TRUE(ExecuteScriptAndExtractBool(
active_web_contents, "isInPictureInPicture();", &in_picture_in_picture));
EXPECT_FALSE(in_picture_in_picture);
}
#endif // !defined(OS_ANDROID) #endif // !defined(OS_ANDROID)
...@@ -604,6 +604,10 @@ void OverlayWindowViews::OnNativeWidgetSizeChanged(const gfx::Size& new_size) { ...@@ -604,6 +604,10 @@ void OverlayWindowViews::OnNativeWidgetSizeChanged(const gfx::Size& new_size) {
views::Widget::OnNativeWidgetSizeChanged(new_size); views::Widget::OnNativeWidgetSizeChanged(new_size);
} }
void OverlayWindowViews::OnNativeWidgetDestroyed() {
controller_->OnWindowDestroyed();
}
void OverlayWindowViews::TogglePlayPause() { void OverlayWindowViews::TogglePlayPause() {
// Retrieve expected active state based on what command was sent in // Retrieve expected active state based on what command was sent in
// TogglePlayPause() since the IPC message may not have been propogated // TogglePlayPause() since the IPC message may not have been propogated
......
...@@ -51,6 +51,7 @@ class OverlayWindowViews : public content::OverlayWindow, public views::Widget { ...@@ -51,6 +51,7 @@ class OverlayWindowViews : public content::OverlayWindow, public views::Widget {
void OnNativeBlur() override; void OnNativeBlur() override;
void OnNativeWidgetMove() override; void OnNativeWidgetMove() override;
void OnNativeWidgetSizeChanged(const gfx::Size& new_size) override; void OnNativeWidgetSizeChanged(const gfx::Size& new_size) override;
void OnNativeWidgetDestroyed() override;
// Gets the bounds of the controls. // Gets the bounds of the controls.
gfx::Rect GetCloseControlsBounds(); gfx::Rect GetCloseControlsBounds();
......
...@@ -58,8 +58,7 @@ PictureInPictureWindowControllerImpl::PictureInPictureWindowControllerImpl( ...@@ -58,8 +58,7 @@ PictureInPictureWindowControllerImpl::PictureInPictureWindowControllerImpl(
media_web_contents_observer_ = initiator_->media_web_contents_observer(); media_web_contents_observer_ = initiator_->media_web_contents_observer();
window_ = EnsureWindow();
GetContentClient()->browser()->CreateWindowForPictureInPicture(this);
DCHECK(window_) << "Picture in Picture requires a valid window."; DCHECK(window_) << "Picture in Picture requires a valid window.";
} }
...@@ -84,23 +83,25 @@ void PictureInPictureWindowControllerImpl::ClickCustomControl( ...@@ -84,23 +83,25 @@ void PictureInPictureWindowControllerImpl::ClickCustomControl(
} }
void PictureInPictureWindowControllerImpl::Close(bool should_pause_video) { void PictureInPictureWindowControllerImpl::Close(bool should_pause_video) {
DCHECK(window_); if (!window_ || !window_->IsVisible())
if (!window_->IsVisible())
return; return;
window_->Hide(); window_->Hide();
initiator_->SetHasPictureInPictureVideo(false); CloseInternal(should_pause_video);
}
surface_id_ = viz::SurfaceId();
OnLeavingPictureInPicture(should_pause_video); void PictureInPictureWindowControllerImpl::OnWindowDestroyed() {
window_ = nullptr;
embedder_ = nullptr;
CloseInternal(true /* should_pause_video */);
} }
void PictureInPictureWindowControllerImpl::EmbedSurface( void PictureInPictureWindowControllerImpl::EmbedSurface(
const viz::SurfaceId& surface_id, const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) { const gfx::Size& natural_size) {
EnsureWindow();
DCHECK(window_); DCHECK(window_);
DCHECK(surface_id.is_valid()); DCHECK(surface_id.is_valid());
surface_id_ = surface_id; surface_id_ = surface_id;
...@@ -195,4 +196,21 @@ void PictureInPictureWindowControllerImpl::OnLeavingPictureInPicture( ...@@ -195,4 +196,21 @@ void PictureInPictureWindowControllerImpl::OnLeavingPictureInPicture(
} }
} }
void PictureInPictureWindowControllerImpl::CloseInternal(
bool should_pause_video) {
initiator_->SetHasPictureInPictureVideo(false);
surface_id_ = viz::SurfaceId();
OnLeavingPictureInPicture(should_pause_video);
}
void PictureInPictureWindowControllerImpl::EnsureWindow() {
if (window_)
return;
window_ =
GetContentClient()->browser()->CreateWindowForPictureInPicture(this);
}
} // namespace content } // namespace content
...@@ -36,6 +36,7 @@ class PictureInPictureWindowControllerImpl ...@@ -36,6 +36,7 @@ class PictureInPictureWindowControllerImpl
// PictureInPictureWindowController: // PictureInPictureWindowController:
CONTENT_EXPORT gfx::Size Show() override; CONTENT_EXPORT gfx::Size Show() override;
CONTENT_EXPORT void Close(bool should_pause_video) override; CONTENT_EXPORT void Close(bool should_pause_video) override;
CONTENT_EXPORT void OnWindowDestroyed() override;
CONTENT_EXPORT void ClickCustomControl( CONTENT_EXPORT void ClickCustomControl(
const std::string& control_id) override; const std::string& control_id) override;
CONTENT_EXPORT void EmbedSurface(const viz::SurfaceId& surface_id, CONTENT_EXPORT void EmbedSurface(const viz::SurfaceId& surface_id,
...@@ -59,6 +60,14 @@ class PictureInPictureWindowControllerImpl ...@@ -59,6 +60,14 @@ class PictureInPictureWindowControllerImpl
// Signal to the media player that |this| is leaving Picture-in-Picture mode. // Signal to the media player that |this| is leaving Picture-in-Picture mode.
void OnLeavingPictureInPicture(bool should_pause_video); void OnLeavingPictureInPicture(bool should_pause_video);
// Internal method to set the states after the window was closed, whether via
// the system or Chromium.
void CloseInternal(bool should_pause_video);
// Creates a new window if the previous one was destroyed. It can happen
// because of the system control of the window.
void EnsureWindow();
std::unique_ptr<OverlayWindow> window_; std::unique_ptr<OverlayWindow> window_;
std::unique_ptr<OverlaySurfaceEmbedder> embedder_; std::unique_ptr<OverlaySurfaceEmbedder> embedder_;
WebContentsImpl* const initiator_; WebContentsImpl* const initiator_;
......
...@@ -38,7 +38,14 @@ class PictureInPictureWindowController { ...@@ -38,7 +38,14 @@ class PictureInPictureWindowController {
// Returns the size of the window in pixels. // Returns the size of the window in pixels.
virtual gfx::Size Show() = 0; virtual gfx::Size Show() = 0;
// Called to notify the controller that the window was requested to be closed
// by the user or the content.
virtual void Close(bool should_pause_video) = 0; virtual void Close(bool should_pause_video) = 0;
// Called by the window implementation to notify the controller that the
// window was requested to be closed and destroyed by the system.
virtual void OnWindowDestroyed() = 0;
virtual void ClickCustomControl(const std::string& control_id) = 0; virtual void ClickCustomControl(const std::string& control_id) = 0;
virtual void EmbedSurface(const viz::SurfaceId& surface_id, virtual void EmbedSurface(const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) = 0; const gfx::Size& natural_size) = 0;
......
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