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