summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/background/background_contents_service.cc14
-rw-r--r--chrome/browser/chromeos/locale_change_guard.cc13
-rw-r--r--chrome/browser/chromeos/notifications/system_notification.cc5
-rw-r--r--chrome/browser/chromeos/notifications/system_notification.h1
-rw-r--r--chrome/browser/notifications/OWNERS2
-rw-r--r--chrome/browser/notifications/balloon_collection_base.cc11
-rw-r--r--chrome/browser/notifications/balloon_collection_base.h4
-rw-r--r--chrome/browser/notifications/desktop_notification_service_win.cc3
-rw-r--r--chrome/browser/notifications/notification.cc23
-rw-r--r--chrome/browser/notifications/notification.h50
-rw-r--r--chrome/browser/notifications/notification_delegate.h9
-rw-r--r--chrome/browser/notifications/notification_object_proxy.cc4
-rw-r--r--chrome/browser/notifications/notification_object_proxy.h3
-rw-r--r--chrome/browser/notifications/notification_test_util.cc4
-rw-r--r--chrome/browser/notifications/notification_test_util.h15
-rw-r--r--chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc16
-rw-r--r--chrome/browser/status_icons/desktop_notification_balloon.cc3
-rw-r--r--chrome/browser/ui/cocoa/notifications/balloon_controller_unittest.mm3
-rw-r--r--chrome/browser/ui/views/ash/balloon_collection_impl_ash.cc107
-rw-r--r--chrome/browser/ui/views/ash/balloon_collection_impl_ash.h17
-rw-r--r--chrome/browser/ui/views/ash/balloon_view_ash.cc165
-rw-r--r--chrome/browser/ui/views/ash/balloon_view_ash.h38
-rw-r--r--chrome/chrome_browser.gypi2
23 files changed, 463 insertions, 49 deletions
diff --git a/chrome/browser/background/background_contents_service.cc b/chrome/browser/background/background_contents_service.cc
index 909ef7a..c1edaba 100644
--- a/chrome/browser/background/background_contents_service.cc
+++ b/chrome/browser/background/background_contents_service.cc
@@ -64,13 +64,13 @@ class CrashNotificationDelegate : public NotificationDelegate {
extension_id_(extension->id()) {
}
- void Display() {}
+ virtual void Display() OVERRIDE {}
- void Error() {}
+ virtual void Error() OVERRIDE {}
- void Close(bool by_user) {}
+ virtual void Close(bool by_user) OVERRIDE {}
- void Click() {
+ virtual void Click() OVERRIDE {
if (is_hosted_app_) {
// There can be a race here: user clicks the balloon, and simultaneously
// reloads the sad tab for the app. So we check here to be safe before
@@ -88,10 +88,14 @@ class CrashNotificationDelegate : public NotificationDelegate {
ScheduleCloseBalloon(extension_id_);
}
- std::string id() const {
+ virtual std::string id() const OVERRIDE {
return kNotificationPrefix + extension_id_;
}
+ virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE {
+ return NULL;
+ }
+
private:
virtual ~CrashNotificationDelegate() {}
diff --git a/chrome/browser/chromeos/locale_change_guard.cc b/chrome/browser/chromeos/locale_change_guard.cc
index 8365677..4ceb92b 100644
--- a/chrome/browser/chromeos/locale_change_guard.cc
+++ b/chrome/browser/chromeos/locale_change_guard.cc
@@ -36,11 +36,14 @@ namespace chromeos {
class LocaleChangeGuard::Delegate : public NotificationDelegate {
public:
explicit Delegate(chromeos::LocaleChangeGuard* master) : master_(master) {}
- void Close(bool by_user);
- void Display() {}
- void Error() {}
- void Click() {}
- std::string id() const;
+ virtual void Close(bool by_user) OVERRIDE;
+ virtual void Display() OVERRIDE {}
+ virtual void Error() OVERRIDE {}
+ virtual void Click() OVERRIDE {}
+ virtual std::string id() const OVERRIDE;
+ virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE {
+ return NULL;
+ }
private:
chromeos::LocaleChangeGuard* master_;
diff --git a/chrome/browser/chromeos/notifications/system_notification.cc b/chrome/browser/chromeos/notifications/system_notification.cc
index ba01260..efaaa1d 100644
--- a/chrome/browser/chromeos/notifications/system_notification.cc
+++ b/chrome/browser/chromeos/notifications/system_notification.cc
@@ -136,4 +136,9 @@ std::string SystemNotification::Delegate::id() const {
return id_;
}
+content::RenderViewHost*
+SystemNotification::Delegate::GetRenderViewHost() const {
+ return NULL;
+}
+
} // namespace chromeos
diff --git a/chrome/browser/chromeos/notifications/system_notification.h b/chrome/browser/chromeos/notifications/system_notification.h
index 3c930ba..40d97de 100644
--- a/chrome/browser/chromeos/notifications/system_notification.h
+++ b/chrome/browser/chromeos/notifications/system_notification.h
@@ -77,6 +77,7 @@ class SystemNotification : public PowerManagerClient::Observer {
virtual void Close(bool by_user) OVERRIDE {}
virtual void Click() OVERRIDE {}
virtual std::string id() const OVERRIDE;
+ virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE;
private:
std::string id_;
diff --git a/chrome/browser/notifications/OWNERS b/chrome/browser/notifications/OWNERS
index 967c65c..05f7e95d 100644
--- a/chrome/browser/notifications/OWNERS
+++ b/chrome/browser/notifications/OWNERS
@@ -1 +1 @@
-johnnyg@chromium.org
+stevenjb@chormium.org
diff --git a/chrome/browser/notifications/balloon_collection_base.cc b/chrome/browser/notifications/balloon_collection_base.cc
index 278f4a9..d66d7e92 100644
--- a/chrome/browser/notifications/balloon_collection_base.cc
+++ b/chrome/browser/notifications/balloon_collection_base.cc
@@ -75,14 +75,17 @@ void BalloonCollectionBase::CloseAll() {
(*iter)->CloseByScript();
}
-Balloon* BalloonCollectionBase::FindBalloon(
- const Notification& notification) {
+Balloon* BalloonCollectionBase::FindBalloonById(
+ const std::string& notification_id) {
Balloons::iterator iter;
for (iter = balloons_.begin(); iter != balloons_.end(); ++iter) {
- if ((*iter)->notification().notification_id() ==
- notification.notification_id()) {
+ if ((*iter)->notification().notification_id() == notification_id) {
return *iter;
}
}
return NULL;
}
+
+Balloon* BalloonCollectionBase::FindBalloon(const Notification& notification) {
+ return FindBalloonById(notification.notification_id());
+}
diff --git a/chrome/browser/notifications/balloon_collection_base.h b/chrome/browser/notifications/balloon_collection_base.h
index 578c76e..bc5a291 100644
--- a/chrome/browser/notifications/balloon_collection_base.h
+++ b/chrome/browser/notifications/balloon_collection_base.h
@@ -48,6 +48,10 @@ class BalloonCollectionBase {
const Balloons& balloons() const { return balloons_; }
+ // Returns the balloon matching the given notification id, or
+ // NULL if there is no matching balloon.
+ Balloon* FindBalloonById(const std::string& notification_id);
+
// Returns the balloon matching the given notification, or
// NULL if there is no matching balloon.
Balloon* FindBalloon(const Notification& notification);
diff --git a/chrome/browser/notifications/desktop_notification_service_win.cc b/chrome/browser/notifications/desktop_notification_service_win.cc
index 3cba517..3f9bd29 100644
--- a/chrome/browser/notifications/desktop_notification_service_win.cc
+++ b/chrome/browser/notifications/desktop_notification_service_win.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "base/win/metro.h"
#include "chrome/browser/notifications/notification.h"
+#include "chrome/browser/notifications/notification_object_proxy.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
@@ -54,5 +55,3 @@ void DesktopNotificationService::ShowNotification(
}
GetUIManager()->Add(notification, profile_);
}
-
-
diff --git a/chrome/browser/notifications/notification.cc b/chrome/browser/notifications/notification.cc
index 8af6ba1..282ccbd 100644
--- a/chrome/browser/notifications/notification.cc
+++ b/chrome/browser/notifications/notification.cc
@@ -28,6 +28,7 @@ Notification::Notification(const GURL& origin_url,
const string16& replace_id,
NotificationDelegate* delegate)
: origin_url_(origin_url),
+ icon_url_(icon_url),
is_html_(false),
title_(title),
body_(body),
@@ -39,8 +40,28 @@ Notification::Notification(const GURL& origin_url,
icon_url, title, body, dir));
}
+Notification::Notification(const GURL& origin_url,
+ const gfx::ImageSkia& icon,
+ const string16& title,
+ const string16& body,
+ WebKit::WebTextDirection dir,
+ const string16& display_source,
+ const string16& replace_id,
+ NotificationDelegate* delegate)
+ : origin_url_(origin_url),
+ icon_(icon),
+ is_html_(false),
+ title_(title),
+ body_(body),
+ display_source_(display_source),
+ replace_id_(replace_id),
+ delegate_(delegate) {
+}
+
Notification::Notification(const Notification& notification)
: origin_url_(notification.origin_url()),
+ icon_(notification.icon()),
+ icon_url_(notification.icon_url()),
is_html_(notification.is_html()),
content_url_(notification.content_url()),
title_(notification.title()),
@@ -54,6 +75,8 @@ Notification::~Notification() {}
Notification& Notification::operator=(const Notification& notification) {
origin_url_ = notification.origin_url();
+ icon_ = notification.icon_;
+ icon_url_ = notification.icon_url();
is_html_ = notification.is_html();
content_url_ = notification.content_url();
title_ = notification.title();
diff --git a/chrome/browser/notifications/notification.h b/chrome/browser/notifications/notification.h
index f6b41d4..5868dea 100644
--- a/chrome/browser/notifications/notification.h
+++ b/chrome/browser/notifications/notification.h
@@ -10,15 +10,15 @@
#include "base/basictypes.h"
#include "base/string16.h"
-#include "chrome/browser/notifications/notification_object_proxy.h"
+#include "chrome/browser/notifications/notification_delegate.h"
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebTextDirection.h"
+#include "ui/gfx/image/image_skia.h"
-class NotificationDelegate;
-
-// Representation of an notification to be shown to the user. All
-// notifications at this level are HTML, although they may be
-// data: URLs representing simple text+icon notifications.
+// Representation of a notification to be shown to the user.
+// On non-Ash platforms these are rendered as HTML, sometimes described by a
+// data url converted from text + icon data. On Ash they are rendered as
+// formated text and icon data.
class Notification {
public:
// Initializes a notification with HTML content.
@@ -27,9 +27,9 @@ class Notification {
const string16& display_source,
const string16& replace_id,
NotificationDelegate* delegate);
- // Initializes a notification with text content, and then creates a
- // HTML representation of it for display (satisfying the invariant outlined
- // at the top of this class).
+
+ // Initializes a notification with text content. On non-ash platforms, this
+ // creates an HTML representation using a data: URL for display.
Notification(const GURL& origin_url,
const GURL& icon_url,
const string16& title,
@@ -38,6 +38,18 @@ class Notification {
const string16& display_source,
const string16& replace_id,
NotificationDelegate* delegate);
+
+ // Initializes a notification with text content and an icon image. Currently
+ // only used on Ash. Does not generate content_url_.
+ Notification(const GURL& origin_url,
+ const gfx::ImageSkia& icon,
+ const string16& title,
+ const string16& body,
+ WebKit::WebTextDirection dir,
+ const string16& display_source,
+ const string16& replace_id,
+ NotificationDelegate* delegate);
+
Notification(const Notification& notification);
~Notification();
Notification& operator=(const Notification& notification);
@@ -48,16 +60,23 @@ class Notification {
// The URL (may be data:) containing the contents for the notification.
const GURL& content_url() const { return content_url_; }
- // Parameters for text-only notifications.
+ // Title and message text of the notification.
const string16& title() const { return title_; }
const string16& body() const { return body_; }
// The origin URL of the script which requested the notification.
const GURL& origin_url() const { return origin_url_; }
+ // A url for the icon to be shown (optional).
+ const GURL& icon_url() const { return icon_url_; }
+
+ // An image for the icon to be shown (optional).
+ const gfx::ImageSkia& icon() const { return icon_; }
+
// A display string for the source of the notification.
const string16& display_source() const { return display_source_; }
+ // A unique identifier used to update (replace) or remove a notification.
const string16& replace_id() const { return replace_id_; }
void Display() const { delegate()->Display(); }
@@ -67,12 +86,23 @@ class Notification {
std::string notification_id() const { return delegate()->id(); }
+ content::RenderViewHost* GetRenderViewHost() const {
+ return delegate()->GetRenderViewHost();
+ }
+
private:
NotificationDelegate* delegate() const { return delegate_.get(); }
// The Origin of the page/worker which created this notification.
GURL origin_url_;
+ // Image data for the associated icon, used by Ash when available.
+ gfx::ImageSkia icon_;
+
+ // URL for the icon associated with the notification. Requires delegate_
+ // to have a non NULL RenderViewHost.
+ GURL icon_url_;
+
// If this is a HTML notification, the content is in |content_url_|. If
// false, the data is in |title_| and |body_|.
bool is_html_;
diff --git a/chrome/browser/notifications/notification_delegate.h b/chrome/browser/notifications/notification_delegate.h
index 81a4a00f..2434af5 100644
--- a/chrome/browser/notifications/notification_delegate.h
+++ b/chrome/browser/notifications/notification_delegate.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -10,6 +10,10 @@
#include "base/memory/ref_counted.h"
+namespace content {
+class RenderViewHost;
+}
+
// Delegate for a notification. This class has two role, to implement
// callback methods for notification, and provides an identify of
// the associated notification.
@@ -33,6 +37,9 @@ class NotificationDelegate
// Returns unique id of the notification.
virtual std::string id() const = 0;
+ // Returns the RenderViewHost that generated the notification, or NULL.
+ virtual content::RenderViewHost* GetRenderViewHost() const = 0;
+
protected:
virtual ~NotificationDelegate() {}
diff --git a/chrome/browser/notifications/notification_object_proxy.cc b/chrome/browser/notifications/notification_object_proxy.cc
index 6c838df..f918724 100644
--- a/chrome/browser/notifications/notification_object_proxy.cc
+++ b/chrome/browser/notifications/notification_object_proxy.cc
@@ -49,3 +49,7 @@ std::string NotificationObjectProxy::id() const {
return StringPrintf("%d:%d:%d:%d", process_id_, route_id_,
notification_id_, worker_);
}
+
+RenderViewHost* NotificationObjectProxy::GetRenderViewHost() const {
+ return RenderViewHost::FromID(process_id_, route_id_);
+}
diff --git a/chrome/browser/notifications/notification_object_proxy.h b/chrome/browser/notifications/notification_object_proxy.h
index 6373a11..a9c93f4 100644
--- a/chrome/browser/notifications/notification_object_proxy.h
+++ b/chrome/browser/notifications/notification_object_proxy.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -27,6 +27,7 @@ class NotificationObjectProxy
virtual void Close(bool by_user) OVERRIDE;
virtual void Click() OVERRIDE;
virtual std::string id() const OVERRIDE;
+ virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE;
protected:
friend class base::RefCountedThreadSafe<NotificationObjectProxy>;
diff --git a/chrome/browser/notifications/notification_test_util.cc b/chrome/browser/notifications/notification_test_util.cc
index 1803c67..89dca71 100644
--- a/chrome/browser/notifications/notification_test_util.cc
+++ b/chrome/browser/notifications/notification_test_util.cc
@@ -14,6 +14,10 @@ std::string MockNotificationDelegate::id() const {
return id_;
}
+content::RenderViewHost* MockNotificationDelegate::GetRenderViewHost() const {
+ return NULL;
+}
+
void MockBalloonView::Close(bool by_user) {
balloon_->OnClose(by_user);
}
diff --git a/chrome/browser/notifications/notification_test_util.h b/chrome/browser/notifications/notification_test_util.h
index 7ea3ac7..418f672 100644
--- a/chrome/browser/notifications/notification_test_util.h
+++ b/chrome/browser/notifications/notification_test_util.h
@@ -24,6 +24,7 @@ class MockNotificationDelegate : public NotificationDelegate {
virtual void Close(bool by_user) OVERRIDE {}
virtual void Click() OVERRIDE {}
virtual std::string id() const OVERRIDE;
+ virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE;
private:
virtual ~MockNotificationDelegate();
@@ -47,24 +48,28 @@ class LoggingNotificationDelegate : public NotificationDelegate {
}
// NotificationObjectProxy override
- virtual void Display() {
+ virtual void Display() OVERRIDE {
Logger::log("notification displayed\n");
}
- virtual void Error() {
+ virtual void Error() OVERRIDE {
Logger::log("notification error\n");
}
- virtual void Click() {
+ virtual void Click() OVERRIDE {
Logger::log("notification clicked\n");
}
- virtual void Close(bool by_user) {
+ virtual void Close(bool by_user) OVERRIDE {
if (by_user)
Logger::log("notification closed by user\n");
else
Logger::log("notification closed by script\n");
}
- virtual std::string id() const {
+ virtual std::string id() const OVERRIDE {
return notification_id_;
}
+ virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE {
+ return NULL;
+ }
+
private:
std::string notification_id_;
diff --git a/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc b/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc
index ef27791..e171b00 100644
--- a/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc
+++ b/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc
@@ -38,21 +38,27 @@ class CloudPrintProxyService::TokenExpiredNotificationDelegate
: cloud_print_service_(cloud_print_service) {
}
- void Display() {}
+ virtual void Display() OVERRIDE {}
- void Error() {
+ virtual void Error() OVERRIDE {
cloud_print_service_->OnTokenExpiredNotificationError();
}
- void Close(bool by_user) {
+ virtual void Close(bool by_user) OVERRIDE {
cloud_print_service_->OnTokenExpiredNotificationClosed(by_user);
}
- void Click() {
+ virtual void Click() OVERRIDE {
cloud_print_service_->OnTokenExpiredNotificationClick();
}
- std::string id() const { return "cloudprint.tokenexpired"; }
+ virtual std::string id() const OVERRIDE {
+ return "cloudprint.tokenexpired";
+ }
+
+ virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE {
+ return NULL;
+ }
private:
virtual ~TokenExpiredNotificationDelegate() {}
diff --git a/chrome/browser/status_icons/desktop_notification_balloon.cc b/chrome/browser/status_icons/desktop_notification_balloon.cc
index 70d46ee..d49a8bb 100644
--- a/chrome/browser/status_icons/desktop_notification_balloon.cc
+++ b/chrome/browser/status_icons/desktop_notification_balloon.cc
@@ -49,6 +49,9 @@ class DummyNotificationDelegate : public NotificationDelegate {
virtual void Close(bool by_user) OVERRIDE {}
virtual void Click() OVERRIDE {}
virtual std::string id() const OVERRIDE { return id_; }
+ virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE {
+ return NULL;
+ }
private:
virtual ~DummyNotificationDelegate() {}
diff --git a/chrome/browser/ui/cocoa/notifications/balloon_controller_unittest.mm b/chrome/browser/ui/cocoa/notifications/balloon_controller_unittest.mm
index 1832517..1b9bd25 100644
--- a/chrome/browser/ui/cocoa/notifications/balloon_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/notifications/balloon_controller_unittest.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -7,6 +7,7 @@
#include "chrome/browser/notifications/balloon.h"
#include "chrome/browser/notifications/balloon_collection.h"
#include "chrome/browser/notifications/notification.h"
+#include "chrome/browser/notifications/notification_object_proxy.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/cocoa/cocoa_test_helper.h"
#include "chrome/browser/ui/cocoa/notifications/balloon_controller.h"
diff --git a/chrome/browser/ui/views/ash/balloon_collection_impl_ash.cc b/chrome/browser/ui/views/ash/balloon_collection_impl_ash.cc
index 646af7d..bc9de45 100644
--- a/chrome/browser/ui/views/ash/balloon_collection_impl_ash.cc
+++ b/chrome/browser/ui/views/ash/balloon_collection_impl_ash.cc
@@ -4,17 +4,103 @@
#include "chrome/browser/ui/views/ash/balloon_collection_impl_ash.h"
+#include "ash/ash_switches.h"
+#include "ash/shell.h"
+#include "ash/system/status_area_widget.h"
+#include "base/command_line.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/notifications/balloon.h"
+#include "chrome/browser/notifications/desktop_notification_service.h"
+#include "chrome/browser/notifications/desktop_notification_service_factory.h"
#include "chrome/browser/notifications/notification.h"
-#include "chrome/browser/ui/views/notifications/balloon_view_views.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/views/ash/balloon_view_ash.h"
#include "chrome/browser/ui/views/notifications/balloon_view_host.h"
+#include "chrome/browser/ui/views/notifications/balloon_view_views.h"
+
+namespace {
+
+bool IsAshNotifyEnabled() {
+ return CommandLine::ForCurrentProcess()->HasSwitch(ash::switches::kAshNotify);
+}
+
+} // namespace
BalloonCollectionImplAsh::BalloonCollectionImplAsh() {
+ if (IsAshNotifyEnabled()) {
+ ash::Shell::GetInstance()->status_area_widget()->
+ web_notification_tray()->SetDelegate(this);
+ }
}
BalloonCollectionImplAsh::~BalloonCollectionImplAsh() {
}
+bool BalloonCollectionImplAsh::HasSpace() const {
+ if (!IsAshNotifyEnabled())
+ return BalloonCollectionImpl::HasSpace();
+ return true; // Overflow is handled by ash::WebNotificationTray.
+}
+
+void BalloonCollectionImplAsh::Add(const Notification& notification,
+ Profile* profile) {
+ if (IsAshNotifyEnabled()) {
+ if (notification.is_html())
+ return; // HTML notifications are not supported in Ash.
+ if (notification.title().empty() && notification.body().empty())
+ return; // Empty notification, don't show.
+ }
+ return BalloonCollectionImpl::Add(notification, profile);
+}
+
+void BalloonCollectionImplAsh::DisableExtension(
+ const std::string& notifcation_id) {
+ Balloon* balloon = base().FindBalloonById(notifcation_id);
+ if (!balloon)
+ return;
+ ExtensionService* extension_service =
+ balloon->profile()->GetExtensionService();
+ const GURL& origin = balloon->notification().origin_url();
+ const extensions::Extension* extension =
+ extension_service->extensions()->GetExtensionOrAppByURL(
+ ExtensionURLInfo(origin));
+ if (!extension)
+ return;
+ extension_service->DisableExtension(
+ extension->id(), extensions::Extension::DISABLE_USER_ACTION);
+}
+
+void BalloonCollectionImplAsh::DisableNotificationsFromSource(
+ const std::string& notifcation_id) {
+ Balloon* balloon = base().FindBalloonById(notifcation_id);
+ if (!balloon)
+ return;
+ DesktopNotificationService* service =
+ DesktopNotificationServiceFactory::GetForProfile(balloon->profile());
+ service->DenyPermission(balloon->notification().origin_url());
+}
+
+void BalloonCollectionImplAsh::NotificationRemoved(
+ const std::string& notifcation_id) {
+ RemoveById(notifcation_id);
+}
+
+void BalloonCollectionImplAsh::ShowSettings(const std::string& notifcation_id) {
+ Balloon* balloon = base().FindBalloonById(notifcation_id);
+ Profile* profile =
+ balloon ? balloon->profile() : ProfileManager::GetDefaultProfile();
+ Browser* browser = browser::FindOrCreateTabbedBrowser(profile);
+ browser->ShowContentSettingsPage(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
+}
+
+void BalloonCollectionImplAsh::OnClicked(const std::string& notifcation_id) {
+ Balloon* balloon = base().FindBalloonById(notifcation_id);
+ if (!balloon)
+ return;
+ balloon->OnClick();
+}
+
bool BalloonCollectionImplAsh::AddWebUIMessageCallback(
const Notification& notification,
const std::string& message,
@@ -65,13 +151,18 @@ bool BalloonCollectionImplAsh::UpdateAndShowNotification(
Balloon* BalloonCollectionImplAsh::MakeBalloon(
const Notification& notification, Profile* profile) {
Balloon* balloon = new Balloon(notification, profile, this);
- ::BalloonViewImpl* balloon_view = new ::BalloonViewImpl(this);
- if (system_notifications_.find(notification.notification_id()) !=
- system_notifications_.end())
- balloon_view->set_enable_web_ui(true);
- balloon->set_view(balloon_view);
- gfx::Size size(layout().min_balloon_width(), layout().min_balloon_height());
- balloon->set_content_size(size);
+ if (!IsAshNotifyEnabled()) {
+ ::BalloonViewImpl* balloon_view = new ::BalloonViewImpl(this);
+ if (system_notifications_.find(notification.notification_id()) !=
+ system_notifications_.end())
+ balloon_view->set_enable_web_ui(true);
+ balloon->set_view(balloon_view);
+ gfx::Size size(layout().min_balloon_width(), layout().min_balloon_height());
+ balloon->set_content_size(size);
+ } else {
+ BalloonViewAsh* balloon_view = new BalloonViewAsh(this);
+ balloon->set_view(balloon_view);
+ }
return balloon;
}
diff --git a/chrome/browser/ui/views/ash/balloon_collection_impl_ash.h b/chrome/browser/ui/views/ash/balloon_collection_impl_ash.h
index d457d6d..e590ce1 100644
--- a/chrome/browser/ui/views/ash/balloon_collection_impl_ash.h
+++ b/chrome/browser/ui/views/ash/balloon_collection_impl_ash.h
@@ -8,16 +8,31 @@
#include <set>
+#include "ash/system/web_notification/web_notification_tray.h"
#include "chrome/browser/chromeos/notifications/balloon_view_host_chromeos.h" // MessageCallback
#include "chrome/browser/notifications/balloon_collection_impl.h"
// Wrapper on top of ::BalloonCollectionImpl to provide an interface for
// chromeos::SystemNotification.
-class BalloonCollectionImplAsh : public ::BalloonCollectionImpl {
+class BalloonCollectionImplAsh : public BalloonCollectionImpl,
+ public ash::WebNotificationTray::Delegate {
public:
BalloonCollectionImplAsh();
virtual ~BalloonCollectionImplAsh();
+ // Overridden from BalloonCollectionImpl.
+ virtual void Add(const Notification& notification,
+ Profile* profile) OVERRIDE;
+ virtual bool HasSpace() const OVERRIDE;
+
+ // Overridden from WebNotificationTray::Delegate.
+ virtual void NotificationRemoved(const std::string& notifcation_id) OVERRIDE;
+ virtual void DisableExtension(const std::string& notifcation_id) OVERRIDE;
+ virtual void DisableNotificationsFromSource(
+ const std::string& notifcation_id) OVERRIDE;
+ virtual void ShowSettings(const std::string& notifcation_id) OVERRIDE;
+ virtual void OnClicked(const std::string& notifcation_id) OVERRIDE;
+
// Adds a callback for WebUI message. Returns true if the callback
// is succssfully registered, or false otherwise. It fails to add if
// there is no notification that matches NotificationDelegate::id(),
diff --git a/chrome/browser/ui/views/ash/balloon_view_ash.cc b/chrome/browser/ui/views/ash/balloon_view_ash.cc
new file mode 100644
index 0000000..3b8b4be
--- /dev/null
+++ b/chrome/browser/ui/views/ash/balloon_view_ash.cc
@@ -0,0 +1,165 @@
+// Copyright (c) 2012 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/ui/views/ash/balloon_view_ash.h"
+
+#include "ash/shell.h"
+#include "ash/system/status_area_widget.h"
+#include "ash/system/web_notification/web_notification_tray.h"
+#include "base/logging.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/notifications/balloon_collection.h"
+#include "chrome/browser/notifications/notification.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/icon_messages.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/site_instance.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_delegate.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_message_macros.h"
+#include "ui/gfx/image/image_skia.h"
+#include "webkit/glue/image_resource_fetcher.h"
+
+namespace {
+
+const int kNotificationIconImageSize = 32;
+
+ash::WebNotificationTray* GetWebNotificationTray() {
+ return ash::Shell::GetInstance()->
+ status_area_widget()->web_notification_tray();
+}
+
+} // namespace
+
+class BalloonViewAsh::IconFetcher : public content::WebContentsObserver {
+ public:
+ IconFetcher(content::WebContents* web_contents,
+ const std::string& notification_id,
+ const GURL& icon_url)
+ : content::WebContentsObserver(web_contents),
+ request_id_(0),
+ notification_id_(notification_id),
+ icon_url_(icon_url) {
+ Observe(web_contents);
+ content::RenderViewHost* host = web_contents->GetRenderViewHost();
+ host->Send(new IconMsg_DownloadFavicon(host->GetRoutingID(),
+ ++request_id_,
+ icon_url,
+ kNotificationIconImageSize));
+ }
+
+ // content::WebContentsObserver override.
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
+ bool message_handled = false; // Allow other handlers to receive these.
+ IPC_BEGIN_MESSAGE_MAP(IconFetcher, message)
+ IPC_MESSAGE_HANDLER(IconHostMsg_DidDownloadFavicon, OnDidDownloadFavicon)
+ IPC_MESSAGE_UNHANDLED(message_handled = false)
+ IPC_END_MESSAGE_MAP()
+ return message_handled;
+ }
+
+ void OnDidDownloadFavicon(int id,
+ const GURL& image_url,
+ bool errored,
+ const SkBitmap& bitmap) {
+ if (image_url != icon_url_ || id != request_id_)
+ return;
+ GetWebNotificationTray()->SetNotificationImage(
+ notification_id_, gfx::ImageSkia(bitmap));
+ }
+
+ private:
+ int request_id_;
+ std::string notification_id_;
+ GURL icon_url_;
+
+ DISALLOW_COPY_AND_ASSIGN(IconFetcher);
+};
+
+BalloonViewAsh::BalloonViewAsh(BalloonCollection* collection)
+ : collection_(collection),
+ balloon_(NULL) {
+}
+
+BalloonViewAsh::~BalloonViewAsh() {
+}
+
+// BalloonView interface.
+void BalloonViewAsh::Show(Balloon* balloon) {
+ balloon_ = balloon;
+ const Notification& notification = balloon_->notification();
+ std::string extension_id = GetExtensionId(balloon);
+ GetWebNotificationTray()->AddNotification(notification.notification_id(),
+ notification.title(),
+ notification.body(),
+ notification.display_source(),
+ extension_id);
+ FetchIcon(notification);
+}
+
+void BalloonViewAsh::Update() {
+ const Notification& notification = balloon_->notification();
+ GetWebNotificationTray()->UpdateNotification(notification.notification_id(),
+ notification.title(),
+ notification.body());
+ FetchIcon(notification);
+}
+
+void BalloonViewAsh::RepositionToBalloon() {
+}
+
+void BalloonViewAsh::Close(bool by_user) {
+ Notification notification(balloon_->notification()); // Copy notification
+ collection_->OnBalloonClosed(balloon_); // Deletes balloon.
+ notification.Close(by_user);
+ GetWebNotificationTray()->RemoveNotification(notification.notification_id());
+}
+
+gfx::Size BalloonViewAsh::GetSize() const {
+ return gfx::Size();
+}
+
+BalloonHost* BalloonViewAsh::GetHost() const {
+ return NULL;
+}
+
+void BalloonViewAsh::FetchIcon(const Notification& notification) {
+ if (!notification.icon().empty()) {
+ ash::Shell::GetInstance()->status_area_widget()->
+ web_notification_tray()->SetNotificationImage(
+ notification.notification_id(), notification.icon());
+ return;
+ }
+ if (notification.icon_url().is_empty())
+ return;
+ content::RenderViewHost* rvh = notification.GetRenderViewHost();
+ if (!rvh) {
+ LOG(WARNING) << "Notification has icon url but no RenderViewHost";
+ return;
+ }
+ content::WebContents* web_contents =
+ content::WebContents::FromRenderViewHost(rvh);
+ if (!web_contents) {
+ LOG(WARNING) << "Notification has icon url but no WebContents";
+ return;
+ }
+ icon_fetcher_.reset(new IconFetcher(web_contents,
+ notification.notification_id(),
+ notification.icon_url()));
+}
+
+std::string BalloonViewAsh::GetExtensionId(Balloon* balloon) {
+ ExtensionService* extension_service =
+ balloon_->profile()->GetExtensionService();
+ const GURL& origin = balloon_->notification().origin_url();
+ const extensions::Extension* extension =
+ extension_service->extensions()->GetExtensionOrAppByURL(
+ ExtensionURLInfo(origin));
+ if (extension)
+ return extension->id();
+ return std::string();
+}
diff --git a/chrome/browser/ui/views/ash/balloon_view_ash.h b/chrome/browser/ui/views/ash/balloon_view_ash.h
new file mode 100644
index 0000000..2fe20f2
--- /dev/null
+++ b/chrome/browser/ui/views/ash/balloon_view_ash.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2012 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_UI_VIEWS_ASH_BALLOON_VIEW_ASH_H_
+#define CHROME_BROWSER_UI_VIEWS_ASH_BALLOON_VIEW_ASH_H_
+#pragma once
+
+#include "chrome/browser/notifications/balloon.h"
+
+// On Ash, a "BalloonView" is just a wrapper for ash notification entries.
+class BalloonViewAsh : public BalloonView {
+ public:
+ explicit BalloonViewAsh(BalloonCollection* collection);
+ virtual ~BalloonViewAsh();
+
+ // BalloonView interface.
+ virtual void Show(Balloon* balloon) OVERRIDE;
+ virtual void Update() OVERRIDE;
+ virtual void RepositionToBalloon() OVERRIDE;
+ virtual void Close(bool by_user) OVERRIDE;
+ virtual gfx::Size GetSize() const OVERRIDE;
+ virtual BalloonHost* GetHost() const OVERRIDE;
+
+ private:
+ class IconFetcher;
+
+ void FetchIcon(const Notification& notification);
+ std::string GetExtensionId(Balloon* balloon);
+
+ BalloonCollection* collection_;
+ Balloon* balloon_;
+ scoped_ptr<IconFetcher> icon_fetcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(BalloonViewAsh);
+};
+
+#endif // CHROME_BROWSER_UI_VIEWS_ASH_BALLOON_VIEW_ASH_H_
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index e39bd85..45588c4 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -3351,6 +3351,8 @@
'browser/ui/views/ash/app_list/search_builder.h',
'browser/ui/views/ash/balloon_collection_impl_ash.cc',
'browser/ui/views/ash/balloon_collection_impl_ash.h',
+ 'browser/ui/views/ash/balloon_view_ash.cc',
+ 'browser/ui/views/ash/balloon_view_ash.h',
'browser/ui/views/ash/brightness_controller_chromeos.cc',
'browser/ui/views/ash/brightness_controller_chromeos.h',
'browser/ui/views/ash/browser_non_client_frame_view_ash.h',