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