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,
#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)
......@@ -604,6 +604,10 @@ void OverlayWindowViews::OnNativeWidgetSizeChanged(const gfx::Size& new_size) {
views::Widget::OnNativeWidgetSizeChanged(new_size);
}
void OverlayWindowViews::OnNativeWidgetDestroyed() {
controller_->OnWindowDestroyed();
}
void OverlayWindowViews::TogglePlayPause() {
// Retrieve expected active state based on what command was sent in
// TogglePlayPause() since the IPC message may not have been propogated
......
......@@ -51,6 +51,7 @@ class OverlayWindowViews : public content::OverlayWindow, public views::Widget {
void OnNativeBlur() override;
void OnNativeWidgetMove() override;
void OnNativeWidgetSizeChanged(const gfx::Size& new_size) override;
void OnNativeWidgetDestroyed() override;
// Gets the bounds of the controls.
gfx::Rect GetCloseControlsBounds();
......
......@@ -58,8 +58,7 @@ PictureInPictureWindowControllerImpl::PictureInPictureWindowControllerImpl(
media_web_contents_observer_ = initiator_->media_web_contents_observer();
window_ =
GetContentClient()->browser()->CreateWindowForPictureInPicture(this);
EnsureWindow();
DCHECK(window_) << "Picture in Picture requires a valid window.";
}
......@@ -84,23 +83,25 @@ void PictureInPictureWindowControllerImpl::ClickCustomControl(
}
void PictureInPictureWindowControllerImpl::Close(bool should_pause_video) {
DCHECK(window_);
if (!window_->IsVisible())
if (!window_ || !window_->IsVisible())
return;
window_->Hide();
initiator_->SetHasPictureInPictureVideo(false);
surface_id_ = viz::SurfaceId();
CloseInternal(should_pause_video);
}
OnLeavingPictureInPicture(should_pause_video);
void PictureInPictureWindowControllerImpl::OnWindowDestroyed() {
window_ = nullptr;
embedder_ = nullptr;
CloseInternal(true /* should_pause_video */);
}
void PictureInPictureWindowControllerImpl::EmbedSurface(
const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) {
EnsureWindow();
DCHECK(window_);
DCHECK(surface_id.is_valid());
surface_id_ = surface_id;
......@@ -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
......@@ -36,6 +36,7 @@ class PictureInPictureWindowControllerImpl
// PictureInPictureWindowController:
CONTENT_EXPORT gfx::Size Show() override;
CONTENT_EXPORT void Close(bool should_pause_video) override;
CONTENT_EXPORT void OnWindowDestroyed() override;
CONTENT_EXPORT void ClickCustomControl(
const std::string& control_id) override;
CONTENT_EXPORT void EmbedSurface(const viz::SurfaceId& surface_id,
......@@ -59,6 +60,14 @@ class PictureInPictureWindowControllerImpl
// Signal to the media player that |this| is leaving Picture-in-Picture mode.
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<OverlaySurfaceEmbedder> embedder_;
WebContentsImpl* const initiator_;
......
......@@ -38,7 +38,14 @@ class PictureInPictureWindowController {
// Returns the size of the window in pixels.
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;
// 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 EmbedSurface(const viz::SurfaceId& surface_id,
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