media_notification_view_modern_impl_unittest.cc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. // Copyright 2020 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. #include "components/media_message_center/media_notification_view_modern_impl.h"
  5. #include <memory>
  6. #include "base/bind.h"
  7. #include "base/callback_helpers.h"
  8. #include "base/containers/flat_set.h"
  9. #include "base/memory/raw_ptr.h"
  10. #include "base/strings/utf_string_conversions.h"
  11. #include "base/test/metrics/histogram_tester.h"
  12. #include "base/test/mock_callback.h"
  13. #include "base/test/task_environment.h"
  14. #include "base/unguessable_token.h"
  15. #include "build/build_config.h"
  16. #include "components/media_message_center/media_controls_progress_view.h"
  17. #include "components/media_message_center/media_notification_background_impl.h"
  18. #include "components/media_message_center/media_notification_container.h"
  19. #include "components/media_message_center/media_notification_util.h"
  20. #include "components/media_message_center/mock_media_notification_item.h"
  21. #include "services/media_session/public/mojom/media_session.mojom.h"
  22. #include "testing/gmock/include/gmock/gmock.h"
  23. #include "ui/accessibility/ax_enums.mojom.h"
  24. #include "ui/accessibility/ax_node_data.h"
  25. #include "ui/events/base_event_utils.h"
  26. #include "ui/message_center/message_center.h"
  27. #include "ui/message_center/public/cpp/message_center_constants.h"
  28. #include "ui/message_center/views/notification_control_buttons_view.h"
  29. #include "ui/message_center/views/notification_header_view.h"
  30. #include "ui/views/controls/image_view.h"
  31. #include "ui/views/test/button_test_api.h"
  32. #include "ui/views/test/views_test_base.h"
  33. namespace media_message_center {
  34. using media_session::mojom::MediaSessionAction;
  35. using testing::_;
  36. using testing::Expectation;
  37. using testing::Invoke;
  38. using testing::Return;
  39. namespace {
  40. const int kMediaButtonIconSize = 20;
  41. const int kPipButtonIconSize = 18;
  42. const gfx::Size kWidgetSize(500, 500);
  43. constexpr int kViewWidth = 350;
  44. const gfx::Size kViewSize(kViewWidth, 400);
  45. class MockMediaNotificationContainer : public MediaNotificationContainer {
  46. public:
  47. MockMediaNotificationContainer() = default;
  48. MockMediaNotificationContainer(const MockMediaNotificationContainer&) =
  49. delete;
  50. MockMediaNotificationContainer& operator=(
  51. const MockMediaNotificationContainer&) = delete;
  52. ~MockMediaNotificationContainer() override = default;
  53. // MediaNotificationContainer implementation.
  54. MOCK_METHOD1(OnExpanded, void(bool expanded));
  55. MOCK_METHOD1(
  56. OnMediaSessionInfoChanged,
  57. void(const media_session::mojom::MediaSessionInfoPtr& session_info));
  58. MOCK_METHOD1(OnMediaSessionMetadataChanged,
  59. void(const media_session::MediaMetadata& metadata));
  60. MOCK_METHOD1(OnVisibleActionsChanged,
  61. void(const base::flat_set<MediaSessionAction>& actions));
  62. MOCK_METHOD1(OnMediaArtworkChanged, void(const gfx::ImageSkia& image));
  63. MOCK_METHOD3(OnColorsChanged,
  64. void(SkColor foreground,
  65. SkColor foreground_disabled,
  66. SkColor background));
  67. MOCK_METHOD0(OnHeaderClicked, void());
  68. };
  69. } // namespace
  70. class MediaNotificationViewModernImplTest : public views::ViewsTestBase {
  71. public:
  72. MediaNotificationViewModernImplTest()
  73. : views::ViewsTestBase(
  74. base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
  75. MediaNotificationViewModernImplTest(
  76. const MediaNotificationViewModernImplTest&) = delete;
  77. MediaNotificationViewModernImplTest& operator=(
  78. const MediaNotificationViewModernImplTest&) = delete;
  79. ~MediaNotificationViewModernImplTest() override = default;
  80. void SetUp() override {
  81. views::ViewsTestBase::SetUp();
  82. // Create a widget to show on the screen for testing screen coordinates and
  83. // focus.
  84. widget_ = std::make_unique<views::Widget>();
  85. views::Widget::InitParams params =
  86. CreateParams(views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
  87. params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  88. params.bounds = gfx::Rect(kWidgetSize);
  89. widget_->Init(std::move(params));
  90. widget_->Show();
  91. // Creates the view and adds it to the widget.
  92. CreateView();
  93. }
  94. void TearDown() override {
  95. view_ = nullptr;
  96. widget_.reset();
  97. actions_.clear();
  98. views::ViewsTestBase::TearDown();
  99. }
  100. void EnableAllActions() {
  101. actions_.insert(MediaSessionAction::kPlay);
  102. actions_.insert(MediaSessionAction::kPause);
  103. actions_.insert(MediaSessionAction::kPreviousTrack);
  104. actions_.insert(MediaSessionAction::kNextTrack);
  105. actions_.insert(MediaSessionAction::kSeekBackward);
  106. actions_.insert(MediaSessionAction::kSeekForward);
  107. actions_.insert(MediaSessionAction::kStop);
  108. actions_.insert(MediaSessionAction::kEnterPictureInPicture);
  109. actions_.insert(MediaSessionAction::kExitPictureInPicture);
  110. NotifyUpdatedActions();
  111. }
  112. void EnableAction(MediaSessionAction action) {
  113. actions_.insert(action);
  114. NotifyUpdatedActions();
  115. }
  116. void DisableAction(MediaSessionAction action) {
  117. actions_.erase(action);
  118. NotifyUpdatedActions();
  119. }
  120. MockMediaNotificationContainer& container() { return container_; }
  121. MediaNotificationViewModernImpl* view() const { return view_; }
  122. const std::u16string& accessible_name() const {
  123. return view()->accessible_name_;
  124. }
  125. test::MockMediaNotificationItem& item() { return item_; }
  126. views::Label* title_label() const { return view()->title_label_; }
  127. views::Label* subtitle_label() const { return view()->subtitle_label_; }
  128. views::View* artwork_container() const { return view()->artwork_container_; }
  129. views::View* media_controls_container() const {
  130. return view()->media_controls_container_;
  131. }
  132. views::Button* picture_in_picture_button() const {
  133. return view()->picture_in_picture_button_for_testing();
  134. }
  135. std::vector<views::Button*> media_control_buttons() const {
  136. std::vector<views::Button*> buttons;
  137. auto children = view()->media_controls_container_->children();
  138. std::transform(
  139. children.begin(), children.end(), std::back_inserter(buttons),
  140. [](views::View* child) { return views::Button::AsButton(child); });
  141. buttons.push_back(views::Button::AsButton(picture_in_picture_button()));
  142. return buttons;
  143. }
  144. MediaControlsProgressView* progress_view() const { return view()->progress_; }
  145. views::Button* GetButtonForAction(MediaSessionAction action) const {
  146. auto buttons = media_control_buttons();
  147. const auto i = std::find_if(
  148. buttons.begin(), buttons.end(), [action](const views::Button* button) {
  149. return button->tag() == static_cast<int>(action);
  150. });
  151. return (i == buttons.end()) ? nullptr : *i;
  152. }
  153. bool IsActionButtonVisible(MediaSessionAction action) const {
  154. return GetButtonForAction(action)->GetVisible();
  155. }
  156. const gfx::ImageSkia& GetArtworkImage() const {
  157. return static_cast<MediaNotificationBackgroundImpl*>(
  158. view()->GetMediaNotificationBackground())
  159. ->artwork_;
  160. }
  161. void SimulateButtonClick(MediaSessionAction action) {
  162. views::Button* button = GetButtonForAction(action);
  163. EXPECT_TRUE(button->GetVisible());
  164. views::test::ButtonTestApi(button).NotifyClick(
  165. ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
  166. ui::EventTimeForNow(), 0, 0));
  167. }
  168. void SimulateTab() {
  169. ui::KeyEvent pressed_tab(ui::ET_KEY_PRESSED, ui::VKEY_TAB, ui::EF_NONE);
  170. view()->GetFocusManager()->OnKeyEvent(pressed_tab);
  171. }
  172. void ExpectHistogramArtworkRecorded(bool present, int count) {
  173. histogram_tester_.ExpectBucketCount(
  174. MediaNotificationViewModernImpl::kArtworkHistogramName,
  175. static_cast<base::HistogramBase::Sample>(present), count);
  176. }
  177. void ExpectHistogramMetadataRecorded(
  178. MediaNotificationViewModernImpl::Metadata metadata,
  179. int count) {
  180. histogram_tester_.ExpectBucketCount(
  181. MediaNotificationViewModernImpl::kMetadataHistogramName,
  182. static_cast<base::HistogramBase::Sample>(metadata), count);
  183. }
  184. private:
  185. void NotifyUpdatedActions() { view_->UpdateWithMediaActions(actions_); }
  186. void CreateView() {
  187. // On creation, the view should notify |item_|.
  188. auto view = std::make_unique<MediaNotificationViewModernImpl>(
  189. &container_, item_.GetWeakPtr(), std::make_unique<views::View>(),
  190. std::make_unique<views::View>(), kViewWidth);
  191. view->SetSize(kViewSize);
  192. media_session::MediaMetadata metadata;
  193. metadata.title = u"title";
  194. metadata.artist = u"artist";
  195. metadata.source_title = u"source title";
  196. view->UpdateWithMediaMetadata(metadata);
  197. view->UpdateWithMediaActions(actions_);
  198. // Display it in |widget_|. Widget now owns |view|.
  199. view_ = widget_->SetContentsView(std::move(view));
  200. }
  201. base::HistogramTester histogram_tester_;
  202. base::flat_set<MediaSessionAction> actions_;
  203. MockMediaNotificationContainer container_;
  204. test::MockMediaNotificationItem item_;
  205. raw_ptr<MediaNotificationViewModernImpl> view_;
  206. std::unique_ptr<views::Widget> widget_;
  207. };
  208. TEST_F(MediaNotificationViewModernImplTest, ButtonsSanityCheck) {
  209. EnableAllActions();
  210. EXPECT_TRUE(media_controls_container()->GetVisible());
  211. EXPECT_GT(media_controls_container()->width(), 0);
  212. EXPECT_GT(media_controls_container()->height(), 0);
  213. auto buttons = media_control_buttons();
  214. EXPECT_EQ(6u, buttons.size());
  215. for (auto* button : buttons) {
  216. EXPECT_TRUE(button->GetVisible());
  217. if (button == picture_in_picture_button()) {
  218. EXPECT_LT(kPipButtonIconSize, button->width());
  219. EXPECT_LT(kPipButtonIconSize, button->height());
  220. } else {
  221. EXPECT_LT(kMediaButtonIconSize, button->width());
  222. EXPECT_LT(kMediaButtonIconSize, button->height());
  223. }
  224. EXPECT_FALSE(views::Button::AsButton(button)->GetAccessibleName().empty());
  225. }
  226. EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
  227. EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPreviousTrack));
  228. EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kNextTrack));
  229. EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kSeekBackward));
  230. EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kSeekForward));
  231. EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kEnterPictureInPicture));
  232. // |kPause| cannot be present if |kPlay| is.
  233. EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
  234. EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kExitPictureInPicture));
  235. }
  236. #if BUILDFLAG(IS_WIN)
  237. #define MAYBE_ButtonsFocusCheck DISABLED_ButtonsFocusCheck
  238. #else
  239. #define MAYBE_ButtonsFocusCheck ButtonsFocusCheck
  240. #endif
  241. TEST_F(MediaNotificationViewModernImplTest, MAYBE_ButtonsFocusCheck) {
  242. // Expand and enable all actions to show all buttons.
  243. EnableAllActions();
  244. views::FocusManager* focus_manager = view()->GetFocusManager();
  245. {
  246. // Focus the first action button.
  247. auto* button = GetButtonForAction(MediaSessionAction::kPreviousTrack);
  248. focus_manager->SetFocusedView(button);
  249. EXPECT_EQ(button, focus_manager->GetFocusedView());
  250. }
  251. SimulateTab();
  252. EXPECT_EQ(GetButtonForAction(MediaSessionAction::kSeekBackward),
  253. focus_manager->GetFocusedView());
  254. SimulateTab();
  255. EXPECT_EQ(GetButtonForAction(MediaSessionAction::kPlay),
  256. focus_manager->GetFocusedView());
  257. SimulateTab();
  258. EXPECT_EQ(GetButtonForAction(MediaSessionAction::kSeekForward),
  259. focus_manager->GetFocusedView());
  260. SimulateTab();
  261. EXPECT_EQ(GetButtonForAction(MediaSessionAction::kNextTrack),
  262. focus_manager->GetFocusedView());
  263. }
  264. TEST_F(MediaNotificationViewModernImplTest, PlayPauseButtonTooltipCheck) {
  265. EnableAction(MediaSessionAction::kPlay);
  266. EnableAction(MediaSessionAction::kPause);
  267. EXPECT_CALL(container(), OnMediaSessionInfoChanged(_));
  268. auto* button = GetButtonForAction(MediaSessionAction::kPlay);
  269. std::u16string tooltip = button->GetTooltipText(gfx::Point());
  270. EXPECT_FALSE(tooltip.empty());
  271. auto session_info = media_session::mojom::MediaSessionInfo::New();
  272. session_info->playback_state =
  273. media_session::mojom::MediaPlaybackState::kPlaying;
  274. session_info->is_controllable = true;
  275. view()->UpdateWithMediaSessionInfo(std::move(session_info));
  276. std::u16string new_tooltip = button->GetTooltipText(gfx::Point());
  277. EXPECT_FALSE(new_tooltip.empty());
  278. EXPECT_NE(tooltip, new_tooltip);
  279. }
  280. TEST_F(MediaNotificationViewModernImplTest, NextTrackButtonClick) {
  281. EnableAction(MediaSessionAction::kNextTrack);
  282. EXPECT_CALL(item(), OnMediaSessionActionButtonPressed(
  283. MediaSessionAction::kNextTrack));
  284. SimulateButtonClick(MediaSessionAction::kNextTrack);
  285. }
  286. TEST_F(MediaNotificationViewModernImplTest, PlayButtonClick) {
  287. EnableAction(MediaSessionAction::kPlay);
  288. EXPECT_CALL(item(),
  289. OnMediaSessionActionButtonPressed(MediaSessionAction::kPlay));
  290. SimulateButtonClick(MediaSessionAction::kPlay);
  291. }
  292. TEST_F(MediaNotificationViewModernImplTest, PauseButtonClick) {
  293. EnableAction(MediaSessionAction::kPause);
  294. auto session_info = media_session::mojom::MediaSessionInfo::New();
  295. session_info->playback_state =
  296. media_session::mojom::MediaPlaybackState::kPlaying;
  297. session_info->is_controllable = true;
  298. EXPECT_CALL(container(), OnMediaSessionInfoChanged(_));
  299. view()->UpdateWithMediaSessionInfo(session_info.Clone());
  300. testing::Mock::VerifyAndClearExpectations(&container());
  301. EXPECT_CALL(item(),
  302. OnMediaSessionActionButtonPressed(MediaSessionAction::kPause));
  303. SimulateButtonClick(MediaSessionAction::kPause);
  304. }
  305. TEST_F(MediaNotificationViewModernImplTest, PreviousTrackButtonClick) {
  306. EnableAction(MediaSessionAction::kPreviousTrack);
  307. EXPECT_CALL(item(), OnMediaSessionActionButtonPressed(
  308. MediaSessionAction::kPreviousTrack));
  309. SimulateButtonClick(MediaSessionAction::kPreviousTrack);
  310. }
  311. TEST_F(MediaNotificationViewModernImplTest, SeekBackwardButtonClick) {
  312. EnableAction(MediaSessionAction::kSeekBackward);
  313. EXPECT_CALL(item(), OnMediaSessionActionButtonPressed(
  314. MediaSessionAction::kSeekBackward));
  315. SimulateButtonClick(MediaSessionAction::kSeekBackward);
  316. }
  317. TEST_F(MediaNotificationViewModernImplTest, SeekForwardButtonClick) {
  318. EnableAction(MediaSessionAction::kSeekForward);
  319. EXPECT_CALL(item(), OnMediaSessionActionButtonPressed(
  320. MediaSessionAction::kSeekForward));
  321. SimulateButtonClick(MediaSessionAction::kSeekForward);
  322. }
  323. TEST_F(MediaNotificationViewModernImplTest, PlayToggle_FromObserver_Empty) {
  324. EnableAction(MediaSessionAction::kPlay);
  325. {
  326. views::Button* button = GetButtonForAction(MediaSessionAction::kPlay);
  327. EXPECT_NE(button, nullptr);
  328. EXPECT_EQ(button->tag(), static_cast<int>(MediaSessionAction::kPlay));
  329. }
  330. view()->UpdateWithMediaSessionInfo(
  331. media_session::mojom::MediaSessionInfo::New());
  332. {
  333. views::Button* button = GetButtonForAction(MediaSessionAction::kPlay);
  334. EXPECT_NE(button, nullptr);
  335. EXPECT_EQ(button->tag(), static_cast<int>(MediaSessionAction::kPlay));
  336. }
  337. }
  338. TEST_F(MediaNotificationViewModernImplTest,
  339. PlayToggle_FromObserver_PlaybackState) {
  340. EnableAction(MediaSessionAction::kPlay);
  341. EnableAction(MediaSessionAction::kPause);
  342. {
  343. views::Button* button = GetButtonForAction(MediaSessionAction::kPlay);
  344. EXPECT_NE(button, nullptr);
  345. EXPECT_EQ(button->tag(), static_cast<int>(MediaSessionAction::kPlay));
  346. }
  347. media_session::mojom::MediaSessionInfoPtr session_info(
  348. media_session::mojom::MediaSessionInfo::New());
  349. session_info->playback_state =
  350. media_session::mojom::MediaPlaybackState::kPlaying;
  351. view()->UpdateWithMediaSessionInfo(session_info.Clone());
  352. {
  353. views::Button* button = GetButtonForAction(MediaSessionAction::kPause);
  354. EXPECT_NE(button, nullptr);
  355. EXPECT_EQ(button->tag(), static_cast<int>(MediaSessionAction::kPause));
  356. }
  357. session_info->playback_state =
  358. media_session::mojom::MediaPlaybackState::kPaused;
  359. view()->UpdateWithMediaSessionInfo(session_info.Clone());
  360. {
  361. views::Button* button = GetButtonForAction(MediaSessionAction::kPlay);
  362. EXPECT_NE(button, nullptr);
  363. EXPECT_EQ(button->tag(), static_cast<int>(MediaSessionAction::kPlay));
  364. }
  365. }
  366. TEST_F(MediaNotificationViewModernImplTest, MetadataIsDisplayed) {
  367. EnableAllActions();
  368. EXPECT_TRUE(title_label()->GetVisible());
  369. EXPECT_TRUE(subtitle_label()->GetVisible());
  370. EXPECT_EQ(u"title", title_label()->GetText());
  371. EXPECT_EQ(u"source title", subtitle_label()->GetText());
  372. }
  373. TEST_F(MediaNotificationViewModernImplTest, UpdateMetadata_FromObserver) {
  374. EnableAllActions();
  375. ExpectHistogramMetadataRecorded(
  376. MediaNotificationViewModernImpl::Metadata::kTitle, 1);
  377. ExpectHistogramMetadataRecorded(
  378. MediaNotificationViewModernImpl::Metadata::kSource, 1);
  379. ExpectHistogramMetadataRecorded(
  380. MediaNotificationViewModernImpl::Metadata::kCount, 1);
  381. media_session::MediaMetadata metadata;
  382. metadata.title = u"title2";
  383. metadata.source_title = u"source title2";
  384. metadata.artist = u"artist2";
  385. metadata.album = u"album";
  386. EXPECT_CALL(container(), OnMediaSessionMetadataChanged(_));
  387. view()->UpdateWithMediaMetadata(metadata);
  388. testing::Mock::VerifyAndClearExpectations(&container());
  389. EXPECT_TRUE(title_label()->GetVisible());
  390. EXPECT_TRUE(subtitle_label()->GetVisible());
  391. EXPECT_EQ(metadata.title, title_label()->GetText());
  392. EXPECT_EQ(metadata.source_title, subtitle_label()->GetText());
  393. EXPECT_EQ(u"title2 - artist2 - album", accessible_name());
  394. ExpectHistogramMetadataRecorded(
  395. MediaNotificationViewModernImpl::Metadata::kTitle, 2);
  396. ExpectHistogramMetadataRecorded(
  397. MediaNotificationViewModernImpl::Metadata::kSource, 2);
  398. ExpectHistogramMetadataRecorded(
  399. MediaNotificationViewModernImpl::Metadata::kCount, 2);
  400. }
  401. TEST_F(MediaNotificationViewModernImplTest, ActionButtonsHiddenByDefault) {
  402. EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kPlay));
  403. EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kNextTrack));
  404. EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kPreviousTrack));
  405. EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kSeekForward));
  406. EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kSeekBackward));
  407. }
  408. TEST_F(MediaNotificationViewModernImplTest, ActionButtonsToggleVisibility) {
  409. EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kNextTrack));
  410. EnableAction(MediaSessionAction::kNextTrack);
  411. EXPECT_TRUE(IsActionButtonVisible(MediaSessionAction::kNextTrack));
  412. DisableAction(MediaSessionAction::kNextTrack);
  413. EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kNextTrack));
  414. }
  415. TEST_F(MediaNotificationViewModernImplTest, UpdateArtworkFromItem) {
  416. int labels_container_width = title_label()->parent()->width();
  417. gfx::Size size = view()->size();
  418. EXPECT_CALL(container(), OnMediaArtworkChanged(_)).Times(2);
  419. EXPECT_CALL(container(), OnColorsChanged(_, _, _)).Times(2);
  420. SkBitmap image;
  421. image.allocN32Pixels(10, 10);
  422. image.eraseColor(SK_ColorGREEN);
  423. EXPECT_TRUE(GetArtworkImage().isNull());
  424. view()->UpdateWithMediaArtwork(gfx::ImageSkia::CreateFrom1xBitmap(image));
  425. ExpectHistogramArtworkRecorded(true, 1);
  426. // The size of the labels container should not change when there is artwork.
  427. EXPECT_EQ(labels_container_width, title_label()->parent()->width());
  428. // Ensure that the labels container does not extend into the artwork bounds.
  429. EXPECT_FALSE(artwork_container()->bounds().Intersects(
  430. title_label()->parent()->bounds()));
  431. // Ensure that when the image is displayed that the size of the notification
  432. // was not affected.
  433. EXPECT_FALSE(GetArtworkImage().isNull());
  434. EXPECT_EQ(gfx::Size(10, 10), GetArtworkImage().size());
  435. EXPECT_EQ(size, view()->size());
  436. view()->UpdateWithMediaArtwork(
  437. gfx::ImageSkia::CreateFrom1xBitmap(SkBitmap()));
  438. ExpectHistogramArtworkRecorded(false, 1);
  439. // Ensure the labels container goes back to the original width now that we
  440. // do not have any artwork.
  441. EXPECT_EQ(labels_container_width, title_label()->parent()->width());
  442. // Ensure that the artwork was reset and the size was still not
  443. // affected.
  444. EXPECT_TRUE(GetArtworkImage().isNull());
  445. EXPECT_EQ(size, view()->size());
  446. }
  447. TEST_F(MediaNotificationViewModernImplTest, UpdateProgressBar) {
  448. media_session::MediaPosition media_position(
  449. /*playback_rate=*/1.0, /*duration=*/base::Seconds(600),
  450. /*position=*/base::Seconds(0), /*end_of_media=*/false);
  451. view()->UpdateWithMediaPosition(media_position);
  452. EXPECT_EQ(progress_view()->duration_for_testing(), u"10:00");
  453. }
  454. TEST_F(MediaNotificationViewModernImplTest, AccessibleNodeData) {
  455. ui::AXNodeData data;
  456. view()->GetAccessibleNodeData(&data);
  457. EXPECT_TRUE(
  458. data.HasStringAttribute(ax::mojom::StringAttribute::kRoleDescription));
  459. EXPECT_EQ(u"title - artist", accessible_name());
  460. }
  461. class MediaNotificationViewModernImplCastTest
  462. : public MediaNotificationViewModernImplTest {
  463. public:
  464. void SetUp() override {
  465. EXPECT_CALL(item(), SourceType())
  466. .WillRepeatedly(Return(media_message_center::SourceType::kCast));
  467. MediaNotificationViewModernImplTest::SetUp();
  468. }
  469. };
  470. TEST_F(MediaNotificationViewModernImplCastTest, PictureInPictureButton) {
  471. // We should not create picture-in-picture button for cast session.
  472. EXPECT_EQ(picture_in_picture_button(), nullptr);
  473. }
  474. } // namespace media_message_center