0

[video pip] Display origin in 2024 UI

This CL adds the Media Session's source title (generally the origin of
the page) to the video picture-in-picture controls.

Bug: 360357715
Change-Id: I350068155c418e523f2b2a654d5c1610a25406de
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6016211
Reviewed-by: Michael Thiessen <mthiesse@chromium.org>
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
Reviewed-by: Peter Kvitek <kvitekp@chromium.org>
Reviewed-by: Fr <beaufort.francois@gmail.com>
Commit-Queue: Tommy Steimel <steimel@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1383886}
This commit is contained in:
Tommy Steimel
2024-11-16 00:16:36 +00:00
committed by Chromium LUCI CQ
parent 0ddf597f41
commit 414b11f49b
13 changed files with 95 additions and 3 deletions

@ -80,6 +80,7 @@ class OverlayWindowAndroid : public content::VideoOverlayWindow,
void SetNextSlideButtonVisibility(bool is_visible) override;
void SetPreviousSlideButtonVisibility(bool is_visible) override;
void SetMediaPosition(const media_session::MediaPosition&) override {}
void SetSourceTitle(const std::u16string& source_title) override {}
void SetFaviconImages(
const std::vector<media_session::MediaImage>& images) override {}
void SetSurfaceId(const viz::SurfaceId& surface_id) override;

@ -876,6 +876,7 @@ void VideoOverlayWindowViews::SetUpViews() {
// These controls may be different (or even nonexistent) depending on whether
// the 2024 updated UI is enabled.
std::unique_ptr<views::ImageView> favicon_view;
std::unique_ptr<views::Label> origin;
std::unique_ptr<OverlayWindowMinimizeButton> minimize_button;
std::unique_ptr<OverlayWindowBackToTabButton> back_to_tab_button;
std::unique_ptr<BackToTabLabelButton> back_to_tab_label_button;
@ -897,6 +898,13 @@ void VideoOverlayWindowViews::SetUpViews() {
{kPlaybackButtonSize, kPlaybackButtonSize});
favicon_view = std::make_unique<views::ImageView>();
favicon_view->SetSize(kFaviconSize);
origin = std::make_unique<views::Label>(std::u16string(),
views::style::CONTEXT_LABEL,
views::style::STYLE_BODY_4_MEDIUM);
origin->SetEnabledColorId(ui::kColorSysOnSurface);
origin->SetBackgroundColor(SK_ColorTRANSPARENT);
origin->SetHorizontalAlignment(gfx::ALIGN_LEFT);
origin->SetElideBehavior(gfx::ELIDE_HEAD);
minimize_button = std::make_unique<
OverlayWindowMinimizeButton>(base::BindRepeating(
[](VideoOverlayWindowViews* overlay) {
@ -1100,6 +1108,11 @@ void VideoOverlayWindowViews::SetUpViews() {
favicon_view->layer()->SetFillsBoundsOpaquely(false);
favicon_view->layer()->SetName("FaviconView");
// Displays the source title (website's origin or extension/PWA name). ----
origin->SetPaintToLayer(ui::LAYER_TEXTURED);
origin->layer()->SetFillsBoundsOpaquely(false);
origin->layer()->SetName("Origin");
// views::View that closes the window without pausing. --------------------
minimize_button->SetPaintToLayer(ui::LAYER_TEXTURED);
minimize_button->layer()->SetFillsBoundsOpaquely(false);
@ -1201,6 +1214,7 @@ void VideoOverlayWindowViews::SetUpViews() {
controls_container_view->AddChildView(std::move(favicon_view));
UpdateFavicon(gfx::ImageSkia());
origin_ = controls_container_view->AddChildView(std::move(origin));
minimize_button_ =
controls_container_view->AddChildView(std::move(minimize_button));
back_to_tab_button_ =
@ -1346,7 +1360,11 @@ void VideoOverlayWindowViews::OnUpdateControlsBounds() {
constexpr int kTopControlsHeight = 34;
constexpr int kBottomControlsHeight = 64;
constexpr int kFaviconLeftMargin = 8;
constexpr int kFaviconTopMargin = 8;
constexpr int kFaviconTopMargin = 5;
constexpr int kFaviconRightMargin = 4;
constexpr int kOriginTopMargin = 5;
constexpr int kOriginHeight = 24;
constexpr int kOriginRightMargin = 80;
constexpr int kProgressBarHeight = 26;
constexpr int kPlayPauseButtonMargin = 16;
constexpr int kControlHorizontalMargin = 8;
@ -1374,8 +1392,18 @@ void VideoOverlayWindowViews::OnUpdateControlsBounds() {
gfx::Rect middle_controls_bounds = gfx::BoundingRect(
top_controls_bounds.bottom_left(), bottom_controls_bounds.top_right());
favicon_view_->SetPosition({top_controls_bounds.x() + kFaviconLeftMargin,
top_controls_bounds.y() + kFaviconTopMargin});
gfx::Rect favicon_view_bounds({top_controls_bounds.x() + kFaviconLeftMargin,
top_controls_bounds.y() + kFaviconTopMargin},
kFaviconSize);
favicon_view_->SetPosition(favicon_view_bounds.origin());
gfx::Point origin_position(
favicon_view_bounds.right() + kFaviconRightMargin, kOriginTopMargin);
origin_->SetPosition(origin_position);
origin_->SetSize(
{top_controls_bounds.width() - origin_position.x() - kOriginRightMargin,
kOriginHeight});
minimize_button_->SetPosition(GetBounds().size(), quadrant);
back_to_tab_button_->SetPosition(GetBounds().size(), quadrant);
@ -1776,6 +1804,13 @@ void VideoOverlayWindowViews::SetMediaPosition(
UpdateTimestampLabel(position_.GetPosition(), position_.duration());
}
void VideoOverlayWindowViews::SetSourceTitle(
const std::u16string& source_title) {
if (Use2024UI()) {
origin_->SetText(source_title);
}
}
void VideoOverlayWindowViews::SetFaviconImages(
const std::vector<media_session::MediaImage>& images) {
if (!Use2024UI()) {
@ -2086,6 +2121,10 @@ views::ImageView* VideoOverlayWindowViews::favicon_view_for_testing() const {
return favicon_view_;
}
views::Label* VideoOverlayWindowViews::origin_for_testing() const {
return origin_;
}
CloseImageButton* VideoOverlayWindowViews::close_button_for_testing() const {
return close_controls_view_;
}

@ -86,6 +86,7 @@ class VideoOverlayWindowViews : public content::VideoOverlayWindow,
void SetPreviousSlideButtonVisibility(bool is_visible) override;
void SetNextSlideButtonVisibility(bool is_visible) override;
void SetMediaPosition(const media_session::MediaPosition& position) override;
void SetSourceTitle(const std::u16string& source_title) override;
void SetFaviconImages(
const std::vector<media_session::MediaImage>& images) override;
void SetSurfaceId(const viz::SurfaceId& surface_id) override;
@ -184,6 +185,7 @@ class VideoOverlayWindowViews : public content::VideoOverlayWindow,
global_media_controls::MediaProgressView* progress_view_for_testing() const;
views::Label* timestamp_for_testing() const;
views::ImageView* favicon_view_for_testing() const;
views::Label* origin_for_testing() const;
CloseImageButton* close_button_for_testing() const;
OverlayWindowMinimizeButton* minimize_button_for_testing() const;
OverlayWindowBackToTabButton* back_to_tab_button_for_testing() const;
@ -364,6 +366,7 @@ class VideoOverlayWindowViews : public content::VideoOverlayWindow,
raw_ptr<views::View> controls_scrim_view_ = nullptr;
raw_ptr<views::View> controls_container_view_ = nullptr;
raw_ptr<views::ImageView> favicon_view_ = nullptr;
raw_ptr<views::Label> origin_ = nullptr;
raw_ptr<CloseImageButton> close_controls_view_ = nullptr;
raw_ptr<OverlayWindowMinimizeButton> minimize_button_ = nullptr;
raw_ptr<OverlayWindowBackToTabButton> back_to_tab_button_ = nullptr;

@ -780,6 +780,12 @@ TEST_F(VideoOverlayWindowViewsTest, FaviconNotDrawnWhen2024UIIsDisabled) {
ASSERT_EQ(nullptr, favicon);
}
TEST_F(VideoOverlayWindowViewsTest, OriginNotDrawnWhen2024UIIsDisabled) {
overlay_window().ForceControlsVisibleForTesting(true);
views::Label* origin = overlay_window().origin_for_testing();
ASSERT_EQ(nullptr, origin);
}
class VideoOverlayWindowViewsWith2024UITest
: public VideoOverlayWindowViewsTest {
public:
@ -961,3 +967,13 @@ TEST_F(VideoOverlayWindowViewsWith2024UITest, DisplaysFavicon) {
&vector_icons::kGlobeIcon);
}
}
TEST_F(VideoOverlayWindowViewsWith2024UITest, DisplaysOrigin) {
overlay_window().ForceControlsVisibleForTesting(true);
views::Label* origin = overlay_window().origin_for_testing();
ASSERT_NE(nullptr, origin);
EXPECT_TRUE(origin->IsDrawn());
overlay_window().SetSourceTitle(u"google.com");
EXPECT_EQ(origin->GetText(), u"google.com");
}

@ -71,6 +71,7 @@ class TestVideoOverlayWindow : public VideoOverlayWindow {
void SetNextSlideButtonVisibility(bool is_visible) override {}
void SetPreviousSlideButtonVisibility(bool is_visible) override {}
void SetMediaPosition(const media_session::MediaPosition&) override {}
void SetSourceTitle(const std::u16string& source_title) override {}
void SetFaviconImages(
const std::vector<media_session::MediaImage>& images) override {}
void SetSurfaceId(const viz::SurfaceId& surface_id) override {}

@ -1762,6 +1762,7 @@ void MediaSessionImpl::UpdateVideoPictureInPictureWindowController(
pip_controller->MediaSessionImagesChanged(images_);
pip_controller->MediaSessionPositionChanged(position_);
pip_controller->MediaSessionInfoChanged(session_info_);
pip_controller->MediaSessionMetadataChanged(metadata_);
}
base::WeakPtr<MediaSessionImpl> MediaSessionImpl::GetWeakPtr() {
@ -1874,6 +1875,11 @@ void MediaSessionImpl::RebuildAndNotifyMetadataChanged() {
observer->MediaSessionImagesChanged(this->images_);
}
}
if (auto* pip_window_controller =
VideoPictureInPictureWindowControllerImpl::FromWebContents(
web_contents())) {
pip_window_controller->MediaSessionMetadataChanged(metadata_);
}
}
#if BUILDFLAG(IS_CHROMEOS)

@ -93,6 +93,7 @@ class TestOverlayWindow : public VideoOverlayWindow {
void SetNextSlideButtonVisibility(bool is_visible) override {}
void SetPreviousSlideButtonVisibility(bool is_visible) override {}
void SetMediaPosition(const media_session::MediaPosition&) override {}
void SetSourceTitle(const std::u16string& source_title) override {}
void SetFaviconImages(
const std::vector<media_session::MediaImage>& images) override {}
void SetSurfaceId(const viz::SurfaceId& surface_id) override {}

@ -73,6 +73,7 @@ class TestVideoOverlayWindow : public VideoOverlayWindow {
void SetNextSlideButtonVisibility(bool is_visible) override {}
void SetPreviousSlideButtonVisibility(bool is_visible) override {}
void SetMediaPosition(const media_session::MediaPosition&) override {}
void SetSourceTitle(const std::u16string& source_title) override {}
void SetFaviconImages(
const std::vector<media_session::MediaImage>& images) override {}
void SetSurfaceId(const viz::SurfaceId& surface_id) override {}

@ -106,6 +106,7 @@ void VideoPictureInPictureWindowControllerImpl::Show() {
window_->SetPreviousSlideButtonVisibility(
media_session_action_previous_slide_handled_);
window_->SetFaviconImages(favicon_images_);
window_->SetSourceTitle(source_title_);
window_->ShowInactive();
GetWebContentsImpl()->SetHasPictureInPictureVideo(true);
}
@ -500,6 +501,19 @@ void VideoPictureInPictureWindowControllerImpl::MediaSessionImagesChanged(
}
}
void VideoPictureInPictureWindowControllerImpl::MediaSessionMetadataChanged(
const std::optional<media_session::MediaMetadata>& metadata) {
if (metadata) {
source_title_ = metadata->source_title;
} else {
source_title_.clear();
}
if (window_) {
window_->SetSourceTitle(source_title_);
}
}
gfx::Size VideoPictureInPictureWindowControllerImpl::GetSize() {
return window_->GetBounds().size();
}

@ -111,6 +111,9 @@ class CONTENT_EXPORT VideoPictureInPictureWindowControllerImpl
const base::flat_map<media_session::mojom::MediaSessionImageType,
std::vector<media_session::MediaImage>>& images);
void MediaSessionMetadataChanged(
const std::optional<media_session::MediaMetadata>& metadata);
gfx::Size GetSize();
// WebContentsObserver:
@ -224,6 +227,10 @@ class CONTENT_EXPORT VideoPictureInPictureWindowControllerImpl
// The media position info as last reported to us by MediaSessionImpl.
std::optional<media_session::MediaPosition> media_position_;
// The media metadata's source title as last reported to us by
// MediaSessionImpl.
std::u16string source_title_;
// True if the last media_session::MediaPosition we received in
// |MediaSessionPositionChanged()| was sent to |window_|. Used to track
// whether we should send it again.

@ -71,6 +71,7 @@ class VideoOverlayWindow {
virtual void SetPreviousSlideButtonVisibility(bool is_visible) = 0;
virtual void SetMediaPosition(
const media_session::MediaPosition& position) = 0;
virtual void SetSourceTitle(const std::u16string& source_title) = 0;
virtual void SetFaviconImages(
const std::vector<media_session::MediaImage>& images) = 0;

@ -150,6 +150,7 @@ class BoundsMatchVideoSizeOverlayWindow : public VideoOverlayWindow {
void SetNextSlideButtonVisibility(bool is_visible) override {}
void SetPreviousSlideButtonVisibility(bool is_visible) override {}
void SetMediaPosition(const media_session::MediaPosition&) override {}
void SetSourceTitle(const std::u16string& source_title) override {}
void SetFaviconImages(
const std::vector<media_session::MediaImage>& images) override {}
void SetSurfaceId(const viz::SurfaceId& surface_id) override {}

@ -108,6 +108,7 @@ class HeadlessVideoOverlayWindow : public content::VideoOverlayWindow {
void SetNextSlideButtonVisibility(bool is_visible) override {}
void SetPreviousSlideButtonVisibility(bool is_visible) override {}
void SetMediaPosition(const media_session::MediaPosition&) override {}
void SetSourceTitle(const std::u16string& source_title) override {}
void SetFaviconImages(
const std::vector<media_session::MediaImage>& images) override {}