| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/media_message_center/media_notification_view_modern_impl.h" |
| |
| #include <memory> |
| |
| #include "base/bind.h" |
| #include "base/callback_helpers.h" |
| #include "base/containers/flat_set.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/mock_callback.h" |
| #include "base/test/task_environment.h" |
| #include "base/unguessable_token.h" |
| #include "build/build_config.h" |
| #include "components/media_message_center/media_controls_progress_view.h" |
| #include "components/media_message_center/media_notification_background_impl.h" |
| #include "components/media_message_center/media_notification_container.h" |
| #include "components/media_message_center/media_notification_util.h" |
| #include "components/media_message_center/mock_media_notification_item.h" |
| #include "services/media_session/public/mojom/media_session.mojom.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "ui/accessibility/ax_enums.mojom.h" |
| #include "ui/accessibility/ax_node_data.h" |
| #include "ui/events/base_event_utils.h" |
| #include "ui/message_center/message_center.h" |
| #include "ui/message_center/public/cpp/message_center_constants.h" |
| #include "ui/message_center/views/notification_control_buttons_view.h" |
| #include "ui/message_center/views/notification_header_view.h" |
| #include "ui/views/controls/image_view.h" |
| #include "ui/views/test/button_test_api.h" |
| #include "ui/views/test/views_test_base.h" |
| |
| namespace media_message_center { |
| |
| using media_session::mojom::MediaSessionAction; |
| using testing::_; |
| using testing::Expectation; |
| using testing::Invoke; |
| using testing::Return; |
| |
| namespace { |
| |
| const int kMediaButtonIconSize = 20; |
| const int kPipButtonIconSize = 18; |
| |
| const gfx::Size kWidgetSize(500, 500); |
| |
| constexpr int kViewWidth = 350; |
| const gfx::Size kViewSize(kViewWidth, 400); |
| |
| class MockMediaNotificationContainer : public MediaNotificationContainer { |
| public: |
| MockMediaNotificationContainer() = default; |
| MockMediaNotificationContainer(const MockMediaNotificationContainer&) = |
| delete; |
| MockMediaNotificationContainer& operator=( |
| const MockMediaNotificationContainer&) = delete; |
| ~MockMediaNotificationContainer() override = default; |
| |
| // MediaNotificationContainer implementation. |
| MOCK_METHOD1(OnExpanded, void(bool expanded)); |
| MOCK_METHOD1( |
| OnMediaSessionInfoChanged, |
| void(const media_session::mojom::MediaSessionInfoPtr& session_info)); |
| MOCK_METHOD1(OnMediaSessionMetadataChanged, |
| void(const media_session::MediaMetadata& metadata)); |
| MOCK_METHOD1(OnVisibleActionsChanged, |
| void(const base::flat_set<MediaSessionAction>& actions)); |
| MOCK_METHOD1(OnMediaArtworkChanged, void(const gfx::ImageSkia& image)); |
| MOCK_METHOD3(OnColorsChanged, |
| void(SkColor foreground, |
| SkColor foreground_disabled, |
| SkColor background)); |
| MOCK_METHOD0(OnHeaderClicked, void()); |
| }; |
| |
| } // namespace |
| |
| class MediaNotificationViewModernImplTest : public views::ViewsTestBase { |
| public: |
| MediaNotificationViewModernImplTest() |
| : views::ViewsTestBase( |
| base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} |
| MediaNotificationViewModernImplTest( |
| const MediaNotificationViewModernImplTest&) = delete; |
| MediaNotificationViewModernImplTest& operator=( |
| const MediaNotificationViewModernImplTest&) = delete; |
| ~MediaNotificationViewModernImplTest() override = default; |
| |
| void SetUp() override { |
| views::ViewsTestBase::SetUp(); |
| |
| // Create a widget to show on the screen for testing screen coordinates and |
| // focus. |
| widget_ = std::make_unique<views::Widget>(); |
| views::Widget::InitParams params = |
| CreateParams(views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); |
| params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| params.bounds = gfx::Rect(kWidgetSize); |
| widget_->Init(std::move(params)); |
| widget_->Show(); |
| |
| // Creates the view and adds it to the widget. |
| CreateView(); |
| } |
| |
| void TearDown() override { |
| view_ = nullptr; |
| widget_.reset(); |
| |
| actions_.clear(); |
| |
| views::ViewsTestBase::TearDown(); |
| } |
| |
| void EnableAllActions() { |
| actions_.insert(MediaSessionAction::kPlay); |
| actions_.insert(MediaSessionAction::kPause); |
| actions_.insert(MediaSessionAction::kPreviousTrack); |
| actions_.insert(MediaSessionAction::kNextTrack); |
| actions_.insert(MediaSessionAction::kSeekBackward); |
| actions_.insert(MediaSessionAction::kSeekForward); |
| actions_.insert(MediaSessionAction::kStop); |
| actions_.insert(MediaSessionAction::kEnterPictureInPicture); |
| actions_.insert(MediaSessionAction::kExitPictureInPicture); |
| |
| NotifyUpdatedActions(); |
| } |
| |
| void EnableAction(MediaSessionAction action) { |
| actions_.insert(action); |
| NotifyUpdatedActions(); |
| } |
| |
| void DisableAction(MediaSessionAction action) { |
| actions_.erase(action); |
| NotifyUpdatedActions(); |
| } |
| |
| MockMediaNotificationContainer& container() { return container_; } |
| |
| MediaNotificationViewModernImpl* view() const { return view_; } |
| |
| const std::u16string& accessible_name() const { |
| return view()->accessible_name_; |
| } |
| |
| test::MockMediaNotificationItem& item() { return item_; } |
| |
| views::Label* title_label() const { return view()->title_label_; } |
| |
| views::Label* subtitle_label() const { return view()->subtitle_label_; } |
| |
| views::View* artwork_container() const { return view()->artwork_container_; } |
| |
| views::View* media_controls_container() const { |
| return view()->media_controls_container_; |
| } |
| |
| views::Button* picture_in_picture_button() const { |
| return view()->picture_in_picture_button_for_testing(); |
| } |
| |
| std::vector<views::Button*> media_control_buttons() const { |
| std::vector<views::Button*> buttons; |
| auto children = view()->media_controls_container_->children(); |
| std::transform( |
| children.begin(), children.end(), std::back_inserter(buttons), |
| [](views::View* child) { return views::Button::AsButton(child); }); |
| buttons.push_back(views::Button::AsButton(picture_in_picture_button())); |
| return buttons; |
| } |
| |
| MediaControlsProgressView* progress_view() const { return view()->progress_; } |
| |
| views::Button* GetButtonForAction(MediaSessionAction action) const { |
| auto buttons = media_control_buttons(); |
| const auto i = std::find_if( |
| buttons.begin(), buttons.end(), [action](const views::Button* button) { |
| return button->tag() == static_cast<int>(action); |
| }); |
| return (i == buttons.end()) ? nullptr : *i; |
| } |
| |
| bool IsActionButtonVisible(MediaSessionAction action) const { |
| return GetButtonForAction(action)->GetVisible(); |
| } |
| |
| const gfx::ImageSkia& GetArtworkImage() const { |
| return static_cast<MediaNotificationBackgroundImpl*>( |
| view()->GetMediaNotificationBackground()) |
| ->artwork_; |
| } |
| |
| void SimulateButtonClick(MediaSessionAction action) { |
| views::Button* button = GetButtonForAction(action); |
| EXPECT_TRUE(button->GetVisible()); |
| |
| views::test::ButtonTestApi(button).NotifyClick( |
| ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), |
| ui::EventTimeForNow(), 0, 0)); |
| } |
| |
| void SimulateTab() { |
| ui::KeyEvent pressed_tab(ui::ET_KEY_PRESSED, ui::VKEY_TAB, ui::EF_NONE); |
| view()->GetFocusManager()->OnKeyEvent(pressed_tab); |
| } |
| |
| void ExpectHistogramArtworkRecorded(bool present, int count) { |
| histogram_tester_.ExpectBucketCount( |
| MediaNotificationViewModernImpl::kArtworkHistogramName, |
| static_cast<base::HistogramBase::Sample>(present), count); |
| } |
| |
| void ExpectHistogramMetadataRecorded( |
| MediaNotificationViewModernImpl::Metadata metadata, |
| int count) { |
| histogram_tester_.ExpectBucketCount( |
| MediaNotificationViewModernImpl::kMetadataHistogramName, |
| static_cast<base::HistogramBase::Sample>(metadata), count); |
| } |
| |
| private: |
| void NotifyUpdatedActions() { view_->UpdateWithMediaActions(actions_); } |
| |
| void CreateView() { |
| // On creation, the view should notify |item_|. |
| auto view = std::make_unique<MediaNotificationViewModernImpl>( |
| &container_, item_.GetWeakPtr(), std::make_unique<views::View>(), |
| std::make_unique<views::View>(), kViewWidth); |
| view->SetSize(kViewSize); |
| |
| media_session::MediaMetadata metadata; |
| metadata.title = u"title"; |
| metadata.artist = u"artist"; |
| metadata.source_title = u"source title"; |
| view->UpdateWithMediaMetadata(metadata); |
| |
| view->UpdateWithMediaActions(actions_); |
| |
| // Display it in |widget_|. Widget now owns |view|. |
| view_ = widget_->SetContentsView(std::move(view)); |
| } |
| |
| base::HistogramTester histogram_tester_; |
| |
| base::flat_set<MediaSessionAction> actions_; |
| |
| MockMediaNotificationContainer container_; |
| test::MockMediaNotificationItem item_; |
| raw_ptr<MediaNotificationViewModernImpl> view_; |
| std::unique_ptr<views::Widget> widget_; |
| }; |
| |
| TEST_F(MediaNotificationViewModernImplTest, ButtonsSanityCheck) { |
| EnableAllActions(); |
| |
| EXPECT_TRUE(media_controls_container()->GetVisible()); |
| EXPECT_GT(media_controls_container()->width(), 0); |
| EXPECT_GT(media_controls_container()->height(), 0); |
| |
| auto buttons = media_control_buttons(); |
| EXPECT_EQ(6u, buttons.size()); |
| |
| for (auto* button : buttons) { |
| EXPECT_TRUE(button->GetVisible()); |
| if (button == picture_in_picture_button()) { |
| EXPECT_LT(kPipButtonIconSize, button->width()); |
| EXPECT_LT(kPipButtonIconSize, button->height()); |
| } else { |
| EXPECT_LT(kMediaButtonIconSize, button->width()); |
| EXPECT_LT(kMediaButtonIconSize, button->height()); |
| } |
| EXPECT_FALSE(views::Button::AsButton(button)->GetAccessibleName().empty()); |
| } |
| |
| EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay)); |
| EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPreviousTrack)); |
| EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kNextTrack)); |
| EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kSeekBackward)); |
| EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kSeekForward)); |
| EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kEnterPictureInPicture)); |
| |
| // |kPause| cannot be present if |kPlay| is. |
| EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause)); |
| EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kExitPictureInPicture)); |
| } |
| |
| #if BUILDFLAG(IS_WIN) |
| #define MAYBE_ButtonsFocusCheck DISABLED_ButtonsFocusCheck |
| #else |
| #define MAYBE_ButtonsFocusCheck ButtonsFocusCheck |
| #endif |
| TEST_F(MediaNotificationViewModernImplTest, MAYBE_ButtonsFocusCheck) { |
| // Expand and enable all actions to show all buttons. |
| EnableAllActions(); |
| |
| views::FocusManager* focus_manager = view()->GetFocusManager(); |
| |
| { |
| // Focus the first action button. |
| auto* button = GetButtonForAction(MediaSessionAction::kPreviousTrack); |
| focus_manager->SetFocusedView(button); |
| EXPECT_EQ(button, focus_manager->GetFocusedView()); |
| } |
| |
| SimulateTab(); |
| EXPECT_EQ(GetButtonForAction(MediaSessionAction::kSeekBackward), |
| focus_manager->GetFocusedView()); |
| |
| SimulateTab(); |
| EXPECT_EQ(GetButtonForAction(MediaSessionAction::kPlay), |
| focus_manager->GetFocusedView()); |
| |
| SimulateTab(); |
| EXPECT_EQ(GetButtonForAction(MediaSessionAction::kSeekForward), |
| focus_manager->GetFocusedView()); |
| |
| SimulateTab(); |
| EXPECT_EQ(GetButtonForAction(MediaSessionAction::kNextTrack), |
| focus_manager->GetFocusedView()); |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, PlayPauseButtonTooltipCheck) { |
| EnableAction(MediaSessionAction::kPlay); |
| EnableAction(MediaSessionAction::kPause); |
| |
| EXPECT_CALL(container(), OnMediaSessionInfoChanged(_)); |
| |
| auto* button = GetButtonForAction(MediaSessionAction::kPlay); |
| std::u16string tooltip = button->GetTooltipText(gfx::Point()); |
| EXPECT_FALSE(tooltip.empty()); |
| |
| auto session_info = media_session::mojom::MediaSessionInfo::New(); |
| session_info->playback_state = |
| media_session::mojom::MediaPlaybackState::kPlaying; |
| session_info->is_controllable = true; |
| view()->UpdateWithMediaSessionInfo(std::move(session_info)); |
| |
| std::u16string new_tooltip = button->GetTooltipText(gfx::Point()); |
| EXPECT_FALSE(new_tooltip.empty()); |
| EXPECT_NE(tooltip, new_tooltip); |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, NextTrackButtonClick) { |
| EnableAction(MediaSessionAction::kNextTrack); |
| |
| EXPECT_CALL(item(), OnMediaSessionActionButtonPressed( |
| MediaSessionAction::kNextTrack)); |
| SimulateButtonClick(MediaSessionAction::kNextTrack); |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, PlayButtonClick) { |
| EnableAction(MediaSessionAction::kPlay); |
| |
| EXPECT_CALL(item(), |
| OnMediaSessionActionButtonPressed(MediaSessionAction::kPlay)); |
| SimulateButtonClick(MediaSessionAction::kPlay); |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, PauseButtonClick) { |
| EnableAction(MediaSessionAction::kPause); |
| |
| auto session_info = media_session::mojom::MediaSessionInfo::New(); |
| session_info->playback_state = |
| media_session::mojom::MediaPlaybackState::kPlaying; |
| session_info->is_controllable = true; |
| |
| EXPECT_CALL(container(), OnMediaSessionInfoChanged(_)); |
| view()->UpdateWithMediaSessionInfo(session_info.Clone()); |
| testing::Mock::VerifyAndClearExpectations(&container()); |
| |
| EXPECT_CALL(item(), |
| OnMediaSessionActionButtonPressed(MediaSessionAction::kPause)); |
| SimulateButtonClick(MediaSessionAction::kPause); |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, PreviousTrackButtonClick) { |
| EnableAction(MediaSessionAction::kPreviousTrack); |
| |
| EXPECT_CALL(item(), OnMediaSessionActionButtonPressed( |
| MediaSessionAction::kPreviousTrack)); |
| SimulateButtonClick(MediaSessionAction::kPreviousTrack); |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, SeekBackwardButtonClick) { |
| EnableAction(MediaSessionAction::kSeekBackward); |
| |
| EXPECT_CALL(item(), OnMediaSessionActionButtonPressed( |
| MediaSessionAction::kSeekBackward)); |
| SimulateButtonClick(MediaSessionAction::kSeekBackward); |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, SeekForwardButtonClick) { |
| EnableAction(MediaSessionAction::kSeekForward); |
| |
| EXPECT_CALL(item(), OnMediaSessionActionButtonPressed( |
| MediaSessionAction::kSeekForward)); |
| SimulateButtonClick(MediaSessionAction::kSeekForward); |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, PlayToggle_FromObserver_Empty) { |
| EnableAction(MediaSessionAction::kPlay); |
| |
| { |
| views::Button* button = GetButtonForAction(MediaSessionAction::kPlay); |
| EXPECT_NE(button, nullptr); |
| EXPECT_EQ(button->tag(), static_cast<int>(MediaSessionAction::kPlay)); |
| } |
| |
| view()->UpdateWithMediaSessionInfo( |
| media_session::mojom::MediaSessionInfo::New()); |
| |
| { |
| views::Button* button = GetButtonForAction(MediaSessionAction::kPlay); |
| EXPECT_NE(button, nullptr); |
| EXPECT_EQ(button->tag(), static_cast<int>(MediaSessionAction::kPlay)); |
| } |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, |
| PlayToggle_FromObserver_PlaybackState) { |
| EnableAction(MediaSessionAction::kPlay); |
| EnableAction(MediaSessionAction::kPause); |
| |
| { |
| views::Button* button = GetButtonForAction(MediaSessionAction::kPlay); |
| EXPECT_NE(button, nullptr); |
| EXPECT_EQ(button->tag(), static_cast<int>(MediaSessionAction::kPlay)); |
| } |
| |
| media_session::mojom::MediaSessionInfoPtr session_info( |
| media_session::mojom::MediaSessionInfo::New()); |
| |
| session_info->playback_state = |
| media_session::mojom::MediaPlaybackState::kPlaying; |
| view()->UpdateWithMediaSessionInfo(session_info.Clone()); |
| |
| { |
| views::Button* button = GetButtonForAction(MediaSessionAction::kPause); |
| EXPECT_NE(button, nullptr); |
| EXPECT_EQ(button->tag(), static_cast<int>(MediaSessionAction::kPause)); |
| } |
| |
| session_info->playback_state = |
| media_session::mojom::MediaPlaybackState::kPaused; |
| view()->UpdateWithMediaSessionInfo(session_info.Clone()); |
| |
| { |
| views::Button* button = GetButtonForAction(MediaSessionAction::kPlay); |
| EXPECT_NE(button, nullptr); |
| EXPECT_EQ(button->tag(), static_cast<int>(MediaSessionAction::kPlay)); |
| } |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, MetadataIsDisplayed) { |
| EnableAllActions(); |
| |
| EXPECT_TRUE(title_label()->GetVisible()); |
| EXPECT_TRUE(subtitle_label()->GetVisible()); |
| |
| EXPECT_EQ(u"title", title_label()->GetText()); |
| EXPECT_EQ(u"source title", subtitle_label()->GetText()); |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, UpdateMetadata_FromObserver) { |
| EnableAllActions(); |
| |
| ExpectHistogramMetadataRecorded( |
| MediaNotificationViewModernImpl::Metadata::kTitle, 1); |
| ExpectHistogramMetadataRecorded( |
| MediaNotificationViewModernImpl::Metadata::kSource, 1); |
| ExpectHistogramMetadataRecorded( |
| MediaNotificationViewModernImpl::Metadata::kCount, 1); |
| |
| media_session::MediaMetadata metadata; |
| metadata.title = u"title2"; |
| metadata.source_title = u"source title2"; |
| metadata.artist = u"artist2"; |
| metadata.album = u"album"; |
| |
| EXPECT_CALL(container(), OnMediaSessionMetadataChanged(_)); |
| view()->UpdateWithMediaMetadata(metadata); |
| testing::Mock::VerifyAndClearExpectations(&container()); |
| |
| EXPECT_TRUE(title_label()->GetVisible()); |
| EXPECT_TRUE(subtitle_label()->GetVisible()); |
| |
| EXPECT_EQ(metadata.title, title_label()->GetText()); |
| EXPECT_EQ(metadata.source_title, subtitle_label()->GetText()); |
| |
| EXPECT_EQ(u"title2 - artist2 - album", accessible_name()); |
| |
| ExpectHistogramMetadataRecorded( |
| MediaNotificationViewModernImpl::Metadata::kTitle, 2); |
| ExpectHistogramMetadataRecorded( |
| MediaNotificationViewModernImpl::Metadata::kSource, 2); |
| ExpectHistogramMetadataRecorded( |
| MediaNotificationViewModernImpl::Metadata::kCount, 2); |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, ActionButtonsHiddenByDefault) { |
| EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kPlay)); |
| EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kNextTrack)); |
| EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kPreviousTrack)); |
| EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kSeekForward)); |
| EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kSeekBackward)); |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, ActionButtonsToggleVisibility) { |
| EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kNextTrack)); |
| |
| EnableAction(MediaSessionAction::kNextTrack); |
| |
| EXPECT_TRUE(IsActionButtonVisible(MediaSessionAction::kNextTrack)); |
| |
| DisableAction(MediaSessionAction::kNextTrack); |
| |
| EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kNextTrack)); |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, UpdateArtworkFromItem) { |
| int labels_container_width = title_label()->parent()->width(); |
| gfx::Size size = view()->size(); |
| EXPECT_CALL(container(), OnMediaArtworkChanged(_)).Times(2); |
| EXPECT_CALL(container(), OnColorsChanged(_, _, _)).Times(2); |
| |
| SkBitmap image; |
| image.allocN32Pixels(10, 10); |
| image.eraseColor(SK_ColorGREEN); |
| |
| EXPECT_TRUE(GetArtworkImage().isNull()); |
| |
| view()->UpdateWithMediaArtwork(gfx::ImageSkia::CreateFrom1xBitmap(image)); |
| |
| ExpectHistogramArtworkRecorded(true, 1); |
| |
| // The size of the labels container should not change when there is artwork. |
| EXPECT_EQ(labels_container_width, title_label()->parent()->width()); |
| |
| // Ensure that the labels container does not extend into the artwork bounds. |
| EXPECT_FALSE(artwork_container()->bounds().Intersects( |
| title_label()->parent()->bounds())); |
| |
| // Ensure that when the image is displayed that the size of the notification |
| // was not affected. |
| EXPECT_FALSE(GetArtworkImage().isNull()); |
| EXPECT_EQ(gfx::Size(10, 10), GetArtworkImage().size()); |
| EXPECT_EQ(size, view()->size()); |
| |
| view()->UpdateWithMediaArtwork( |
| gfx::ImageSkia::CreateFrom1xBitmap(SkBitmap())); |
| |
| ExpectHistogramArtworkRecorded(false, 1); |
| |
| // Ensure the labels container goes back to the original width now that we |
| // do not have any artwork. |
| EXPECT_EQ(labels_container_width, title_label()->parent()->width()); |
| |
| // Ensure that the artwork was reset and the size was still not |
| // affected. |
| EXPECT_TRUE(GetArtworkImage().isNull()); |
| EXPECT_EQ(size, view()->size()); |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, UpdateProgressBar) { |
| media_session::MediaPosition media_position( |
| /*playback_rate=*/1.0, /*duration=*/base::Seconds(600), |
| /*position=*/base::Seconds(0), /*end_of_media=*/false); |
| view()->UpdateWithMediaPosition(media_position); |
| EXPECT_EQ(progress_view()->duration_for_testing(), u"10:00"); |
| } |
| |
| TEST_F(MediaNotificationViewModernImplTest, AccessibleNodeData) { |
| ui::AXNodeData data; |
| view()->GetAccessibleNodeData(&data); |
| |
| EXPECT_TRUE( |
| data.HasStringAttribute(ax::mojom::StringAttribute::kRoleDescription)); |
| EXPECT_EQ(u"title - artist", accessible_name()); |
| } |
| |
| class MediaNotificationViewModernImplCastTest |
| : public MediaNotificationViewModernImplTest { |
| public: |
| void SetUp() override { |
| EXPECT_CALL(item(), SourceType()) |
| .WillRepeatedly(Return(media_message_center::SourceType::kCast)); |
| MediaNotificationViewModernImplTest::SetUp(); |
| } |
| }; |
| |
| TEST_F(MediaNotificationViewModernImplCastTest, PictureInPictureButton) { |
| // We should not create picture-in-picture button for cast session. |
| EXPECT_EQ(picture_in_picture_button(), nullptr); |
| } |
| |
| } // namespace media_message_center |