1 // Copyright 2018 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 "components/media_message_center/media_notification_view_impl.h"
6 
7 #include <memory>
8 
9 #include "base/bind.h"
10 #include "base/callback_helpers.h"
11 #include "base/containers/flat_set.h"
12 #include "base/macros.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/test/metrics/histogram_tester.h"
15 #include "base/test/mock_callback.h"
16 #include "base/test/task_environment.h"
17 #include "base/unguessable_token.h"
18 #include "build/build_config.h"
19 #include "components/media_message_center/media_notification_background_impl.h"
20 #include "components/media_message_center/media_notification_constants.h"
21 #include "components/media_message_center/media_notification_container.h"
22 #include "components/media_message_center/media_notification_controller.h"
23 #include "components/media_message_center/media_session_notification_item.h"
24 #include "services/media_session/public/cpp/test/test_media_controller.h"
25 #include "services/media_session/public/mojom/audio_focus.mojom.h"
26 #include "services/media_session/public/mojom/media_session.mojom.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "ui/accessibility/ax_enums.mojom.h"
29 #include "ui/accessibility/ax_node_data.h"
30 #include "ui/events/base_event_utils.h"
31 #include "ui/message_center/message_center.h"
32 #include "ui/message_center/public/cpp/message_center_constants.h"
33 #include "ui/message_center/views/message_view_factory.h"
34 #include "ui/message_center/views/notification_control_buttons_view.h"
35 #include "ui/message_center/views/notification_header_view.h"
36 #include "ui/views/controls/image_view.h"
37 #include "ui/views/test/button_test_api.h"
38 #include "ui/views/test/views_test_base.h"
39 
40 namespace media_message_center {
41 
42 using media_session::mojom::MediaSessionAction;
43 using media_session::test::TestMediaController;
44 using testing::_;
45 using testing::Expectation;
46 using testing::Invoke;
47 
48 namespace {
49 
50 // The icons size is 24 and INSETS_VECTOR_IMAGE_BUTTON will add padding around
51 // the image.
52 const int kMediaButtonIconSize = 24;
53 
54 // The title artist row should always have the same height.
55 const int kMediaTitleArtistRowExpectedHeight = 48;
56 
57 const char kTestDefaultAppName[] = "default app name";
58 const char kTestAppName[] = "app name";
59 
60 const gfx::Size kWidgetSize(500, 500);
61 
62 constexpr int kViewWidth = 400;
63 constexpr int kViewArtworkWidth = kViewWidth * 0.4;
64 const gfx::Size kViewSize(kViewWidth, 400);
65 
66 class MockMediaNotificationController : public MediaNotificationController {
67  public:
68   MockMediaNotificationController() = default;
69   ~MockMediaNotificationController() = default;
70 
71   // MediaNotificationController implementation.
72   MOCK_METHOD(void, ShowNotification, (const std::string& id));
73   MOCK_METHOD(void, HideNotification, (const std::string& id));
74   MOCK_METHOD(void, RemoveItem, (const std::string& id));
GetTaskRunner() const75   scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() const override {
76     return nullptr;
77   }
78   MOCK_METHOD(void,
79               LogMediaSessionActionButtonPressed,
80               (const std::string& id,
81                media_session::mojom::MediaSessionAction action));
82 
83  private:
84   DISALLOW_COPY_AND_ASSIGN(MockMediaNotificationController);
85 };
86 
87 class MockMediaNotificationContainer : public MediaNotificationContainer {
88  public:
89   MockMediaNotificationContainer() = default;
90   ~MockMediaNotificationContainer() = default;
91 
92   // MediaNotificationContainer implementation.
93   MOCK_METHOD1(OnExpanded, void(bool expanded));
94   MOCK_METHOD1(
95       OnMediaSessionInfoChanged,
96       void(const media_session::mojom::MediaSessionInfoPtr& session_info));
97   MOCK_METHOD1(OnMediaSessionMetadataChanged,
98                void(const media_session::MediaMetadata& metadata));
99   MOCK_METHOD1(OnVisibleActionsChanged,
100                void(const base::flat_set<MediaSessionAction>& actions));
101   MOCK_METHOD1(OnMediaArtworkChanged, void(const gfx::ImageSkia& image));
102   MOCK_METHOD2(OnColorsChanged, void(SkColor foreground, SkColor background));
103   MOCK_METHOD0(OnHeaderClicked, void());
104 
view() const105   MediaNotificationViewImpl* view() const { return view_; }
SetView(MediaNotificationViewImpl * view)106   void SetView(MediaNotificationViewImpl* view) { view_ = view; }
107 
108  private:
109   MediaNotificationViewImpl* view_;
110 
111   DISALLOW_COPY_AND_ASSIGN(MockMediaNotificationContainer);
112 };
113 
114 }  // namespace
115 
116 class MediaNotificationViewImplTest : public views::ViewsTestBase {
117  public:
MediaNotificationViewImplTest()118   MediaNotificationViewImplTest()
119       : views::ViewsTestBase(
120             base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
121   ~MediaNotificationViewImplTest() override = default;
122 
SetUp()123   void SetUp() override {
124     views::ViewsTestBase::SetUp();
125 
126     request_id_ = base::UnguessableToken::Create();
127 
128     // Create a new MediaNotificationViewImpl whenever the
129     // MediaSessionNotificationItem says to show the notification.
130     EXPECT_CALL(controller_, ShowNotification(request_id_.ToString()))
131         .WillRepeatedly(InvokeWithoutArgs(
132             this, &MediaNotificationViewImplTest::CreateView));
133 
134     // Create a widget to show on the screen for testing screen coordinates and
135     // focus.
136     widget_ = std::make_unique<views::Widget>();
137     views::Widget::InitParams params =
138         CreateParams(views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
139     params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
140     params.bounds = gfx::Rect(kWidgetSize);
141     widget_->Init(std::move(params));
142     widget_->Show();
143 
144     CreateViewFromMediaSessionInfo(
145         media_session::mojom::MediaSessionInfo::New());
146   }
147 
CreateViewFromMediaSessionInfo(media_session::mojom::MediaSessionInfoPtr session_info)148   void CreateViewFromMediaSessionInfo(
149       media_session::mojom::MediaSessionInfoPtr session_info) {
150     session_info->is_controllable = true;
151     mojo::Remote<media_session::mojom::MediaController> controller;
152     item_ = std::make_unique<MediaSessionNotificationItem>(
153         &controller_, request_id_.ToString(), std::string(),
154         std::move(controller), std::move(session_info));
155 
156     // Update the metadata.
157     media_session::MediaMetadata metadata;
158     metadata.title = base::ASCIIToUTF16("title");
159     metadata.artist = base::ASCIIToUTF16("artist");
160     item_->MediaSessionMetadataChanged(metadata);
161 
162     // Inject the test media controller into the item.
163     media_controller_ = std::make_unique<TestMediaController>();
164     item_->SetMediaControllerForTesting(
165         media_controller_->CreateMediaControllerRemote());
166   }
167 
TearDown()168   void TearDown() override {
169     container_.SetView(nullptr);
170     widget_.reset();
171 
172     actions_.clear();
173 
174     views::ViewsTestBase::TearDown();
175   }
176 
EnableAllActions()177   void EnableAllActions() {
178     actions_.insert(MediaSessionAction::kPlay);
179     actions_.insert(MediaSessionAction::kPause);
180     actions_.insert(MediaSessionAction::kPreviousTrack);
181     actions_.insert(MediaSessionAction::kNextTrack);
182     actions_.insert(MediaSessionAction::kSeekBackward);
183     actions_.insert(MediaSessionAction::kSeekForward);
184     actions_.insert(MediaSessionAction::kStop);
185     actions_.insert(MediaSessionAction::kEnterPictureInPicture);
186     actions_.insert(MediaSessionAction::kExitPictureInPicture);
187 
188     NotifyUpdatedActions();
189   }
190 
EnableAction(MediaSessionAction action)191   void EnableAction(MediaSessionAction action) {
192     actions_.insert(action);
193     NotifyUpdatedActions();
194   }
195 
DisableAction(MediaSessionAction action)196   void DisableAction(MediaSessionAction action) {
197     actions_.erase(action);
198     NotifyUpdatedActions();
199   }
200 
container()201   MockMediaNotificationContainer& container() { return container_; }
202 
controller()203   MockMediaNotificationController& controller() { return controller_; }
204 
view() const205   MediaNotificationViewImpl* view() const { return container_.view(); }
206 
media_controller() const207   TestMediaController* media_controller() const {
208     return media_controller_.get();
209   }
210 
GetHeaderRow(MediaNotificationViewImpl * view) const211   message_center::NotificationHeaderView* GetHeaderRow(
212       MediaNotificationViewImpl* view) const {
213     return view->header_row_;
214   }
215 
header_row() const216   message_center::NotificationHeaderView* header_row() const {
217     return GetHeaderRow(view());
218   }
219 
accessible_name() const220   const base::string16& accessible_name() const {
221     return view()->accessible_name_;
222   }
223 
button_row() const224   views::View* button_row() const { return view()->button_row_; }
225 
playback_button_container() const226   const views::View* playback_button_container() const {
227     return view()->playback_button_container_;
228   }
229 
title_artist_row() const230   views::View* title_artist_row() const { return view()->title_artist_row_; }
231 
title_label() const232   views::Label* title_label() const { return view()->title_label_; }
233 
artist_label() const234   views::Label* artist_label() const { return view()->artist_label_; }
235 
GetButtonForAction(MediaSessionAction action) const236   views::Button* GetButtonForAction(MediaSessionAction action) const {
237     auto buttons = view()->get_buttons_for_testing();
238     const auto i = std::find_if(
239         buttons.begin(), buttons.end(), [action](const views::View* v) {
240           return views::Button::AsButton(v)->tag() == static_cast<int>(action);
241         });
242     return (i == buttons.end()) ? nullptr : views::Button::AsButton(*i);
243   }
244 
IsActionButtonVisible(MediaSessionAction action) const245   bool IsActionButtonVisible(MediaSessionAction action) const {
246     return GetButtonForAction(action)->GetVisible();
247   }
248 
GetItem() const249   MediaSessionNotificationItem* GetItem() const { return item_.get(); }
250 
GetArtworkImage() const251   const gfx::ImageSkia& GetArtworkImage() const {
252     return static_cast<MediaNotificationBackgroundImpl*>(
253                view()->GetMediaNotificationBackground())
254         ->artwork_;
255   }
256 
GetAppIcon() const257   const gfx::ImageSkia& GetAppIcon() const {
258     return header_row()->app_icon_for_testing();
259   }
260 
expand_button_enabled() const261   bool expand_button_enabled() const {
262     return header_row()->expand_button()->GetVisible();
263   }
264 
IsActuallyExpanded() const265   bool IsActuallyExpanded() const { return view()->IsActuallyExpanded(); }
266 
SimulateButtonClick(MediaSessionAction action)267   void SimulateButtonClick(MediaSessionAction action) {
268     views::Button* button = GetButtonForAction(action);
269     EXPECT_TRUE(button->GetVisible());
270 
271     views::test::ButtonTestApi(button).NotifyClick(
272         ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
273                        ui::EventTimeForNow(), 0, 0));
274   }
275 
SimulateHeaderClick()276   void SimulateHeaderClick() {
277     views::test::ButtonTestApi(header_row())
278         .NotifyClick(ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(),
279                                     gfx::Point(), ui::EventTimeForNow(), 0, 0));
280   }
281 
SimulateTab()282   void SimulateTab() {
283     ui::KeyEvent pressed_tab(ui::ET_KEY_PRESSED, ui::VKEY_TAB, ui::EF_NONE);
284     view()->GetFocusManager()->OnKeyEvent(pressed_tab);
285   }
286 
ExpectHistogramActionRecorded(MediaSessionAction action)287   void ExpectHistogramActionRecorded(MediaSessionAction action) {
288     histogram_tester_.ExpectUniqueSample(
289         MediaSessionNotificationItem::kUserActionHistogramName,
290         static_cast<base::HistogramBase::Sample>(action), 1);
291   }
292 
ExpectHistogramArtworkRecorded(bool present,int count)293   void ExpectHistogramArtworkRecorded(bool present, int count) {
294     histogram_tester_.ExpectBucketCount(
295         MediaNotificationViewImpl::kArtworkHistogramName,
296         static_cast<base::HistogramBase::Sample>(present), count);
297   }
298 
ExpectHistogramMetadataRecorded(MediaNotificationViewImpl::Metadata metadata,int count)299   void ExpectHistogramMetadataRecorded(
300       MediaNotificationViewImpl::Metadata metadata,
301       int count) {
302     histogram_tester_.ExpectBucketCount(
303         MediaNotificationViewImpl::kMetadataHistogramName,
304         static_cast<base::HistogramBase::Sample>(metadata), count);
305   }
306 
AdvanceClockMilliseconds(int milliseconds)307   void AdvanceClockMilliseconds(int milliseconds) {
308     task_environment()->FastForwardBy(
309         base::TimeDelta::FromMilliseconds(milliseconds));
310   }
311 
312  private:
NotifyUpdatedActions()313   void NotifyUpdatedActions() {
314     item_->MediaSessionActionsChanged(
315         std::vector<MediaSessionAction>(actions_.begin(), actions_.end()));
316   }
317 
CreateView()318   void CreateView() {
319     // Create a MediaNotificationViewImpl.
320     auto view = std::make_unique<MediaNotificationViewImpl>(
321         &container_, item_->GetWeakPtr(),
322         nullptr /* header_row_controls_view */,
323         base::ASCIIToUTF16(kTestDefaultAppName), kViewWidth,
324         /*should_show_icon=*/true);
325     view->SetSize(kViewSize);
326 
327     // Display it in |widget_|. Widget now owns |view|.
328     // And associate it with |container_|.
329     container_.SetView(widget_->SetContentsView(std::move(view)));
330   }
331 
332   base::UnguessableToken request_id_;
333 
334   base::HistogramTester histogram_tester_;
335 
336   base::flat_set<MediaSessionAction> actions_;
337 
338   std::unique_ptr<TestMediaController> media_controller_;
339   MockMediaNotificationContainer container_;
340   MockMediaNotificationController controller_;
341   std::unique_ptr<MediaSessionNotificationItem> item_;
342   std::unique_ptr<views::Widget> widget_;
343 
344   DISALLOW_COPY_AND_ASSIGN(MediaNotificationViewImplTest);
345 };
346 
347 // TODO(crbug.com/1009287): many of these tests are failing on TSan builds.
348 #if defined(THREAD_SANITIZER)
349 #define MAYBE_MediaNotificationViewImplTest \
350   DISABLED_MediaNotificationViewImplTest
351 class DISABLED_MediaNotificationViewImplTest
352     : public MediaNotificationViewImplTest {};
353 #else
354 #define MAYBE_MediaNotificationViewImplTest MediaNotificationViewImplTest
355 #endif
356 
TEST_F(MAYBE_MediaNotificationViewImplTest,ButtonsSanityCheck)357 TEST_F(MAYBE_MediaNotificationViewImplTest, ButtonsSanityCheck) {
358   view()->SetExpanded(true);
359 
360   EnableAllActions();
361 
362   EXPECT_TRUE(button_row()->GetVisible());
363   EXPECT_GT(button_row()->width(), 0);
364   EXPECT_GT(button_row()->height(), 0);
365 
366   auto buttons = view()->get_buttons_for_testing();
367   EXPECT_EQ(6u, buttons.size());
368 
369   for (auto* button : buttons) {
370     EXPECT_TRUE(button->GetVisible());
371     EXPECT_LT(kMediaButtonIconSize, button->width());
372     EXPECT_LT(kMediaButtonIconSize, button->height());
373     EXPECT_FALSE(views::Button::AsButton(button)->GetAccessibleName().empty());
374   }
375 
376   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
377   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPreviousTrack));
378   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kNextTrack));
379   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kSeekBackward));
380   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kSeekForward));
381   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kEnterPictureInPicture));
382 
383   // |kPause| cannot be present if |kPlay| is.
384   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
385   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kExitPictureInPicture));
386 }
387 
388 #if defined(OS_WIN)
389 #define MAYBE_ButtonsFocusCheck DISABLED_ButtonsFocusCheck
390 #else
391 #define MAYBE_ButtonsFocusCheck ButtonsFocusCheck
392 #endif
TEST_F(MAYBE_MediaNotificationViewImplTest,MAYBE_ButtonsFocusCheck)393 TEST_F(MAYBE_MediaNotificationViewImplTest, MAYBE_ButtonsFocusCheck) {
394   // Expand and enable all actions to show all buttons.
395   view()->SetExpanded(true);
396   EnableAllActions();
397 
398   views::FocusManager* focus_manager = view()->GetFocusManager();
399 
400   {
401     // Focus the first action button.
402     auto* button = GetButtonForAction(MediaSessionAction::kPreviousTrack);
403     focus_manager->SetFocusedView(button);
404     EXPECT_EQ(button, focus_manager->GetFocusedView());
405   }
406 
407   SimulateTab();
408   EXPECT_EQ(GetButtonForAction(MediaSessionAction::kSeekBackward),
409             focus_manager->GetFocusedView());
410 
411   SimulateTab();
412   EXPECT_EQ(GetButtonForAction(MediaSessionAction::kPlay),
413             focus_manager->GetFocusedView());
414 
415   SimulateTab();
416   EXPECT_EQ(GetButtonForAction(MediaSessionAction::kSeekForward),
417             focus_manager->GetFocusedView());
418 
419   SimulateTab();
420   EXPECT_EQ(GetButtonForAction(MediaSessionAction::kNextTrack),
421             focus_manager->GetFocusedView());
422 }
423 
TEST_F(MAYBE_MediaNotificationViewImplTest,PlayPauseButtonTooltipCheck)424 TEST_F(MAYBE_MediaNotificationViewImplTest, PlayPauseButtonTooltipCheck) {
425   EnableAction(MediaSessionAction::kPlay);
426   EnableAction(MediaSessionAction::kPause);
427 
428   EXPECT_CALL(container(), OnMediaSessionInfoChanged(_));
429 
430   auto* button = GetButtonForAction(MediaSessionAction::kPlay);
431   base::string16 tooltip = button->GetTooltipText(gfx::Point());
432   EXPECT_FALSE(tooltip.empty());
433 
434   media_session::mojom::MediaSessionInfoPtr session_info(
435       media_session::mojom::MediaSessionInfo::New());
436   session_info->playback_state =
437       media_session::mojom::MediaPlaybackState::kPlaying;
438   session_info->is_controllable = true;
439   GetItem()->MediaSessionInfoChanged(session_info.Clone());
440 
441   base::string16 new_tooltip = button->GetTooltipText(gfx::Point());
442   EXPECT_FALSE(new_tooltip.empty());
443   EXPECT_NE(tooltip, new_tooltip);
444 }
445 
TEST_F(MAYBE_MediaNotificationViewImplTest,NextTrackButtonClick)446 TEST_F(MAYBE_MediaNotificationViewImplTest, NextTrackButtonClick) {
447   EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed(
448                                 _, MediaSessionAction::kNextTrack));
449   EnableAction(MediaSessionAction::kNextTrack);
450 
451   EXPECT_EQ(0, media_controller()->next_track_count());
452 
453   SimulateButtonClick(MediaSessionAction::kNextTrack);
454   GetItem()->FlushForTesting();
455 
456   EXPECT_EQ(1, media_controller()->next_track_count());
457   ExpectHistogramActionRecorded(MediaSessionAction::kNextTrack);
458 }
459 
TEST_F(MAYBE_MediaNotificationViewImplTest,PlayButtonClick)460 TEST_F(MAYBE_MediaNotificationViewImplTest, PlayButtonClick) {
461   EXPECT_CALL(controller(),
462               LogMediaSessionActionButtonPressed(_, MediaSessionAction::kPlay));
463   EnableAction(MediaSessionAction::kPlay);
464 
465   EXPECT_EQ(0, media_controller()->resume_count());
466 
467   SimulateButtonClick(MediaSessionAction::kPlay);
468   GetItem()->FlushForTesting();
469 
470   EXPECT_EQ(1, media_controller()->resume_count());
471   ExpectHistogramActionRecorded(MediaSessionAction::kPlay);
472 }
473 
TEST_F(MAYBE_MediaNotificationViewImplTest,PauseButtonClick)474 TEST_F(MAYBE_MediaNotificationViewImplTest, PauseButtonClick) {
475   EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed(
476                                 _, MediaSessionAction::kPause));
477   EnableAction(MediaSessionAction::kPause);
478   EXPECT_CALL(container(), OnMediaSessionInfoChanged(_));
479 
480   EXPECT_EQ(0, media_controller()->suspend_count());
481 
482   media_session::mojom::MediaSessionInfoPtr session_info(
483       media_session::mojom::MediaSessionInfo::New());
484   session_info->playback_state =
485       media_session::mojom::MediaPlaybackState::kPlaying;
486   session_info->is_controllable = true;
487   GetItem()->MediaSessionInfoChanged(session_info.Clone());
488 
489   SimulateButtonClick(MediaSessionAction::kPause);
490   GetItem()->FlushForTesting();
491 
492   EXPECT_EQ(1, media_controller()->suspend_count());
493   ExpectHistogramActionRecorded(MediaSessionAction::kPause);
494 }
495 
TEST_F(MAYBE_MediaNotificationViewImplTest,PreviousTrackButtonClick)496 TEST_F(MAYBE_MediaNotificationViewImplTest, PreviousTrackButtonClick) {
497   EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed(
498                                 _, MediaSessionAction::kPreviousTrack));
499   EnableAction(MediaSessionAction::kPreviousTrack);
500 
501   EXPECT_EQ(0, media_controller()->previous_track_count());
502 
503   SimulateButtonClick(MediaSessionAction::kPreviousTrack);
504   GetItem()->FlushForTesting();
505 
506   EXPECT_EQ(1, media_controller()->previous_track_count());
507   ExpectHistogramActionRecorded(MediaSessionAction::kPreviousTrack);
508 }
509 
TEST_F(MAYBE_MediaNotificationViewImplTest,SeekBackwardButtonClick)510 TEST_F(MAYBE_MediaNotificationViewImplTest, SeekBackwardButtonClick) {
511   EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed(
512                                 _, MediaSessionAction::kSeekBackward));
513   EnableAction(MediaSessionAction::kSeekBackward);
514 
515   EXPECT_EQ(0, media_controller()->seek_backward_count());
516 
517   SimulateButtonClick(MediaSessionAction::kSeekBackward);
518   GetItem()->FlushForTesting();
519 
520   EXPECT_EQ(1, media_controller()->seek_backward_count());
521   ExpectHistogramActionRecorded(MediaSessionAction::kSeekBackward);
522 }
523 
TEST_F(MAYBE_MediaNotificationViewImplTest,SeekForwardButtonClick)524 TEST_F(MAYBE_MediaNotificationViewImplTest, SeekForwardButtonClick) {
525   EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed(
526                                 _, MediaSessionAction::kSeekForward));
527   EnableAction(MediaSessionAction::kSeekForward);
528 
529   EXPECT_EQ(0, media_controller()->seek_forward_count());
530 
531   SimulateButtonClick(MediaSessionAction::kSeekForward);
532   GetItem()->FlushForTesting();
533 
534   EXPECT_EQ(1, media_controller()->seek_forward_count());
535   ExpectHistogramActionRecorded(MediaSessionAction::kSeekForward);
536 }
537 
TEST_F(MAYBE_MediaNotificationViewImplTest,PlayToggle_FromObserver_Empty)538 TEST_F(MAYBE_MediaNotificationViewImplTest, PlayToggle_FromObserver_Empty) {
539   EnableAction(MediaSessionAction::kPlay);
540 
541   {
542     views::ToggleImageButton* button = static_cast<views::ToggleImageButton*>(
543         GetButtonForAction(MediaSessionAction::kPlay));
544     ASSERT_EQ(views::ToggleImageButton::kViewClassName, button->GetClassName());
545     EXPECT_FALSE(button->GetToggled());
546   }
547 
548   view()->UpdateWithMediaSessionInfo(
549       media_session::mojom::MediaSessionInfo::New());
550 
551   {
552     views::ToggleImageButton* button = static_cast<views::ToggleImageButton*>(
553         GetButtonForAction(MediaSessionAction::kPlay));
554     ASSERT_EQ(views::ToggleImageButton::kViewClassName, button->GetClassName());
555     EXPECT_FALSE(button->GetToggled());
556   }
557 }
558 
TEST_F(MAYBE_MediaNotificationViewImplTest,PlayToggle_FromObserver_PlaybackState)559 TEST_F(MAYBE_MediaNotificationViewImplTest,
560        PlayToggle_FromObserver_PlaybackState) {
561   EnableAction(MediaSessionAction::kPlay);
562   EnableAction(MediaSessionAction::kPause);
563 
564   {
565     views::ToggleImageButton* button = static_cast<views::ToggleImageButton*>(
566         GetButtonForAction(MediaSessionAction::kPlay));
567     ASSERT_EQ(views::ToggleImageButton::kViewClassName, button->GetClassName());
568     EXPECT_FALSE(button->GetToggled());
569   }
570 
571   media_session::mojom::MediaSessionInfoPtr session_info(
572       media_session::mojom::MediaSessionInfo::New());
573 
574   session_info->playback_state =
575       media_session::mojom::MediaPlaybackState::kPlaying;
576   view()->UpdateWithMediaSessionInfo(session_info.Clone());
577 
578   {
579     views::ToggleImageButton* button = static_cast<views::ToggleImageButton*>(
580         GetButtonForAction(MediaSessionAction::kPause));
581     ASSERT_EQ(views::ToggleImageButton::kViewClassName, button->GetClassName());
582     EXPECT_TRUE(button->GetToggled());
583   }
584 
585   session_info->playback_state =
586       media_session::mojom::MediaPlaybackState::kPaused;
587   view()->UpdateWithMediaSessionInfo(session_info.Clone());
588 
589   {
590     views::ToggleImageButton* button = static_cast<views::ToggleImageButton*>(
591         GetButtonForAction(MediaSessionAction::kPlay));
592     ASSERT_EQ(views::ToggleImageButton::kViewClassName, button->GetClassName());
593     EXPECT_FALSE(button->GetToggled());
594   }
595 }
596 
TEST_F(MAYBE_MediaNotificationViewImplTest,MetadataIsDisplayed)597 TEST_F(MAYBE_MediaNotificationViewImplTest, MetadataIsDisplayed) {
598   view()->SetExpanded(true);
599 
600   EnableAllActions();
601 
602   EXPECT_TRUE(title_artist_row()->GetVisible());
603   EXPECT_TRUE(title_label()->GetVisible());
604   EXPECT_TRUE(artist_label()->GetVisible());
605 
606   EXPECT_EQ(base::ASCIIToUTF16("title"), title_label()->GetText());
607   EXPECT_EQ(base::ASCIIToUTF16("artist"), artist_label()->GetText());
608 
609   EXPECT_EQ(kMediaTitleArtistRowExpectedHeight, title_artist_row()->height());
610 }
611 
TEST_F(MAYBE_MediaNotificationViewImplTest,UpdateMetadata_FromObserver)612 TEST_F(MAYBE_MediaNotificationViewImplTest, UpdateMetadata_FromObserver) {
613   EnableAllActions();
614 
615   ExpectHistogramMetadataRecorded(MediaNotificationViewImpl::Metadata::kTitle,
616                                   1);
617   ExpectHistogramMetadataRecorded(MediaNotificationViewImpl::Metadata::kArtist,
618                                   1);
619   ExpectHistogramMetadataRecorded(MediaNotificationViewImpl::Metadata::kAlbum,
620                                   0);
621   ExpectHistogramMetadataRecorded(MediaNotificationViewImpl::Metadata::kCount,
622                                   1);
623 
624   EXPECT_FALSE(header_row()->summary_text_for_testing()->GetVisible());
625 
626   media_session::MediaMetadata metadata;
627   metadata.title = base::ASCIIToUTF16("title2");
628   metadata.artist = base::ASCIIToUTF16("artist2");
629   metadata.album = base::ASCIIToUTF16("album");
630 
631   EXPECT_CALL(container(), OnMediaSessionMetadataChanged(_));
632   GetItem()->MediaSessionMetadataChanged(metadata);
633   view()->SetExpanded(true);
634 
635   EXPECT_TRUE(title_artist_row()->GetVisible());
636   EXPECT_TRUE(title_label()->GetVisible());
637   EXPECT_TRUE(artist_label()->GetVisible());
638   EXPECT_TRUE(header_row()->summary_text_for_testing()->GetVisible());
639 
640   EXPECT_EQ(metadata.title, title_label()->GetText());
641   EXPECT_EQ(metadata.artist, artist_label()->GetText());
642   EXPECT_EQ(metadata.album,
643             header_row()->summary_text_for_testing()->GetText());
644 
645   EXPECT_EQ(kMediaTitleArtistRowExpectedHeight, title_artist_row()->height());
646 
647   EXPECT_EQ(base::ASCIIToUTF16("title2 - artist2 - album"), accessible_name());
648 
649   ExpectHistogramMetadataRecorded(MediaNotificationViewImpl::Metadata::kTitle,
650                                   2);
651   ExpectHistogramMetadataRecorded(MediaNotificationViewImpl::Metadata::kArtist,
652                                   2);
653   ExpectHistogramMetadataRecorded(MediaNotificationViewImpl::Metadata::kAlbum,
654                                   1);
655   ExpectHistogramMetadataRecorded(MediaNotificationViewImpl::Metadata::kCount,
656                                   2);
657 }
658 
TEST_F(MAYBE_MediaNotificationViewImplTest,UpdateMetadata_AppName)659 TEST_F(MAYBE_MediaNotificationViewImplTest, UpdateMetadata_AppName) {
660   EXPECT_EQ(base::ASCIIToUTF16(kTestDefaultAppName),
661             header_row()->app_name_for_testing());
662 
663   {
664     media_session::MediaMetadata metadata;
665     metadata.title = base::ASCIIToUTF16("title");
666     metadata.artist = base::ASCIIToUTF16("artist");
667     metadata.source_title = base::ASCIIToUTF16(kTestAppName);
668     GetItem()->MediaSessionMetadataChanged(metadata);
669   }
670 
671   EXPECT_EQ(base::ASCIIToUTF16(kTestAppName),
672             header_row()->app_name_for_testing());
673 
674   {
675     media_session::MediaMetadata metadata;
676     metadata.title = base::ASCIIToUTF16("title");
677     metadata.artist = base::ASCIIToUTF16("artist");
678     GetItem()->MediaSessionMetadataChanged(metadata);
679   }
680 
681   EXPECT_EQ(base::ASCIIToUTF16(kTestDefaultAppName),
682             header_row()->app_name_for_testing());
683 }
684 
TEST_F(MAYBE_MediaNotificationViewImplTest,Buttons_WhenCollapsed)685 TEST_F(MAYBE_MediaNotificationViewImplTest, Buttons_WhenCollapsed) {
686   EXPECT_CALL(
687       container(),
688       OnVisibleActionsChanged(base::flat_set<MediaSessionAction>(
689           {MediaSessionAction::kPlay, MediaSessionAction::kPreviousTrack,
690            MediaSessionAction::kNextTrack, MediaSessionAction::kSeekBackward,
691            MediaSessionAction::kSeekForward,
692            MediaSessionAction::kEnterPictureInPicture})));
693   EnableAllActions();
694   view()->SetExpanded(false);
695   testing::Mock::VerifyAndClearExpectations(&container());
696 
697   EXPECT_FALSE(IsActuallyExpanded());
698 
699   EXPECT_TRUE(IsActionButtonVisible(MediaSessionAction::kPlay));
700   EXPECT_TRUE(IsActionButtonVisible(MediaSessionAction::kPreviousTrack));
701   EXPECT_TRUE(IsActionButtonVisible(MediaSessionAction::kNextTrack));
702   EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kSeekBackward));
703   EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kSeekForward));
704 
705   EXPECT_CALL(
706       container(),
707       OnVisibleActionsChanged(base::flat_set<MediaSessionAction>(
708           {MediaSessionAction::kPlay, MediaSessionAction::kSeekBackward,
709            MediaSessionAction::kNextTrack, MediaSessionAction::kSeekForward,
710            MediaSessionAction::kEnterPictureInPicture})));
711   DisableAction(MediaSessionAction::kPreviousTrack);
712   testing::Mock::VerifyAndClearExpectations(&container());
713   EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kPreviousTrack));
714 
715   EXPECT_CALL(
716       container(),
717       OnVisibleActionsChanged(base::flat_set<MediaSessionAction>(
718           {MediaSessionAction::kPlay, MediaSessionAction::kPreviousTrack,
719            MediaSessionAction::kNextTrack, MediaSessionAction::kSeekBackward,
720            MediaSessionAction::kSeekForward,
721            MediaSessionAction::kEnterPictureInPicture})));
722   EnableAction(MediaSessionAction::kPreviousTrack);
723   testing::Mock::VerifyAndClearExpectations(&container());
724   EXPECT_TRUE(IsActionButtonVisible(MediaSessionAction::kPreviousTrack));
725 
726   EXPECT_CALL(
727       container(),
728       OnVisibleActionsChanged(base::flat_set<MediaSessionAction>(
729           {MediaSessionAction::kPlay, MediaSessionAction::kPreviousTrack,
730            MediaSessionAction::kNextTrack, MediaSessionAction::kSeekBackward,
731            MediaSessionAction::kEnterPictureInPicture})));
732   DisableAction(MediaSessionAction::kSeekForward);
733   testing::Mock::VerifyAndClearExpectations(&container());
734   EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kSeekForward));
735 
736   EXPECT_CALL(
737       container(),
738       OnVisibleActionsChanged(base::flat_set<MediaSessionAction>(
739           {MediaSessionAction::kPlay, MediaSessionAction::kPreviousTrack,
740            MediaSessionAction::kNextTrack, MediaSessionAction::kSeekBackward,
741            MediaSessionAction::kSeekForward,
742            MediaSessionAction::kEnterPictureInPicture})));
743   EnableAction(MediaSessionAction::kSeekForward);
744   testing::Mock::VerifyAndClearExpectations(&container());
745   EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kSeekForward));
746 }
747 
TEST_F(MAYBE_MediaNotificationViewImplTest,Buttons_WhenExpanded)748 TEST_F(MAYBE_MediaNotificationViewImplTest, Buttons_WhenExpanded) {
749   EXPECT_CALL(
750       container(),
751       OnVisibleActionsChanged(base::flat_set<MediaSessionAction>(
752           {MediaSessionAction::kPlay, MediaSessionAction::kPreviousTrack,
753            MediaSessionAction::kNextTrack, MediaSessionAction::kSeekBackward,
754            MediaSessionAction::kSeekForward,
755            MediaSessionAction::kEnterPictureInPicture})));
756   EnableAllActions();
757   testing::Mock::VerifyAndClearExpectations(&container());
758 
759   EXPECT_CALL(
760       container(),
761       OnVisibleActionsChanged(base::flat_set<MediaSessionAction>(
762           {MediaSessionAction::kPlay, MediaSessionAction::kPreviousTrack,
763            MediaSessionAction::kNextTrack, MediaSessionAction::kSeekBackward,
764            MediaSessionAction::kSeekForward,
765            MediaSessionAction::kEnterPictureInPicture})));
766   view()->SetExpanded(true);
767   testing::Mock::VerifyAndClearExpectations(&container());
768 
769   EXPECT_TRUE(IsActuallyExpanded());
770 
771   EXPECT_TRUE(IsActionButtonVisible(MediaSessionAction::kPlay));
772   EXPECT_TRUE(IsActionButtonVisible(MediaSessionAction::kPreviousTrack));
773   EXPECT_TRUE(IsActionButtonVisible(MediaSessionAction::kNextTrack));
774   EXPECT_TRUE(IsActionButtonVisible(MediaSessionAction::kSeekBackward));
775   EXPECT_TRUE(IsActionButtonVisible(MediaSessionAction::kSeekForward));
776 }
777 
TEST_F(MAYBE_MediaNotificationViewImplTest,ClickHeader_ToggleExpand)778 TEST_F(MAYBE_MediaNotificationViewImplTest, ClickHeader_ToggleExpand) {
779   view()->SetExpanded(true);
780   EnableAllActions();
781 
782   EXPECT_TRUE(IsActuallyExpanded());
783 
784   SimulateHeaderClick();
785 
786   EXPECT_FALSE(IsActuallyExpanded());
787 
788   SimulateHeaderClick();
789 
790   EXPECT_TRUE(IsActuallyExpanded());
791 }
792 
TEST_F(MAYBE_MediaNotificationViewImplTest,ActionButtonsHiddenByDefault)793 TEST_F(MAYBE_MediaNotificationViewImplTest, ActionButtonsHiddenByDefault) {
794   EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kPlay));
795   EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kNextTrack));
796   EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kPreviousTrack));
797   EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kSeekForward));
798   EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kSeekBackward));
799 }
800 
TEST_F(MAYBE_MediaNotificationViewImplTest,ActionButtonsToggleVisibility)801 TEST_F(MAYBE_MediaNotificationViewImplTest, ActionButtonsToggleVisibility) {
802   EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kNextTrack));
803 
804   EnableAction(MediaSessionAction::kNextTrack);
805 
806   EXPECT_TRUE(IsActionButtonVisible(MediaSessionAction::kNextTrack));
807 
808   DisableAction(MediaSessionAction::kNextTrack);
809 
810   EXPECT_FALSE(IsActionButtonVisible(MediaSessionAction::kNextTrack));
811 }
812 
TEST_F(MAYBE_MediaNotificationViewImplTest,UpdateArtworkFromItem)813 TEST_F(MAYBE_MediaNotificationViewImplTest, UpdateArtworkFromItem) {
814   int title_artist_width = title_artist_row()->width();
815   const SkColor accent = header_row()->accent_color_for_testing().value();
816   gfx::Size size = view()->size();
817   EXPECT_CALL(container(), OnMediaArtworkChanged(_)).Times(2);
818   EXPECT_CALL(container(), OnColorsChanged(_, _)).Times(2);
819 
820   SkBitmap image;
821   image.allocN32Pixels(10, 10);
822   image.eraseColor(SK_ColorGREEN);
823 
824   EXPECT_TRUE(GetArtworkImage().isNull());
825 
826   GetItem()->MediaControllerImageChanged(
827       media_session::mojom::MediaSessionImageType::kArtwork, image);
828 
829   ExpectHistogramArtworkRecorded(true, 1);
830 
831   // Ensure the title artist row has a small width than before now that we
832   // have artwork.
833   EXPECT_GT(title_artist_width, title_artist_row()->width());
834 
835   // Ensure that the title artist row does not extend into the artwork bounds.
836   EXPECT_LE(kViewWidth - kViewArtworkWidth, title_artist_row()->width());
837 
838   // Ensure that the image is displayed in the background artwork and that the
839   // size of the notification was not affected.
840   EXPECT_FALSE(GetArtworkImage().isNull());
841   EXPECT_EQ(gfx::Size(10, 10), GetArtworkImage().size());
842   EXPECT_EQ(size, view()->size());
843   auto accent_color = header_row()->accent_color_for_testing();
844   ASSERT_TRUE(accent_color.has_value());
845   EXPECT_NE(accent, accent_color.value());
846 
847   GetItem()->MediaControllerImageChanged(
848       media_session::mojom::MediaSessionImageType::kArtwork, SkBitmap());
849 
850   ExpectHistogramArtworkRecorded(false, 1);
851 
852   // Ensure the title artist row goes back to the original width now that we
853   // do not have any artwork.
854   EXPECT_EQ(title_artist_width, title_artist_row()->width());
855 
856   // Ensure that the background artwork was reset and the size was still not
857   // affected.
858   EXPECT_TRUE(GetArtworkImage().isNull());
859   EXPECT_EQ(size, view()->size());
860   accent_color = header_row()->accent_color_for_testing();
861   ASSERT_TRUE(accent_color.has_value());
862   EXPECT_EQ(accent, accent_color.value());
863 }
864 
TEST_F(MAYBE_MediaNotificationViewImplTest,ExpandableDefaultState)865 TEST_F(MAYBE_MediaNotificationViewImplTest, ExpandableDefaultState) {
866   EXPECT_FALSE(IsActuallyExpanded());
867   EXPECT_FALSE(expand_button_enabled());
868 }
869 
TEST_F(MAYBE_MediaNotificationViewImplTest,ExpandablePlayPauseActionCountsOnce)870 TEST_F(MAYBE_MediaNotificationViewImplTest,
871        ExpandablePlayPauseActionCountsOnce) {
872   view()->SetExpanded(true);
873 
874   EXPECT_FALSE(IsActuallyExpanded());
875   EXPECT_FALSE(expand_button_enabled());
876 
877   EnableAction(MediaSessionAction::kPreviousTrack);
878   EnableAction(MediaSessionAction::kNextTrack);
879   EnableAction(MediaSessionAction::kPlay);
880   EnableAction(MediaSessionAction::kPause);
881 
882   EXPECT_FALSE(IsActuallyExpanded());
883   EXPECT_FALSE(expand_button_enabled());
884 
885   media_session::mojom::MediaSessionInfoPtr session_info(
886       media_session::mojom::MediaSessionInfo::New());
887   session_info->playback_state =
888       media_session::mojom::MediaPlaybackState::kPlaying;
889   view()->UpdateWithMediaSessionInfo(session_info);
890 
891   EXPECT_FALSE(IsActuallyExpanded());
892   EXPECT_FALSE(expand_button_enabled());
893 
894   EnableAction(MediaSessionAction::kSeekForward);
895 
896   EXPECT_TRUE(IsActuallyExpanded());
897   EXPECT_TRUE(expand_button_enabled());
898 }
899 
TEST_F(MAYBE_MediaNotificationViewImplTest,BecomeExpandableAndWasNotExpandable)900 TEST_F(MAYBE_MediaNotificationViewImplTest,
901        BecomeExpandableAndWasNotExpandable) {
902   view()->SetExpanded(true);
903 
904   EXPECT_FALSE(IsActuallyExpanded());
905   EXPECT_FALSE(expand_button_enabled());
906 
907   EnableAllActions();
908 
909   EXPECT_TRUE(IsActuallyExpanded());
910   EXPECT_TRUE(expand_button_enabled());
911 }
912 
TEST_F(MAYBE_MediaNotificationViewImplTest,BecomeExpandableButWasAlreadyExpandable)913 TEST_F(MAYBE_MediaNotificationViewImplTest,
914        BecomeExpandableButWasAlreadyExpandable) {
915   view()->SetExpanded(true);
916 
917   EXPECT_FALSE(IsActuallyExpanded());
918   EXPECT_FALSE(expand_button_enabled());
919 
920   EnableAllActions();
921 
922   EXPECT_TRUE(IsActuallyExpanded());
923   EXPECT_TRUE(expand_button_enabled());
924 
925   DisableAction(MediaSessionAction::kSeekForward);
926 
927   EXPECT_TRUE(IsActuallyExpanded());
928   EXPECT_TRUE(expand_button_enabled());
929 }
930 
TEST_F(MAYBE_MediaNotificationViewImplTest,BecomeNotExpandableAndWasExpandable)931 TEST_F(MAYBE_MediaNotificationViewImplTest,
932        BecomeNotExpandableAndWasExpandable) {
933   view()->SetExpanded(true);
934 
935   EXPECT_FALSE(IsActuallyExpanded());
936   EXPECT_FALSE(expand_button_enabled());
937 
938   EnableAllActions();
939 
940   EXPECT_TRUE(IsActuallyExpanded());
941   EXPECT_TRUE(expand_button_enabled());
942 
943   DisableAction(MediaSessionAction::kPreviousTrack);
944   DisableAction(MediaSessionAction::kNextTrack);
945   DisableAction(MediaSessionAction::kSeekBackward);
946   DisableAction(MediaSessionAction::kSeekForward);
947 
948   EXPECT_FALSE(IsActuallyExpanded());
949   EXPECT_FALSE(expand_button_enabled());
950 }
951 
TEST_F(MAYBE_MediaNotificationViewImplTest,BecomeNotExpandableButWasAlreadyNotExpandable)952 TEST_F(MAYBE_MediaNotificationViewImplTest,
953        BecomeNotExpandableButWasAlreadyNotExpandable) {
954   view()->SetExpanded(true);
955 
956   EXPECT_FALSE(IsActuallyExpanded());
957   EXPECT_FALSE(expand_button_enabled());
958 
959   EnableAction(MediaSessionAction::kSeekForward);
960 
961   EXPECT_FALSE(IsActuallyExpanded());
962   EXPECT_FALSE(expand_button_enabled());
963 }
964 
TEST_F(MAYBE_MediaNotificationViewImplTest,ActionButtonRowSizeAndAlignment)965 TEST_F(MAYBE_MediaNotificationViewImplTest, ActionButtonRowSizeAndAlignment) {
966   EnableAction(MediaSessionAction::kPlay);
967 
968   views::Button* button = GetButtonForAction(MediaSessionAction::kPlay);
969   int button_x = button->GetBoundsInScreen().x();
970 
971   // When collapsed the button row should be a fixed width.
972   EXPECT_FALSE(IsActuallyExpanded());
973   EXPECT_EQ(124, button_row()->width());
974 
975   EnableAllActions();
976   view()->SetExpanded(true);
977 
978   // When expanded the button row should be wider and the play button should
979   // have shifted to the left.
980   EXPECT_TRUE(IsActuallyExpanded());
981   EXPECT_LT(124, button_row()->width());
982   EXPECT_GT(button_x, button->GetBoundsInScreen().x());
983 }
984 
TEST_F(MAYBE_MediaNotificationViewImplTest,NotifysContainerOfExpandedState)985 TEST_F(MAYBE_MediaNotificationViewImplTest, NotifysContainerOfExpandedState) {
986   // Track the expanded state given to |container_|.
987   bool expanded = false;
988   EXPECT_CALL(container(), OnExpanded(_))
989       .WillRepeatedly(Invoke([&expanded](bool exp) { expanded = exp; }));
990 
991   // Expand the view implicitly via |EnableAllActions()|.
992   view()->SetExpanded(true);
993   EnableAllActions();
994   EXPECT_TRUE(expanded);
995 
996   // Explicitly contract the view.
997   view()->SetExpanded(false);
998   EXPECT_FALSE(expanded);
999 
1000   // Explicitly expand the view.
1001   view()->SetExpanded(true);
1002   EXPECT_TRUE(expanded);
1003 
1004   // Implicitly contract the view by removing available actions.
1005   DisableAction(MediaSessionAction::kPreviousTrack);
1006   DisableAction(MediaSessionAction::kNextTrack);
1007   DisableAction(MediaSessionAction::kSeekBackward);
1008   DisableAction(MediaSessionAction::kSeekForward);
1009   EXPECT_FALSE(expanded);
1010 }
1011 
TEST_F(MAYBE_MediaNotificationViewImplTest,AccessibleNodeData)1012 TEST_F(MAYBE_MediaNotificationViewImplTest, AccessibleNodeData) {
1013   ui::AXNodeData data;
1014   view()->GetAccessibleNodeData(&data);
1015 
1016   EXPECT_TRUE(
1017       data.HasStringAttribute(ax::mojom::StringAttribute::kRoleDescription));
1018   EXPECT_EQ(base::ASCIIToUTF16("title - artist"), accessible_name());
1019 }
1020 
TEST_F(MAYBE_MediaNotificationViewImplTest,Freezing_DoNotUpdateMetadata)1021 TEST_F(MAYBE_MediaNotificationViewImplTest, Freezing_DoNotUpdateMetadata) {
1022   media_session::MediaMetadata metadata;
1023   metadata.title = base::ASCIIToUTF16("title2");
1024   metadata.artist = base::ASCIIToUTF16("artist2");
1025   metadata.album = base::ASCIIToUTF16("album");
1026 
1027   EXPECT_CALL(container(), OnMediaSessionMetadataChanged(_)).Times(0);
1028   GetItem()->Freeze(base::DoNothing());
1029   GetItem()->MediaSessionMetadataChanged(metadata);
1030 
1031   EXPECT_EQ(base::ASCIIToUTF16("title"), title_label()->GetText());
1032   EXPECT_EQ(base::ASCIIToUTF16("artist"), artist_label()->GetText());
1033 }
1034 
TEST_F(MAYBE_MediaNotificationViewImplTest,Freezing_DoNotUpdateImage)1035 TEST_F(MAYBE_MediaNotificationViewImplTest, Freezing_DoNotUpdateImage) {
1036   SkBitmap image;
1037   image.allocN32Pixels(10, 10);
1038   image.eraseColor(SK_ColorMAGENTA);
1039   EXPECT_CALL(container(), OnMediaArtworkChanged(_)).Times(0);
1040   EXPECT_CALL(container(), OnColorsChanged(_, _)).Times(0);
1041 
1042   GetItem()->Freeze(base::DoNothing());
1043   GetItem()->MediaControllerImageChanged(
1044       media_session::mojom::MediaSessionImageType::kArtwork, image);
1045 
1046   EXPECT_TRUE(GetArtworkImage().isNull());
1047 }
1048 
TEST_F(MAYBE_MediaNotificationViewImplTest,Freezing_DoNotUpdatePlaybackState)1049 TEST_F(MAYBE_MediaNotificationViewImplTest, Freezing_DoNotUpdatePlaybackState) {
1050   EnableAction(MediaSessionAction::kPlay);
1051   EnableAction(MediaSessionAction::kPause);
1052 
1053   EXPECT_CALL(container(), OnMediaSessionInfoChanged(_)).Times(0);
1054 
1055   GetItem()->Freeze(base::DoNothing());
1056 
1057   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
1058   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
1059 
1060   media_session::mojom::MediaSessionInfoPtr session_info(
1061       media_session::mojom::MediaSessionInfo::New());
1062   session_info->playback_state =
1063       media_session::mojom::MediaPlaybackState::kPlaying;
1064   GetItem()->MediaSessionInfoChanged(session_info.Clone());
1065 
1066   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
1067   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
1068 }
1069 
TEST_F(MAYBE_MediaNotificationViewImplTest,Freezing_DoNotUpdateActions)1070 TEST_F(MAYBE_MediaNotificationViewImplTest, Freezing_DoNotUpdateActions) {
1071   EXPECT_FALSE(
1072       GetButtonForAction(MediaSessionAction::kSeekForward)->GetVisible());
1073 
1074   GetItem()->Freeze(base::DoNothing());
1075   EnableAction(MediaSessionAction::kSeekForward);
1076 
1077   EXPECT_FALSE(
1078       GetButtonForAction(MediaSessionAction::kSeekForward)->GetVisible());
1079 }
1080 
TEST_F(MAYBE_MediaNotificationViewImplTest,Freezing_DisableInteraction)1081 TEST_F(MAYBE_MediaNotificationViewImplTest, Freezing_DisableInteraction) {
1082   EnableAllActions();
1083 
1084   EXPECT_EQ(0, media_controller()->next_track_count());
1085 
1086   GetItem()->Freeze(base::DoNothing());
1087 
1088   SimulateButtonClick(MediaSessionAction::kNextTrack);
1089   GetItem()->FlushForTesting();
1090 
1091   EXPECT_EQ(0, media_controller()->next_track_count());
1092 }
1093 
TEST_F(MAYBE_MediaNotificationViewImplTest,UnfreezingDoesntMissUpdates)1094 TEST_F(MAYBE_MediaNotificationViewImplTest, UnfreezingDoesntMissUpdates) {
1095   EnableAction(MediaSessionAction::kPlay);
1096   EnableAction(MediaSessionAction::kPause);
1097 
1098   // Freeze the item and clear the metadata.
1099   base::MockOnceClosure unfrozen_callback;
1100   EXPECT_CALL(unfrozen_callback, Run).Times(0);
1101   GetItem()->Freeze(unfrozen_callback.Get());
1102   GetItem()->MediaSessionInfoChanged(nullptr);
1103   GetItem()->MediaSessionMetadataChanged(base::nullopt);
1104 
1105   // The item should be frozen and the view should contain the old data.
1106   EXPECT_TRUE(GetItem()->frozen());
1107   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
1108   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
1109   EXPECT_EQ(base::ASCIIToUTF16("title"), title_label()->GetText());
1110   EXPECT_EQ(base::ASCIIToUTF16("artist"), artist_label()->GetText());
1111 
1112   // Bind the item to a new controller that's playing instead of paused.
1113   auto new_media_controller = std::make_unique<TestMediaController>();
1114   media_session::mojom::MediaSessionInfoPtr session_info(
1115       media_session::mojom::MediaSessionInfo::New());
1116   session_info->playback_state =
1117       media_session::mojom::MediaPlaybackState::kPlaying;
1118   session_info->is_controllable = true;
1119   GetItem()->SetController(new_media_controller->CreateMediaControllerRemote(),
1120                            session_info.Clone());
1121 
1122   // The item will receive a MediaSessionInfoChanged.
1123   GetItem()->MediaSessionInfoChanged(session_info.Clone());
1124 
1125   // The item should still be frozen, and the view should contain the old data.
1126   EXPECT_TRUE(GetItem()->frozen());
1127   testing::Mock::VerifyAndClearExpectations(&unfrozen_callback);
1128   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
1129   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
1130   EXPECT_EQ(base::ASCIIToUTF16("title"), title_label()->GetText());
1131   EXPECT_EQ(base::ASCIIToUTF16("artist"), artist_label()->GetText());
1132 
1133   // Update the metadata.
1134   EXPECT_CALL(unfrozen_callback, Run);
1135   media_session::MediaMetadata metadata;
1136   metadata.title = base::ASCIIToUTF16("title2");
1137   metadata.artist = base::ASCIIToUTF16("artist2");
1138   GetItem()->MediaSessionMetadataChanged(metadata);
1139 
1140   // The item should no longer be frozen, and we should see the updated data.
1141   EXPECT_FALSE(GetItem()->frozen());
1142   testing::Mock::VerifyAndClearExpectations(&unfrozen_callback);
1143   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPlay));
1144   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPause));
1145   EXPECT_EQ(base::ASCIIToUTF16("title2"), title_label()->GetText());
1146   EXPECT_EQ(base::ASCIIToUTF16("artist2"), artist_label()->GetText());
1147 }
1148 
TEST_F(MAYBE_MediaNotificationViewImplTest,UnfreezingWaitsForArtwork_Timeout)1149 TEST_F(MAYBE_MediaNotificationViewImplTest, UnfreezingWaitsForArtwork_Timeout) {
1150   EnableAction(MediaSessionAction::kPlay);
1151   EnableAction(MediaSessionAction::kPause);
1152 
1153   // Set an image before freezing.
1154   SkBitmap initial_image;
1155   initial_image.allocN32Pixels(10, 10);
1156   initial_image.eraseColor(SK_ColorMAGENTA);
1157   GetItem()->MediaControllerImageChanged(
1158       media_session::mojom::MediaSessionImageType::kArtwork, initial_image);
1159   EXPECT_FALSE(GetArtworkImage().isNull());
1160 
1161   // Freeze the item and clear the metadata.
1162   base::MockOnceClosure unfrozen_callback;
1163   EXPECT_CALL(unfrozen_callback, Run).Times(0);
1164   GetItem()->Freeze(unfrozen_callback.Get());
1165   GetItem()->MediaSessionInfoChanged(nullptr);
1166   GetItem()->MediaSessionMetadataChanged(base::nullopt);
1167   GetItem()->MediaControllerImageChanged(
1168       media_session::mojom::MediaSessionImageType::kArtwork, SkBitmap());
1169 
1170   // The item should be frozen and the view should contain the old data.
1171   EXPECT_TRUE(GetItem()->frozen());
1172   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
1173   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
1174   EXPECT_EQ(base::ASCIIToUTF16("title"), title_label()->GetText());
1175   EXPECT_EQ(base::ASCIIToUTF16("artist"), artist_label()->GetText());
1176   EXPECT_FALSE(GetArtworkImage().isNull());
1177 
1178   // Bind the item to a new controller that's playing instead of paused.
1179   auto new_media_controller = std::make_unique<TestMediaController>();
1180   media_session::mojom::MediaSessionInfoPtr session_info(
1181       media_session::mojom::MediaSessionInfo::New());
1182   session_info->playback_state =
1183       media_session::mojom::MediaPlaybackState::kPlaying;
1184   session_info->is_controllable = true;
1185   GetItem()->SetController(new_media_controller->CreateMediaControllerRemote(),
1186                            session_info.Clone());
1187 
1188   // The item will receive a MediaSessionInfoChanged.
1189   GetItem()->MediaSessionInfoChanged(session_info.Clone());
1190 
1191   // The item should still be frozen, and the view should contain the old data.
1192   EXPECT_TRUE(GetItem()->frozen());
1193   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
1194   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
1195   EXPECT_EQ(base::ASCIIToUTF16("title"), title_label()->GetText());
1196   EXPECT_EQ(base::ASCIIToUTF16("artist"), artist_label()->GetText());
1197   EXPECT_FALSE(GetArtworkImage().isNull());
1198 
1199   // Update the metadata.
1200   media_session::MediaMetadata metadata;
1201   metadata.title = base::ASCIIToUTF16("title2");
1202   metadata.artist = base::ASCIIToUTF16("artist2");
1203   GetItem()->MediaSessionMetadataChanged(metadata);
1204 
1205   // The item should still be frozen, and waiting for a new image.
1206   EXPECT_TRUE(GetItem()->frozen());
1207   testing::Mock::VerifyAndClearExpectations(&unfrozen_callback);
1208   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
1209   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
1210   EXPECT_EQ(base::ASCIIToUTF16("title"), title_label()->GetText());
1211   EXPECT_EQ(base::ASCIIToUTF16("artist"), artist_label()->GetText());
1212   EXPECT_FALSE(GetArtworkImage().isNull());
1213 
1214   // Once the freeze timer fires, the item should unfreeze even if there's no
1215   // artwork.
1216   EXPECT_CALL(unfrozen_callback, Run);
1217   AdvanceClockMilliseconds(2600);
1218 
1219   EXPECT_FALSE(GetItem()->frozen());
1220   testing::Mock::VerifyAndClearExpectations(&unfrozen_callback);
1221   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPlay));
1222   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPause));
1223   EXPECT_EQ(base::ASCIIToUTF16("title2"), title_label()->GetText());
1224   EXPECT_EQ(base::ASCIIToUTF16("artist2"), artist_label()->GetText());
1225   EXPECT_TRUE(GetArtworkImage().isNull());
1226 }
1227 
TEST_F(MAYBE_MediaNotificationViewImplTest,UnfreezingWaitsForActions)1228 TEST_F(MAYBE_MediaNotificationViewImplTest, UnfreezingWaitsForActions) {
1229   EnableAction(MediaSessionAction::kPlay);
1230   EnableAction(MediaSessionAction::kPause);
1231   EnableAction(MediaSessionAction::kNextTrack);
1232   EnableAction(MediaSessionAction::kPreviousTrack);
1233 
1234   // Freeze the item and clear the metadata and actions.
1235   base::MockOnceClosure unfrozen_callback;
1236   EXPECT_CALL(unfrozen_callback, Run).Times(0);
1237   GetItem()->Freeze(unfrozen_callback.Get());
1238   GetItem()->MediaSessionInfoChanged(nullptr);
1239   GetItem()->MediaSessionMetadataChanged(base::nullopt);
1240   DisableAction(MediaSessionAction::kPlay);
1241   DisableAction(MediaSessionAction::kPause);
1242   DisableAction(MediaSessionAction::kNextTrack);
1243   DisableAction(MediaSessionAction::kPreviousTrack);
1244 
1245   // The item should be frozen and the view should contain the old data.
1246   EXPECT_TRUE(GetItem()->frozen());
1247   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
1248   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
1249   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kNextTrack));
1250   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPreviousTrack));
1251   EXPECT_EQ(base::ASCIIToUTF16("title"), title_label()->GetText());
1252   EXPECT_EQ(base::ASCIIToUTF16("artist"), artist_label()->GetText());
1253 
1254   // Bind the item to a new controller that's playing instead of paused.
1255   auto new_media_controller = std::make_unique<TestMediaController>();
1256   media_session::mojom::MediaSessionInfoPtr session_info(
1257       media_session::mojom::MediaSessionInfo::New());
1258   session_info->playback_state =
1259       media_session::mojom::MediaPlaybackState::kPlaying;
1260   session_info->is_controllable = true;
1261   GetItem()->SetController(new_media_controller->CreateMediaControllerRemote(),
1262                            session_info.Clone());
1263 
1264   // The item will receive a MediaSessionInfoChanged.
1265   GetItem()->MediaSessionInfoChanged(session_info.Clone());
1266 
1267   // The item should still be frozen, and the view should contain the old data.
1268   EXPECT_TRUE(GetItem()->frozen());
1269   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
1270   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
1271   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kNextTrack));
1272   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPreviousTrack));
1273   EXPECT_EQ(base::ASCIIToUTF16("title"), title_label()->GetText());
1274   EXPECT_EQ(base::ASCIIToUTF16("artist"), artist_label()->GetText());
1275 
1276   // Update the metadata.
1277   media_session::MediaMetadata metadata;
1278   metadata.title = base::ASCIIToUTF16("title2");
1279   metadata.artist = base::ASCIIToUTF16("artist2");
1280   GetItem()->MediaSessionMetadataChanged(metadata);
1281 
1282   // The item should still be frozen, and waiting for new actions.
1283   EXPECT_TRUE(GetItem()->frozen());
1284   testing::Mock::VerifyAndClearExpectations(&unfrozen_callback);
1285   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
1286   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
1287   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kNextTrack));
1288   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPreviousTrack));
1289   EXPECT_EQ(base::ASCIIToUTF16("title"), title_label()->GetText());
1290   EXPECT_EQ(base::ASCIIToUTF16("artist"), artist_label()->GetText());
1291 
1292   // Once we receive actions, the item should unfreeze.
1293   EXPECT_CALL(unfrozen_callback, Run);
1294   EnableAction(MediaSessionAction::kPlay);
1295   EnableAction(MediaSessionAction::kPause);
1296   EnableAction(MediaSessionAction::kSeekForward);
1297   EnableAction(MediaSessionAction::kSeekBackward);
1298 
1299   EXPECT_FALSE(GetItem()->frozen());
1300   testing::Mock::VerifyAndClearExpectations(&unfrozen_callback);
1301   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPlay));
1302   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPause));
1303   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kSeekForward));
1304   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kSeekBackward));
1305   EXPECT_EQ(base::ASCIIToUTF16("title2"), title_label()->GetText());
1306   EXPECT_EQ(base::ASCIIToUTF16("artist2"), artist_label()->GetText());
1307 }
1308 
TEST_F(MAYBE_MediaNotificationViewImplTest,UnfreezingWaitsForArtwork_ReceiveArtwork)1309 TEST_F(MAYBE_MediaNotificationViewImplTest,
1310        UnfreezingWaitsForArtwork_ReceiveArtwork) {
1311   EnableAction(MediaSessionAction::kPlay);
1312   EnableAction(MediaSessionAction::kPause);
1313 
1314   // Set an image before freezing.
1315   SkBitmap initial_image;
1316   initial_image.allocN32Pixels(10, 10);
1317   initial_image.eraseColor(SK_ColorMAGENTA);
1318   GetItem()->MediaControllerImageChanged(
1319       media_session::mojom::MediaSessionImageType::kArtwork, initial_image);
1320   EXPECT_FALSE(GetArtworkImage().isNull());
1321 
1322   // Freeze the item and clear the metadata.
1323   base::MockOnceClosure unfrozen_callback;
1324   EXPECT_CALL(unfrozen_callback, Run).Times(0);
1325   GetItem()->Freeze(unfrozen_callback.Get());
1326   GetItem()->MediaSessionInfoChanged(nullptr);
1327   GetItem()->MediaSessionMetadataChanged(base::nullopt);
1328   GetItem()->MediaControllerImageChanged(
1329       media_session::mojom::MediaSessionImageType::kArtwork, SkBitmap());
1330 
1331   // The item should be frozen and the view should contain the old data.
1332   EXPECT_TRUE(GetItem()->frozen());
1333   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
1334   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
1335   EXPECT_EQ(base::ASCIIToUTF16("title"), title_label()->GetText());
1336   EXPECT_EQ(base::ASCIIToUTF16("artist"), artist_label()->GetText());
1337   EXPECT_FALSE(GetArtworkImage().isNull());
1338 
1339   // Bind the item to a new controller that's playing instead of paused.
1340   auto new_media_controller = std::make_unique<TestMediaController>();
1341   media_session::mojom::MediaSessionInfoPtr session_info(
1342       media_session::mojom::MediaSessionInfo::New());
1343   session_info->playback_state =
1344       media_session::mojom::MediaPlaybackState::kPlaying;
1345   session_info->is_controllable = true;
1346   GetItem()->SetController(new_media_controller->CreateMediaControllerRemote(),
1347                            session_info.Clone());
1348 
1349   // The item will receive a MediaSessionInfoChanged.
1350   GetItem()->MediaSessionInfoChanged(session_info.Clone());
1351 
1352   // The item should still be frozen, and the view should contain the old data.
1353   EXPECT_TRUE(GetItem()->frozen());
1354   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
1355   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
1356   EXPECT_EQ(base::ASCIIToUTF16("title"), title_label()->GetText());
1357   EXPECT_EQ(base::ASCIIToUTF16("artist"), artist_label()->GetText());
1358   EXPECT_FALSE(GetArtworkImage().isNull());
1359 
1360   // Update the metadata.
1361   media_session::MediaMetadata metadata;
1362   metadata.title = base::ASCIIToUTF16("title2");
1363   metadata.artist = base::ASCIIToUTF16("artist2");
1364   GetItem()->MediaSessionMetadataChanged(metadata);
1365 
1366   // The item should still be frozen, and waiting for a new image.
1367   EXPECT_TRUE(GetItem()->frozen());
1368   testing::Mock::VerifyAndClearExpectations(&unfrozen_callback);
1369   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay));
1370   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause));
1371   EXPECT_EQ(base::ASCIIToUTF16("title"), title_label()->GetText());
1372   EXPECT_EQ(base::ASCIIToUTF16("artist"), artist_label()->GetText());
1373   EXPECT_FALSE(GetArtworkImage().isNull());
1374 
1375   // Once we receive artwork, the item should unfreeze.
1376   EXPECT_CALL(unfrozen_callback, Run);
1377   SkBitmap new_image;
1378   new_image.allocN32Pixels(10, 10);
1379   new_image.eraseColor(SK_ColorYELLOW);
1380   GetItem()->MediaControllerImageChanged(
1381       media_session::mojom::MediaSessionImageType::kArtwork, new_image);
1382 
1383   EXPECT_FALSE(GetItem()->frozen());
1384   testing::Mock::VerifyAndClearExpectations(&unfrozen_callback);
1385   EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPlay));
1386   EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPause));
1387   EXPECT_EQ(base::ASCIIToUTF16("title2"), title_label()->GetText());
1388   EXPECT_EQ(base::ASCIIToUTF16("artist2"), artist_label()->GetText());
1389   EXPECT_FALSE(GetArtworkImage().isNull());
1390 }
1391 
TEST_F(MAYBE_MediaNotificationViewImplTest,ForcedExpandedState)1392 TEST_F(MAYBE_MediaNotificationViewImplTest, ForcedExpandedState) {
1393   // Make the view expandable.
1394   EnableAllActions();
1395 
1396   // Force it to be expanded.
1397   bool expanded_state = true;
1398   view()->SetForcedExpandedState(&expanded_state);
1399   EXPECT_TRUE(IsActuallyExpanded());
1400 
1401   // Since it's forced, clicking on the header should not toggle the expanded
1402   // state.
1403   SimulateHeaderClick();
1404   EXPECT_TRUE(IsActuallyExpanded());
1405 
1406   // Force it to be not expanded.
1407   expanded_state = false;
1408   view()->SetForcedExpandedState(&expanded_state);
1409   EXPECT_FALSE(IsActuallyExpanded());
1410 
1411   // Since it's forced, clicking on the header should not toggle the expanded
1412   // state.
1413   SimulateHeaderClick();
1414   EXPECT_FALSE(IsActuallyExpanded());
1415 
1416   // Stop forcing expanded state.
1417   view()->SetForcedExpandedState(nullptr);
1418   EXPECT_FALSE(IsActuallyExpanded());
1419 
1420   // Clicking on the header should toggle the expanded state.
1421   SimulateHeaderClick();
1422   EXPECT_TRUE(IsActuallyExpanded());
1423 }
1424 
TEST_F(MAYBE_MediaNotificationViewImplTest,AllowsHidingOfAppIcon)1425 TEST_F(MAYBE_MediaNotificationViewImplTest, AllowsHidingOfAppIcon) {
1426   MediaNotificationViewImpl shows_icon(&container(), nullptr, nullptr,
1427                                        base::string16(), kViewWidth,
1428                                        /*should_show_icon=*/true);
1429   MediaNotificationViewImpl hides_icon(&container(), nullptr, nullptr,
1430                                        base::string16(), kViewWidth,
1431                                        /*should_show_icon=*/false);
1432 
1433   EXPECT_TRUE(
1434       GetHeaderRow(&shows_icon)->app_icon_view_for_testing()->GetVisible());
1435   EXPECT_FALSE(
1436       GetHeaderRow(&hides_icon)->app_icon_view_for_testing()->GetVisible());
1437 }
1438 
TEST_F(MAYBE_MediaNotificationViewImplTest,ClickHeader_NotifyContainer)1439 TEST_F(MAYBE_MediaNotificationViewImplTest, ClickHeader_NotifyContainer) {
1440   EXPECT_CALL(container(), OnHeaderClicked());
1441   SimulateHeaderClick();
1442 }
1443 
1444 }  // namespace media_message_center
1445