1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/picture_in_picture/picture_in_picture_session.h"
6
7 #include <utility>
8
9 #include "base/bind_helpers.h"
10 #include "content/browser/picture_in_picture/picture_in_picture_service_impl.h"
11 #include "content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h"
12 #include "content/browser/web_contents/web_contents_impl.h"
13
14 namespace content {
15
PictureInPictureSession(PictureInPictureServiceImpl * service,const MediaPlayerId & player_id,const base::Optional<viz::SurfaceId> & surface_id,const gfx::Size & natural_size,bool show_play_pause_button,mojo::PendingReceiver<blink::mojom::PictureInPictureSession> receiver,mojo::PendingRemote<blink::mojom::PictureInPictureSessionObserver> observer,gfx::Size * window_size)16 PictureInPictureSession::PictureInPictureSession(
17 PictureInPictureServiceImpl* service,
18 const MediaPlayerId& player_id,
19 const base::Optional<viz::SurfaceId>& surface_id,
20 const gfx::Size& natural_size,
21 bool show_play_pause_button,
22 mojo::PendingReceiver<blink::mojom::PictureInPictureSession> receiver,
23 mojo::PendingRemote<blink::mojom::PictureInPictureSessionObserver> observer,
24 gfx::Size* window_size)
25 : service_(service),
26 receiver_(this, std::move(receiver)),
27 player_id_(player_id),
28 observer_(std::move(observer)) {
29 receiver_.set_disconnect_handler(base::BindOnce(
30 &PictureInPictureSession::OnConnectionError, base::Unretained(this)));
31
32 GetController().SetActiveSession(this);
33 GetController().EmbedSurface(surface_id.value(), natural_size);
34 GetController().SetAlwaysHidePlayPauseButton(show_play_pause_button);
35 GetController().Show();
36
37 *window_size = GetController().GetSize();
38 }
39
~PictureInPictureSession()40 PictureInPictureSession::~PictureInPictureSession() {
41 DCHECK(is_stopping_);
42 }
43
Stop(StopCallback callback)44 void PictureInPictureSession::Stop(StopCallback callback) {
45 StopInternal(std::move(callback));
46 }
47
Update(uint32_t player_id,const base::Optional<viz::SurfaceId> & surface_id,const gfx::Size & natural_size,bool show_play_pause_button)48 void PictureInPictureSession::Update(
49 uint32_t player_id,
50 const base::Optional<viz::SurfaceId>& surface_id,
51 const gfx::Size& natural_size,
52 bool show_play_pause_button) {
53 player_id_ = MediaPlayerId(service_->render_frame_host_, player_id);
54
55 GetController().EmbedSurface(surface_id.value(), natural_size);
56 GetController().SetAlwaysHidePlayPauseButton(show_play_pause_button);
57 GetController().SetActiveSession(this);
58 }
59
NotifyWindowResized(const gfx::Size & size)60 void PictureInPictureSession::NotifyWindowResized(const gfx::Size& size) {
61 observer_->OnWindowSizeChanged(size);
62 }
63
Shutdown()64 void PictureInPictureSession::Shutdown() {
65 if (is_stopping_)
66 return;
67
68 StopInternal(base::NullCallback());
69 }
70
StopInternal(StopCallback callback)71 void PictureInPictureSession::StopInternal(StopCallback callback) {
72 DCHECK(!is_stopping_);
73
74 is_stopping_ = true;
75
76 GetWebContentsImpl()->ExitPictureInPicture();
77
78 // `OnStopped()` should only be called if there is no callback to run, as a
79 // contract in the API.
80 if (callback)
81 std::move(callback).Run();
82 else
83 observer_->OnStopped();
84
85 GetController().SetActiveSession(nullptr);
86
87 // Reset must happen after everything is done as it will destroy |this|.
88 service_->active_session_.reset();
89 }
90
OnConnectionError()91 void PictureInPictureSession::OnConnectionError() {
92 // StopInternal() will self destruct which will close the bindings.
93 StopInternal(base::NullCallback());
94 }
95
GetWebContentsImpl()96 WebContentsImpl* PictureInPictureSession::GetWebContentsImpl() {
97 return static_cast<WebContentsImpl*>(
98 WebContents::FromRenderFrameHost(service_->render_frame_host()));
99 }
100
GetController()101 PictureInPictureWindowControllerImpl& PictureInPictureSession::GetController() {
102 return *PictureInPictureWindowControllerImpl::GetOrCreateForWebContents(
103 GetWebContentsImpl());
104 }
105
106 } // namespace content
107