blob: be2621e039998fdb5c14ecdfb17435c705321127 [file] [log] [blame]
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001// 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"
Ben Murdocheb525c52013-07-10 11:40:50 +010012#include "base/memory/weak_ptr.h"
13#include "base/prefs/pref_member.h"
14#include "base/time/time.h"
15#include "base/timer/timer.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000016#include "chrome/browser/notifications/notification.h"
17#include "chrome/browser/notifications/notification_ui_manager.h"
18#include "chrome/browser/notifications/notification_ui_manager_impl.h"
Ben Murdoch2385ea32013-08-06 11:01:04 +010019#include "content/public/browser/notification_observer.h"
20#include "content/public/browser/notification_registrar.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000021#include "ui/message_center/message_center.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010022#include "ui/message_center/message_center_observer.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000023#include "ui/message_center/message_center_tray_delegate.h"
24
25class MessageCenterSettingsController;
26class Notification;
Ben Murdocheb525c52013-07-10 11:40:50 +010027class PrefService;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000028class Profile;
29
30// This class extends NotificationUIManagerImpl and delegates actual display
31// of notifications to MessageCenter, doing necessary conversions.
32class MessageCenterNotificationManager
33 : public NotificationUIManagerImpl,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010034 public message_center::MessageCenter::Delegate,
35 public message_center::MessageCenterObserver {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000036 public:
Ben Murdochbb1529c2013-08-08 10:24:53 +010037 MessageCenterNotificationManager(
Ben Murdocheb525c52013-07-10 11:40:50 +010038 message_center::MessageCenter* message_center,
Ben Murdochbb1529c2013-08-08 10:24:53 +010039 PrefService* local_state,
40 scoped_ptr<message_center::NotifierSettingsProvider> settings_provider);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000041 virtual ~MessageCenterNotificationManager();
42
43 // NotificationUIManager
Ben Murdoch558790d2013-07-30 15:19:42 +010044 virtual const Notification* FindById(
45 const std::string& notification_id) const OVERRIDE;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000046 virtual bool CancelById(const std::string& notification_id) OVERRIDE;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010047 virtual std::set<std::string> GetAllIdsByProfileAndSourceOrigin(
48 Profile* profile,
49 const GURL& source) OVERRIDE;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000050 virtual bool CancelAllBySourceOrigin(const GURL& source_origin) OVERRIDE;
51 virtual bool CancelAllByProfile(Profile* profile) OVERRIDE;
52 virtual void CancelAll() OVERRIDE;
53
54 // NotificationUIManagerImpl
55 virtual bool ShowNotification(const Notification& notification,
56 Profile* profile) OVERRIDE;
57 virtual bool UpdateNotification(const Notification& notification,
58 Profile* profile) OVERRIDE;
59
60 // MessageCenter::Delegate
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000061 virtual void DisableExtension(const std::string& notification_id) OVERRIDE;
62 virtual void DisableNotificationsFromSource(
63 const std::string& notification_id) OVERRIDE;
64 virtual void ShowSettings(const std::string& notification_id) OVERRIDE;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010065
66 // MessageCenterObserver
67 virtual void OnNotificationRemoved(const std::string& notification_id,
68 bool by_user) OVERRIDE;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010069 virtual void OnNotificationCenterClosed() OVERRIDE;
Ben Murdocheb525c52013-07-10 11:40:50 +010070 virtual void OnNotificationUpdated(const std::string& notification_id)
71 OVERRIDE;
72
73#if defined(OS_WIN)
74 // Called when the pref changes for the first run balloon. The first run
75 // balloon is only displayed on Windows, since the visibility of the tray
76 // icon is limited.
77 void DisplayFirstRunBalloon();
78
79 void SetFirstRunTimeoutForTest(base::TimeDelta timeout);
80 bool FirstRunTimerIsActive() const;
81#endif
82
83 // Takes ownership of |delegate|.
84 void SetMessageCenterTrayDelegateForTest(
85 message_center::MessageCenterTrayDelegate* delegate);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000086
Ben Murdoch2385ea32013-08-06 11:01:04 +010087 protected:
88 // content::NotificationObserver override.
89 virtual void Observe(int type,
90 const content::NotificationSource& source,
91 const content::NotificationDetails& details) OVERRIDE;
92
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000093 private:
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010094 class ImageDownloadsObserver {
95 public:
96 virtual void OnDownloadsCompleted() = 0;
97 };
98
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000099 typedef base::Callback<void(const gfx::Image&)> SetImageCallback;
100 class ImageDownloads
101 : public base::SupportsWeakPtr<ImageDownloads> {
102 public:
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100103 ImageDownloads(
104 message_center::MessageCenter* message_center,
105 ImageDownloadsObserver* observer);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000106 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 int size,
113 const SetImageCallback& callback);
114 void StartDownloadByKey(const Notification& notification,
115 const char* key,
116 int size,
117 const SetImageCallback& callback);
118
119 // FaviconHelper callback.
120 void DownloadComplete(const SetImageCallback& callback,
121 int download_id,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100122 int http_status_code,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000123 const GURL& image_url,
124 int requested_size,
125 const std::vector<SkBitmap>& bitmaps);
126 private:
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100127 // Used to keep track of the number of pending downloads. Once this
128 // reaches zero, we can tell the delegate that we don't need the
129 // RenderViewHost anymore.
130 void AddPendingDownload();
131 void PendingDownloadCompleted();
132
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000133 // Weak reference to global message center.
134 message_center::MessageCenter* message_center_;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100135
136 // Count of downloads that remain.
137 size_t pending_downloads_;
138
139 // Weak.
140 ImageDownloadsObserver* observer_;
141
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000142 DISALLOW_COPY_AND_ASSIGN(ImageDownloads);
143 };
144
145 // This class keeps a set of original Notification objects and corresponding
146 // Profiles, so when MessageCenter calls back with a notification_id, this
147 // class has necessary mapping to other source info - for example, it calls
148 // NotificationDelegate supplied by client when someone clicks on a
149 // Notification in MessageCenter. Likewise, if a Profile or Extension is
150 // being removed, the map makes it possible to revoke the notifications from
151 // MessageCenter. To keep that set, we use the private ProfileNotification
152 // class that stores a superset of all information about a notification.
153
154 // TODO(dimich): Consider merging all 4 types (Notification,
155 // QueuedNotification, ProfileNotification and NotificationList::Notification)
156 // into a single class.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100157 class ProfileNotification : public ImageDownloadsObserver {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000158 public:
159 ProfileNotification(Profile* profile,
160 const Notification& notification,
161 message_center::MessageCenter* message_center);
162 virtual ~ProfileNotification();
163
164 void StartDownloads();
165
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100166 // Overridden from ImageDownloadsObserver.
167 virtual void OnDownloadsCompleted() OVERRIDE;
168
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000169 Profile* profile() const { return profile_; }
170 const Notification& notification() const { return notification_; }
171
172 // Returns extension_id if the notification originates from an extension,
173 // empty string otherwise.
174 std::string GetExtensionId();
175
176 private:
177 // Weak, guaranteed not to be used after profile removal by parent class.
178 Profile* profile_;
179 Notification notification_;
180 // Track the downloads for this notification so the notification can be
181 // updated properly.
182 scoped_ptr<ImageDownloads> downloads_;
183 };
184
185 scoped_ptr<message_center::MessageCenterTrayDelegate> tray_;
186 message_center::MessageCenter* message_center_; // Weak, global.
187
188 // Use a map by notification_id since this mapping is the most often used.
189 typedef std::map<std::string, ProfileNotification*> NotificationMap;
190 NotificationMap profile_notifications_;
191
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000192 // Helpers that add/remove the notification from local map and MessageCenter.
193 // They take ownership of profile_notification object.
194 void AddProfileNotification(ProfileNotification* profile_notification);
195 void RemoveProfileNotification(ProfileNotification* profile_notification,
196 bool by_user);
197
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100198 // Returns the ProfileNotification for the |id|, or NULL if no such
199 // notification is found.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000200 ProfileNotification* FindProfileNotification(const std::string& id) const;
201
Ben Murdocheb525c52013-07-10 11:40:50 +0100202#if defined(OS_WIN)
203 // This function is run on update to ensure that the notification balloon is
204 // shown only when there are no popups present.
205 void CheckFirstRunTimer();
206
207 // |first_run_pref_| is used to keep track of whether we've ever shown the
208 // first run balloon before, even across restarts.
209 BooleanPrefMember first_run_pref_;
210
211 // The timer after which we will show the first run balloon. This timer is
212 // restarted every time the message center is closed and every time the last
213 // popup disappears from the screen.
214 base::OneShotTimer<MessageCenterNotificationManager> first_run_balloon_timer_;
215
216 // The first-run balloon will be shown |first_run_idle_timeout_| after all
217 // popups go away and the user has notifications in the message center.
218 base::TimeDelta first_run_idle_timeout_;
219
220 // Provides weak pointers for the purpose of the first run timer.
221 base::WeakPtrFactory<MessageCenterNotificationManager> weak_factory_;
222#endif
223
Ben Murdochbb1529c2013-08-08 10:24:53 +0100224 scoped_ptr<message_center::NotifierSettingsProvider> settings_provider_;
Ben Murdocheb525c52013-07-10 11:40:50 +0100225
Ben Murdoch2385ea32013-08-06 11:01:04 +0100226 // Registrar for the other kind of notifications (event signaling).
227 content::NotificationRegistrar registrar_;
228
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000229 DISALLOW_COPY_AND_ASSIGN(MessageCenterNotificationManager);
230};
231
232#endif // CHROME_BROWSER_NOTIFICATIONS_MESSAGE_CENTER_NOTIFICATION_MANAGER_H_