text: // 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/macros.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 {
  class StatusAreaWidget;
  class WebNotificationBubbleWrapper;
  class WebNotificationButton;
  class AshPopupAlignmentDelegate;
  
  class ASH_EXPORT WebNotificationTray
      : public TrayBackgroundView,
        public views::TrayBubbleView::Delegate,
        public message_center::MessageCenterTrayDelegate,
        public views::ButtonListener,
        public base::SupportsWeakPtr<WebNotificationTray>,
        public ui::SimpleMenuModel::Delegate {
   public:
    explicit WebNotificationTray(StatusAreaWidget* status_area_widget);
    ~WebNotificationTray() override;
  
    // 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 shelf.
    bool ShouldBlockShelfAutoHide() 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.
    void SetShelfAlignment(ShelfAlignment alignment) override;
    void AnchorUpdated() override;
    base::string16 GetAccessibleNameForTray() override;
    void HideBubbleWithView(const views::TrayBubbleView* bubble_view) override;
    bool ClickedOutsideBubble() override;
  
    // Overridden from ActionableView.
    bool PerformAction(const ui::Event& event) override;
  
    // Overridden from views::TrayBubbleView::Delegate.
    void BubbleViewDestroyed() override;
    void OnMouseEnteredView() override;
    void OnMouseExitedView() override;
    base::string16 GetAccessibleNameForBubble() override;
    gfx::Rect GetAnchorRect(views::Widget* anchor_widget,
                            AnchorType anchor_type,
                            AnchorAlignment anchor_alignment) const override;
    void HideBubble(const views::TrayBubbleView* bubble_view) override;
  
    // Overridden from ButtonListener.
    void ButtonPressed(views::Button* sender, const ui::Event& event) override;
  
    // Overridden from MessageCenterTrayDelegate.
    void OnMessageCenterTrayChanged() override;
    bool ShowMessageCenter() override;
    void HideMessageCenter() override;
    bool ShowPopups() override;
    void HidePopups() override;
    bool ShowNotifierSettings() override;
    bool IsContextMenuEnabled() const override;
    message_center::MessageCenterTray* GetMessageCenterTray() override;
  
    // Overridden from SimpleMenuModel::Delegate.
    bool IsCommandIdChecked(int command_id) const override;
    bool IsCommandIdEnabled(int command_id) const override;
    bool GetAcceleratorForCommandId(int command_id,
                                    ui::Accelerator* accelerator) override;
    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();
  
    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<WebNotificationBubbleWrapper> message_center_bubble_;
    scoped_ptr<message_center::MessagePopupCollection> popup_collection_;
    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_;
  
    scoped_ptr<AshPopupAlignmentDelegate> popup_alignment_delegate_;
  
    DISALLOW_COPY_AND_ASSIGN(WebNotificationTray);
  };
  
  }  // namespace ash
  
  #endif  // ASH_SYSTEM_WEB_NOTIFICATION_WEB_NOTIFICATION_TRAY_H_
  