[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:

committed by
Chromium LUCI CQ

parent
0ddf597f41
commit
414b11f49b
chrome/browser/ui
android
overlay
views
content
browser
compute_pressure
media
session
picture_in_picture
public
browser
web_test
headless/lib/browser
@ -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 {}
|
||||
|
||||
|
Reference in New Issue
Block a user