Home | History | Annotate | Download | only in notifications
      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 CHROME_BROWSER_NOTIFICATIONS_MESSAGE_CENTER_NOTIFICATION_MANAGER_H_
      6 #define CHROME_BROWSER_NOTIFICATIONS_MESSAGE_CENTER_NOTIFICATION_MANAGER_H_
      7 
      8 #include <map>
      9 #include <string>
     10 
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/memory/scoped_vector.h"
     13 #include "base/memory/weak_ptr.h"
     14 #include "base/prefs/pref_member.h"
     15 #include "base/time/time.h"
     16 #include "base/timer/timer.h"
     17 #include "chrome/browser/notifications/google_now_notification_stats_collector.h"
     18 #include "chrome/browser/notifications/message_center_stats_collector.h"
     19 #include "chrome/browser/notifications/notification.h"
     20 #include "chrome/browser/notifications/notification_system_observer.h"
     21 #include "chrome/browser/notifications/notification_ui_manager.h"
     22 #include "ui/message_center/message_center.h"
     23 #include "ui/message_center/message_center_observer.h"
     24 #include "ui/message_center/message_center_tray_delegate.h"
     25 #include "ui/message_center/message_center_types.h"
     26 
     27 class MessageCenterSettingsController;
     28 class Notification;
     29 class PrefRegistrySimple;
     30 class PrefService;
     31 class Profile;
     32 
     33 namespace message_center {
     34 class NotificationBlocker;
     35 FORWARD_DECLARE_TEST(WebNotificationTrayTest, ManuallyCloseMessageCenter);
     36 }
     37 
     38 // This class extends NotificationUIManagerImpl and delegates actual display
     39 // of notifications to MessageCenter, doing necessary conversions.
     40 class MessageCenterNotificationManager
     41     : public NotificationUIManager,
     42       public message_center::MessageCenterObserver {
     43  public:
     44   MessageCenterNotificationManager(
     45       message_center::MessageCenter* message_center,
     46       PrefService* local_state,
     47       scoped_ptr<message_center::NotifierSettingsProvider> settings_provider);
     48   virtual ~MessageCenterNotificationManager();
     49 
     50   // Registers preferences.
     51   static void RegisterPrefs(PrefRegistrySimple* registry);
     52 
     53   // NotificationUIManager
     54   virtual void Add(const Notification& notification,
     55                    Profile* profile) OVERRIDE;
     56   virtual bool Update(const Notification& notification,
     57                       Profile* profile) OVERRIDE;
     58   virtual const Notification* FindById(
     59       const std::string& notification_id) const OVERRIDE;
     60   virtual bool CancelById(const std::string& notification_id) OVERRIDE;
     61   virtual std::set<std::string> GetAllIdsByProfileAndSourceOrigin(
     62       Profile* profile,
     63       const GURL& source) OVERRIDE;
     64   virtual bool CancelAllBySourceOrigin(const GURL& source_origin) OVERRIDE;
     65   virtual bool CancelAllByProfile(Profile* profile) OVERRIDE;
     66   virtual void CancelAll() OVERRIDE;
     67 
     68   // MessageCenterObserver
     69   virtual void OnNotificationRemoved(const std::string& notification_id,
     70                                      bool by_user) OVERRIDE;
     71   virtual void OnCenterVisibilityChanged(message_center::Visibility) OVERRIDE;
     72   virtual void OnNotificationUpdated(const std::string& notification_id)
     73       OVERRIDE;
     74 
     75   void EnsureMessageCenterClosed();
     76 
     77 #if defined(OS_WIN)
     78   // Called when the pref changes for the first run balloon. The first run
     79   // balloon is only displayed on Windows, since the visibility of the tray
     80   // icon is limited.
     81   void DisplayFirstRunBalloon();
     82 
     83   void SetFirstRunTimeoutForTest(base::TimeDelta timeout);
     84   bool FirstRunTimerIsActive() const;
     85 #endif
     86 
     87   // Takes ownership of |delegate|.
     88   void SetMessageCenterTrayDelegateForTest(
     89       message_center::MessageCenterTrayDelegate* delegate);
     90 
     91  private:
     92   FRIEND_TEST_ALL_PREFIXES(message_center::WebNotificationTrayTest,
     93                            ManuallyCloseMessageCenter);
     94   class ImageDownloadsObserver {
     95    public:
     96     virtual void OnDownloadsCompleted() = 0;
     97   };
     98 
     99   typedef base::Callback<void(const gfx::Image&)> SetImageCallback;
    100   class ImageDownloads
    101       : public base::SupportsWeakPtr<ImageDownloads> {
    102    public:
    103     ImageDownloads(
    104         message_center::MessageCenter* message_center,
    105         ImageDownloadsObserver* observer);
    106     virtual ~ImageDownloads();
    107 
    108     void StartDownloads(const Notification& notification);
    109     void StartDownloadWithImage(const Notification& notification,
    110                                 const gfx::Image* image,
    111                                 const GURL& url,
    112                                 const SetImageCallback& callback);
    113     void StartDownloadByKey(const Notification& notification,
    114                             const char* key,
    115                             int size,
    116                             const SetImageCallback& callback);
    117 
    118     // FaviconHelper callback.
    119     void DownloadComplete(const SetImageCallback& callback,
    120                           int download_id,
    121                           int http_status_code,
    122                           const GURL& image_url,
    123                           const std::vector<SkBitmap>& bitmaps,
    124                           const std::vector<gfx::Size>& original_bitmap_sizes);
    125    private:
    126     // Used to keep track of the number of pending downloads.  Once this
    127     // reaches zero, we can tell the delegate that we don't need the
    128     // RenderViewHost anymore.
    129     void AddPendingDownload();
    130     void PendingDownloadCompleted();
    131 
    132     // Weak reference to global message center.
    133     message_center::MessageCenter* message_center_;
    134 
    135     // Count of downloads that remain.
    136     size_t pending_downloads_;
    137 
    138     // Weak.
    139     ImageDownloadsObserver* observer_;
    140 
    141     DISALLOW_COPY_AND_ASSIGN(ImageDownloads);
    142   };
    143 
    144   // This class keeps a set of original Notification objects and corresponding
    145   // Profiles, so when MessageCenter calls back with a notification_id, this
    146   // class has necessary mapping to other source info - for example, it calls
    147   // NotificationDelegate supplied by client when someone clicks on a
    148   // Notification in MessageCenter. Likewise, if a Profile or Extension is
    149   // being removed, the  map makes it possible to revoke the notifications from
    150   // MessageCenter.   To keep that set, we use the private ProfileNotification
    151   // class that stores  a superset of all information about a notification.
    152 
    153   // TODO(dimich): Consider merging all 4 types (Notification,
    154   // QueuedNotification, ProfileNotification and NotificationList::Notification)
    155   // into a single class.
    156   class ProfileNotification : public ImageDownloadsObserver {
    157    public:
    158     ProfileNotification(Profile* profile,
    159                         const Notification& notification,
    160                         message_center::MessageCenter* message_center);
    161     virtual ~ProfileNotification();
    162 
    163     void StartDownloads();
    164 
    165     // Overridden from ImageDownloadsObserver.
    166     virtual void OnDownloadsCompleted() OVERRIDE;
    167 
    168     Profile* profile() const { return profile_; }
    169     const Notification& notification() const { return notification_; }
    170 
    171     // Route a new notification to an app/extension.
    172     void AddToAlternateProvider(const std::string extension_id);
    173 
    174    private:
    175     // Weak, guaranteed not to be used after profile removal by parent class.
    176     Profile* profile_;
    177     Notification notification_;
    178     // Track the downloads for this notification so the notification can be
    179     // updated properly.
    180     scoped_ptr<ImageDownloads> downloads_;
    181   };
    182 
    183   scoped_ptr<message_center::MessageCenterTrayDelegate> tray_;
    184   message_center::MessageCenter* message_center_;  // Weak, global.
    185 
    186   // Use a map by notification_id since this mapping is the most often used.
    187   typedef std::map<std::string, ProfileNotification*> NotificationMap;
    188   NotificationMap profile_notifications_;
    189 
    190   // Helpers that add/remove the notification from local map.
    191   // The local map takes ownership of profile_notification object.
    192   void AddProfileNotification(ProfileNotification* profile_notification);
    193   void RemoveProfileNotification(ProfileNotification* profile_notification);
    194 
    195   // Returns the ProfileNotification for the |id|, or NULL if no such
    196   // notification is found.
    197   ProfileNotification* FindProfileNotification(const std::string& id) const;
    198 
    199   // Get the extension ID of the extension that the user chose to take over
    200   // Chorme Notification Center.
    201   std::string GetExtensionTakingOverNotifications(Profile* profile);
    202 
    203 #if defined(OS_WIN)
    204   // This function is run on update to ensure that the notification balloon is
    205   // shown only when there are no popups present.
    206   void CheckFirstRunTimer();
    207 
    208   // |first_run_pref_| is used to keep track of whether we've ever shown the
    209   // first run balloon before, even across restarts.
    210   BooleanPrefMember first_run_pref_;
    211 
    212   // The timer after which we will show the first run balloon.  This timer is
    213   // restarted every time the message center is closed and every time the last
    214   // popup disappears from the screen.
    215   base::OneShotTimer<MessageCenterNotificationManager> first_run_balloon_timer_;
    216 
    217   // The first-run balloon will be shown |first_run_idle_timeout_| after all
    218   // popups go away and the user has notifications in the message center.
    219   base::TimeDelta first_run_idle_timeout_;
    220 
    221   // Provides weak pointers for the purpose of the first run timer.
    222   base::WeakPtrFactory<MessageCenterNotificationManager> weak_factory_;
    223 #endif
    224 
    225   scoped_ptr<message_center::NotifierSettingsProvider> settings_provider_;
    226 
    227   // To own the blockers.
    228   ScopedVector<message_center::NotificationBlocker> blockers_;
    229 
    230   NotificationSystemObserver system_observer_;
    231 
    232   // Keeps track of all notification statistics for UMA purposes.
    233   MessageCenterStatsCollector stats_collector_;
    234 
    235   // Keeps track of notifications specific to Google Now for UMA purposes.
    236   GoogleNowNotificationStatsCollector google_now_stats_collector_;
    237 
    238   DISALLOW_COPY_AND_ASSIGN(MessageCenterNotificationManager);
    239 };
    240 
    241 #endif  // CHROME_BROWSER_NOTIFICATIONS_MESSAGE_CENTER_NOTIFICATION_MANAGER_H_
    242