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 28 namespace views { 29 class ImageButton; 30 class MenuRunner; 31 } 32 33 namespace message_center { 34 class MessageBubbleBase; 35 class MessageCenter; 36 class MessageCenterBubble; 37 class MessagePopupCollection; 38 } 39 40 namespace ash { 41 class StatusAreaWidget; 42 class WebNotificationBubbleWrapper; 43 class WebNotificationButton; 44 class AshPopupAlignmentDelegate; 45 46 class 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 message_center_bubble()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