summaryrefslogtreecommitdiff
path: root/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc')
-rw-r--r--chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc96
1 files changed, 75 insertions, 21 deletions
diff --git a/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc b/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
index e3c6e4fa4ed..f0835214f02 100644
--- a/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
+++ b/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
@@ -40,30 +40,48 @@ PictureInPictureWindowControllerImpl::GetOrCreateForWebContents(
PictureInPictureWindowControllerImpl::~PictureInPictureWindowControllerImpl() {
if (window_)
window_->Close();
+
+ // If the initiator WebContents is being destroyed, there is no need to put
+ // the video's media player in a post-Picture-in-Picture mode. In fact, some
+ // things, such as the MediaWebContentsObserver, may already been torn down.
+ if (initiator_->IsBeingDestroyed())
+ return;
+
+ initiator_->SetHasPictureInPictureVideo(false);
+ OnLeavingPictureInPicture();
}
PictureInPictureWindowControllerImpl::PictureInPictureWindowControllerImpl(
WebContents* initiator)
- : initiator_(initiator) {
+ : initiator_(static_cast<WebContentsImpl* const>(initiator)) {
DCHECK(initiator_);
+ media_web_contents_observer_ = initiator_->media_web_contents_observer();
+
window_ =
- content::GetContentClient()->browser()->CreateWindowForPictureInPicture(
- this);
+ GetContentClient()->browser()->CreateWindowForPictureInPicture(this);
DCHECK(window_) << "Picture in Picture requires a valid window.";
}
-void PictureInPictureWindowControllerImpl::Show() {
+gfx::Size PictureInPictureWindowControllerImpl::Show() {
DCHECK(window_);
DCHECK(surface_id_.is_valid());
+
window_->Show();
+ initiator_->SetHasPictureInPictureVideo(true);
+
+ return window_->GetBounds().size();
}
void PictureInPictureWindowControllerImpl::Close() {
- if (window_)
- window_->Close();
+ DCHECK(window_);
+
+ window_->Hide();
+ initiator_->SetHasPictureInPictureVideo(false);
surface_id_ = viz::SurfaceId();
+
+ OnLeavingPictureInPicture();
}
void PictureInPictureWindowControllerImpl::EmbedSurface(
@@ -73,6 +91,13 @@ void PictureInPictureWindowControllerImpl::EmbedSurface(
DCHECK(surface_id.is_valid());
surface_id_ = surface_id;
+ // Update the media player id in step with the video surface id. If the
+ // surface id was updated for the same video, this is a no-op. This could
+ // be updated for a different video if another media player on the same
+ // |initiator_| enters Picture-in-Picture mode.
+ media_player_id_ =
+ media_web_contents_observer_->GetPictureInPictureVideoMediaPlayerId();
+
window_->UpdateVideoSize(natural_size);
if (!embedder_)
@@ -84,23 +109,52 @@ OverlayWindow* PictureInPictureWindowControllerImpl::GetWindowForTesting() {
return window_.get();
}
-void PictureInPictureWindowControllerImpl::TogglePlayPause() {
+void PictureInPictureWindowControllerImpl::UpdateLayerBounds() {
+ if (window_) {
+ media_web_contents_observer_->OnPictureInPictureWindowResize(
+ window_->GetBounds().size());
+ }
+
+ if (embedder_)
+ embedder_->UpdateLayerBounds();
+}
+
+bool PictureInPictureWindowControllerImpl::IsPlayerActive() {
+ if (!media_player_id_.has_value())
+ media_web_contents_observer_->GetPictureInPictureVideoMediaPlayerId();
+
+ return media_player_id_.has_value() &&
+ media_web_contents_observer_->IsPlayerActive(*media_player_id_);
+}
+
+WebContents* PictureInPictureWindowControllerImpl::GetInitiatorWebContents() {
+ return initiator_;
+}
+
+bool PictureInPictureWindowControllerImpl::TogglePlayPause() {
DCHECK(window_ && window_->IsActive());
- content::MediaWebContentsObserver* observer =
- static_cast<content::WebContentsImpl* const>(initiator_)
- ->media_web_contents_observer();
- base::Optional<content::WebContentsObserver::MediaPlayerId> player_id =
- observer->GetPictureInPictureVideoMediaPlayerId();
- DCHECK(player_id.has_value());
-
- if (observer->IsPlayerActive(*player_id)) {
- player_id->first->Send(new MediaPlayerDelegateMsg_Pause(
- player_id->first->GetRoutingID(), player_id->second));
- } else {
- player_id->first->Send(new MediaPlayerDelegateMsg_Play(
- player_id->first->GetRoutingID(), player_id->second));
+ if (IsPlayerActive()) {
+ media_player_id_->first->Send(new MediaPlayerDelegateMsg_Pause(
+ media_player_id_->first->GetRoutingID(), media_player_id_->second));
+ return false;
+ }
+
+ media_player_id_->first->Send(new MediaPlayerDelegateMsg_Play(
+ media_player_id_->first->GetRoutingID(), media_player_id_->second));
+ return true;
+}
+
+void PictureInPictureWindowControllerImpl::OnLeavingPictureInPicture() {
+ if (IsPlayerActive()) {
+ // Pause the current video so there is only one video playing at a time.
+ media_player_id_->first->Send(new MediaPlayerDelegateMsg_Pause(
+ media_player_id_->first->GetRoutingID(), media_player_id_->second));
}
+
+ media_player_id_->first->Send(
+ new MediaPlayerDelegateMsg_EndPictureInPictureMode(
+ media_player_id_->first->GetRoutingID(), media_player_id_->second));
}
-} // namespace content \ No newline at end of file
+} // namespace content