1// Copyright (c) 2012 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 ASH_SYSTEM_WEB_NOTIFICATION_WEB_NOTIFICATION_TRAY_H_
6#define ASH_SYSTEM_WEB_NOTIFICATION_WEB_NOTIFICATION_TRAY_H_
7
8#include "ash/ash_export.h"
9#include "ash/system/tray/tray_background_view.h"
10#include "ash/system/user/login_status.h"
11#include "base/gtest_prod_util.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/memory/weak_ptr.h"
14#include "ui/base/models/simple_menu_model.h"
15#include "ui/message_center/message_center_tray.h"
16#include "ui/message_center/message_center_tray_delegate.h"
17#include "ui/views/bubble/tray_bubble_view.h"
18#include "ui/views/controls/button/button.h"
19
20// Status area tray for showing browser and app notifications. This hosts
21// a MessageCenter class which manages the notification list. This class
22// contains the Ash specific tray implementation.
23//
24// Note: These are not related to system notifications (i.e NotificationView
25// generated by SystemTrayItem). Visibility of one notification type or other
26// is controlled by StatusAreaWidget.
27
28namespace views {
29class ImageButton;
30class MenuRunner;
31}
32
33namespace message_center {
34class MessageBubbleBase;
35class MessageCenter;
36class MessageCenterBubble;
37class MessagePopupCollection;
38}
39
40namespace ash {
41class StatusAreaWidget;
42class WebNotificationBubbleWrapper;
43class WebNotificationButton;
44class AshPopupAlignmentDelegate;
45
46class ASH_EXPORT WebNotificationTray
47    : public TrayBackgroundView,
48      public views::TrayBubbleView::Delegate,
49      public message_center::MessageCenterTrayDelegate,
50      public views::ButtonListener,
51      public base::SupportsWeakPtr<WebNotificationTray>,
52      public ui::SimpleMenuModel::Delegate {
53 public:
54  explicit WebNotificationTray(StatusAreaWidget* status_area_widget);
55  virtual ~WebNotificationTray();
56
57  // Sets the height of the system tray from the edge of the work area so that
58  // the notification popups don't overlap with the tray. Passes 0 if no UI is
59  // shown in the system tray side.
60  void SetSystemTrayHeight(int height);
61
62  // Returns true if it should block the auto hide behavior of the shelf.
63  bool ShouldBlockShelfAutoHide() const;
64
65  // Returns true if the message center bubble is visible.
66  bool IsMessageCenterBubbleVisible() const;
67
68  // Returns true if the mouse is inside the notification bubble.
69  bool IsMouseInNotificationBubble() const;
70
71  // Shows the message center bubble.
72  void ShowMessageCenterBubble();
73
74  // Called when the login status is changed.
75  void UpdateAfterLoginStatusChange(user::LoginStatus login_status);
76
77  // Overridden from TrayBackgroundView.
78  virtual void SetShelfAlignment(ShelfAlignment alignment) OVERRIDE;
79  virtual void AnchorUpdated() OVERRIDE;
80  virtual base::string16 GetAccessibleNameForTray() OVERRIDE;
81  virtual void HideBubbleWithView(
82      const views::TrayBubbleView* bubble_view) OVERRIDE;
83  virtual bool ClickedOutsideBubble() OVERRIDE;
84
85  // Overridden from ActionableView.
86  virtual bool PerformAction(const ui::Event& event) OVERRIDE;
87
88  // Overridden from views::TrayBubbleView::Delegate.
89  virtual void BubbleViewDestroyed() OVERRIDE;
90  virtual void OnMouseEnteredView() OVERRIDE;
91  virtual void OnMouseExitedView() OVERRIDE;
92  virtual base::string16 GetAccessibleNameForBubble() OVERRIDE;
93  virtual gfx::Rect GetAnchorRect(
94      views::Widget* anchor_widget,
95      AnchorType anchor_type,
96      AnchorAlignment anchor_alignment) const OVERRIDE;
97  virtual void HideBubble(const views::TrayBubbleView* bubble_view) OVERRIDE;
98
99  // Overridden from ButtonListener.
100  virtual void ButtonPressed(views::Button* sender,
101                             const ui::Event& event) OVERRIDE;
102
103  // Overridden from MessageCenterTrayDelegate.
104  virtual void OnMessageCenterTrayChanged() OVERRIDE;
105  virtual bool ShowMessageCenter() OVERRIDE;
106  virtual void HideMessageCenter() OVERRIDE;
107  virtual bool ShowPopups() OVERRIDE;
108  virtual void HidePopups() OVERRIDE;
109  virtual bool ShowNotifierSettings() OVERRIDE;
110  virtual bool IsContextMenuEnabled() const OVERRIDE;
111  virtual message_center::MessageCenterTray* GetMessageCenterTray() OVERRIDE;
112
113  // Overridden from SimpleMenuModel::Delegate.
114  virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
115  virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
116  virtual bool GetAcceleratorForCommandId(
117      int command_id,
118      ui::Accelerator* accelerator) OVERRIDE;
119  virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
120
121  message_center::MessageCenter* message_center() const;
122
123 private:
124  friend class WebNotificationTrayTest;
125
126  FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest, WebNotifications);
127  FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest, WebNotificationPopupBubble);
128  FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest,
129                           ManyMessageCenterNotifications);
130  FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest, ManyPopupNotifications);
131  FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest, PopupShownOnBothDisplays);
132  FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest, PopupAndSystemTray);
133  FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest, PopupAndAutoHideShelf);
134
135  void UpdateTrayContent();
136
137  // The actual process to show the message center. Set |show_settings| to true
138  // if the message center should be initialized with the settings visible.
139  // Returns true if the center is successfully created.
140  bool ShowMessageCenterInternal(bool show_settings);
141
142  // Queries login status and the status area widget to determine visibility of
143  // the message center.
144  bool ShouldShowMessageCenter();
145
146  // Returns true if it should show the quiet mode menu.
147  bool ShouldShowQuietModeMenu(const ui::Event& event);
148
149  // Shows the quiet mode menu.
150  void ShowQuietModeMenu(const ui::Event& event);
151
152  // Creates the menu model for quiet mode and returns it.
153  ui::MenuModel* CreateQuietModeMenu();
154
155  WebNotificationBubbleWrapper* message_center_bubble() const {
156    return message_center_bubble_.get();
157  }
158
159  // Testing accessors.
160  bool IsPopupVisible() const;
161  message_center::MessageCenterBubble* GetMessageCenterBubbleForTest();
162
163  scoped_ptr<message_center::MessageCenterTray> message_center_tray_;
164  scoped_ptr<WebNotificationBubbleWrapper> message_center_bubble_;
165  scoped_ptr<message_center::MessagePopupCollection> popup_collection_;
166  WebNotificationButton* button_;
167
168  bool show_message_center_on_unlock_;
169
170  bool should_update_tray_content_;
171
172  // True when the shelf auto hide behavior has to be blocked. Previously
173  // this was done by checking |message_center_bubble_| but actually
174  // the check can be called when creating this object, so it would cause
175  // flickers of the shelf from hidden to shown. See: crbug.com/181213
176  bool should_block_shelf_auto_hide_;
177
178  scoped_ptr<AshPopupAlignmentDelegate> popup_alignment_delegate_;
179
180  DISALLOW_COPY_AND_ASSIGN(WebNotificationTray);
181};
182
183}  // namespace ash
184
185#endif  // ASH_SYSTEM_WEB_NOTIFICATION_WEB_NOTIFICATION_TRAY_H_
186