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 
5 #ifndef COMPONENTS_MEDIA_MESSAGE_CENTER_MEDIA_NOTIFICATION_VIEW_MODERN_IMPL_H_
6 #define COMPONENTS_MEDIA_MESSAGE_CENTER_MEDIA_NOTIFICATION_VIEW_MODERN_IMPL_H_
7 
8 #include "components/media_message_center/media_notification_view.h"
9 
10 #include "base/component_export.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/optional.h"
13 #include "components/media_message_center/media_notification_view.h"
14 #include "services/media_session/public/mojom/media_session.mojom.h"
15 #include "ui/views/controls/button/image_button.h"
16 #include "ui/views/controls/image_view.h"
17 #include "ui/views/controls/label.h"
18 
19 namespace views {
20 class Button;
21 class ToggleImageButton;
22 }  // namespace views
23 
24 namespace media_message_center {
25 
26 namespace {
27 class MediaArtworkView;
28 }  // anonymous namespace
29 
30 class MediaNotificationBackground;
31 class MediaNotificationContainer;
32 class MediaNotificationItem;
33 
COMPONENT_EXPORT(MEDIA_MESSAGE_CENTER)34 class COMPONENT_EXPORT(MEDIA_MESSAGE_CENTER) MediaNotificationViewModernImpl
35     : public MediaNotificationView {
36  public:
37   // The name of the histogram used when recording whether the artwork was
38   // present.
39   static const char kArtworkHistogramName[];
40 
41   // The name of the histogram used when recording the type of metadata that was
42   // displayed.
43   static const char kMetadataHistogramName[];
44 
45   // The type of metadata that was displayed. This is used in metrics so new
46   // values must only be added to the end.
47   enum class Metadata {
48     kTitle,
49     kArtist,
50     kAlbum,
51     kCount,
52     kSource,
53     kMaxValue = kSource,
54   };
55 
56   MediaNotificationViewModernImpl(
57       MediaNotificationContainer* container,
58       base::WeakPtr<MediaNotificationItem> item,
59       std::unique_ptr<views::View> notification_controls_view,
60       int notification_width);
61   MediaNotificationViewModernImpl(const MediaNotificationViewModernImpl&) =
62       delete;
63   MediaNotificationViewModernImpl& operator=(
64       const MediaNotificationViewModernImpl&) = delete;
65   ~MediaNotificationViewModernImpl() override;
66 
67   // views::View:
68   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
69   void OnThemeChanged() override;
70 
71   // MediaNotificationView
72   void SetForcedExpandedState(bool* forced_expanded_state) override {}
73   void SetExpanded(bool expanded) override {}
74   void UpdateCornerRadius(int top_radius, int bottom_radius) override;
75   void UpdateWithMediaSessionInfo(
76       const media_session::mojom::MediaSessionInfoPtr& session_info) override;
77   void UpdateWithMediaMetadata(
78       const media_session::MediaMetadata& metadata) override;
79   void UpdateWithMediaActions(
80       const base::flat_set<media_session::mojom::MediaSessionAction>& actions)
81       override;
82   void UpdateWithMediaArtwork(const gfx::ImageSkia& image) override;
83   void UpdateWithFavicon(const gfx::ImageSkia& icon) override;
84   void UpdateWithVectorIcon(const gfx::VectorIcon& vector_icon) override {}
85   void UpdateDeviceSelectorAvailability(bool availability) override;
86 
87   // Testing methods
88   const views::Label* title_label_for_testing() const { return title_label_; }
89 
90   const views::Label* subtitle_label_for_testing() const {
91     return subtitle_label_;
92   }
93 
94   const views::Button* picture_in_picture_button_for_testing() const {
95     return picture_in_picture_button_;
96   }
97 
98   const views::View* media_controls_container_for_testing() const {
99     return media_controls_container_;
100   }
101 
102  private:
103   friend class MediaNotificationViewModernImplTest;
104 
105   // Creates an image button with an icon that matches |action| and adds it
106   // to |parent_view|. When clicked it will trigger |action| on the session.
107   // |accessible_name| is the text used for screen readers and the
108   // button's tooltip.
109   void CreateMediaButton(views::View* parent_view,
110                          media_session::mojom::MediaSessionAction action,
111                          const base::string16& accessible_name);
112 
113   void UpdateActionButtonsVisibility();
114 
115   MediaNotificationBackground* GetMediaNotificationBackground();
116 
117   void UpdateForegroundColor();
118 
119   void ButtonPressed(views::Button* button);
120 
121   // Container that receives events.
122   MediaNotificationContainer* const container_;
123 
124   // Keeps track of media metadata and controls the session when buttons are
125   // clicked.
126   base::WeakPtr<MediaNotificationItem> item_;
127 
128   bool has_artwork_ = false;
129 
130   // Set of enabled actions.
131   base::flat_set<media_session::mojom::MediaSessionAction> enabled_actions_;
132 
133   // Stores the text to be read by screen readers describing the notification.
134   // Contains the title, artist and album separated by hyphens.
135   base::string16 accessible_name_;
136 
137   MediaNotificationBackground* background_;
138 
139   // Container views directly attached to this view.
140   views::View* artwork_container_ = nullptr;
141   MediaArtworkView* artwork_ = nullptr;
142   views::Label* title_label_ = nullptr;
143   views::Label* subtitle_label_ = nullptr;
144   views::ToggleImageButton* picture_in_picture_button_ = nullptr;
145   views::View* notification_controls_spacer_ = nullptr;
146   views::View* media_controls_container_ = nullptr;
147   views::ToggleImageButton* play_pause_button_ = nullptr;
148 };
149 
150 }  // namespace media_message_center
151 
152 #endif  // COMPONENTS_MEDIA_MESSAGE_CENTER_MEDIA_NOTIFICATION_VIEW_MODERN_IMPL_H_
153