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