diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h index ff1361bb2103ebfccf6036909d7d47068e20b461..328331820f31a9b800691a11f14951d0e80ac614 100644 --- a/chrome/browser/browser_process.h +++ b/chrome/browser/browser_process.h @@ -23,6 +23,7 @@ class DownloadRequestManager; class GoogleURLTracker; class IconManager; class MetricsService; +class NotificationUIManager; class PrefService; class ProfileManager; class DebuggerWrapper; @@ -69,6 +70,9 @@ class BrowserProcess { virtual DevToolsManager* devtools_manager() = 0; virtual Clipboard* clipboard() = 0; + // Returns the manager for desktop notifications. + virtual NotificationUIManager* notification_ui_manager() = 0; + // Returns the thread that we perform I/O coordination on (network requests, // communication with renderers, etc. // NOTE: You should ONLY use this to pass to IPC or other objects which must diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index ebfb0bf911407d774eae6b3175c91075845ed57e..2195f423a92270fc263d41e64c62f958fb7187fd 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -22,6 +22,7 @@ #include "chrome/browser/metrics/metrics_service.h" #include "chrome/browser/net/dns_global.h" #include "chrome/browser/net/sdch_dictionary_fetcher.h" +#include "chrome/browser/notifications/notification_ui_manager.h" #include "chrome/browser/plugin_service.h" #include "chrome/browser/profile_manager.h" #include "chrome/browser/renderer_host/render_process_host.h" @@ -147,6 +148,7 @@ BrowserProcessImpl::BrowserProcessImpl(const CommandLine& command_line) created_icon_manager_(false), created_debugger_wrapper_(false), created_devtools_manager_(false), + created_notification_ui_manager_(false), module_ref_count_(0), checked_for_new_frames_(false), using_new_frames_(false), @@ -433,6 +435,12 @@ void BrowserProcessImpl::CreateGoogleURLTracker() { google_url_tracker_.swap(google_url_tracker); } +void BrowserProcessImpl::CreateNotificationUIManager() { + DCHECK(notification_ui_manager_.get() == NULL); + notification_ui_manager_.reset(NotificationUIManager::Create()); + created_notification_ui_manager_ = true; +} + // The BrowserProcess object must outlive the file thread so we use traits // which don't do any management. template <> diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index a949ae446565e56623e61b4654df694d58bb973d..ea9efb4187c8e99e91e160c8ea9aa289ac3b686e 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h @@ -126,6 +126,13 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe { return clipboard_.get(); } + virtual NotificationUIManager* notification_ui_manager() { + DCHECK(CalledOnValidThread()); + if (!created_notification_ui_manager_) + CreateNotificationUIManager(); + return notification_ui_manager_.get(); + } + virtual IconManager* icon_manager() { DCHECK(CalledOnValidThread()); if (!created_icon_manager_) @@ -217,6 +224,7 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe { void CreateDebuggerWrapper(int port); void CreateDevToolsManager(); void CreateGoogleURLTracker(); + void CreateNotificationUIManager(); #if defined(OS_WIN) void InitBrokerServices(sandbox::BrokerServices* broker_services); @@ -267,6 +275,10 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe { scoped_ptr<Clipboard> clipboard_; + // Manager for desktop notification UI. + bool created_notification_ui_manager_; + scoped_ptr<NotificationUIManager> notification_ui_manager_; + scoped_ptr<AutomationProviderList> automation_provider_list_; scoped_ptr<GoogleURLTracker> google_url_tracker_; diff --git a/chrome/browser/notifications/desktop_notification_service.h b/chrome/browser/notifications/desktop_notification_service.h index 38e0b27b299cfb6fd5bbede65e379bd1b1f63f51..d7fbfda29a4a1011cc4b2818a9476b1213b739e1 100644 --- a/chrome/browser/notifications/desktop_notification_service.h +++ b/chrome/browser/notifications/desktop_notification_service.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_NOTIFICATIONS_DESKTOP_NOTIFICATION_SERVICE_H -#define CHROME_BROWSER_NOTIFICATIONS_DESKTOP_NOTIFICATION_SERVICE_H +#ifndef CHROME_BROWSER_NOTIFICATIONS_DESKTOP_NOTIFICATION_SERVICE_H_ +#define CHROME_BROWSER_NOTIFICATIONS_DESKTOP_NOTIFICATION_SERVICE_H_ #include <set> @@ -75,4 +75,4 @@ class DesktopNotificationService { DISALLOW_COPY_AND_ASSIGN(DesktopNotificationService); }; -#endif // #ifndef CHROME_BROWSER_NOTIFICATIONS_DESKTOP_NOTIFICATION_SERVICE_H +#endif // CHROME_BROWSER_NOTIFICATIONS_DESKTOP_NOTIFICATION_SERVICE_H_ diff --git a/chrome/browser/notifications/desktop_notification_service_win.cc b/chrome/browser/notifications/desktop_notification_service_win.cc index 41e3e298170e0abd21a2925b0ca14211c12e81f1..f6494cd68b111755f4b00aa9bc2ac12be741d647 100644 --- a/chrome/browser/notifications/desktop_notification_service_win.cc +++ b/chrome/browser/notifications/desktop_notification_service_win.cc @@ -12,9 +12,9 @@ #include "chrome/browser/browser_list.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/notifications/notification_object_proxy.h" +#include "chrome/browser/notifications/notification_ui_manager.h" #include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/browser/renderer_host/site_instance.h" -#include "chrome/browser/worker_host/worker_process_host.h" #include "chrome/common/child_process_host.h" #include "grit/browser_resources.h" #include "grit/generated_resources.h" @@ -59,9 +59,7 @@ static string16 CreateDataUrl(const GURL& icon_url, const string16& title, // put the notification with the requested parameters on the desktop. void DesktopNotificationService::ShowNotification( const Notification& notification) { - SiteInstance* site_instance = SiteInstance::CreateSiteInstance(profile_); - // TODO(johnnyg): When UI Manager is available, add from here. - // ui_manager_->Add(notification, profile_, site_instance); + ui_manager_->Add(notification, profile_); } // Shows a notification bubble which contains the contents of url. @@ -94,4 +92,3 @@ bool DesktopNotificationService::ShowDesktopNotificationText( ShowNotification(notif); return true; } - diff --git a/chrome/browser/notifications/notification_ui_manager.cc b/chrome/browser/notifications/notification_ui_manager.cc new file mode 100644 index 0000000000000000000000000000000000000000..6818a42081f7b70181f386aacf220d2ad5244bc1 --- /dev/null +++ b/chrome/browser/notifications/notification_ui_manager.cc @@ -0,0 +1,77 @@ +// Copyright (c) 2009 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. + +#include "chrome/browser/notifications/notification_ui_manager.h" + +#include "base/logging.h" +#include "base/scoped_ptr.h" +#include "base/stl_util-inl.h" +#include "chrome/browser/notifications/balloon_collection.h" +#include "chrome/browser/notifications/notification.h" +#include "chrome/browser/renderer_host/site_instance.h" + +// A class which represents a notification waiting to be shown. +class QueuedNotification { + public: + QueuedNotification(const Notification& notification, Profile* profile) + : notification_(notification), + profile_(profile) { + } + + const Notification& notification() const { return notification_; } + Profile* profile() const { return profile_; } + + private: + // The notification to be shown. + Notification notification_; + + // Non owned pointer to the user's profile. + Profile* profile_; + + DISALLOW_COPY_AND_ASSIGN(QueuedNotification); +}; + +NotificationUIManager::NotificationUIManager() + : balloon_collection_(NULL) { +} + +NotificationUIManager::~NotificationUIManager() { + STLDeleteElements(&show_queue_); +} + +// static +NotificationUIManager* NotificationUIManager::Create() { + BalloonCollectionImpl* balloons = new BalloonCollectionImpl(); + NotificationUIManager* instance = new NotificationUIManager(); + instance->Initialize(balloons); + balloons->set_space_change_listener(instance); + return instance; +} + +void NotificationUIManager::Add(const Notification& notification, + Profile* profile) { + LOG(INFO) << "Added notification. URL: " + << notification.content_url().spec().c_str(); + show_queue_.push_back( + new QueuedNotification(notification, profile)); + CheckAndShowNotifications(); +} + +void NotificationUIManager::CheckAndShowNotifications() { + // TODO(johnnyg): http://crbug.com/25061 - Check for user idle/presentation. + ShowNotifications(); +} + +void NotificationUIManager::ShowNotifications() { + while (!show_queue_.empty() && balloon_collection_->HasSpace()) { + scoped_ptr<QueuedNotification> queued_notification(show_queue_.front()); + show_queue_.pop_front(); + balloon_collection_->Add(queued_notification->notification(), + queued_notification->profile()); + } +} + +void NotificationUIManager::OnBalloonSpaceChanged() { + CheckAndShowNotifications(); +} diff --git a/chrome/browser/notifications/notification_ui_manager.h b/chrome/browser/notifications/notification_ui_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..192058f9e5b3296e729a7647900e6c7716cb3cb3 --- /dev/null +++ b/chrome/browser/notifications/notification_ui_manager.h @@ -0,0 +1,66 @@ +// Copyright (c) 2009 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 CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_UI_MANAGER_H_ +#define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_UI_MANAGER_H_ + +#include <deque> + +#include "base/id_map.h" +#include "base/scoped_ptr.h" +#include "chrome/browser/notifications/balloon.h" +#include "chrome/browser/notifications/balloon_collection.h" + +class Notification; +class Profile; +class QueuedNotification; +class SiteInstance; + +// The notification manager manages use of the desktop for notifications. +// It maintains a queue of pending notifications when space becomes constrained. +class NotificationUIManager : + public BalloonCollectionImpl::BalloonSpaceChangeListener { + public: + NotificationUIManager(); + virtual ~NotificationUIManager(); + + // Creates an initialized UI manager with a new balloon collection + // and the listener relationship setup. + // Except for unit tests, this is the way to construct the object. + static NotificationUIManager* Create(); + + // Initializes the UI manager with a balloon collection; this object + // takes ownership of the balloon collection. + void Initialize(BalloonCollection* balloon_collection) { + DCHECK(!balloon_collection_.get()); + DCHECK(balloon_collection); + balloon_collection_.reset(balloon_collection); + } + + // Adds a notification to be displayed. Virtual for unit test override. + virtual void Add(const Notification& notification, + Profile* profile); + + private: + // Attempts to display notifications from the show_queue if the user + // is active. + void CheckAndShowNotifications(); + + // Attempts to display notifications from the show_queue. + void ShowNotifications(); + + // BalloonCollectionObserver implementation. + virtual void OnBalloonSpaceChanged(); + + // An owned pointer to the collection of active balloons. + scoped_ptr<BalloonCollection> balloon_collection_; + + // A queue of notifications which are waiting to be shown. + typedef std::deque<QueuedNotification*> NotificationDeque; + NotificationDeque show_queue_; + + DISALLOW_COPY_AND_ASSIGN(NotificationUIManager); +}; + +#endif // CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_UI_MANAGER_H_ diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc index 7d715f0e6790dcd0212cab4f16b5f0366d919ca3..cafba63768340328bc0b2f8de240b491e0a03421 100644 --- a/chrome/browser/profile.cc +++ b/chrome/browser/profile.cc @@ -1318,11 +1318,9 @@ WebKitContext* ProfileImpl::GetWebKitContext() { DesktopNotificationService* ProfileImpl::GetDesktopNotificationService() { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); if (!desktop_notification_service_.get()) { - // TODO(johnnyg): hook this up with notification UI manager. desktop_notification_service_.reset(new DesktopNotificationService( - this, NULL)); + this, g_browser_process->notification_ui_manager())); } - return desktop_notification_service_.get(); } diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 0bfaf484867d4ee81cec77e835696cded528471b..accb720785b4425952bdbb2f65d94ff9581d1276 100755 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -1813,6 +1813,8 @@ 'browser/notifications/notification.h', 'browser/notifications/notification_object_proxy.cc', 'browser/notifications/notification_object_proxy.h', + 'browser/notifications/notification_ui_manager.cc', + 'browser/notifications/notification_ui_manager.h', 'browser/notifications/notifications_prefs_cache.cc', 'browser/notifications/notifications_prefs_cache.h', 'browser/ntp_background_util.cc', diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index fc59c19c83c19a84592fff134dafb7901ccd1272..2aa316710c249625c6e02b5661d9837dba830f6a 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -188,7 +188,7 @@ class RenderView : public RenderWidget, const WebKit::WebString& source_name, unsigned source_line); virtual void printPage(WebKit::WebFrame* frame); virtual WebKit::WebNotificationPresenter* notificationPresenter() { - return NULL; + return notification_provider_.get(); } virtual void didStartLoading(); virtual void didStopLoading(); diff --git a/chrome/test/testing_browser_process.h b/chrome/test/testing_browser_process.h index 93444ad06183e7b837cf76e3ae8948b1488b4a92..070c865f78137512999a0c055e8bd90ba6f90a7a 100644 --- a/chrome/test/testing_browser_process.h +++ b/chrome/test/testing_browser_process.h @@ -103,6 +103,10 @@ class TestingBrowserProcess : public BrowserProcess { return clipboard_.get(); } + virtual NotificationUIManager* notification_ui_manager() { + return NULL; + } + virtual GoogleURLTracker* google_url_tracker() { return NULL; }