Skip to content

Commit

Permalink
Picture-in-Picture: notifies the controller when window closed via sy…
Browse files Browse the repository at this point in the history
…stem.

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/1147252
Reviewed-by: Camille Lamy <[email protected]>
Reviewed-by: apacible <[email protected]>
Commit-Queue: Mounir Lamouri <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#577594}(cherry picked from commit c04a9a2)
Reviewed-on: https://chromium-review.googlesource.com/1150580
Reviewed-by: Mounir Lamouri <[email protected]>
Cr-Commit-Position: refs/branch-heads/3497@{#83}
Cr-Branched-From: 271eaf5-refs/heads/master@{#576753}
  • Loading branch information
mounirlamouri committed Jul 25, 2018
1 parent 7f5bca9 commit 05cac71
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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)
4 changes: 4 additions & 0 deletions chrome/browser/ui/views/overlay/overlay_window_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,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
Expand Down
1 change: 1 addition & 0 deletions chrome/browser/ui/views/overlay/overlay_window_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.";
}

Expand All @@ -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;

Expand Down Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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_;
Expand Down
7 changes: 7 additions & 0 deletions content/public/browser/picture_in_picture_window_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 05cac71

Please sign in to comment.