summaryrefslogtreecommitdiffstats
path: root/chromium/ash/system/web_notification/web_notification_tray.h
blob: e08afbc8d10f86b2454e3b7b4895c24baf80860b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ASH_SYSTEM_WEB_NOTIFICATION_WEB_NOTIFICATION_TRAY_H_
#define ASH_SYSTEM_WEB_NOTIFICATION_WEB_NOTIFICATION_TRAY_H_

#include "ash/ash_export.h"
#include "ash/system/tray/tray_background_view.h"
#include "ash/system/user/login_status.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/message_center/message_center_tray.h"
#include "ui/message_center/message_center_tray_delegate.h"
#include "ui/views/bubble/tray_bubble_view.h"
#include "ui/views/controls/button/button.h"

// Status area tray for showing browser and app notifications. This hosts
// a MessageCenter class which manages the notification list. This class
// contains the Ash specific tray implementation.
//
// Note: These are not related to system notifications (i.e NotificationView
// generated by SystemTrayItem). Visibility of one notification type or other
// is controlled by StatusAreaWidget.

namespace views {
class ImageButton;
class MenuRunner;
}

namespace message_center {
class MessageBubbleBase;
class MessageCenter;
class MessageCenterBubble;
class MessagePopupCollection;
}

namespace ash {
namespace internal {
class StatusAreaWidget;
class WebNotificationBubbleWrapper;
class WebNotificationButton;
class WorkAreaObserver;
}

class ASH_EXPORT WebNotificationTray
    : public internal::TrayBackgroundView,
      public views::TrayBubbleView::Delegate,
      public message_center::MessageCenterTrayDelegate,
      public views::ButtonListener,
      public base::SupportsWeakPtr<WebNotificationTray>,
      public ui::SimpleMenuModel::Delegate {
 public:
  explicit WebNotificationTray(
      internal::StatusAreaWidget* status_area_widget);
  virtual ~WebNotificationTray();

  // Sets the height of the system tray from the edge of the work area so that
  // the notification popups don't overlap with the tray. Passes 0 if no UI is
  // shown in the system tray side.
  void SetSystemTrayHeight(int height);

  // Returns true if it should block the auto hide behavior of the launcher.
  bool ShouldBlockLauncherAutoHide() const;

  // Returns true if the message center bubble is visible.
  bool IsMessageCenterBubbleVisible() const;

  // Returns true if the mouse is inside the notification bubble.
  bool IsMouseInNotificationBubble() const;

  // Shows the message center bubble.
  void ShowMessageCenterBubble();

  // Called when the login status is changed.
  void UpdateAfterLoginStatusChange(user::LoginStatus login_status);

  // Overridden from TrayBackgroundView.
  virtual void SetShelfAlignment(ShelfAlignment alignment) OVERRIDE;
  virtual void AnchorUpdated() OVERRIDE;
  virtual base::string16 GetAccessibleNameForTray() OVERRIDE;
  virtual void HideBubbleWithView(
      const views::TrayBubbleView* bubble_view) OVERRIDE;
  virtual bool ClickedOutsideBubble() OVERRIDE;

  // Overridden from internal::ActionableView.
  virtual bool PerformAction(const ui::Event& event) OVERRIDE;

  // Overridden from views::TrayBubbleView::Delegate.
  virtual void BubbleViewDestroyed() OVERRIDE;
  virtual void OnMouseEnteredView() OVERRIDE;
  virtual void OnMouseExitedView() OVERRIDE;
  virtual base::string16 GetAccessibleNameForBubble() OVERRIDE;
  virtual gfx::Rect GetAnchorRect(views::Widget* anchor_widget,
                                  AnchorType anchor_type,
                                  AnchorAlignment anchor_alignment) OVERRIDE;
  virtual void HideBubble(const views::TrayBubbleView* bubble_view) OVERRIDE;

  // Overridden from ButtonListener.
  virtual void ButtonPressed(views::Button* sender,
                             const ui::Event& event) OVERRIDE;

  // Overridden from MessageCenterTrayDelegate.
  virtual void OnMessageCenterTrayChanged() OVERRIDE;
  virtual bool ShowMessageCenter() OVERRIDE;
  virtual void HideMessageCenter() OVERRIDE;
  virtual bool ShowPopups() OVERRIDE;
  virtual void HidePopups() OVERRIDE;
  virtual bool ShowNotifierSettings() OVERRIDE;
  virtual message_center::MessageCenterTray* GetMessageCenterTray() OVERRIDE;

  // Overridden from SimpleMenuModel::Delegate.
  virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
  virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
  virtual bool GetAcceleratorForCommandId(
      int command_id,
      ui::Accelerator* accelerator) OVERRIDE;
  virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;

  message_center::MessageCenter* message_center() const;

 private:
  friend class WebNotificationTrayTest;

  FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest, WebNotifications);
  FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest, WebNotificationPopupBubble);
  FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest,
                           ManyMessageCenterNotifications);
  FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest, ManyPopupNotifications);
  FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest, PopupShownOnBothDisplays);
  FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest, PopupAndSystemTray);
  FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest, PopupAndAutoHideShelf);

  void UpdateTrayContent();

  // The actual process to show the message center. Set |show_settings| to true
  // if the message center should be initialized with the settings visible.
  // Returns true if the center is successfully created.
  bool ShowMessageCenterInternal(bool show_settings);

  // Queries login status and the status area widget to determine visibility of
  // the message center.
  bool ShouldShowMessageCenter();

  // Returns true if it should show the quiet mode menu.
  bool ShouldShowQuietModeMenu(const ui::Event& event);

  // Shows the quiet mode menu.
  void ShowQuietModeMenu(const ui::Event& event);

  // Creates the menu model for quiet mode and returns it.
  ui::MenuModel* CreateQuietModeMenu();

  internal::WebNotificationBubbleWrapper* message_center_bubble() const {
    return message_center_bubble_.get();
  }

  // Testing accessors.
  bool IsPopupVisible() const;
  message_center::MessageCenterBubble* GetMessageCenterBubbleForTest();

  scoped_ptr<message_center::MessageCenterTray> message_center_tray_;
  scoped_ptr<internal::WebNotificationBubbleWrapper> message_center_bubble_;
  scoped_ptr<message_center::MessagePopupCollection> popup_collection_;
  internal::WebNotificationButton* button_;

  bool show_message_center_on_unlock_;

  bool should_update_tray_content_;

  // True when the shelf auto hide behavior has to be blocked. Previously
  // this was done by checking |message_center_bubble_| but actually
  // the check can be called when creating this object, so it would cause
  // flickers of the shelf from hidden to shown. See: crbug.com/181213
  bool should_block_shelf_auto_hide_;

  // Observes the work area for |popup_collection_| and notifies to it.
  scoped_ptr<internal::WorkAreaObserver> work_area_observer_;

  DISALLOW_COPY_AND_ASSIGN(WebNotificationTray);
};

}  // namespace ash

#endif  // ASH_SYSTEM_WEB_NOTIFICATION_WEB_NOTIFICATION_TRAY_H_