summaryrefslogtreecommitdiff
path: root/chromium/ui/message_center
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-01-29 16:35:13 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-02-01 15:33:35 +0000
commitc8c2d1901aec01e934adf561a9fdf0cc776cdef8 (patch)
tree9157c3d9815e5870799e070b113813bec53e0535 /chromium/ui/message_center
parentabefd5095b41dac94ca451d784ab6e27372e981a (diff)
downloadqtwebengine-chromium-c8c2d1901aec01e934adf561a9fdf0cc776cdef8.tar.gz
BASELINE: Update Chromium to 64.0.3282.139
Change-Id: I1cae68fe9c94ff7608b26b8382fc19862cdb293a Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/ui/message_center')
-rw-r--r--chromium/ui/message_center/BUILD.gn40
-rw-r--r--chromium/ui/message_center/change_queue.cc164
-rw-r--r--chromium/ui/message_center/change_queue.h73
-rw-r--r--chromium/ui/message_center/change_queue_unittest.cc133
-rw-r--r--chromium/ui/message_center/cocoa/notification_controller.mm3
-rw-r--r--chromium/ui/message_center/cocoa/notification_controller_unittest.mm16
-rw-r--r--chromium/ui/message_center/cocoa/popup_collection.mm10
-rw-r--r--chromium/ui/message_center/cocoa/popup_collection_unittest.mm8
-rw-r--r--chromium/ui/message_center/fake_message_center.cc39
-rw-r--r--chromium/ui/message_center/fake_message_center.h10
-rw-r--r--chromium/ui/message_center/fake_message_center_tray_delegate.cc44
-rw-r--r--chromium/ui/message_center/fake_message_center_tray_delegate.h43
-rw-r--r--chromium/ui/message_center/fake_ui_delegate.cc34
-rw-r--r--chromium/ui/message_center/fake_ui_delegate.h41
-rw-r--r--chromium/ui/message_center/message_center.h34
-rw-r--r--chromium/ui/message_center/message_center_impl.cc358
-rw-r--r--chromium/ui/message_center/message_center_impl.h52
-rw-r--r--chromium/ui/message_center/message_center_impl_unittest.cc164
-rw-r--r--chromium/ui/message_center/message_center_observer.h10
-rw-r--r--chromium/ui/message_center/message_center_tray.cc260
-rw-r--r--chromium/ui/message_center/message_center_tray_unittest.cc299
-rw-r--r--chromium/ui/message_center/mojo/BUILD.gn7
-rw-r--r--chromium/ui/message_center/mojo/DEPS1
-rw-r--r--chromium/ui/message_center/mojo/notification.mojom32
-rw-r--r--chromium/ui/message_center/mojo/notification.typemap8
-rw-r--r--chromium/ui/message_center/mojo/notification_struct_traits.cc141
-rw-r--r--chromium/ui/message_center/mojo/notification_struct_traits.h75
-rw-r--r--chromium/ui/message_center/mojo/notifier_id.mojom26
-rw-r--r--chromium/ui/message_center/mojo/notifier_id.typemap14
-rw-r--r--chromium/ui/message_center/mojo/notifier_id_struct_traits.cc47
-rw-r--r--chromium/ui/message_center/mojo/notifier_id_struct_traits.h71
-rw-r--r--chromium/ui/message_center/mojo/struct_traits_unittest.cc24
-rw-r--r--chromium/ui/message_center/mojo/typemaps.gni5
-rw-r--r--chromium/ui/message_center/notification.cc37
-rw-r--r--chromium/ui/message_center/notification.h53
-rw-r--r--chromium/ui/message_center/notification_delegate.cc18
-rw-r--r--chromium/ui/message_center/notification_delegate.h31
-rw-r--r--chromium/ui/message_center/notification_delegate_unittest.cc4
-rw-r--r--chromium/ui/message_center/notification_delegate_views.cc17
-rw-r--r--chromium/ui/message_center/notification_list.cc24
-rw-r--r--chromium/ui/message_center/notification_list.h9
-rw-r--r--chromium/ui/message_center/notification_list_unittest.cc47
-rw-r--r--chromium/ui/message_center/notifier_id.cc (renamed from chromium/ui/message_center/notifier_settings.cc)35
-rw-r--r--chromium/ui/message_center/notifier_id.h65
-rw-r--r--chromium/ui/message_center/notifier_settings.h208
-rw-r--r--chromium/ui/message_center/popup_timers_controller.cc16
-rw-r--r--chromium/ui/message_center/public/cpp/message_center_constants.h20
-rw-r--r--chromium/ui/message_center/ui_controller.cc201
-rw-r--r--chromium/ui/message_center/ui_controller.h (renamed from chromium/ui/message_center/message_center_tray.h)52
-rw-r--r--chromium/ui/message_center/ui_controller_unittest.cc251
-rw-r--r--chromium/ui/message_center/ui_delegate.h (renamed from chromium/ui/message_center/message_center_tray_delegate.h)25
-rw-r--r--chromium/ui/message_center/views/bounded_label.cc13
-rw-r--r--chromium/ui/message_center/views/bounded_label.h3
-rw-r--r--chromium/ui/message_center/views/desktop_popup_alignment_delegate.cc9
-rw-r--r--chromium/ui/message_center/views/message_popup_collection.cc35
-rw-r--r--chromium/ui/message_center/views/message_popup_collection.h18
-rw-r--r--chromium/ui/message_center/views/message_popup_collection_unittest.cc4
-rw-r--r--chromium/ui/message_center/views/message_view.cc46
-rw-r--r--chromium/ui/message_center/views/message_view.h23
-rw-r--r--chromium/ui/message_center/views/message_view_context_menu_controller.cc13
-rw-r--r--chromium/ui/message_center/views/message_view_context_menu_controller.h6
-rw-r--r--chromium/ui/message_center/views/message_view_delegate.h (renamed from chromium/ui/message_center/views/message_center_controller.h)19
-rw-r--r--chromium/ui/message_center/views/message_view_factory.cc27
-rw-r--r--chromium/ui/message_center/views/message_view_factory.h26
-rw-r--r--chromium/ui/message_center/views/notification_header_view.cc14
-rw-r--r--chromium/ui/message_center/views/notification_menu_model.cc69
-rw-r--r--chromium/ui/message_center/views/notification_menu_model.h35
-rw-r--r--chromium/ui/message_center/views/notification_menu_model_unittest.cc113
-rw-r--r--chromium/ui/message_center/views/notification_view.cc18
-rw-r--r--chromium/ui/message_center/views/notification_view.h2
-rw-r--r--chromium/ui/message_center/views/notification_view_md.cc198
-rw-r--r--chromium/ui/message_center/views/notification_view_md.h58
-rw-r--r--chromium/ui/message_center/views/notification_view_md_unittest.cc131
-rw-r--r--chromium/ui/message_center/views/notification_view_unittest.cc69
-rw-r--r--chromium/ui/message_center/views/toast_contents_view.cc24
-rw-r--r--chromium/ui/message_center/views/toast_contents_view.h14
76 files changed, 2716 insertions, 1670 deletions
diff --git a/chromium/ui/message_center/BUILD.gn b/chromium/ui/message_center/BUILD.gn
index b42aef2955c..d0faf6f4d20 100644
--- a/chromium/ui/message_center/BUILD.gn
+++ b/chromium/ui/message_center/BUILD.gn
@@ -57,6 +57,8 @@ component("message_center") {
"//build/config/compiler:no_size_t_to_int_warning",
]
sources = [
+ "change_queue.cc",
+ "change_queue.h",
"cocoa/notification_controller.h",
"cocoa/notification_controller.mm",
"cocoa/opaque_views.h",
@@ -73,9 +75,6 @@ component("message_center") {
"message_center_observer.h",
"message_center_style.cc",
"message_center_style.h",
- "message_center_tray.cc",
- "message_center_tray.h",
- "message_center_tray_delegate.h",
"message_center_types.h",
"notification.cc",
"notification.h",
@@ -87,12 +86,15 @@ component("message_center") {
"notification_list.h",
"notification_types.cc",
"notification_types.h",
- "notifier_settings.cc",
- "notifier_settings.h",
+ "notifier_id.cc",
+ "notifier_id.h",
"popup_timer.cc",
"popup_timer.h",
"popup_timers_controller.cc",
"popup_timers_controller.h",
+ "ui_controller.cc",
+ "ui_controller.h",
+ "ui_delegate.h",
]
sources += get_target_outputs(":message_center_vector_icons")
@@ -115,19 +117,18 @@ component("message_center") {
# with message_center_unittests below.
if (toolkit_views && !is_mac) {
sources += [
- "notification_delegate_views.cc",
"views/bounded_label.cc",
"views/bounded_label.h",
"views/constants.h",
"views/desktop_popup_alignment_delegate.cc",
"views/desktop_popup_alignment_delegate.h",
- "views/message_center_controller.h",
"views/message_popup_collection.cc",
"views/message_popup_collection.h",
"views/message_view.cc",
"views/message_view.h",
"views/message_view_context_menu_controller.cc",
"views/message_view_context_menu_controller.h",
+ "views/message_view_delegate.h",
"views/message_view_factory.cc",
"views/message_view_factory.h",
"views/notification_button.cc",
@@ -136,6 +137,8 @@ component("message_center") {
"views/notification_control_buttons_view.h",
"views/notification_header_view.cc",
"views/notification_header_view.h",
+ "views/notification_menu_model.cc",
+ "views/notification_menu_model.h",
"views/notification_view.cc",
"views/notification_view.h",
"views/notification_view_md.cc",
@@ -172,8 +175,8 @@ component("message_center") {
sources += [
"notification.cc",
"notification.h",
- "notifier_settings.cc",
- "notifier_settings.h",
+ "notifier_id.cc",
+ "notifier_id.h",
]
}
}
@@ -186,8 +189,8 @@ if (enable_message_center) {
sources = [
"fake_message_center.cc",
"fake_message_center.h",
- "fake_message_center_tray_delegate.cc",
- "fake_message_center_tray_delegate.h",
+ "fake_ui_delegate.cc",
+ "fake_ui_delegate.h",
]
deps = [
@@ -205,15 +208,15 @@ if (enable_message_center) {
test("message_center_unittests") {
sources = [
+ "change_queue_unittest.cc",
"cocoa/notification_controller_unittest.mm",
"cocoa/popup_collection_unittest.mm",
"cocoa/popup_controller_unittest.mm",
"message_center_impl_unittest.cc",
- "message_center_tray_unittest.cc",
- "mojo/struct_traits_unittest.cc",
"notification_delegate_unittest.cc",
"notification_list_unittest.cc",
"test/run_all_unittests.cc",
+ "ui_controller_unittest.cc",
]
deps = [
@@ -221,7 +224,6 @@ if (enable_message_center) {
":test_support",
"//base",
"//base/test:test_support",
- "//mojo/edk/system",
"//skia",
"//testing/gmock",
"//testing/gtest",
@@ -234,7 +236,6 @@ if (enable_message_center) {
"//ui/gfx/geometry",
"//ui/gl",
"//ui/gl:test_support",
- "//ui/message_center/mojo:test_interfaces",
"//ui/message_center/public/cpp",
"//ui/resources",
"//ui/resources:ui_test_pak",
@@ -246,6 +247,14 @@ if (enable_message_center) {
"//ui/resources:ui_test_pak_data",
]
+ if (is_chromeos) {
+ sources += [ "mojo/struct_traits_unittest.cc" ]
+ deps += [
+ "//mojo/edk/system",
+ "//ui/message_center/mojo:test_interfaces",
+ ]
+ }
+
if (is_mac) {
deps += [ "//ui/gfx:test_support" ]
}
@@ -254,6 +263,7 @@ if (enable_message_center) {
sources += [
"views/bounded_label_unittest.cc",
"views/message_popup_collection_unittest.cc",
+ "views/notification_menu_model_unittest.cc",
"views/notification_view_md_unittest.cc",
"views/notification_view_unittest.cc",
]
diff --git a/chromium/ui/message_center/change_queue.cc b/chromium/ui/message_center/change_queue.cc
new file mode 100644
index 00000000000..a61dcd2989e
--- /dev/null
+++ b/chromium/ui/message_center/change_queue.cc
@@ -0,0 +1,164 @@
+// Copyright 2017 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 "ui/message_center/change_queue.h"
+
+#include "ui/message_center/message_center_impl.h"
+#include "ui/message_center/notification.h"
+
+namespace message_center {
+
+// Change represents an operation made on a notification. Since it contains
+// the final state of the notification, except complex cases, we generally
+// optimize the list and keep only the last change for a particular notification
+// that is in the notification list around. There are two ids; |id_| is the
+// post-update notification id that has been assigned by an update, and
+// |previous_id| is the previous id of the notification before the Change.
+// The two ids are same unless the Change changes the id of the notification.
+// See the comments of id() and previous_id() for reference.
+class ChangeQueue::Change {
+ public:
+ Change(ChangeType type,
+ const std::string& id,
+ std::unique_ptr<Notification> notification);
+ ~Change();
+
+ // Used to transfer ownership of the contained notification.
+ std::unique_ptr<Notification> PassNotification();
+
+ Notification* notification() const { return notification_.get(); }
+ // Returns the post-update ID. It means:
+ // - ADD event: ID of the notification to be added. In this case, this must be
+ // same as |previous_id()|.
+ // - UPDATE event: ID of the notification after the change. If the change
+ // doesn't update its ID, this value is same as |previous_id()|.
+ // - DELETE event: ID of the notification to be deleted. This must be same as
+ // |previous_id()|.
+ const std::string& id() const { return id_; }
+ ChangeType type() const { return type_; }
+ bool by_user() const { return by_user_; }
+ void set_by_user(bool by_user) { by_user_ = by_user; }
+ // Returns the ID which is used in the notification list. In other word, it
+ // means the ID before the change.
+ const std::string& previous_id() const { return previous_id_; }
+ void set_type(const ChangeType new_type) { type_ = new_type; }
+ void ReplaceNotification(std::unique_ptr<Notification> new_notification);
+
+ private:
+ ChangeType type_;
+ std::string id_;
+ std::string previous_id_;
+ bool by_user_;
+ std::unique_ptr<Notification> notification_;
+
+ DISALLOW_COPY_AND_ASSIGN(Change);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// ChangeFinder
+
+struct ChangeFinder {
+ explicit ChangeFinder(const std::string& id) : id(id) {}
+ bool operator()(const std::unique_ptr<ChangeQueue::Change>& change) {
+ return change->id() == id;
+ }
+
+ std::string id;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// ChangeQueue::Change
+
+ChangeQueue::Change::Change(ChangeType type,
+ const std::string& id,
+ std::unique_ptr<Notification> notification)
+ : type_(type),
+ previous_id_(id),
+ by_user_(false),
+ notification_(std::move(notification)) {
+ DCHECK(!id.empty());
+ DCHECK(type != CHANGE_TYPE_DELETE || !notification_);
+
+ id_ = notification_ ? notification_->id() : previous_id_;
+}
+
+ChangeQueue::Change::~Change() {}
+
+std::unique_ptr<Notification> ChangeQueue::Change::PassNotification() {
+ return std::move(notification_);
+}
+
+void ChangeQueue::Change::ReplaceNotification(
+ std::unique_ptr<Notification> new_notification) {
+ id_ = new_notification ? new_notification->id() : previous_id_;
+ notification_.swap(new_notification);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ChangeQueue
+
+ChangeQueue::ChangeQueue() = default;
+
+ChangeQueue::~ChangeQueue() = default;
+
+void ChangeQueue::ApplyChanges(MessageCenterImpl* message_center) {
+ while (!changes_.empty()) {
+ auto iter = changes_.begin();
+ std::unique_ptr<Change> change(std::move(*iter));
+ changes_.erase(iter);
+ ApplyChangeInternal(message_center, std::move(change));
+ }
+}
+
+void ChangeQueue::AddNotification(std::unique_ptr<Notification> notification) {
+ std::string id = notification->id();
+ changes_.push_back(
+ std::make_unique<Change>(CHANGE_TYPE_ADD, id, std::move(notification)));
+}
+
+void ChangeQueue::UpdateNotification(
+ const std::string& old_id,
+ std::unique_ptr<Notification> notification) {
+ changes_.push_back(std::make_unique<Change>(CHANGE_TYPE_UPDATE, old_id,
+ std::move(notification)));
+}
+
+void ChangeQueue::RemoveNotification(const std::string& id, bool by_user) {
+ auto change = std::make_unique<Change>(CHANGE_TYPE_DELETE, id, nullptr);
+ change->set_by_user(by_user);
+ changes_.push_back(std::move(change));
+}
+
+Notification* ChangeQueue::GetLatestNotification(const std::string& id) const {
+ auto iter =
+ std::find_if(changes_.rbegin(), changes_.rend(), ChangeFinder(id));
+ if (iter == changes_.rend())
+ return nullptr;
+
+ if ((*iter)->type() == CHANGE_TYPE_DELETE)
+ return nullptr;
+
+ return (*iter)->notification();
+}
+
+void ChangeQueue::ApplyChangeInternal(MessageCenterImpl* message_center,
+ std::unique_ptr<Change> change) {
+ switch (change->type()) {
+ case CHANGE_TYPE_ADD:
+ message_center->AddNotificationImmediately(change->PassNotification());
+ break;
+ case CHANGE_TYPE_UPDATE:
+ message_center->UpdateNotificationImmediately(change->previous_id(),
+ change->PassNotification());
+ break;
+ case CHANGE_TYPE_DELETE:
+ message_center->RemoveNotificationImmediately(change->previous_id(),
+ change->by_user());
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+} // namespace message_center
diff --git a/chromium/ui/message_center/change_queue.h b/chromium/ui/message_center/change_queue.h
new file mode 100644
index 00000000000..b2c9d287c6b
--- /dev/null
+++ b/chromium/ui/message_center/change_queue.h
@@ -0,0 +1,73 @@
+// Copyright 2017 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 UI_MESSAGE_CENTER_CHANGE_QUEUE_H_
+#define UI_MESSAGE_CENTER_CHANGE_QUEUE_H_
+
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "ui/message_center/message_center_export.h"
+
+namespace message_center {
+
+class MessageCenterImpl;
+class Notification;
+
+// ChangeQueue keeps track of all the changes. This class can be used for
+// queuing changes during the message center can't be updated.
+class MESSAGE_CENTER_EXPORT ChangeQueue {
+ public:
+ enum ChangeType {
+ CHANGE_TYPE_ADD = 0,
+ CHANGE_TYPE_UPDATE,
+ CHANGE_TYPE_DELETE
+ };
+
+ // Change represents an operation made on a notification. Since it contains
+ // the final state of the notification, we only keep the last change for a
+ // particular notification that is in the notification list around. There are
+ // two ids; |id_| is the newest notification id that has been assigned by an
+ // update, and |notification_list_id_| is the id of the notification it should
+ // be updating as it exists in the notification list.
+ class Change;
+
+ ChangeQueue();
+ ~ChangeQueue();
+
+ // Called when the message center has appropriate visibility. Modifies
+ // |message_center| but does not retain it. This also causes the queue to
+ // empty itself.
+ void ApplyChanges(MessageCenterImpl* message_center);
+
+ // Causes a TYPE_ADD change to be added to the queue.
+ void AddNotification(std::unique_ptr<Notification> notification);
+
+ // Causes a TYPE_UPDATE change to be added to the queue.
+ void UpdateNotification(const std::string& old_id,
+ std::unique_ptr<Notification> notification);
+
+ // Causes a TYPE_DELETE change to be added to the queue.
+ void RemoveNotification(const std::string& id, bool by_user);
+
+ // Returns the pointer to the Notification in the latest Change which has the
+ // given ID. If the Change is UPDATE, the ID after the change is searched.
+ // If the Change id REMOVE, this returns nullptr.
+ // ChangeQueue keeps retaining ownership of the Notification. The returned
+ // notification can be modified or be copied by caller.
+ Notification* GetLatestNotification(const std::string& id) const;
+
+ private:
+ void ApplyChangeInternal(MessageCenterImpl* message_center,
+ std::unique_ptr<Change> change);
+
+ std::vector<std::unique_ptr<Change>> changes_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChangeQueue);
+};
+
+} // namespace message_center
+
+#endif // UI_MESSAGE_CENTER_CHANGE_QUEUE_H_
diff --git a/chromium/ui/message_center/change_queue_unittest.cc b/chromium/ui/message_center/change_queue_unittest.cc
new file mode 100644
index 00000000000..bf475f2d052
--- /dev/null
+++ b/chromium/ui/message_center/change_queue_unittest.cc
@@ -0,0 +1,133 @@
+// Copyright 2017 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 "ui/message_center/change_queue.h"
+
+#include <utility>
+
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/message_center/message_center_impl.h"
+
+using base::UTF8ToUTF16;
+
+namespace message_center {
+
+namespace {
+
+Notification* CreateSimpleNotification(const std::string& id) {
+ RichNotificationData optional_fields;
+ optional_fields.buttons.push_back(ButtonInfo(UTF8ToUTF16("foo")));
+ optional_fields.buttons.push_back(ButtonInfo(UTF8ToUTF16("foo")));
+ return new Notification(
+ NOTIFICATION_TYPE_SIMPLE, id, UTF8ToUTF16("title"), UTF8ToUTF16(id),
+ gfx::Image() /* icon */, base::string16() /* display_source */, GURL(),
+ NotifierId(NotifierId::APPLICATION, "change_queue_test"), optional_fields,
+ NULL);
+}
+
+} // namespace
+
+class ChangeQueueTest : public testing::Test {
+ public:
+ ChangeQueueTest() = default;
+ ~ChangeQueueTest() override = default;
+
+ MessageCenterImpl* message_center() { return &message_center_; }
+
+ private:
+ MessageCenterImpl message_center_;
+};
+
+TEST_F(ChangeQueueTest, Queueing) {
+ ChangeQueue queue;
+ std::string id("id1");
+ std::string id2("id2");
+ NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
+
+ // First, add and update a notification to ensure updates happen
+ // normally.
+ std::unique_ptr<Notification> notification(CreateSimpleNotification(id));
+ message_center()->AddNotification(std::move(notification));
+ notification.reset(CreateSimpleNotification(id2));
+ message_center()->UpdateNotification(id, std::move(notification));
+ EXPECT_TRUE(message_center()->FindVisibleNotificationById(id2));
+ EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
+
+ // Then update a notification; nothing should have happened.
+ notification.reset(CreateSimpleNotification(id));
+ queue.UpdateNotification(id2, std::move(notification));
+ EXPECT_TRUE(message_center()->FindVisibleNotificationById(id2));
+ EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
+
+ // Apply the changes from the queue.
+ queue.ApplyChanges(message_center());
+
+ // Close the message center; then the update should have propagated.
+ EXPECT_FALSE(message_center()->FindVisibleNotificationById(id2));
+ EXPECT_TRUE(message_center()->FindVisibleNotificationById(id));
+}
+
+TEST_F(ChangeQueueTest, SimpleQueueing) {
+ ChangeQueue queue;
+ std::string ids[6] = {"0", "1", "2", "3", "4", "5"};
+ NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
+
+ std::unique_ptr<Notification> notification;
+ // Prepare initial notifications on NotificationList.
+ // NL: ["0", "1", "2", "4"]
+ int i = 0;
+ for (; i < 3; i++) {
+ notification.reset(CreateSimpleNotification(ids[i]));
+ message_center()->AddNotification(std::move(notification));
+ }
+ for (i = 0; i < 3; i++) {
+ EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[i]));
+ }
+ for (; i < 6; i++) {
+ EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[i]));
+ }
+
+ // This should update notification "1" to have id "4".
+ notification.reset(CreateSimpleNotification(ids[4]));
+ queue.AddNotification(std::move(notification));
+
+ // Change the ID: "2" -> "5", "5" -> "3".
+ notification.reset(CreateSimpleNotification(ids[5]));
+ queue.UpdateNotification(ids[2], std::move(notification));
+ notification.reset(CreateSimpleNotification(ids[3]));
+ queue.UpdateNotification(ids[5], std::move(notification));
+
+ // This should update notification "4" to "5".
+ notification.reset(CreateSimpleNotification(ids[5]));
+ queue.UpdateNotification(ids[4], std::move(notification));
+
+ // This should create a new "4", that doesn't overwrite the update from 4
+ // before.
+ notification.reset(CreateSimpleNotification(ids[4]));
+ queue.AddNotification(std::move(notification));
+
+ // The NL should still be the same: ["0", "1", "2", "4"]
+ EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[0]));
+ EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[1]));
+ EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[2]));
+ EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[3]));
+ EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[4]));
+ EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[5]));
+ EXPECT_EQ(message_center()->GetVisibleNotifications().size(), 3u);
+
+ // Apply the changes from the queue.
+ queue.ApplyChanges(message_center());
+
+ // Changes should be applied.
+ EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[0]));
+ EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[1]));
+ EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[2]));
+ EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[3]));
+ EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[4]));
+ EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[5]));
+ EXPECT_EQ(message_center()->GetVisibleNotifications().size(), 5u);
+}
+
+} // namespace message_center
diff --git a/chromium/ui/message_center/cocoa/notification_controller.mm b/chromium/ui/message_center/cocoa/notification_controller.mm
index 580f72215a1..1b9ff3e657e 100644
--- a/chromium/ui/message_center/cocoa/notification_controller.mm
+++ b/chromium/ui/message_center/cocoa/notification_controller.mm
@@ -340,8 +340,7 @@
[rootView addSubview:[self createSmallImageInFrame:rootFrame]];
// Create the settings button.
- if (notification_->delegate() &&
- notification_->delegate()->ShouldDisplaySettingsButton()) {
+ if (notification_->should_show_settings_button()) {
[self configureSettingsButtonInFrame:rootFrame];
[rootView addSubview:settingsButton_];
}
diff --git a/chromium/ui/message_center/cocoa/notification_controller_unittest.mm b/chromium/ui/message_center/cocoa/notification_controller_unittest.mm
index 0d3c73378db..5b385a5ef00 100644
--- a/chromium/ui/message_center/cocoa/notification_controller_unittest.mm
+++ b/chromium/ui/message_center/cocoa/notification_controller_unittest.mm
@@ -24,16 +24,6 @@ using base::UTF8ToUTF16;
namespace {
-// A test delegate used for tests that deal with the notification settings
-// button.
-class NotificationSettingsDelegate
- : public message_center::NotificationDelegate {
- bool ShouldDisplaySettingsButton() override { return true; }
-
- private:
- ~NotificationSettingsDelegate() override {}
-};
-
class MockMessageCenter : public message_center::FakeMessageCenter {
public:
MockMessageCenter()
@@ -157,14 +147,14 @@ TEST_F(NotificationControllerTest, BasicLayout) {
}
TEST_F(NotificationControllerTest, NotificationSetttingsButtonLayout) {
+ message_center::RichNotificationData data;
+ data.settings_button_handler = SettingsButtonHandler::TRAY;
std::unique_ptr<message_center::Notification> notification(
new message_center::Notification(
message_center::NOTIFICATION_TYPE_SIMPLE, "",
ASCIIToUTF16("Added to circles"),
ASCIIToUTF16("Jonathan and 5 others"), gfx::Image(), base::string16(),
- GURL("https://plus.com"), DummyNotifierId(),
- message_center::RichNotificationData(),
- new NotificationSettingsDelegate()));
+ GURL("https://plus.com"), DummyNotifierId(), data, NULL));
base::scoped_nsobject<MCNotificationController> controller(
[[MCNotificationController alloc] initWithNotification:notification.get()
diff --git a/chromium/ui/message_center/cocoa/popup_collection.mm b/chromium/ui/message_center/cocoa/popup_collection.mm
index d13a1bab6f9..b4df87a8a11 100644
--- a/chromium/ui/message_center/cocoa/popup_collection.mm
+++ b/chromium/ui/message_center/cocoa/popup_collection.mm
@@ -167,8 +167,8 @@ class PopupCollectionObserver : public message_center::MessageCenterObserver {
NSRect screenFrame = [self screenFrame];
NSRect popupFrame = [popup bounds];
- CGFloat x = NSMaxX(screenFrame) - message_center::kMarginBetweenItems -
- NSWidth(popupFrame);
+ CGFloat x = NSMaxX(screenFrame) - message_center::kMarginBetweenPopups -
+ NSWidth(popupFrame);
CGFloat y = 0;
MCPopupController* bottomPopup = [popups_ lastObject];
@@ -178,7 +178,7 @@ class PopupCollectionObserver : public message_center::MessageCenterObserver {
y = NSMinY([bottomPopup bounds]);
}
- y -= message_center::kMarginBetweenItems + NSHeight(popupFrame);
+ y -= message_center::kMarginBetweenPopups + NSHeight(popupFrame);
if (y > NSMinY(screenFrame)) {
animatingNotificationIDs_.insert(notification->id());
@@ -264,8 +264,8 @@ class PopupCollectionObserver : public message_center::MessageCenterObserver {
MCPopupController* popup = [popups_ objectAtIndex:i];
NSRect oldFrame = [popup bounds];
NSRect frame = oldFrame;
- frame.origin.y = maxY - message_center::kMarginBetweenItems -
- NSHeight(frame);
+ frame.origin.y =
+ maxY - message_center::kMarginBetweenPopups - NSHeight(frame);
// If this popup does not fit on screen, stop repositioning and close this
// and subsequent popups.
diff --git a/chromium/ui/message_center/cocoa/popup_collection_unittest.mm b/chromium/ui/message_center/cocoa/popup_collection_unittest.mm
index 3a7201fdb5b..b1e645240f5 100644
--- a/chromium/ui/message_center/cocoa/popup_collection_unittest.mm
+++ b/chromium/ui/message_center/cocoa/popup_collection_unittest.mm
@@ -85,8 +85,8 @@ class PopupCollectionTest : public ui::CocoaTest {
CGFloat minY = NSMinY([[upper window] frame]);
CGFloat maxY = NSMaxY([[lower window] frame]);
CGFloat delta = minY - maxY;
- EXPECT_EQ(message_center::kMarginBetweenItems, delta);
- return delta == message_center::kMarginBetweenItems;
+ EXPECT_EQ(message_center::kMarginBetweenPopups, delta);
+ return delta == message_center::kMarginBetweenPopups;
}
void WaitForAnimationEnded() {
@@ -154,7 +154,7 @@ TEST_F(PopupCollectionTest, LayoutSpacing) {
AddThreeNotifications();
NSArray* popups = [collection_ popups];
- EXPECT_EQ(message_center::kMarginBetweenItems,
+ EXPECT_EQ(message_center::kMarginBetweenPopups,
kScreenSize - NSMaxY([[[popups objectAtIndex:0] window] frame]));
EXPECT_TRUE(CheckSpacingBetween([popups objectAtIndex:0],
@@ -186,7 +186,7 @@ TEST_F(PopupCollectionTest, LayoutSpacing) {
// Remove "1".
center_->RemoveNotification("2", true);
WaitForAnimationEnded();
- EXPECT_EQ(message_center::kMarginBetweenItems,
+ EXPECT_EQ(message_center::kMarginBetweenPopups,
kScreenSize - NSMaxY([[[popups objectAtIndex:0] window] frame]));
EXPECT_TRUE(CheckSpacingBetween([popups objectAtIndex:0],
[popups objectAtIndex:1]));
diff --git a/chromium/ui/message_center/fake_message_center.cc b/chromium/ui/message_center/fake_message_center.cc
index 8adac41d1bd..0d507fc5d25 100644
--- a/chromium/ui/message_center/fake_message_center.cc
+++ b/chromium/ui/message_center/fake_message_center.cc
@@ -31,10 +31,6 @@ size_t FakeMessageCenter::NotificationCount() const {
return 0u;
}
-size_t FakeMessageCenter::UnreadNotificationCount() const {
- return 0u;
-}
-
bool FakeMessageCenter::HasPopupNotifications() const {
return false;
}
@@ -43,14 +39,6 @@ bool FakeMessageCenter::IsQuietMode() const {
return false;
}
-bool FakeMessageCenter::IsLockedState() const {
- return false;
-}
-
-bool FakeMessageCenter::HasClickedListener(const std::string& id) {
- return false;
-}
-
message_center::Notification* FakeMessageCenter::FindVisibleNotificationById(
const std::string& id) {
for (auto* notification : GetVisibleNotifications()) {
@@ -81,6 +69,9 @@ void FakeMessageCenter::RemoveNotification(const std::string& id,
bool by_user) {
}
+void FakeMessageCenter::RemoveNotificationsForNotifierId(
+ const NotifierId& notifier_id) {}
+
void FakeMessageCenter::RemoveAllNotifications(bool by_user, RemoveType type) {}
void FakeMessageCenter::SetNotificationIcon(const std::string& notification_id,
@@ -104,29 +95,21 @@ void FakeMessageCenter::ClickOnNotificationButton(const std::string& id,
int button_index) {
}
+void FakeMessageCenter::ClickOnNotificationButtonWithReply(
+ const std::string& id,
+ int button_index,
+ const base::string16& reply) {}
+
void FakeMessageCenter::ClickOnSettingsButton(const std::string& id) {}
void FakeMessageCenter::MarkSinglePopupAsShown(const std::string& id,
bool mark_notification_as_read) {
}
-void FakeMessageCenter::DisplayedNotification(
- const std::string& id,
- const DisplaySource source) {
-}
-
-void FakeMessageCenter::SetNotifierSettingsProvider(
- NotifierSettingsProvider* provider) {
-}
-
-NotifierSettingsProvider* FakeMessageCenter::GetNotifierSettingsProvider() {
- return NULL;
-}
-
-void FakeMessageCenter::SetQuietMode(bool in_quiet_mode) {
-}
+void FakeMessageCenter::DisplayedNotification(const std::string& id,
+ const DisplaySource source) {}
-void FakeMessageCenter::SetLockedState(bool locked) {}
+void FakeMessageCenter::SetQuietMode(bool in_quiet_mode) {}
void FakeMessageCenter::EnterQuietModeWithExpire(
const base::TimeDelta& expires_in) {
diff --git a/chromium/ui/message_center/fake_message_center.h b/chromium/ui/message_center/fake_message_center.h
index c1c789b62a4..2a89a1e321f 100644
--- a/chromium/ui/message_center/fake_message_center.h
+++ b/chromium/ui/message_center/fake_message_center.h
@@ -25,11 +25,8 @@ class FakeMessageCenter : public MessageCenter {
void AddNotificationBlocker(NotificationBlocker* blocker) override;
void RemoveNotificationBlocker(NotificationBlocker* blocker) override;
size_t NotificationCount() const override;
- size_t UnreadNotificationCount() const override;
bool HasPopupNotifications() const override;
bool IsQuietMode() const override;
- bool IsLockedState() const override;
- bool HasClickedListener(const std::string& id) override;
message_center::Notification* FindVisibleNotificationById(
const std::string& id) override;
const NotificationList::Notifications& GetVisibleNotifications() override;
@@ -40,6 +37,7 @@ class FakeMessageCenter : public MessageCenter {
std::unique_ptr<Notification> new_notification) override;
void RemoveNotification(const std::string& id, bool by_user) override;
+ void RemoveNotificationsForNotifierId(const NotifierId& notifier_id) override;
void RemoveAllNotifications(bool by_user, RemoveType type) override;
void SetNotificationIcon(const std::string& notification_id,
const gfx::Image& image) override;
@@ -53,15 +51,15 @@ class FakeMessageCenter : public MessageCenter {
void ClickOnNotification(const std::string& id) override;
void ClickOnNotificationButton(const std::string& id,
int button_index) override;
+ void ClickOnNotificationButtonWithReply(const std::string& id,
+ int button_index,
+ const base::string16& reply) override;
void ClickOnSettingsButton(const std::string& id) override;
void MarkSinglePopupAsShown(const std::string& id,
bool mark_notification_as_read) override;
void DisplayedNotification(const std::string& id,
const DisplaySource source) override;
- void SetNotifierSettingsProvider(NotifierSettingsProvider* provider) override;
- NotifierSettingsProvider* GetNotifierSettingsProvider() override;
void SetQuietMode(bool in_quiet_mode) override;
- void SetLockedState(bool locked) override;
void EnterQuietModeWithExpire(const base::TimeDelta& expires_in) override;
void SetVisibility(Visibility visible) override;
bool IsMessageCenterVisible() const override;
diff --git a/chromium/ui/message_center/fake_message_center_tray_delegate.cc b/chromium/ui/message_center/fake_message_center_tray_delegate.cc
deleted file mode 100644
index 748385425fd..00000000000
--- a/chromium/ui/message_center/fake_message_center_tray_delegate.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2014 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 "ui/message_center/fake_message_center_tray_delegate.h"
-
-#include "base/message_loop/message_loop.h"
-#include "ui/message_center/message_center_tray.h"
-
-namespace message_center {
-
-FakeMessageCenterTrayDelegate::FakeMessageCenterTrayDelegate(
- MessageCenter* message_center)
- : tray_(new MessageCenterTray(this, message_center)) {}
-
-FakeMessageCenterTrayDelegate::~FakeMessageCenterTrayDelegate() {
-}
-
-void FakeMessageCenterTrayDelegate::OnMessageCenterTrayChanged() {
-}
-
-bool FakeMessageCenterTrayDelegate::ShowPopups() {
- return false;
-}
-
-void FakeMessageCenterTrayDelegate::HidePopups() {
-}
-
-bool FakeMessageCenterTrayDelegate::ShowMessageCenter(bool show_by_click) {
- return false;
-}
-
-void FakeMessageCenterTrayDelegate::HideMessageCenter() {
-}
-
-bool FakeMessageCenterTrayDelegate::ShowNotifierSettings() {
- return false;
-}
-
-MessageCenterTray* FakeMessageCenterTrayDelegate::GetMessageCenterTray() {
- return tray_.get();
-}
-
-} // namespace message_center
diff --git a/chromium/ui/message_center/fake_message_center_tray_delegate.h b/chromium/ui/message_center/fake_message_center_tray_delegate.h
deleted file mode 100644
index 2a7917db3f9..00000000000
--- a/chromium/ui/message_center/fake_message_center_tray_delegate.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2014 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 UI_MESSAGE_CENTER_FAKE_MESSAGE_CENTER_TRAY_DELEGATE_H_
-#define UI_MESSAGE_CENTER_FAKE_MESSAGE_CENTER_TRAY_DELEGATE_H_
-
-#include <memory>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "ui/message_center/message_center_tray_delegate.h"
-
-namespace message_center {
-
-class MessageCenter;
-class MessageCenterTray;
-
-// A message center tray delegate which does nothing.
-class FakeMessageCenterTrayDelegate : public MessageCenterTrayDelegate {
- public:
- explicit FakeMessageCenterTrayDelegate(MessageCenter* message_center);
- ~FakeMessageCenterTrayDelegate() override;
-
- // Overridden from MessageCenterTrayDelegate:
- void OnMessageCenterTrayChanged() override;
- bool ShowPopups() override;
- void HidePopups() override;
- bool ShowMessageCenter(bool show_by_click) override;
- void HideMessageCenter() override;
- bool ShowNotifierSettings() override;
- MessageCenterTray* GetMessageCenterTray() override;
-
- private:
- std::unique_ptr<MessageCenterTray> tray_;
- base::Closure quit_closure_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeMessageCenterTrayDelegate);
-};
-
-} // namespace message_center
-
-#endif // UI_MESSAGE_CENTER_FAKE_MESSAGE_CENTER_TRAY_DELEGATE_H_
diff --git a/chromium/ui/message_center/fake_ui_delegate.cc b/chromium/ui/message_center/fake_ui_delegate.cc
new file mode 100644
index 00000000000..605b95b07b7
--- /dev/null
+++ b/chromium/ui/message_center/fake_ui_delegate.cc
@@ -0,0 +1,34 @@
+// Copyright 2014 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 "ui/message_center/fake_ui_delegate.h"
+
+#include "base/message_loop/message_loop.h"
+#include "ui/message_center/ui_controller.h"
+
+namespace message_center {
+
+FakeUiDelegate::FakeUiDelegate() : tray_(new UiController(this)) {}
+
+FakeUiDelegate::~FakeUiDelegate() {}
+
+void FakeUiDelegate::OnMessageCenterContentsChanged() {}
+
+bool FakeUiDelegate::ShowPopups() {
+ return false;
+}
+
+void FakeUiDelegate::HidePopups() {}
+
+bool FakeUiDelegate::ShowMessageCenter(bool show_by_click) {
+ return false;
+}
+
+void FakeUiDelegate::HideMessageCenter() {}
+
+bool FakeUiDelegate::ShowNotifierSettings() {
+ return false;
+}
+
+} // namespace message_center
diff --git a/chromium/ui/message_center/fake_ui_delegate.h b/chromium/ui/message_center/fake_ui_delegate.h
new file mode 100644
index 00000000000..8729eba8ce3
--- /dev/null
+++ b/chromium/ui/message_center/fake_ui_delegate.h
@@ -0,0 +1,41 @@
+// Copyright 2014 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 UI_MESSAGE_CENTER_FAKE_UI_DELEGATE_H_
+#define UI_MESSAGE_CENTER_FAKE_UI_DELEGATE_H_
+
+#include <memory>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "ui/message_center/ui_delegate.h"
+
+namespace message_center {
+
+class UiController;
+
+// A message center UI delegate which does nothing.
+class FakeUiDelegate : public UiDelegate {
+ public:
+ FakeUiDelegate();
+ ~FakeUiDelegate() override;
+
+ // Overridden from UiDelegate:
+ void OnMessageCenterContentsChanged() override;
+ bool ShowPopups() override;
+ void HidePopups() override;
+ bool ShowMessageCenter(bool show_by_click) override;
+ void HideMessageCenter() override;
+ bool ShowNotifierSettings() override;
+
+ private:
+ std::unique_ptr<UiController> tray_;
+ base::Closure quit_closure_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeUiDelegate);
+};
+
+} // namespace message_center
+
+#endif // UI_MESSAGE_CENTER_FAKE_UI_DELEGATE_H_
diff --git a/chromium/ui/message_center/message_center.h b/chromium/ui/message_center/message_center.h
index 2ca6562c31c..fab8ce5964d 100644
--- a/chromium/ui/message_center/message_center.h
+++ b/chromium/ui/message_center/message_center.h
@@ -42,7 +42,6 @@ class MessagePopupCollectionTest;
class MessageCenterObserver;
class MessageCenterImplTest;
class NotificationBlocker;
-class NotifierSettingsProvider;
class MESSAGE_CENTER_EXPORT MessageCenter {
public:
@@ -56,8 +55,8 @@ class MESSAGE_CENTER_EXPORT MessageCenter {
// Creates the global message center object.
static void Initialize();
- // Returns the global message center object. Returns NULL if Initialize is not
- // called.
+ // Returns the global message center object. Returns null if Initialize is
+ // not called.
static MessageCenter* Get();
// Destroys the global message_center object.
@@ -69,14 +68,11 @@ class MESSAGE_CENTER_EXPORT MessageCenter {
// Queries of current notification list status.
virtual size_t NotificationCount() const = 0;
- virtual size_t UnreadNotificationCount() const = 0;
virtual bool HasPopupNotifications() const = 0;
virtual bool IsQuietMode() const = 0;
- virtual bool IsLockedState() const = 0;
- virtual bool HasClickedListener(const std::string& id) = 0;
- // Find the notification with the corresponding id. Returns NULL if not found.
- // The returned instance is owned by the message center.
+ // Find the notification with the corresponding id. Returns null if not
+ // found. The returned instance is owned by the message center.
virtual message_center::Notification* FindVisibleNotificationById(
const std::string& id) = 0;
@@ -106,6 +102,8 @@ class MESSAGE_CENTER_EXPORT MessageCenter {
// Removes an existing notification.
virtual void RemoveNotification(const std::string& id, bool by_user) = 0;
+ virtual void RemoveNotificationsForNotifierId(
+ const NotifierId& notifier_id) = 0;
virtual void RemoveAllNotifications(bool by_user, RemoveType type) = 0;
// Sets the icon image. Icon appears at the top-left of the notification.
@@ -133,6 +131,14 @@ class MESSAGE_CENTER_EXPORT MessageCenter {
virtual void ClickOnNotificationButton(const std::string& id,
int button_index) = 0;
+ // This should be called by UI classes when a notification button with an
+ // input is clicked to trigger the notification's delegate callback and also
+ // update the message center observers.
+ virtual void ClickOnNotificationButtonWithReply(
+ const std::string& id,
+ int button_index,
+ const base::string16& reply) = 0;
+
// Called by the UI classes when the settings buttons is clicked
// to trigger the notification's delegate and update the message
// center observers.
@@ -152,19 +158,9 @@ class MESSAGE_CENTER_EXPORT MessageCenter {
const std::string& id,
const DisplaySource source) = 0;
- // Setter/getter of notifier settings provider. This will be a weak reference.
- // This should be set at the initialization process. The getter may return
- // NULL for tests.
- virtual void SetNotifierSettingsProvider(
- NotifierSettingsProvider* provider) = 0;
- virtual NotifierSettingsProvider* GetNotifierSettingsProvider() = 0;
-
// This can be called to change the quiet mode state (without a timeout).
virtual void SetQuietMode(bool in_quiet_mode) = 0;
- // This can be called to change the lock mode state.
- virtual void SetLockedState(bool locked) = 0;
-
// Temporarily enables quiet mode for |expires_in| time.
virtual void EnterQuietModeWithExpire(const base::TimeDelta& expires_in) = 0;
@@ -194,7 +190,7 @@ class MESSAGE_CENTER_EXPORT MessageCenter {
friend class MessageCenterImplTest;
friend class MessageCenterImplTestWithChangeQueue;
friend class MessageCenterImplTestWithoutChangeQueue;
- friend class MessageCenterTrayTest;
+ friend class UiControllerTest;
friend class TrayViewControllerTest;
friend class test::MessagePopupCollectionTest;
virtual void DisableTimersForTest() = 0;
diff --git a/chromium/ui/message_center/message_center_impl.cc b/chromium/ui/message_center/message_center_impl.cc
index 64e45ddc3e4..80e10ed0c7e 100644
--- a/chromium/ui/message_center/message_center_impl.cc
+++ b/chromium/ui/message_center/message_center_impl.cc
@@ -9,6 +9,7 @@
#include <utility>
#include <vector>
+#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
@@ -27,40 +28,51 @@
namespace message_center {
+namespace internal {
+
////////////////////////////////////////////////////////////////////////////////
-// MessageCenterImpl::NotificationCache
+// ScopedNotificationsIterationLock
+
+class ScopedNotificationsIterationLock {
+ public:
+ // Lock may be used recursively.
+ explicit ScopedNotificationsIterationLock(MessageCenterImpl* message_center)
+ : message_center_(message_center),
+ original_value_(message_center->iterating_) {
+ message_center_->iterating_ = true;
+ }
-MessageCenterImpl::NotificationCache::NotificationCache()
- : unread_count(0) {}
+ ~ScopedNotificationsIterationLock() {
+ DCHECK(message_center_->iterating_);
+
+ // |original_value_| must be false. But handle the other case just in case.
+ message_center_->iterating_ = original_value_;
+ if (!original_value_) {
+ message_center_->notification_change_queue_->ApplyChanges(
+ message_center_);
+ }
+ }
-MessageCenterImpl::NotificationCache::~NotificationCache() {}
+ private:
+ MessageCenterImpl* message_center_;
+ const bool original_value_;
-void MessageCenterImpl::NotificationCache::Rebuild(
- const NotificationList::Notifications& notifications) {
- visible_notifications = notifications;
- RecountUnread();
-}
+ DISALLOW_COPY_AND_ASSIGN(ScopedNotificationsIterationLock);
+};
-void MessageCenterImpl::NotificationCache::RecountUnread() {
- unread_count = 0;
- for (auto* notification : visible_notifications) {
- if (!notification->IsRead())
- ++unread_count;
- }
-}
+} // namespace internal
////////////////////////////////////////////////////////////////////////////////
// MessageCenterImpl
MessageCenterImpl::MessageCenterImpl()
: MessageCenter(),
- popup_timers_controller_(new PopupTimersController(this)),
- settings_provider_(NULL) {
+ popup_timers_controller_(new PopupTimersController(this)) {
notification_list_.reset(new NotificationList(this));
+ notification_change_queue_.reset(new ChangeQueue());
}
MessageCenterImpl::~MessageCenterImpl() {
- SetNotifierSettingsProvider(NULL);
}
void MessageCenterImpl::AddObserver(MessageCenterObserver* observer) {
@@ -95,57 +107,49 @@ void MessageCenterImpl::RemoveNotificationBlocker(
void MessageCenterImpl::OnBlockingStateChanged(NotificationBlocker* blocker) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- std::list<std::string> blocked_ids;
+ DCHECK(!iterating_);
+ std::list<const Notification*> blocked;
NotificationList::PopupNotifications popups =
- notification_list_->GetPopupNotifications(blockers_, &blocked_ids);
+ notification_list_->GetPopupNotifications(blockers_, &blocked);
- for (const auto& id : blocked_ids) {
+ // Close already displayed pop-ups that are blocked now.
+ for (const auto* notification : blocked) {
// Do not call MessageCenterImpl::MarkSinglePopupAsShown() directly here
// just for performance reason. MessageCenterImpl::MarkSinglePopupAsShown()
- // calls NotificationList::MarkSinglePopupAsShown() and then updates the
- // unread count, but the whole cache will be recreated below.
- notification_list_->MarkSinglePopupAsShown(id, true);
+ // calls NotificationList::MarkSinglePopupAsShown(), but the whole cache
+ // will be recreated below.
+ if (notification->IsRead())
+ notification_list_->MarkSinglePopupAsShown(notification->id(), true);
}
- notification_cache_.Rebuild(
- notification_list_->GetVisibleNotifications(blockers_));
+ visible_notifications_ =
+ notification_list_->GetVisibleNotifications(blockers_);
- for (const auto& id : blocked_ids) {
- for (auto& observer : observer_list_)
- observer.OnNotificationUpdated(id);
+ {
+ internal::ScopedNotificationsIterationLock lock(this);
+ for (const auto* notification : blocked) {
+ for (auto& observer : observer_list_)
+ observer.OnNotificationUpdated(notification->id());
+ }
}
for (auto& observer : observer_list_)
observer.OnBlockingStateChanged(blocker);
}
-void MessageCenterImpl::UpdateIconImage(const NotifierId& notifier_id,
- const gfx::Image& icon) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-}
-
-void MessageCenterImpl::NotifierGroupChanged() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-}
-
-void MessageCenterImpl::NotifierEnabledChanged(
- const NotifierId& notifier_id, bool enabled) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (!enabled) {
- RemoveNotificationsForNotifierId(notifier_id);
- }
-}
-
void MessageCenterImpl::SetVisibility(Visibility visibility) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!iterating_);
visible_ = (visibility == VISIBILITY_MESSAGE_CENTER);
- if (visible_ && !locked_) {
+ if (visible_) {
std::set<std::string> updated_ids;
notification_list_->SetNotificationsShown(blockers_, &updated_ids);
- notification_cache_.RecountUnread();
- for (const auto& id : updated_ids) {
- for (auto& observer : observer_list_)
- observer.OnNotificationUpdated(id);
+ {
+ internal::ScopedNotificationsIterationLock lock(this);
+ for (const auto& id : updated_ids) {
+ for (auto& observer : observer_list_)
+ observer.OnNotificationUpdated(id);
+ }
}
}
@@ -160,12 +164,7 @@ bool MessageCenterImpl::IsMessageCenterVisible() const {
size_t MessageCenterImpl::NotificationCount() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- return notification_cache_.visible_notifications.size();
-}
-
-size_t MessageCenterImpl::UnreadNotificationCount() const {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- return notification_cache_.unread_count;
+ return visible_notifications_.size();
}
bool MessageCenterImpl::HasPopupNotifications() const {
@@ -179,18 +178,6 @@ bool MessageCenterImpl::IsQuietMode() const {
return notification_list_->quiet_mode();
}
-bool MessageCenterImpl::IsLockedState() const {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- return locked_;
-}
-
-bool MessageCenterImpl::HasClickedListener(const std::string& id) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- scoped_refptr<NotificationDelegate> delegate =
- notification_list_->GetNotificationDelegate(id);
- return delegate.get() && delegate->HasClickedListener();
-}
-
message_center::Notification* MessageCenterImpl::FindVisibleNotificationById(
const std::string& id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -200,7 +187,7 @@ message_center::Notification* MessageCenterImpl::FindVisibleNotificationById(
const NotificationList::Notifications&
MessageCenterImpl::GetVisibleNotifications() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- return notification_cache_.visible_notifications;
+ return visible_notifications_;
}
NotificationList::PopupNotifications
@@ -219,12 +206,18 @@ void MessageCenterImpl::AddNotification(
for (size_t i = 0; i < blockers_.size(); ++i)
blockers_[i]->CheckState();
+ if (iterating_) {
+ notification_change_queue_->AddNotification(std::move(notification));
+ return;
+ }
+
AddNotificationImmediately(std::move(notification));
}
void MessageCenterImpl::AddNotificationImmediately(
std::unique_ptr<Notification> notification) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!iterating_);
const std::string id = notification->id();
// Sometimes the notification can be added with the same id and the
@@ -232,13 +225,15 @@ void MessageCenterImpl::AddNotificationImmediately(
// This is essentially an update rather than addition.
bool already_exists = (notification_list_->GetNotificationById(id) != NULL);
notification_list_->AddNotification(std::move(notification));
- notification_cache_.Rebuild(
- notification_list_->GetVisibleNotifications(blockers_));
+ visible_notifications_ =
+ notification_list_->GetVisibleNotifications(blockers_);
if (already_exists) {
+ internal::ScopedNotificationsIterationLock lock(this);
for (auto& observer : observer_list_)
observer.OnNotificationUpdated(id);
} else {
+ internal::ScopedNotificationsIterationLock lock(this);
for (auto& observer : observer_list_)
observer.OnNotificationAdded(id);
}
@@ -251,6 +246,12 @@ void MessageCenterImpl::UpdateNotification(
for (size_t i = 0; i < blockers_.size(); ++i)
blockers_[i]->CheckState();
+ if (iterating_) {
+ notification_change_queue_->UpdateNotification(old_id,
+ std::move(new_notification));
+ return;
+ }
+
UpdateNotificationImmediately(old_id, std::move(new_notification));
}
@@ -258,15 +259,18 @@ void MessageCenterImpl::UpdateNotificationImmediately(
const std::string& old_id,
std::unique_ptr<Notification> new_notification) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!iterating_);
std::string new_id = new_notification->id();
notification_list_->UpdateNotificationMessage(old_id,
std::move(new_notification));
- notification_cache_.Rebuild(
- notification_list_->GetVisibleNotifications(blockers_));
+ visible_notifications_ =
+ notification_list_->GetVisibleNotifications(blockers_);
if (old_id == new_id) {
+ internal::ScopedNotificationsIterationLock lock(this);
for (auto& observer : observer_list_)
observer.OnNotificationUpdated(new_id);
} else {
+ internal::ScopedNotificationsIterationLock lock(this);
for (auto& observer : observer_list_)
observer.OnNotificationRemoved(old_id, false);
for (auto& observer : observer_list_)
@@ -277,12 +281,20 @@ void MessageCenterImpl::UpdateNotificationImmediately(
void MessageCenterImpl::RemoveNotification(const std::string& id,
bool by_user) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ if (iterating_) {
+ notification_change_queue_->RemoveNotification(id, by_user);
+ return;
+ }
+
RemoveNotificationImmediately(id, by_user);
}
void MessageCenterImpl::RemoveNotificationImmediately(
const std::string& id, bool by_user) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!iterating_);
+
Notification* notification = FindVisibleNotificationById(id);
if (notification == NULL)
return;
@@ -301,10 +313,29 @@ void MessageCenterImpl::RemoveNotificationImmediately(
delegate->Close(by_user);
notification_list_->RemoveNotification(copied_id);
- notification_cache_.Rebuild(
- notification_list_->GetVisibleNotifications(blockers_));
- for (auto& observer : observer_list_)
- observer.OnNotificationRemoved(copied_id, by_user);
+ visible_notifications_ =
+ notification_list_->GetVisibleNotifications(blockers_);
+ {
+ internal::ScopedNotificationsIterationLock lock(this);
+ for (auto& observer : observer_list_)
+ observer.OnNotificationRemoved(copied_id, by_user);
+ }
+}
+
+Notification* MessageCenterImpl::GetLatestNotificationIncludingQueued(
+ const std::string& id) const {
+ Notification* queued_notification =
+ notification_change_queue_->GetLatestNotification(id);
+ if (queued_notification) {
+ DCHECK(iterating_);
+ return queued_notification;
+ }
+
+ Notification* notification = notification_list_->GetNotificationById(id);
+ if (notification)
+ return notification;
+
+ return nullptr;
}
void MessageCenterImpl::RemoveNotificationsForNotifierId(
@@ -315,13 +346,14 @@ void MessageCenterImpl::RemoveNotificationsForNotifierId(
for (auto* notification : notifications)
RemoveNotification(notification->id(), false);
if (!notifications.empty()) {
- notification_cache_.Rebuild(
- notification_list_->GetVisibleNotifications(blockers_));
+ visible_notifications_ =
+ notification_list_->GetVisibleNotifications(blockers_);
}
}
void MessageCenterImpl::RemoveAllNotifications(bool by_user, RemoveType type) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!iterating_);
bool remove_pinned = (type == RemoveType::ALL);
const NotificationBlockers& blockers =
@@ -343,19 +375,37 @@ void MessageCenterImpl::RemoveAllNotifications(bool by_user, RemoveType type) {
}
if (!ids.empty()) {
- notification_cache_.Rebuild(
- notification_list_->GetVisibleNotifications(blockers_));
+ visible_notifications_ =
+ notification_list_->GetVisibleNotifications(blockers_);
}
- for (const auto& id : ids) {
- for (auto& observer : observer_list_)
- observer.OnNotificationRemoved(id, by_user);
+ {
+ internal::ScopedNotificationsIterationLock lock(this);
+ for (const auto& id : ids) {
+ for (auto& observer : observer_list_)
+ observer.OnNotificationRemoved(id, by_user);
+ }
}
}
void MessageCenterImpl::SetNotificationIcon(const std::string& notification_id,
const gfx::Image& image) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ if (iterating_) {
+ Notification* notification =
+ GetLatestNotificationIncludingQueued(notification_id);
+ if (notification) {
+ std::unique_ptr<Notification> copied_notification =
+ std::make_unique<Notification>(*notification);
+ copied_notification->set_icon(image);
+ notification_change_queue_->UpdateNotification(
+ notification_id, std::move(copied_notification));
+ }
+ return;
+ }
+
if (notification_list_->SetNotificationIcon(notification_id, image)) {
+ internal::ScopedNotificationsIterationLock lock(this);
for (auto& observer : observer_list_)
observer.OnNotificationUpdated(notification_id);
}
@@ -363,8 +413,22 @@ void MessageCenterImpl::SetNotificationIcon(const std::string& notification_id,
void MessageCenterImpl::SetNotificationImage(const std::string& notification_id,
const gfx::Image& image) {
+ if (iterating_) {
+ Notification* notification =
+ GetLatestNotificationIncludingQueued(notification_id);
+ if (notification) {
+ std::unique_ptr<Notification> copied_notification =
+ std::make_unique<Notification>(*notification);
+ copied_notification->set_image(image);
+ notification_change_queue_->UpdateNotification(
+ notification_id, std::move(copied_notification));
+ }
+ return;
+ }
+
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (notification_list_->SetNotificationImage(notification_id, image)) {
+ internal::ScopedNotificationsIterationLock lock(this);
for (auto& observer : observer_list_)
observer.OnNotificationUpdated(notification_id);
}
@@ -373,9 +437,23 @@ void MessageCenterImpl::SetNotificationImage(const std::string& notification_id,
void MessageCenterImpl::SetNotificationButtonIcon(
const std::string& notification_id, int button_index,
const gfx::Image& image) {
+ if (iterating_) {
+ Notification* notification =
+ GetLatestNotificationIncludingQueued(notification_id);
+ if (notification) {
+ std::unique_ptr<Notification> copied_notification =
+ std::make_unique<Notification>(*notification);
+ copied_notification->SetButtonIcon(button_index, image);
+ notification_change_queue_->UpdateNotification(
+ notification_id, std::move(copied_notification));
+ }
+ return;
+ }
+
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (notification_list_->SetNotificationButtonIcon(notification_id,
button_index, image)) {
+ internal::ScopedNotificationsIterationLock lock(this);
for (auto& observer : observer_list_)
observer.OnNotificationUpdated(notification_id);
}
@@ -383,6 +461,7 @@ void MessageCenterImpl::SetNotificationButtonIcon(
void MessageCenterImpl::ClickOnNotification(const std::string& id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!iterating_);
if (FindVisibleNotificationById(id) == NULL)
return;
#if defined(OS_CHROMEOS)
@@ -393,14 +472,18 @@ void MessageCenterImpl::ClickOnNotification(const std::string& id) {
notification_list_->GetNotificationDelegate(id);
if (delegate.get())
delegate->Click();
- for (auto& observer : observer_list_)
- observer.OnNotificationClicked(id);
+ {
+ internal::ScopedNotificationsIterationLock lock(this);
+ for (auto& observer : observer_list_)
+ observer.OnNotificationClicked(id);
+ }
}
void MessageCenterImpl::ClickOnNotificationButton(const std::string& id,
int button_index) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (FindVisibleNotificationById(id) == NULL)
+ DCHECK(!iterating_);
+ if (!FindVisibleNotificationById(id))
return;
#if defined(OS_CHROMEOS)
if (HasPopupNotifications())
@@ -410,21 +493,52 @@ void MessageCenterImpl::ClickOnNotificationButton(const std::string& id,
notification_list_->GetNotificationDelegate(id);
if (delegate.get())
delegate->ButtonClick(button_index);
- for (auto& observer : observer_list_)
- observer.OnNotificationButtonClicked(id, button_index);
+ {
+ internal::ScopedNotificationsIterationLock lock(this);
+ for (auto& observer : observer_list_)
+ observer.OnNotificationButtonClicked(id, button_index);
+ }
}
-void MessageCenterImpl::ClickOnSettingsButton(const std::string& id) {
+void MessageCenterImpl::ClickOnNotificationButtonWithReply(
+ const std::string& id,
+ int button_index,
+ const base::string16& reply) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (!FindVisibleNotificationById(id))
+ return;
+#if defined(OS_CHROMEOS)
+ if (HasPopupNotifications())
+ MarkSinglePopupAsShown(id, true);
+#endif
scoped_refptr<NotificationDelegate> delegate =
notification_list_->GetNotificationDelegate(id);
-
- bool handled_by_delegate = false;
if (delegate.get())
- handled_by_delegate = delegate->SettingsClick();
+ delegate->ButtonClickWithReply(button_index, reply);
+ {
+ internal::ScopedNotificationsIterationLock lock(this);
+ for (auto& observer : observer_list_)
+ observer.OnNotificationButtonClickedWithReply(id, button_index, reply);
+ }
+}
- for (auto& observer : observer_list_)
- observer.OnNotificationSettingsClicked(handled_by_delegate);
+void MessageCenterImpl::ClickOnSettingsButton(const std::string& id) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!iterating_);
+ Notification* notification = notification_list_->GetNotificationById(id);
+
+ bool handled_by_delegate =
+ notification &&
+ (notification->rich_notification_data().settings_button_handler ==
+ SettingsButtonHandler::DELEGATE);
+ if (handled_by_delegate)
+ notification->delegate()->SettingsClick();
+
+ {
+ internal::ScopedNotificationsIterationLock lock(this);
+ for (auto& observer : observer_list_)
+ observer.OnNotificationSettingsClicked(handled_by_delegate);
+ }
}
void MessageCenterImpl::MarkSinglePopupAsShown(const std::string& id,
@@ -432,13 +546,21 @@ void MessageCenterImpl::MarkSinglePopupAsShown(const std::string& id,
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (FindVisibleNotificationById(id) == NULL)
return;
+
+// This method doesn't check the |iterating_| flag, since this is called
+// during iteration.
+// TODO(yoshiki): Investigate and not to call this method during iteration if
+// necessary.
+
#if !defined(OS_CHROMEOS)
return this->RemoveNotification(id, false);
#else
notification_list_->MarkSinglePopupAsShown(id, mark_notification_as_read);
- notification_cache_.RecountUnread();
- for (auto& observer : observer_list_)
- observer.OnNotificationUpdated(id);
+ {
+ internal::ScopedNotificationsIterationLock lock(this);
+ for (auto& observer : observer_list_)
+ observer.OnNotificationUpdated(id);
+ }
#endif // defined(OS_CHROMEOS)
}
@@ -446,35 +568,24 @@ void MessageCenterImpl::DisplayedNotification(
const std::string& id,
const DisplaySource source) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ // This method may be called from the handlers, so we shouldn't manipulate
+ // notifications in this method.
+
if (FindVisibleNotificationById(id) == NULL)
return;
if (HasPopupNotifications())
notification_list_->MarkSinglePopupAsDisplayed(id);
- notification_cache_.RecountUnread();
scoped_refptr<NotificationDelegate> delegate =
notification_list_->GetNotificationDelegate(id);
if (delegate.get())
delegate->Display();
- for (auto& observer : observer_list_)
- observer.OnNotificationDisplayed(id, source);
-}
-
-void MessageCenterImpl::SetNotifierSettingsProvider(
- NotifierSettingsProvider* provider) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (settings_provider_) {
- settings_provider_->RemoveObserver(this);
- settings_provider_ = NULL;
+ {
+ internal::ScopedNotificationsIterationLock lock(this);
+ for (auto& observer : observer_list_)
+ observer.OnNotificationDisplayed(id, source);
}
- settings_provider_ = provider;
- if (settings_provider_)
- settings_provider_->AddObserver(this);
-}
-
-NotifierSettingsProvider* MessageCenterImpl::GetNotifierSettingsProvider() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- return settings_provider_;
}
void MessageCenterImpl::SetQuietMode(bool in_quiet_mode) {
@@ -487,15 +598,6 @@ void MessageCenterImpl::SetQuietMode(bool in_quiet_mode) {
quiet_mode_timer_.reset();
}
-void MessageCenterImpl::SetLockedState(bool locked) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (locked != locked_) {
- locked_ = locked;
- for (auto& observer : observer_list_)
- observer.OnLockedStateChanged(locked);
- }
-}
-
void MessageCenterImpl::EnterQuietModeWithExpire(
const base::TimeDelta& expires_in) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
diff --git a/chromium/ui/message_center/message_center_impl.h b/chromium/ui/message_center/message_center_impl.h
index 014cd59dec9..be7cbb87844 100644
--- a/chromium/ui/message_center/message_center_impl.h
+++ b/chromium/ui/message_center/message_center_impl.h
@@ -16,19 +16,24 @@
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
+#include "ui/message_center/change_queue.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_observer.h"
#include "ui/message_center/message_center_types.h"
#include "ui/message_center/notification_blocker.h"
-#include "ui/message_center/notifier_settings.h"
+#include "ui/message_center/notifier_id.h"
#include "ui/message_center/popup_timers_controller.h"
namespace message_center {
+namespace internal {
+class ScopedNotificationsIterationLock;
+};
+
// The default implementation of MessageCenter.
-class MessageCenterImpl : public MessageCenter,
- public NotificationBlocker::Observer,
- public message_center::NotifierSettingsObserver {
+class MESSAGE_CENTER_EXPORT MessageCenterImpl
+ : public MessageCenter,
+ public NotificationBlocker::Observer {
public:
MessageCenterImpl();
~MessageCenterImpl() override;
@@ -41,11 +46,8 @@ class MessageCenterImpl : public MessageCenter,
void SetVisibility(Visibility visible) override;
bool IsMessageCenterVisible() const override;
size_t NotificationCount() const override;
- size_t UnreadNotificationCount() const override;
bool HasPopupNotifications() const override;
bool IsQuietMode() const override;
- bool IsLockedState() const override;
- bool HasClickedListener(const std::string& id) override;
message_center::Notification* FindVisibleNotificationById(
const std::string& id) override;
const NotificationList::Notifications& GetVisibleNotifications() override;
@@ -55,6 +57,7 @@ class MessageCenterImpl : public MessageCenter,
const std::string& old_id,
std::unique_ptr<Notification> new_notification) override;
void RemoveNotification(const std::string& id, bool by_user) override;
+ void RemoveNotificationsForNotifierId(const NotifierId& notifier_id) override;
void RemoveAllNotifications(bool by_user, RemoveType type) override;
void SetNotificationIcon(const std::string& notification_id,
const gfx::Image& image) override;
@@ -66,15 +69,15 @@ class MessageCenterImpl : public MessageCenter,
void ClickOnNotification(const std::string& id) override;
void ClickOnNotificationButton(const std::string& id,
int button_index) override;
+ void ClickOnNotificationButtonWithReply(const std::string& id,
+ int button_index,
+ const base::string16& reply) override;
void ClickOnSettingsButton(const std::string& id) override;
void MarkSinglePopupAsShown(const std::string& id,
bool mark_notification_as_read) override;
void DisplayedNotification(const std::string& id,
const DisplaySource source) override;
- void SetNotifierSettingsProvider(NotifierSettingsProvider* provider) override;
- NotifierSettingsProvider* GetNotifierSettingsProvider() override;
void SetQuietMode(bool in_quiet_mode) override;
- void SetLockedState(bool locked) override;
void EnterQuietModeWithExpire(const base::TimeDelta& expires_in) override;
void RestartPopupTimers() override;
void PausePopupTimers() override;
@@ -84,13 +87,6 @@ class MessageCenterImpl : public MessageCenter,
// NotificationBlocker::Observer overrides:
void OnBlockingStateChanged(NotificationBlocker* blocker) override;
- // message_center::NotifierSettingsObserver overrides:
- void UpdateIconImage(const NotifierId& notifier_id,
- const gfx::Image& icon) override;
- void NotifierGroupChanged() override;
- void NotifierEnabledChanged(const NotifierId& notifier_id,
- bool enabled) override;
-
// Unexposed methods:
void AddNotificationImmediately(std::unique_ptr<Notification> notification);
void UpdateNotificationImmediately(
@@ -102,31 +98,27 @@ class MessageCenterImpl : public MessageCenter,
void DisableTimersForTest() override;
private:
- struct NotificationCache {
- NotificationCache();
- ~NotificationCache();
- void Rebuild(const NotificationList::Notifications& notifications);
- void RecountUnread();
+ friend internal::ScopedNotificationsIterationLock;
+ class ScopedNotificationsLock;
- NotificationList::Notifications visible_notifications;
- size_t unread_count;
- };
-
- void RemoveNotificationsForNotifierId(const NotifierId& notifier_id);
+ Notification* GetLatestNotificationIncludingQueued(
+ const std::string& id) const;
THREAD_CHECKER(thread_checker_);
std::unique_ptr<NotificationList> notification_list_;
- NotificationCache notification_cache_;
+ NotificationList::Notifications visible_notifications_;
base::ObserverList<MessageCenterObserver> observer_list_;
std::unique_ptr<PopupTimersController> popup_timers_controller_;
std::unique_ptr<base::OneShotTimer> quiet_mode_timer_;
- NotifierSettingsProvider* settings_provider_;
std::vector<NotificationBlocker*> blockers_;
+ std::unique_ptr<ChangeQueue> notification_change_queue_;
- bool locked_ = false;
bool visible_ = false;
+ // modified by ScopedNotificationsIterationLock.
+ bool iterating_ = false;
+
base::string16 product_os_name_;
DISALLOW_COPY_AND_ASSIGN(MessageCenterImpl);
diff --git a/chromium/ui/message_center/message_center_impl_unittest.cc b/chromium/ui/message_center/message_center_impl_unittest.cc
index 4bc2a912607..9921fa5f0f7 100644
--- a/chromium/ui/message_center/message_center_impl_unittest.cc
+++ b/chromium/ui/message_center/message_center_impl_unittest.cc
@@ -24,13 +24,55 @@
#include "ui/message_center/message_center_types.h"
#include "ui/message_center/notification_blocker.h"
#include "ui/message_center/notification_types.h"
-#include "ui/message_center/notifier_settings.h"
+#include "ui/message_center/notifier_id.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
using base::UTF8ToUTF16;
namespace message_center {
+namespace {
+
+class CheckObserver : public MessageCenterObserver {
+ public:
+ CheckObserver(MessageCenter* message_center, const std::string& target_id)
+ : message_center_(message_center), target_id_(target_id) {
+ DCHECK(message_center);
+ DCHECK(!target_id.empty());
+ }
+
+ void OnNotificationUpdated(const std::string& notification_id) override {
+ EXPECT_TRUE(message_center_->FindVisibleNotificationById(target_id_));
+ }
+
+ private:
+ MessageCenter* message_center_;
+ std::string target_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(CheckObserver);
+};
+
+class RemoveObserver : public MessageCenterObserver {
+ public:
+ RemoveObserver(MessageCenter* message_center, const std::string& target_id)
+ : message_center_(message_center), target_id_(target_id) {
+ DCHECK(message_center);
+ DCHECK(!target_id.empty());
+ }
+
+ void OnNotificationUpdated(const std::string& notification_id) override {
+ message_center_->RemoveNotification(target_id_, false);
+ }
+
+ private:
+ MessageCenter* message_center_;
+ std::string target_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(RemoveObserver);
+};
+
+} // anonymous namespace
+
class MessageCenterImplTest : public testing::Test,
public MessageCenterObserver {
public:
@@ -52,9 +94,6 @@ class MessageCenterImplTest : public testing::Test,
}
MessageCenter* message_center() const { return message_center_; }
- NotifierSettingsObserver* notifier_settings_observer() const {
- return static_cast<NotifierSettingsObserver*>(message_center_impl());
- }
MessageCenterImpl* message_center_impl() const {
return reinterpret_cast<MessageCenterImpl*>(message_center_);
}
@@ -316,10 +355,15 @@ TEST_F(MessageCenterImplTest, PopupTimersControllerRestartOnUpdate) {
popup_timers_controller->OnNotificationDisplayed("id1", DISPLAY_SOURCE_POPUP);
ASSERT_EQ(popup_timers_controller->timer_finished(), 0);
+#if defined(OS_CHROMEOS)
+ const int dismiss_time = kAutocloseDefaultDelaySeconds;
+#else
+ const int dismiss_time = kAutocloseHighPriorityDelaySeconds;
+#endif
+
// Fast forward the |task_runner| by one second less than the auto-close timer
// frequency for Web Notifications. (As set by the |notifier_id|.)
- task_runner->FastForwardBy(
- base::TimeDelta::FromSeconds(kAutocloseHighPriorityDelaySeconds - 1));
+ task_runner->FastForwardBy(base::TimeDelta::FromSeconds(dismiss_time - 1));
ASSERT_EQ(popup_timers_controller->timer_finished(), 0);
// Trigger a replacement of the notification in the timer controller.
@@ -327,8 +371,7 @@ TEST_F(MessageCenterImplTest, PopupTimersControllerRestartOnUpdate) {
// Fast forward the |task_runner| by one second less than the auto-close timer
// frequency for Web Notifications again. It should have been reset.
- task_runner->FastForwardBy(
- base::TimeDelta::FromSeconds(kAutocloseHighPriorityDelaySeconds - 1));
+ task_runner->FastForwardBy(base::TimeDelta::FromSeconds(dismiss_time - 1));
ASSERT_EQ(popup_timers_controller->timer_finished(), 0);
// Now fast forward the |task_runner| by two seconds (to avoid flakiness),
@@ -359,6 +402,10 @@ TEST_F(MessageCenterImplTest, NotificationBlocker) {
EXPECT_EQ(2u, message_center()->GetPopupNotifications().size());
EXPECT_EQ(2u, message_center()->GetVisibleNotifications().size());
+ // "id1" is displayed as a pop-up so that it will be closed when blocked.
+ message_center()->DisplayedNotification("id1",
+ message_center::DISPLAY_SOURCE_POPUP);
+
// Block all notifications. All popups are gone and message center should be
// hidden.
blocker1.SetNotificationsEnabled(false);
@@ -381,10 +428,14 @@ TEST_F(MessageCenterImplTest, NotificationBlocker) {
EXPECT_TRUE(message_center()->GetPopupNotifications().empty());
EXPECT_EQ(2u, message_center()->GetVisibleNotifications().size());
- // Unblock both blockers, which recovers the global state, but the popups
- // aren't shown.
+ // Unblock both blockers, which recovers the global state, the displayed
+ // pop-ups before blocking aren't shown but the never-displayed ones will
+ // be shown.
blocker2.SetNotificationsEnabled(true);
- EXPECT_TRUE(message_center()->GetPopupNotifications().empty());
+ NotificationList::PopupNotifications popups =
+ message_center()->GetPopupNotifications();
+ EXPECT_EQ(1u, popups.size());
+ EXPECT_TRUE(PopupNotificationsContain(popups, "id2"));
EXPECT_EQ(2u, message_center()->GetVisibleNotifications().size());
}
@@ -400,6 +451,10 @@ TEST_F(MessageCenterImplTest, NotificationsDuringBlocked) {
EXPECT_EQ(1u, message_center()->GetPopupNotifications().size());
EXPECT_EQ(1u, message_center()->GetVisibleNotifications().size());
+ // "id1" is displayed as a pop-up so that it will be closed when blocked.
+ message_center()->DisplayedNotification("id1",
+ message_center::DISPLAY_SOURCE_POPUP);
+
// Create a notification during blocked. Still no popups.
blocker.SetNotificationsEnabled(false);
message_center()->AddNotification(std::unique_ptr<Notification>(
@@ -437,6 +492,10 @@ TEST_F(MessageCenterImplTest, NotificationBlockerAllowsPopups) {
base::string16() /* display_source */, GURL(),
notifier_id2, RichNotificationData(), NULL)));
+ // "id1" is displayed as a pop-up so that it will be closed when blocked.
+ message_center()->DisplayedNotification("id1",
+ message_center::DISPLAY_SOURCE_POPUP);
+
// "id1" is closed but "id2" is still visible as a popup.
blocker.SetNotificationsEnabled(false);
NotificationList::PopupNotifications popups =
@@ -640,41 +699,6 @@ TEST_F(MessageCenterImplTest, RemoveAllNotificationsWithPinned) {
}
#endif
-#if defined(OS_CHROMEOS)
-TEST_F(MessageCenterImplTest, CachedUnreadCount) {
- message_center()->AddNotification(
- std::unique_ptr<Notification>(CreateSimpleNotification("id1")));
- message_center()->AddNotification(
- std::unique_ptr<Notification>(CreateSimpleNotification("id2")));
- message_center()->AddNotification(
- std::unique_ptr<Notification>(CreateSimpleNotification("id3")));
- ASSERT_EQ(3u, message_center()->UnreadNotificationCount());
-
- // Mark 'displayed' on all notifications by using for-loop. This shouldn't
- // recreate |notifications| inside of the loop.
- const NotificationList::Notifications& notifications =
- message_center()->GetVisibleNotifications();
- for (NotificationList::Notifications::const_iterator iter =
- notifications.begin(); iter != notifications.end(); ++iter) {
- message_center()->DisplayedNotification(
- (*iter)->id(), message_center::DISPLAY_SOURCE_MESSAGE_CENTER);
- }
- EXPECT_EQ(0u, message_center()->UnreadNotificationCount());
-
- // Imitate the timeout, which recovers the unread count. Again, this shouldn't
- // recreate |notifications| inside of the loop.
- for (NotificationList::Notifications::const_iterator iter =
- notifications.begin(); iter != notifications.end(); ++iter) {
- message_center()->MarkSinglePopupAsShown((*iter)->id(), false);
- }
- EXPECT_EQ(3u, message_center()->UnreadNotificationCount());
-
- // Opening the message center will reset the unread count.
- message_center()->SetVisibility(VISIBILITY_MESSAGE_CENTER);
- EXPECT_EQ(0u, message_center()->UnreadNotificationCount());
-}
-#endif // OS_CHROMEOS
-
TEST_F(MessageCenterImplTest, NotifierEnabledChanged) {
ASSERT_EQ(0u, message_center()->NotificationCount());
message_center()->AddNotification(std::unique_ptr<Notification>(
@@ -695,24 +719,19 @@ TEST_F(MessageCenterImplTest, NotifierEnabledChanged) {
CreateSimpleNotificationWithNotifierId("id2-5", "app2")));
ASSERT_EQ(8u, message_center()->NotificationCount());
- // Enabling an extension should have no effect on the count.
- notifier_settings_observer()->NotifierEnabledChanged(
- NotifierId(NotifierId::APPLICATION, "app1"), true);
- ASSERT_EQ(8u, message_center()->NotificationCount());
-
// Removing all of app2's notifications should only leave app1's.
- notifier_settings_observer()->NotifierEnabledChanged(
- NotifierId(NotifierId::APPLICATION, "app2"), false);
+ message_center()->RemoveNotificationsForNotifierId(
+ NotifierId(NotifierId::APPLICATION, "app2"));
ASSERT_EQ(3u, message_center()->NotificationCount());
// Removal operations should be idempotent.
- notifier_settings_observer()->NotifierEnabledChanged(
- NotifierId(NotifierId::APPLICATION, "app2"), false);
+ message_center()->RemoveNotificationsForNotifierId(
+ NotifierId(NotifierId::APPLICATION, "app2"));
ASSERT_EQ(3u, message_center()->NotificationCount());
// Now we remove the remaining notifications.
- notifier_settings_observer()->NotifierEnabledChanged(
- NotifierId(NotifierId::APPLICATION, "app1"), false);
+ message_center()->RemoveNotificationsForNotifierId(
+ NotifierId(NotifierId::APPLICATION, "app1"));
ASSERT_EQ(0u, message_center()->NotificationCount());
}
@@ -768,5 +787,36 @@ TEST_F(MessageCenterImplTest, RemoveWhileMessageCenterVisible) {
EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
}
+TEST_F(MessageCenterImplTest, RemoveWhileIteratingObserver) {
+ std::string id("id1");
+ CheckObserver check1(message_center(), id);
+ CheckObserver check2(message_center(), id);
+ RemoveObserver remove(message_center(), id);
+
+ // Prepare a notification
+ std::unique_ptr<Notification> notification(CreateSimpleNotification(id));
+ message_center()->AddNotification(std::move(notification));
+ EXPECT_TRUE(message_center()->FindVisibleNotificationById(id));
+
+ // Install the test handlers
+ message_center()->AddObserver(&check1);
+ message_center()->AddObserver(&remove);
+ message_center()->AddObserver(&check2);
+
+ // Update the notification. The notification will be removed in the observer,
+ // but the actual removal will be done at the end of the iteration.
+ // Notification keeps alive during iteration. This is checked by
+ // CheckObserver.
+ notification.reset(CreateSimpleNotification(id));
+ message_center()->UpdateNotification(id, std::move(notification));
+
+ // Notification is removed correctly.
+ EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
+
+ message_center()->RemoveObserver(&check1);
+ message_center()->RemoveObserver(&remove);
+ message_center()->RemoveObserver(&check2);
+}
+
} // namespace internal
} // namespace message_center
diff --git a/chromium/ui/message_center/message_center_observer.h b/chromium/ui/message_center/message_center_observer.h
index e738bcb910d..feb358bd0a9 100644
--- a/chromium/ui/message_center/message_center_observer.h
+++ b/chromium/ui/message_center/message_center_observer.h
@@ -40,6 +40,13 @@ class MESSAGE_CENTER_EXPORT MessageCenterObserver {
virtual void OnNotificationButtonClicked(const std::string& notification_id,
int button_index) {}
+ // Called when a click event happens on a button with an input indexed by
+ // |button_index| of the notification associated with |notification_id|.
+ virtual void OnNotificationButtonClickedWithReply(
+ const std::string& notification_id,
+ int button_index,
+ const base::string16& reply) {}
+
// Called when notification settings button is clicked. The |handled| argument
// indicates whether the notification delegate already handled the operation.
virtual void OnNotificationSettingsClicked(bool handled) {}
@@ -57,9 +64,6 @@ class MESSAGE_CENTER_EXPORT MessageCenterObserver {
// quiet mode expires.
virtual void OnQuietModeChanged(bool in_quiet_mode) {}
- // Called when the user locks (or unlocks) the screen.
- virtual void OnLockedStateChanged(bool locked) {}
-
// Called when the blocking state of |blocker| is changed.
virtual void OnBlockingStateChanged(NotificationBlocker* blocker) {}
};
diff --git a/chromium/ui/message_center/message_center_tray.cc b/chromium/ui/message_center/message_center_tray.cc
deleted file mode 100644
index e24ad71e928..00000000000
--- a/chromium/ui/message_center/message_center_tray.cc
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright (c) 2013 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 "ui/message_center/message_center_tray.h"
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/observer_list.h"
-#include "base/strings/utf_string_conversions.h"
-#include "build/build_config.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/models/simple_menu_model.h"
-#include "ui/message_center/message_center.h"
-#include "ui/message_center/message_center_tray_delegate.h"
-#include "ui/message_center/message_center_types.h"
-#include "ui/message_center/notification_blocker.h"
-#include "ui/strings/grit/ui_strings.h"
-
-namespace message_center {
-
-namespace {
-
-// Menu constants
-const int kTogglePermissionCommand = 0;
-const int kShowSettingsCommand = 1;
-
-// The model of the context menu for a notification card.
-class NotificationMenuModel : public ui::SimpleMenuModel,
- public ui::SimpleMenuModel::Delegate {
- public:
- NotificationMenuModel(MessageCenterTray* tray,
- const Notification& notification);
- ~NotificationMenuModel() override;
-
- // Overridden from ui::SimpleMenuModel::Delegate:
- bool IsCommandIdChecked(int command_id) const override;
- bool IsCommandIdEnabled(int command_id) const override;
- void ExecuteCommand(int command_id, int event_flags) override;
-
- private:
- MessageCenterTray* tray_;
- Notification notification_;
- DISALLOW_COPY_AND_ASSIGN(NotificationMenuModel);
-};
-
-NotificationMenuModel::NotificationMenuModel(MessageCenterTray* tray,
- const Notification& notification)
- : ui::SimpleMenuModel(this), tray_(tray), notification_(notification) {
- DCHECK(!notification.display_source().empty());
- AddItem(kTogglePermissionCommand,
- l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_NOTIFIER_DISABLE,
- notification.display_source()));
-
-#if defined(OS_CHROMEOS)
- // Add settings menu item.
- AddItem(kShowSettingsCommand,
- l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_SETTINGS));
-#endif
-}
-
-NotificationMenuModel::~NotificationMenuModel() {
-}
-
-bool NotificationMenuModel::IsCommandIdChecked(int command_id) const {
- return false;
-}
-
-bool NotificationMenuModel::IsCommandIdEnabled(int command_id) const {
- // TODO(estade): commands shouldn't always be enabled. For example, a
- // notification's enabled state might be controlled by policy. See
- // http://crbug.com/771269
- return true;
-}
-
-void NotificationMenuModel::ExecuteCommand(int command_id, int event_flags) {
- switch (command_id) {
- case kTogglePermissionCommand:
- notification_.delegate()->DisableNotification();
- // TODO(estade): this will not close other open notifications from the
- // same site.
- MessageCenter::Get()->RemoveNotification(notification_.id(), false);
- break;
- case kShowSettingsCommand:
- tray_->ShowNotifierSettingsBubble();
- break;
- default:
- NOTREACHED();
- }
-}
-
-} // namespace
-
-MessageCenterTray::MessageCenterTray(
- MessageCenterTrayDelegate* delegate,
- message_center::MessageCenter* message_center)
- : message_center_(message_center),
- message_center_visible_(false),
- popups_visible_(false),
- delegate_(delegate) {
- message_center_->AddObserver(this);
-}
-
-MessageCenterTray::~MessageCenterTray() {
- message_center_->RemoveObserver(this);
-}
-
-bool MessageCenterTray::ShowMessageCenterBubble(bool show_by_click) {
- if (message_center_visible_)
- return true;
-
- HidePopupBubbleInternal();
-
- message_center_visible_ = delegate_->ShowMessageCenter(show_by_click);
- if (message_center_visible_) {
- message_center_->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER);
- NotifyMessageCenterTrayChanged();
- }
- return message_center_visible_;
-}
-
-bool MessageCenterTray::HideMessageCenterBubble() {
- if (!message_center_visible_)
- return false;
- delegate_->HideMessageCenter();
- MarkMessageCenterHidden();
- return true;
-}
-
-void MessageCenterTray::MarkMessageCenterHidden() {
- if (!message_center_visible_)
- return;
- message_center_visible_ = false;
- message_center_->SetVisibility(message_center::VISIBILITY_TRANSIENT);
-
- // Some notifications (like system ones) should appear as popups again
- // after the message center is closed.
- if (message_center_->HasPopupNotifications()) {
- ShowPopupBubble();
- return;
- }
-
- NotifyMessageCenterTrayChanged();
-}
-
-void MessageCenterTray::ShowPopupBubble() {
- if (message_center_visible_)
- return;
-
- if (popups_visible_) {
- NotifyMessageCenterTrayChanged();
- return;
- }
-
- if (!message_center_->HasPopupNotifications())
- return;
-
- popups_visible_ = delegate_->ShowPopups();
-
- NotifyMessageCenterTrayChanged();
-}
-
-bool MessageCenterTray::HidePopupBubble() {
- if (!popups_visible_)
- return false;
- HidePopupBubbleInternal();
- NotifyMessageCenterTrayChanged();
-
- return true;
-}
-
-void MessageCenterTray::HidePopupBubbleInternal() {
- if (!popups_visible_)
- return;
-
- delegate_->HidePopups();
- popups_visible_ = false;
-}
-
-void MessageCenterTray::ShowNotifierSettingsBubble() {
- if (popups_visible_)
- HidePopupBubbleInternal();
-
- message_center_visible_ = delegate_->ShowNotifierSettings();
- message_center_->SetVisibility(message_center::VISIBILITY_SETTINGS);
-
- NotifyMessageCenterTrayChanged();
-}
-
-std::unique_ptr<ui::MenuModel> MessageCenterTray::CreateNotificationMenuModel(
- const Notification& notification) {
- return std::make_unique<NotificationMenuModel>(this, notification);
-}
-
-void MessageCenterTray::OnNotificationAdded(
- const std::string& notification_id) {
- OnMessageCenterChanged();
-}
-
-void MessageCenterTray::OnNotificationRemoved(
- const std::string& notification_id,
- bool by_user) {
- OnMessageCenterChanged();
-}
-
-void MessageCenterTray::OnNotificationUpdated(
- const std::string& notification_id) {
- OnMessageCenterChanged();
-}
-
-void MessageCenterTray::OnNotificationClicked(
- const std::string& notification_id) {
- if (popups_visible_)
- OnMessageCenterChanged();
-}
-
-void MessageCenterTray::OnNotificationButtonClicked(
- const std::string& notification_id,
- int button_index) {
- if (popups_visible_)
- OnMessageCenterChanged();
-}
-
-void MessageCenterTray::OnNotificationSettingsClicked(bool handled) {
- if (!handled)
- ShowNotifierSettingsBubble();
-}
-
-void MessageCenterTray::OnNotificationDisplayed(
- const std::string& notification_id,
- const DisplaySource source) {
- NotifyMessageCenterTrayChanged();
-}
-
-void MessageCenterTray::OnQuietModeChanged(bool in_quiet_mode) {
- NotifyMessageCenterTrayChanged();
-}
-
-void MessageCenterTray::OnBlockingStateChanged(NotificationBlocker* blocker) {
- OnMessageCenterChanged();
-}
-
-void MessageCenterTray::OnMessageCenterChanged() {
- if (message_center_visible_ && message_center_->NotificationCount() == 0)
- HideMessageCenterBubble();
-
- if (popups_visible_ && !message_center_->HasPopupNotifications())
- HidePopupBubbleInternal();
- else if (!popups_visible_ && message_center_->HasPopupNotifications())
- ShowPopupBubble();
-
- NotifyMessageCenterTrayChanged();
-}
-
-void MessageCenterTray::NotifyMessageCenterTrayChanged() {
- delegate_->OnMessageCenterTrayChanged();
-}
-
-} // namespace message_center
diff --git a/chromium/ui/message_center/message_center_tray_unittest.cc b/chromium/ui/message_center/message_center_tray_unittest.cc
deleted file mode 100644
index c215306b658..00000000000
--- a/chromium/ui/message_center/message_center_tray_unittest.cc
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright (c) 2013 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 "ui/message_center/message_center_tray.h"
-
-#include <utility>
-
-#include "base/macros.h"
-#include "base/strings/utf_string_conversions.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/base/models/menu_model.h"
-#include "ui/message_center/message_center.h"
-#include "ui/message_center/notification.h"
-#include "ui/message_center/notification_types.h"
-
-using base::ASCIIToUTF16;
-
-namespace message_center {
-namespace {
-
-class TestNotificationDelegate : public message_center::NotificationDelegate {
- public:
- TestNotificationDelegate() = default;
-
- private:
- ~TestNotificationDelegate() override = default;
-
- DISALLOW_COPY_AND_ASSIGN(TestNotificationDelegate);
-};
-
-class MockDelegate : public MessageCenterTrayDelegate {
- public:
- MockDelegate() {}
- ~MockDelegate() override {}
- void OnMessageCenterTrayChanged() override {}
- bool ShowPopups() override { return show_message_center_success_; }
- void HidePopups() override {}
- bool ShowMessageCenter(bool show_by_click) override {
- return show_popups_success_;
- }
- void HideMessageCenter() override {}
- bool ShowNotifierSettings() override { return true; }
-
- MessageCenterTray* GetMessageCenterTray() override { return nullptr; }
-
- bool show_popups_success_ = true;
- bool show_message_center_success_ = true;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockDelegate);
-};
-
-} // namespace
-
-class MessageCenterTrayTest : public testing::Test {
- public:
- MessageCenterTrayTest() {}
- ~MessageCenterTrayTest() override {}
-
- void SetUp() override {
- MessageCenter::Initialize();
- delegate_.reset(new MockDelegate);
- message_center_ = MessageCenter::Get();
- message_center_tray_.reset(
- new MessageCenterTray(delegate_.get(), message_center_));
- }
-
- void TearDown() override {
- message_center_tray_.reset();
- delegate_.reset();
- message_center_ = NULL;
- MessageCenter::Shutdown();
- }
-
- protected:
- NotifierId DummyNotifierId() {
- return NotifierId();
- }
-
- Notification* AddNotification(const std::string& id) {
- return AddNotification(id, DummyNotifierId());
- }
-
- Notification* AddNotification(const std::string& id, NotifierId notifier_id) {
- std::unique_ptr<Notification> notification(
- new Notification(message_center::NOTIFICATION_TYPE_SIMPLE, id,
- ASCIIToUTF16("Test Web Notification"),
- ASCIIToUTF16("Notification message body."),
- gfx::Image(), ASCIIToUTF16("www.test.org"), GURL(),
- notifier_id, message_center::RichNotificationData(),
- new TestNotificationDelegate()));
- Notification* notification_ptr = notification.get();
- message_center_->AddNotification(std::move(notification));
- return notification_ptr;
- }
- std::unique_ptr<MockDelegate> delegate_;
- std::unique_ptr<MessageCenterTray> message_center_tray_;
- MessageCenter* message_center_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MessageCenterTrayTest);
-};
-
-TEST_F(MessageCenterTrayTest, BasicMessageCenter) {
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- bool shown =
- message_center_tray_->ShowMessageCenterBubble(false /* show_by_click */);
- EXPECT_TRUE(shown);
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_TRUE(message_center_tray_->message_center_visible());
-
- message_center_tray_->HideMessageCenterBubble();
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- message_center_tray_->ShowMessageCenterBubble(false /* show_by_click */);
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_TRUE(message_center_tray_->message_center_visible());
-
- message_center_tray_->HideMessageCenterBubble();
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-}
-
-TEST_F(MessageCenterTrayTest, BasicPopup) {
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- message_center_tray_->ShowPopupBubble();
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- AddNotification("BasicPopup");
-
- ASSERT_TRUE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- message_center_tray_->HidePopupBubble();
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-}
-
-TEST_F(MessageCenterTrayTest, MessageCenterClosesPopups) {
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- AddNotification("MessageCenterClosesPopups");
-
- ASSERT_TRUE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- bool shown =
- message_center_tray_->ShowMessageCenterBubble(false /* show_by_click */);
- EXPECT_TRUE(shown);
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_TRUE(message_center_tray_->message_center_visible());
-
- // The notification is queued if it's added when message center is visible.
- AddNotification("MessageCenterClosesPopups2");
-
- message_center_tray_->ShowPopupBubble();
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_TRUE(message_center_tray_->message_center_visible());
-
- message_center_tray_->HideMessageCenterBubble();
-
- // There is no queued notification.
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- message_center_tray_->ShowMessageCenterBubble(false /* show_by_click */);
- message_center_tray_->HideMessageCenterBubble();
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-}
-
-TEST_F(MessageCenterTrayTest, MessageCenterReopenPopupsForSystemPriority) {
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- std::unique_ptr<Notification> notification(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE,
- "MessageCenterReopnPopupsForSystemPriority",
- ASCIIToUTF16("Test Web Notification"),
- ASCIIToUTF16("Notification message body."), gfx::Image(),
- ASCIIToUTF16("www.test.org"), GURL(), DummyNotifierId(),
- message_center::RichNotificationData(), NULL /* delegate */));
- notification->SetSystemPriority();
- message_center_->AddNotification(std::move(notification));
-
- ASSERT_TRUE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- bool shown =
- message_center_tray_->ShowMessageCenterBubble(false /* show_by_click */);
- EXPECT_TRUE(shown);
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_TRUE(message_center_tray_->message_center_visible());
-
- message_center_tray_->HideMessageCenterBubble();
-
- ASSERT_TRUE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-}
-
-TEST_F(MessageCenterTrayTest, ShowBubbleFails) {
- // Now the delegate will signal that it was unable to show a bubble.
- delegate_->show_popups_success_ = false;
- delegate_->show_message_center_success_ = false;
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- AddNotification("ShowBubbleFails");
-
- message_center_tray_->ShowPopupBubble();
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- bool shown =
- message_center_tray_->ShowMessageCenterBubble(false /* show_by_click */);
- EXPECT_FALSE(shown);
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- message_center_tray_->HideMessageCenterBubble();
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- message_center_tray_->ShowMessageCenterBubble(false /* show_by_click */);
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-
- message_center_tray_->HidePopupBubble();
-
- ASSERT_FALSE(message_center_tray_->popups_visible());
- ASSERT_FALSE(message_center_tray_->message_center_visible());
-}
-
-TEST_F(MessageCenterTrayTest, ContextMenuTestWithMessageCenter) {
- const std::string id1 = "id1";
- const std::string id2 = "id2";
- const std::string id3 = "id3";
- Notification* notification1 = AddNotification(id1);
-
- base::string16 display_source = ASCIIToUTF16("www.test.org");
- NotifierId notifier_id = DummyNotifierId();
-
- NotifierId notifier_id2(NotifierId::APPLICATION, "sample-app");
- std::unique_ptr<Notification> notification(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, id2,
- ASCIIToUTF16("Test Web Notification"),
- ASCIIToUTF16("Notification message body."), gfx::Image(), display_source,
- GURL(), notifier_id2, message_center::RichNotificationData(),
- new TestNotificationDelegate()));
- message_center_->AddNotification(std::move(notification));
-
- AddNotification(id3);
-
- std::unique_ptr<ui::MenuModel> model(
- message_center_tray_->CreateNotificationMenuModel(*notification1));
-#if defined(OS_CHROMEOS)
- EXPECT_EQ(2, model->GetItemCount());
-
- // The second item is to open the settings.
- EXPECT_TRUE(model->IsEnabledAt(0));
- EXPECT_TRUE(model->IsEnabledAt(1));
- model->ActivatedAt(1);
- EXPECT_TRUE(message_center_tray_->message_center_visible());
-#else
- EXPECT_EQ(1, model->GetItemCount());
-#endif
-
- message_center_tray_->HideMessageCenterBubble();
-
- // The first item is to disable notifications from the notifier id. It also
- // removes the notification.
- EXPECT_EQ(3u, message_center_->GetVisibleNotifications().size());
- model->ActivatedAt(0);
- EXPECT_EQ(2u, message_center_->GetVisibleNotifications().size());
-}
-
-} // namespace message_center
diff --git a/chromium/ui/message_center/mojo/BUILD.gn b/chromium/ui/message_center/mojo/BUILD.gn
index a19b11a29a3..ca859f3b1f2 100644
--- a/chromium/ui/message_center/mojo/BUILD.gn
+++ b/chromium/ui/message_center/mojo/BUILD.gn
@@ -7,11 +7,12 @@ import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojo") {
sources = [
"notification.mojom",
+ "notifier_id.mojom",
]
public_deps = [
"//mojo/common:common_custom_types",
- "//skia/public/interfaces:interfaces",
+ "//ui/gfx/image/mojo:interfaces",
"//url/mojo:url_mojom_gurl",
]
}
@@ -31,6 +32,8 @@ source_set("struct_traits") {
sources = [
"notification_struct_traits.cc",
"notification_struct_traits.h",
+ "notifier_id_struct_traits.cc",
+ "notifier_id_struct_traits.h",
]
public_deps = [
@@ -38,8 +41,8 @@ source_set("struct_traits") {
"//base",
"//mojo/common:struct_traits",
"//mojo/public/cpp/bindings",
- "//skia/public/interfaces",
"//ui/gfx",
+ "//ui/gfx/image/mojo:struct_traits",
"//ui/message_center",
"//url/mojo:url_mojom_gurl",
]
diff --git a/chromium/ui/message_center/mojo/DEPS b/chromium/ui/message_center/mojo/DEPS
index e8a0f7d5ac5..6cfa565faca 100644
--- a/chromium/ui/message_center/mojo/DEPS
+++ b/chromium/ui/message_center/mojo/DEPS
@@ -1,4 +1,3 @@
include_rules = [
"+mojo/common",
- "+skia/public",
]
diff --git a/chromium/ui/message_center/mojo/notification.mojom b/chromium/ui/message_center/mojo/notification.mojom
index a9651b3eec6..b3764872188 100644
--- a/chromium/ui/message_center/mojo/notification.mojom
+++ b/chromium/ui/message_center/mojo/notification.mojom
@@ -5,18 +5,46 @@
module message_center.mojom;
import "mojo/common/string16.mojom";
-import "skia/public/interfaces/bitmap.mojom";
+import "ui/gfx/image/mojo/image.mojom";
import "url/mojo/url.mojom";
+// Matches message_center::NotificationType.
+enum NotificationType {
+ SIMPLE = 0,
+ BASE_FORMAT = 1,
+ IMAGE = 2,
+ MULTIPLE = 3,
+ PROGRESS = 4,
+ CUSTOM = 5,
+};
+
+// These fields and their meanings are identical to those in
+// message_center::RichNotificationData.
+// TODO(estade): Add the rest of the fields for RichNotificationData.
+struct RichNotificationData {
+ int32 progress;
+ mojo.common.mojom.String16 progress_status;
+ bool should_make_spoken_feedback_for_popup_updates;
+ bool clickable;
+ bool pinned;
+ mojo.common.mojom.String16 accessible_name;
+ uint32 accent_color;
+ bool use_image_as_icon;
+};
+
// TODO(mhashmi): Add the rest of the fields for a Notification
struct Notification {
+ NotificationType type;
+
// TODO(mhashmi): Server-side code (in Ash) needs to make sure this id won't
// collide with ids from different clients
string id;
mojo.common.mojom.String16 title;
mojo.common.mojom.String16 message;
- skia.mojom.Bitmap? icon;
+ gfx.mojom.ImageSkia? icon;
mojo.common.mojom.String16 display_source;
url.mojom.Url origin_url;
+
+ RichNotificationData optional_fields;
};
diff --git a/chromium/ui/message_center/mojo/notification.typemap b/chromium/ui/message_center/mojo/notification.typemap
index f31b7ed39e6..1e613e5e66d 100644
--- a/chromium/ui/message_center/mojo/notification.typemap
+++ b/chromium/ui/message_center/mojo/notification.typemap
@@ -6,7 +6,11 @@ mojom = "//ui/message_center/mojo/notification.mojom"
public_headers = [ "//ui/message_center/notification.h" ]
traits_headers = [ "//ui/message_center/mojo/notification_struct_traits.h" ]
deps = [
+ "//ui/gfx/image/mojo:struct_traits",
"//ui/message_center/mojo:struct_traits",
]
-type_mappings =
- [ "message_center.mojom.Notification=message_center::Notification" ]
+type_mappings = [
+ "message_center.mojom.RichNotificationData=message_center::RichNotificationData",
+ "message_center.mojom.NotificationType=message_center::NotificationType",
+ "message_center.mojom.Notification=message_center::Notification",
+]
diff --git a/chromium/ui/message_center/mojo/notification_struct_traits.cc b/chromium/ui/message_center/mojo/notification_struct_traits.cc
index 3d5d510e1be..6f771b9f2e5 100644
--- a/chromium/ui/message_center/mojo/notification_struct_traits.cc
+++ b/chromium/ui/message_center/mojo/notification_struct_traits.cc
@@ -5,70 +5,141 @@
#include "ui/message_center/mojo/notification_struct_traits.h"
#include "mojo/common/common_custom_types_struct_traits.h"
-#include "skia/public/interfaces/bitmap_skbitmap_struct_traits.h"
+#include "ui/gfx/image/mojo/image_skia_struct_traits.h"
#include "url/mojo/url_gurl_struct_traits.h"
namespace mojo {
+using message_center::mojom::NotificationDataView;
+using message_center::mojom::RichNotificationDataDataView;
+using message_center::Notification;
+using message_center::RichNotificationData;
+using NotificationStructTraits =
+ StructTraits<NotificationDataView, Notification>;
+using RichNotificationDataStructTraits =
+ StructTraits<RichNotificationDataDataView, RichNotificationData>;
+
+// static
+int RichNotificationDataStructTraits::progress(
+ const message_center::RichNotificationData& r) {
+ return r.progress;
+}
+
+// static
+const base::string16& RichNotificationDataStructTraits::progress_status(
+ const message_center::RichNotificationData& r) {
+ return r.progress_status;
+}
+
+// static
+bool RichNotificationDataStructTraits::
+ should_make_spoken_feedback_for_popup_updates(
+ const message_center::RichNotificationData& r) {
+ return r.should_make_spoken_feedback_for_popup_updates;
+}
+
+// static
+bool RichNotificationDataStructTraits::clickable(
+ const message_center::RichNotificationData& r) {
+ return r.clickable;
+}
+
+// static
+bool RichNotificationDataStructTraits::pinned(
+ const message_center::RichNotificationData& r) {
+ return r.pinned;
+}
+
+// static
+const base::string16& RichNotificationDataStructTraits::accessible_name(
+ const message_center::RichNotificationData& r) {
+ return r.accessible_name;
+}
+
+// static
+SkColor RichNotificationDataStructTraits::accent_color(
+ const message_center::RichNotificationData& r) {
+ return r.accent_color;
+}
+
// static
-const std::string& StructTraits<
- message_center::mojom::NotificationDataView,
- message_center::Notification>::id(const message_center::Notification& n) {
+bool RichNotificationDataStructTraits::use_image_as_icon(
+ const message_center::RichNotificationData& r) {
+ return r.use_image_as_icon;
+}
+
+// static
+bool RichNotificationDataStructTraits::Read(RichNotificationDataDataView data,
+ RichNotificationData* out) {
+ out->progress = data.progress();
+ out->should_make_spoken_feedback_for_popup_updates =
+ data.should_make_spoken_feedback_for_popup_updates();
+ out->clickable = data.clickable();
+ out->pinned = data.pinned();
+ out->accent_color = data.accent_color();
+ out->use_image_as_icon = data.use_image_as_icon();
+ return data.ReadProgressStatus(&out->progress_status) &&
+ data.ReadAccessibleName(&out->accessible_name);
+}
+
+// static
+message_center::NotificationType NotificationStructTraits::type(
+ const Notification& n) {
+ return n.type();
+}
+
+// static
+const std::string& NotificationStructTraits::id(const Notification& n) {
return n.id();
}
// static
-const base::string16& StructTraits<message_center::mojom::NotificationDataView,
- message_center::Notification>::
- title(const message_center::Notification& n) {
+const base::string16& NotificationStructTraits::title(const Notification& n) {
return n.title();
}
// static
-const base::string16& StructTraits<message_center::mojom::NotificationDataView,
- message_center::Notification>::
- message(const message_center::Notification& n) {
+const base::string16& NotificationStructTraits::message(const Notification& n) {
return n.message();
}
// static
-const SkBitmap& StructTraits<
- message_center::mojom::NotificationDataView,
- message_center::Notification>::icon(const message_center::Notification& n) {
- // TODO(mhashmi): Remove this when we have a gfx::Image mojom
- static const SkBitmap kNullSkBitmap;
- gfx::Image icon = n.icon();
- return icon.IsEmpty() ? kNullSkBitmap : *icon.ToSkBitmap();
+gfx::ImageSkia NotificationStructTraits::icon(const Notification& n) {
+ return n.icon().AsImageSkia();
}
// static
-const base::string16& StructTraits<message_center::mojom::NotificationDataView,
- message_center::Notification>::
- display_source(const message_center::Notification& n) {
+const base::string16& NotificationStructTraits::display_source(
+ const Notification& n) {
return n.display_source();
}
// static
-const GURL& StructTraits<message_center::mojom::NotificationDataView,
- message_center::Notification>::
- origin_url(const message_center::Notification& n) {
+const GURL& NotificationStructTraits::origin_url(const Notification& n) {
return n.origin_url();
}
// static
-bool StructTraits<message_center::mojom::NotificationDataView,
- message_center::Notification>::
- Read(message_center::mojom::NotificationDataView data,
- message_center::Notification* out) {
- SkBitmap icon;
- if (!data.ReadId(&out->id_) || !data.ReadTitle(&out->title_) ||
- !data.ReadMessage(&out->message_) ||
- !data.ReadDisplaySource(&out->display_source_) || !data.ReadIcon(&icon) ||
- !data.ReadOriginUrl(&out->origin_url_)) {
+const RichNotificationData& NotificationStructTraits::optional_fields(
+ const Notification& n) {
+ return n.rich_notification_data();
+}
+
+// static
+bool NotificationStructTraits::Read(NotificationDataView data,
+ Notification* out) {
+ gfx::ImageSkia icon;
+ if (!data.ReadIcon(&icon))
return false;
- }
- out->icon_ = gfx::Image::CreateFrom1xBitmap(icon);
- return true;
+ out->set_icon(gfx::Image(icon));
+ return EnumTraits<message_center::mojom::NotificationType,
+ message_center::NotificationType>::FromMojom(data.type(),
+ &out->type_) &&
+ data.ReadId(&out->id_) && data.ReadTitle(&out->title_) &&
+ data.ReadMessage(&out->message_) &&
+ data.ReadDisplaySource(&out->display_source_) &&
+ data.ReadOriginUrl(&out->origin_url_) &&
+ data.ReadOptionalFields(&out->optional_fields_);
}
} // namespace mojo
diff --git a/chromium/ui/message_center/mojo/notification_struct_traits.h b/chromium/ui/message_center/mojo/notification_struct_traits.h
index 174a9984ee6..b1ebb81b3d4 100644
--- a/chromium/ui/message_center/mojo/notification_struct_traits.h
+++ b/chromium/ui/message_center/mojo/notification_struct_traits.h
@@ -5,21 +5,94 @@
#ifndef UI_MESSAGE_CENTER_NOTIFICATION_STRUCT_TRAITS_H_
#define UI_MESSAGE_CENTER_NOTIFICATION_STRUCT_TRAITS_H_
+#include "third_party/skia/include/core/SkColor.h"
#include "ui/message_center/mojo/notification.mojom-shared.h"
#include "ui/message_center/notification.h"
namespace mojo {
template <>
+struct EnumTraits<message_center::mojom::NotificationType,
+ message_center::NotificationType> {
+ static message_center::mojom::NotificationType ToMojom(
+ message_center::NotificationType type) {
+ switch (type) {
+ case message_center::NOTIFICATION_TYPE_SIMPLE:
+ return message_center::mojom::NotificationType::SIMPLE;
+ case message_center::NOTIFICATION_TYPE_BASE_FORMAT:
+ return message_center::mojom::NotificationType::BASE_FORMAT;
+ case message_center::NOTIFICATION_TYPE_IMAGE:
+ return message_center::mojom::NotificationType::IMAGE;
+ case message_center::NOTIFICATION_TYPE_MULTIPLE:
+ return message_center::mojom::NotificationType::MULTIPLE;
+ case message_center::NOTIFICATION_TYPE_PROGRESS:
+ return message_center::mojom::NotificationType::PROGRESS;
+ case message_center::NOTIFICATION_TYPE_CUSTOM:
+ return message_center::mojom::NotificationType::CUSTOM;
+ }
+ NOTREACHED();
+ return message_center::mojom::NotificationType::SIMPLE;
+ }
+
+ static bool FromMojom(message_center::mojom::NotificationType input,
+ message_center::NotificationType* out) {
+ switch (input) {
+ case message_center::mojom::NotificationType::SIMPLE:
+ *out = message_center::NOTIFICATION_TYPE_SIMPLE;
+ return true;
+ case message_center::mojom::NotificationType::BASE_FORMAT:
+ *out = message_center::NOTIFICATION_TYPE_BASE_FORMAT;
+ return true;
+ case message_center::mojom::NotificationType::IMAGE:
+ *out = message_center::NOTIFICATION_TYPE_IMAGE;
+ return true;
+ case message_center::mojom::NotificationType::MULTIPLE:
+ *out = message_center::NOTIFICATION_TYPE_MULTIPLE;
+ return true;
+ case message_center::mojom::NotificationType::PROGRESS:
+ *out = message_center::NOTIFICATION_TYPE_PROGRESS;
+ return true;
+ case message_center::mojom::NotificationType::CUSTOM:
+ *out = message_center::NOTIFICATION_TYPE_CUSTOM;
+ return true;
+ }
+ NOTREACHED();
+ return false;
+ }
+};
+
+template <>
+struct StructTraits<message_center::mojom::RichNotificationDataDataView,
+ message_center::RichNotificationData> {
+ static int progress(const message_center::RichNotificationData& r);
+ static const base::string16& progress_status(
+ const message_center::RichNotificationData& r);
+ static bool should_make_spoken_feedback_for_popup_updates(
+ const message_center::RichNotificationData& r);
+ static bool clickable(const message_center::RichNotificationData& r);
+ static bool pinned(const message_center::RichNotificationData& r);
+ static const base::string16& accessible_name(
+ const message_center::RichNotificationData& r);
+ static SkColor accent_color(const message_center::RichNotificationData& r);
+ static bool use_image_as_icon(const message_center::RichNotificationData& r);
+ static bool Read(message_center::mojom::RichNotificationDataDataView data,
+ message_center::RichNotificationData* out);
+};
+
+template <>
struct StructTraits<message_center::mojom::NotificationDataView,
message_center::Notification> {
+ static message_center::NotificationType type(
+ const message_center::Notification& n);
static const std::string& id(const message_center::Notification& n);
static const base::string16& title(const message_center::Notification& n);
static const base::string16& message(const message_center::Notification& n);
- static const SkBitmap& icon(const message_center::Notification& n);
+ static gfx::ImageSkia icon(const message_center::Notification& n);
static const base::string16& display_source(
const message_center::Notification& n);
static const GURL& origin_url(const message_center::Notification& n);
+ static const message_center::RichNotificationData& optional_fields(
+ const message_center::Notification& n);
static bool Read(message_center::mojom::NotificationDataView data,
message_center::Notification* out);
};
diff --git a/chromium/ui/message_center/mojo/notifier_id.mojom b/chromium/ui/message_center/mojo/notifier_id.mojom
new file mode 100644
index 00000000000..cf7a9a6167f
--- /dev/null
+++ b/chromium/ui/message_center/mojo/notifier_id.mojom
@@ -0,0 +1,26 @@
+// Copyright 2017 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.
+
+module message_center.mojom;
+
+import "mojo/common/string16.mojom";
+import "url/mojo/url.mojom";
+
+// Equivalent to message_center::NotifierId::NotifierType. Used in UMA, so it
+// should not be reordered.
+enum NotifierType {
+ APPLICATION,
+ ARC_APPLICATION,
+ WEB_PAGE,
+ SYSTEM_COMPONENT,
+ SIZE,
+};
+
+// Equivalent to message_center::NotifierId.
+struct NotifierId {
+ NotifierType type;
+ string id;
+ url.mojom.Url url;
+ string profile_id;
+};
diff --git a/chromium/ui/message_center/mojo/notifier_id.typemap b/chromium/ui/message_center/mojo/notifier_id.typemap
new file mode 100644
index 00000000000..00a923cd955
--- /dev/null
+++ b/chromium/ui/message_center/mojo/notifier_id.typemap
@@ -0,0 +1,14 @@
+# Copyright 2017 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.
+
+mojom = "//ui/message_center/mojo/notifier_id.mojom"
+public_headers = [ "//ui/message_center/notifier_id.h" ]
+traits_headers = [ "//ui/message_center/mojo/notifier_id_struct_traits.h" ]
+deps = [
+ "//ui/message_center/mojo:struct_traits",
+]
+type_mappings = [
+ "message_center.mojom.NotifierId=message_center::NotifierId",
+ "message_center.mojom.NotifierType=message_center::NotifierId::NotifierType",
+]
diff --git a/chromium/ui/message_center/mojo/notifier_id_struct_traits.cc b/chromium/ui/message_center/mojo/notifier_id_struct_traits.cc
new file mode 100644
index 00000000000..424df76756c
--- /dev/null
+++ b/chromium/ui/message_center/mojo/notifier_id_struct_traits.cc
@@ -0,0 +1,47 @@
+// Copyright 2017 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 "ui/message_center/mojo/notifier_id_struct_traits.h"
+
+#include "mojo/common/common_custom_types_struct_traits.h"
+#include "url/mojo/url_gurl_struct_traits.h"
+
+namespace mojo {
+
+using NotifierIdStructTraits =
+ StructTraits<message_center::mojom::NotifierIdDataView,
+ message_center::NotifierId>;
+
+// static
+const message_center::NotifierId::NotifierType& NotifierIdStructTraits::type(
+ const message_center::NotifierId& n) {
+ return n.type;
+}
+
+// static
+const std::string& NotifierIdStructTraits::id(
+ const message_center::NotifierId& n) {
+ return n.id;
+}
+
+// static
+const GURL& NotifierIdStructTraits::url(const message_center::NotifierId& n) {
+ return n.url;
+}
+
+// static
+const std::string& NotifierIdStructTraits::profile_id(
+ const message_center::NotifierId& n) {
+ return n.profile_id;
+}
+
+// static
+bool NotifierIdStructTraits::Read(
+ message_center::mojom::NotifierIdDataView data,
+ message_center::NotifierId* out) {
+ return data.ReadType(&out->type) && data.ReadId(&out->id) &&
+ data.ReadUrl(&out->url) && data.ReadProfileId(&out->profile_id);
+}
+
+} // namespace mojo
diff --git a/chromium/ui/message_center/mojo/notifier_id_struct_traits.h b/chromium/ui/message_center/mojo/notifier_id_struct_traits.h
new file mode 100644
index 00000000000..bf55f0c266c
--- /dev/null
+++ b/chromium/ui/message_center/mojo/notifier_id_struct_traits.h
@@ -0,0 +1,71 @@
+// Copyright 2017 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 UI_MESSAGE_CENTER_NOTIFIER_ID_STRUCT_TRAITS_H_
+#define UI_MESSAGE_CENTER_NOTIFIER_ID_STRUCT_TRAITS_H_
+
+#include "ui/message_center/mojo/notifier_id.mojom-shared.h"
+#include "ui/message_center/notifier_id.h"
+
+namespace mojo {
+
+template <>
+struct EnumTraits<message_center::mojom::NotifierType,
+ message_center::NotifierId::NotifierType> {
+ static message_center::mojom::NotifierType ToMojom(
+ message_center::NotifierId::NotifierType input) {
+ switch (input) {
+ case message_center::NotifierId::APPLICATION:
+ return message_center::mojom::NotifierType::APPLICATION;
+ case message_center::NotifierId::ARC_APPLICATION:
+ return message_center::mojom::NotifierType::ARC_APPLICATION;
+ case message_center::NotifierId::WEB_PAGE:
+ return message_center::mojom::NotifierType::WEB_PAGE;
+ case message_center::NotifierId::SYSTEM_COMPONENT:
+ return message_center::mojom::NotifierType::SYSTEM_COMPONENT;
+ case message_center::NotifierId::SIZE:
+ break;
+ }
+ NOTREACHED();
+ return message_center::mojom::NotifierType::SIZE;
+ }
+
+ static bool FromMojom(message_center::mojom::NotifierType input,
+ message_center::NotifierId::NotifierType* out) {
+ switch (input) {
+ case message_center::mojom::NotifierType::APPLICATION:
+ *out = message_center::NotifierId::APPLICATION;
+ return true;
+ case message_center::mojom::NotifierType::ARC_APPLICATION:
+ *out = message_center::NotifierId::ARC_APPLICATION;
+ return true;
+ case message_center::mojom::NotifierType::WEB_PAGE:
+ *out = message_center::NotifierId::WEB_PAGE;
+ return true;
+ case message_center::mojom::NotifierType::SYSTEM_COMPONENT:
+ *out = message_center::NotifierId::SYSTEM_COMPONENT;
+ return true;
+ case message_center::mojom::NotifierType::SIZE:
+ break;
+ }
+ NOTREACHED();
+ return false;
+ }
+};
+
+template <>
+struct StructTraits<message_center::mojom::NotifierIdDataView,
+ message_center::NotifierId> {
+ static const message_center::NotifierId::NotifierType& type(
+ const message_center::NotifierId& n);
+ static const std::string& id(const message_center::NotifierId& n);
+ static const GURL& url(const message_center::NotifierId& n);
+ static const std::string& profile_id(const message_center::NotifierId& n);
+ static bool Read(message_center::mojom::NotifierIdDataView data,
+ message_center::NotifierId* out);
+};
+
+} // namespace mojo
+
+#endif // UI_MESSAGE_CENTER_NOTIFIER_ID_STRUCT_TRAITS_H_
diff --git a/chromium/ui/message_center/mojo/struct_traits_unittest.cc b/chromium/ui/message_center/mojo/struct_traits_unittest.cc
index ebe69ac221c..784a0e5bc52 100644
--- a/chromium/ui/message_center/mojo/struct_traits_unittest.cc
+++ b/chromium/ui/message_center/mojo/struct_traits_unittest.cc
@@ -11,7 +11,7 @@
#include "ui/gfx/image/image_unittest_util.h"
#include "ui/message_center/mojo/traits_test_service.mojom.h"
#include "ui/message_center/notification.h"
-#include "ui/message_center/notifier_settings.h"
+#include "ui/message_center/notifier_id.h"
namespace message_center {
namespace {
@@ -28,6 +28,7 @@ class StructTraitsTest : public testing::Test, public mojom::TraitsTestService {
}
void Compare(const Notification& input, const Notification& output) {
+ EXPECT_EQ(input.type(), output.type());
EXPECT_EQ(input.id(), output.id());
EXPECT_EQ(input.title(), output.title());
EXPECT_EQ(input.message(), output.message());
@@ -35,6 +36,16 @@ class StructTraitsTest : public testing::Test, public mojom::TraitsTestService {
EXPECT_EQ(input.icon().Height(), output.icon().Height());
EXPECT_EQ(input.display_source(), output.display_source());
EXPECT_EQ(input.origin_url(), output.origin_url());
+ EXPECT_EQ(input.progress(), output.progress());
+ EXPECT_EQ(input.progress_status(), output.progress_status());
+ EXPECT_EQ(input.rich_notification_data()
+ .should_make_spoken_feedback_for_popup_updates,
+ output.rich_notification_data()
+ .should_make_spoken_feedback_for_popup_updates);
+ EXPECT_EQ(input.clickable(), output.clickable());
+ EXPECT_EQ(input.accessible_name(), output.accessible_name());
+ EXPECT_EQ(input.accent_color(), output.accent_color());
+ EXPECT_EQ(input.use_image_as_icon(), output.use_image_as_icon());
}
private:
@@ -63,10 +74,21 @@ TEST_F(StructTraitsTest, Notification) {
NotifierId notifier_id(NotifierId::NotifierType::APPLICATION, id);
Notification input(type, id, title, message, icon, display_source, origin_url,
notifier_id, RichNotificationData(), nullptr);
+
mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy();
Notification output;
proxy->EchoNotification(input, &output);
Compare(input, output);
+
+ // Set some optional fields to non-default values and test again.
+ input.set_type(NotificationType::NOTIFICATION_TYPE_PROGRESS);
+ input.set_progress(50);
+ input.set_progress_status(base::ASCIIToUTF16("progress text"));
+ input.set_clickable(!input.clickable());
+ input.set_accent_color(SK_ColorMAGENTA);
+ input.set_use_image_as_icon(!input.use_image_as_icon());
+ proxy->EchoNotification(input, &output);
+ Compare(input, output);
}
TEST_F(StructTraitsTest, EmptyIconNotification) {
diff --git a/chromium/ui/message_center/mojo/typemaps.gni b/chromium/ui/message_center/mojo/typemaps.gni
index 211a0d7f8f2..a7f5b3d481c 100644
--- a/chromium/ui/message_center/mojo/typemaps.gni
+++ b/chromium/ui/message_center/mojo/typemaps.gni
@@ -2,4 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-typemaps = [ "//ui/message_center/mojo/notification.typemap" ]
+typemaps = [
+ "//ui/message_center/mojo/notification.typemap",
+ "//ui/message_center/mojo/notifier_id.typemap",
+]
diff --git a/chromium/ui/message_center/notification.cc b/chromium/ui/message_center/notification.cc
index 9b2616a481b..4ef3cb68563 100644
--- a/chromium/ui/message_center/notification.cc
+++ b/chromium/ui/message_center/notification.cc
@@ -33,6 +33,13 @@ const gfx::ImageSkia CreateSolidColorImage(int width,
return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
}
+gfx::Image DeepCopyImage(const gfx::Image& image) {
+ if (image.IsEmpty())
+ return gfx::Image();
+ std::unique_ptr<gfx::ImageSkia> image_skia(image.CopyImageSkia());
+ return gfx::Image(*image_skia);
+}
+
} // namespace
NotificationItem::NotificationItem(const base::string16& title,
@@ -60,6 +67,7 @@ RichNotificationData::RichNotificationData(const RichNotificationData& other)
context_message(other.context_message),
image(other.image),
small_image(other.small_image),
+ vector_small_image(other.vector_small_image),
items(other.items),
progress(other.progress),
progress_status(other.progress_status),
@@ -75,7 +83,9 @@ RichNotificationData::RichNotificationData(const RichNotificationData& other)
silent(other.silent),
accessible_name(other.accessible_name),
accent_color(other.accent_color),
- use_image_as_icon(other.use_image_as_icon) {
+ use_image_as_icon(other.use_image_as_icon),
+ settings_button_handler(other.settings_button_handler),
+ fullscreen_visibility(other.fullscreen_visibility) {
}
RichNotificationData::~RichNotificationData() = default;
@@ -156,6 +166,29 @@ Notification& Notification::operator=(const Notification& other) {
Notification::~Notification() = default;
+// static
+std::unique_ptr<Notification> Notification::DeepCopy(
+ const Notification& notification,
+ bool include_body_image,
+ bool include_small_image,
+ bool include_icon_images) {
+ std::unique_ptr<Notification> notification_copy =
+ std::make_unique<Notification>(notification);
+ notification_copy->set_icon(DeepCopyImage(notification_copy->icon()));
+ notification_copy->set_image(include_body_image
+ ? DeepCopyImage(notification_copy->image())
+ : gfx::Image());
+ notification_copy->set_small_image(
+ include_small_image ? notification_copy->small_image() : gfx::Image());
+ for (size_t i = 0; i < notification_copy->buttons().size(); i++) {
+ notification_copy->SetButtonIcon(
+ i, include_icon_images
+ ? DeepCopyImage(notification_copy->buttons()[i].icon)
+ : gfx::Image());
+ }
+ return notification_copy;
+}
+
bool Notification::IsRead() const {
return is_read_ || optional_fields_.priority == MIN_PRIORITY;
}
@@ -212,6 +245,7 @@ std::unique_ptr<Notification> Notification::CreateSystemNotification(
const gfx::Image& icon,
const std::string& system_component_id,
const base::Closure& click_callback) {
+ DCHECK(!click_callback.is_null());
std::unique_ptr<Notification> notification = CreateSystemNotification(
NOTIFICATION_TYPE_SIMPLE, notification_id, title, message, icon,
base::string16() /* display_source */, GURL(),
@@ -219,6 +253,7 @@ std::unique_ptr<Notification> Notification::CreateSystemNotification(
RichNotificationData(),
new HandleNotificationClickedDelegate(click_callback), gfx::kNoneIcon,
SystemNotificationWarningLevel::CRITICAL_WARNING);
+ notification->set_clickable(true);
notification->SetSystemPriority();
return notification;
}
diff --git a/chromium/ui/message_center/notification.h b/chromium/ui/message_center/notification.h
index 6025b06ce05..17b50bfc879 100644
--- a/chromium/ui/message_center/notification.h
+++ b/chromium/ui/message_center/notification.h
@@ -24,7 +24,7 @@
#include "ui/message_center/message_center_export.h"
#include "ui/message_center/notification_delegate.h"
#include "ui/message_center/notification_types.h"
-#include "ui/message_center/notifier_settings.h"
+#include "ui/message_center/notifier_id.h"
#include "url/gurl.h"
namespace gfx {
@@ -54,6 +54,12 @@ enum class ButtonType {
TEXT
};
+enum class SettingsButtonHandler {
+ NONE, // No button. This is the default.
+ TRAY, // Button shown, the tray handles clicks. Only used on Chrome OS.
+ DELEGATE // Button shown, notification's delegate handles action.
+};
+
enum class SystemNotificationWarningLevel { NORMAL, WARNING, CRITICAL_WARNING };
// Represents a button to be shown as part of a notification.
@@ -79,6 +85,15 @@ struct MESSAGE_CENTER_EXPORT ButtonInfo {
base::string16 placeholder;
};
+// TODO(estade): add an ALWAYS value to mark notifications as additionally
+// visible over system fullscreen windows such as Chrome OS login so we don't
+// need to centrally track Ash system notification IDs.
+enum class FullscreenVisibility {
+ NONE, // Don't show the notification over fullscreen (default).
+ OVER_USER, // Show over the current fullscreened client window.
+ // windows (like Chrome OS login).
+};
+
// Represents rich features available for notifications.
class MESSAGE_CENTER_EXPORT RichNotificationData {
public:
@@ -179,11 +194,18 @@ class MESSAGE_CENTER_EXPORT RichNotificationData {
// and hides the icon when the notification is expanded.
// This is only effective when new style notification is enabled.
bool use_image_as_icon = false;
+
+ // Controls whether a settings button should appear on the notification. See
+ // enum definition. TODO(estade): turn this into a boolean. See
+ // crbug.com/780342
+ SettingsButtonHandler settings_button_handler = SettingsButtonHandler::NONE;
+
+ FullscreenVisibility fullscreen_visibility = FullscreenVisibility::NONE;
};
class MESSAGE_CENTER_EXPORT Notification {
public:
- // Default constructor needed for generated mojom files
+ // Default constructor needed for generated mojom files.
Notification();
// Creates a new notification.
@@ -228,6 +250,15 @@ class MESSAGE_CENTER_EXPORT Notification {
virtual ~Notification();
+ // Performs a deep copy of |notification|, including images and (optionally)
+ // the body image, small image, and icon images which are not supported on all
+ // platforms.
+ static std::unique_ptr<Notification> DeepCopy(
+ const Notification& notification,
+ bool include_body_image,
+ bool include_small_image,
+ bool include_icon_images);
+
// Copies the internal on-memory state from |base|, i.e. shown_as_popup,
// is_read and never_timeout.
void CopyState(Notification* base);
@@ -410,19 +441,35 @@ class MESSAGE_CENTER_EXPORT Notification {
optional_fields_.use_image_as_icon = use_image_as_icon;
}
+ bool should_show_settings_button() const {
+ return optional_fields_.settings_button_handler !=
+ SettingsButtonHandler::NONE;
+ }
+
+ FullscreenVisibility fullscreen_visibility() const {
+ return optional_fields_.fullscreen_visibility;
+ }
+ void set_fullscreen_visibility(FullscreenVisibility visibility) {
+ optional_fields_.fullscreen_visibility = visibility;
+ }
+
NotificationDelegate* delegate() const { return delegate_.get(); }
const RichNotificationData& rich_notification_data() const {
return optional_fields_;
}
+ void set_delegate(scoped_refptr<NotificationDelegate> delegate) {
+ DCHECK(!delegate_);
+ delegate_ = delegate;
+ }
+
// Set the priority to SYSTEM. The system priority user needs to call this
// method explicitly, to avoid setting it accidentally.
void SetSystemPriority();
// Delegate actions.
void Display() const { delegate()->Display(); }
- bool HasClickedListener() const { return delegate()->HasClickedListener(); }
void Click() const { delegate()->Click(); }
void ButtonClick(int index) const { delegate()->ButtonClick(index); }
void Close(bool by_user) const { delegate()->Close(by_user); }
diff --git a/chromium/ui/message_center/notification_delegate.cc b/chromium/ui/message_center/notification_delegate.cc
index b35ee321f10..95b3fe3e91b 100644
--- a/chromium/ui/message_center/notification_delegate.cc
+++ b/chromium/ui/message_center/notification_delegate.cc
@@ -14,8 +14,6 @@ void NotificationDelegate::Display() {}
void NotificationDelegate::Close(bool by_user) {}
-bool NotificationDelegate::HasClickedListener() { return false; }
-
void NotificationDelegate::Click() {}
void NotificationDelegate::ButtonClick(int button_index) {}
@@ -25,13 +23,7 @@ void NotificationDelegate::ButtonClickWithReply(int button_index,
NOTIMPLEMENTED();
}
-bool NotificationDelegate::SettingsClick() {
- return false;
-}
-
-bool NotificationDelegate::ShouldDisplaySettingsButton() {
- return false;
-}
+void NotificationDelegate::SettingsClick() {}
void NotificationDelegate::DisableNotification() {}
@@ -44,10 +36,6 @@ HandleNotificationClickedDelegate::HandleNotificationClickedDelegate(
HandleNotificationClickedDelegate::~HandleNotificationClickedDelegate() {}
-bool HandleNotificationClickedDelegate::HasClickedListener() {
- return !closure_.is_null();
-}
-
void HandleNotificationClickedDelegate::Click() {
if (!closure_.is_null())
closure_.Run();
@@ -68,8 +56,4 @@ void HandleNotificationButtonClickDelegate::ButtonClick(int button_index) {
button_callback_.Run(button_index);
}
-bool NotificationDelegate::ShouldDisplayOverFullscreen() const {
- return false;
-}
-
} // namespace message_center
diff --git a/chromium/ui/message_center/notification_delegate.h b/chromium/ui/message_center/notification_delegate.h
index 00633d1e663..97108481dd4 100644
--- a/chromium/ui/message_center/notification_delegate.h
+++ b/chromium/ui/message_center/notification_delegate.h
@@ -16,10 +16,6 @@
namespace message_center {
-class MessageCenterController;
-class MessageView;
-class Notification;
-
// Delegate for a notification. This class has two roles: to implement callback
// methods for notification, and to provide an identity of the associated
// notification.
@@ -33,9 +29,6 @@ class MESSAGE_CENTER_EXPORT NotificationDelegate
// user explicitly (as opposed to timeout/script), |by_user| should be true.
virtual void Close(bool by_user);
- // Returns true if the delegate can handle click event.
- virtual bool HasClickedListener();
-
// To be called when a desktop notification is clicked.
virtual void Click();
@@ -48,30 +41,13 @@ class MESSAGE_CENTER_EXPORT NotificationDelegate
virtual void ButtonClickWithReply(int button_index,
const base::string16& reply);
- // To be called when the user clicks the settings button in a notification.
- // Returns whether the settings click was handled by the delegate.
- virtual bool SettingsClick();
-
- // To be called in order to detect if a settings button should be displayed.
- // This also controls whether a context menu is enabled (as the context menu
- // is also used for controlling settings).
- virtual bool ShouldDisplaySettingsButton();
+ // To be called when the user clicks the settings button in a notification
+ // which has a CUSTOM settings button action.
+ virtual void SettingsClick();
// Called when the user attempts to disable the notification.
virtual void DisableNotification();
-#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
- // To be called to construct the message view for notifications whose type is
- // NOTIFICATION_TYPE_CUSTOM.
- virtual std::unique_ptr<MessageView> CreateCustomMessageView(
- MessageCenterController* controller,
- const Notification& notification);
-#endif
-
- // Indicates whether this notification should be displayed when there is
- // fullscreen content being displayed.
- virtual bool ShouldDisplayOverFullscreen() const;
-
protected:
virtual ~NotificationDelegate() {}
@@ -87,7 +63,6 @@ class MESSAGE_CENTER_EXPORT HandleNotificationClickedDelegate
// message_center::NotificationDelegate overrides:
void Click() override;
- bool HasClickedListener() override;
protected:
~HandleNotificationClickedDelegate() override;
diff --git a/chromium/ui/message_center/notification_delegate_unittest.cc b/chromium/ui/message_center/notification_delegate_unittest.cc
index 3a8fe7135a5..d168cfe8173 100644
--- a/chromium/ui/message_center/notification_delegate_unittest.cc
+++ b/chromium/ui/message_center/notification_delegate_unittest.cc
@@ -47,7 +47,6 @@ TEST_F(NotificationDelegateTest, ClickedDelegate) {
base::Bind(&NotificationDelegateTest::ClickCallback,
base::Unretained(this))));
- EXPECT_TRUE(delegate->HasClickedListener());
delegate->Click();
EXPECT_EQ(1, GetClickedCallbackAndReset());
@@ -60,7 +59,6 @@ TEST_F(NotificationDelegateTest, NullClickedDelegate) {
scoped_refptr<HandleNotificationClickedDelegate> delegate(
new HandleNotificationClickedDelegate(base::Closure()));
- EXPECT_FALSE(delegate->HasClickedListener());
delegate->Click();
EXPECT_EQ(0, GetClickedCallbackAndReset());
@@ -68,4 +66,4 @@ TEST_F(NotificationDelegateTest, NullClickedDelegate) {
EXPECT_EQ(0, GetClickedCallbackAndReset());
}
-}
+} // namespace message_center
diff --git a/chromium/ui/message_center/notification_delegate_views.cc b/chromium/ui/message_center/notification_delegate_views.cc
deleted file mode 100644
index 6f1bc726b1e..00000000000
--- a/chromium/ui/message_center/notification_delegate_views.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2016 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 "ui/message_center/notification_delegate.h"
-
-#include "ui/message_center/views/message_view.h"
-
-namespace message_center {
-
-std::unique_ptr<MessageView> NotificationDelegate::CreateCustomMessageView(
- MessageCenterController* controller,
- const Notification& notification) {
- return nullptr;
-}
-
-} // namespace message_center
diff --git a/chromium/ui/message_center/notification_list.cc b/chromium/ui/message_center/notification_list.cc
index 4b240c04956..303b61f748a 100644
--- a/chromium/ui/message_center/notification_list.cc
+++ b/chromium/ui/message_center/notification_list.cc
@@ -168,17 +168,17 @@ bool NotificationList::HasPopupNotifications(
for (const auto& notification : notifications_) {
if (notification->priority() < DEFAULT_PRIORITY)
break;
- if (!ShouldShowNotificationAsPopup(*notification.get(), blockers))
- continue;
- if (!notification->shown_as_popup())
+ if (!notification->shown_as_popup() &&
+ ShouldShowNotificationAsPopup(*notification.get(), blockers)) {
return true;
+ }
}
return false;
}
NotificationList::PopupNotifications NotificationList::GetPopupNotifications(
const NotificationBlockers& blockers,
- std::list<std::string>* blocked_ids) {
+ std::list<const Notification*>* blocked) {
PopupNotifications result;
size_t default_priority_popup_count = 0;
@@ -194,8 +194,8 @@ NotificationList::PopupNotifications NotificationList::GetPopupNotifications(
continue;
if (!ShouldShowNotificationAsPopup(*notification, blockers)) {
- if (blocked_ids)
- blocked_ids->push_back(notification->id());
+ if (blocked)
+ blocked->push_back(notification);
continue;
}
@@ -288,18 +288,6 @@ size_t NotificationList::NotificationCount(
return GetVisibleNotifications(blockers).size();
}
-size_t NotificationList::UnreadCount(
- const NotificationBlockers& blockers) const {
- Notifications notifications = GetVisibleNotifications(blockers);
- size_t unread_count = 0;
- for (Notifications::const_iterator iter = notifications.begin();
- iter != notifications.end(); ++iter) {
- if (!(*iter)->IsRead())
- ++unread_count;
- }
- return unread_count;
-}
-
NotificationList::OwnedNotifications::iterator
NotificationList::GetNotification(const std::string& id) {
for (auto iter = notifications_.begin(); iter != notifications_.end();
diff --git a/chromium/ui/message_center/notification_list.h b/chromium/ui/message_center/notification_list.h
index c942fd156bf..9acf7fabcfe 100644
--- a/chromium/ui/message_center/notification_list.h
+++ b/chromium/ui/message_center/notification_list.h
@@ -110,12 +110,12 @@ class MESSAGE_CENTER_EXPORT NotificationList {
// Returns the recent notifications of the priority higher then LOW,
// that have not been shown as a popup. kMaxVisiblePopupNotifications are
// used to limit the number of notifications for the DEFAULT priority.
- // It also stores the list of notification ids which is blocked by |blockers|
- // to |blocked_ids|. |blocked_ids| can be NULL if the caller doesn't care
- // which notifications are blocked.
+ // It also stores the list of notifications which are blocked by |blockers|
+ // to |blocked|. |blocked| can be NULL if the caller doesn't care which
+ // notifications are blocked.
PopupNotifications GetPopupNotifications(
const NotificationBlockers& blockers,
- std::list<std::string>* blocked_ids);
+ std::list<const Notification*>* blocked);
// Marks a specific popup item as shown. Set |mark_notification_as_read| to
// true in case marking the notification as read too.
@@ -145,7 +145,6 @@ class MESSAGE_CENTER_EXPORT NotificationList {
Notifications GetVisibleNotifications(
const NotificationBlockers& blockers) const;
size_t NotificationCount(const NotificationBlockers& blockers) const;
- size_t UnreadCount(const NotificationBlockers& blockers) const;
private:
friend class NotificationListTest;
diff --git a/chromium/ui/message_center/notification_list_unittest.cc b/chromium/ui/message_center/notification_list_unittest.cc
index 2bef6740e73..5f90837e180 100644
--- a/chromium/ui/message_center/notification_list_unittest.cc
+++ b/chromium/ui/message_center/notification_list_unittest.cc
@@ -17,7 +17,7 @@
#include "ui/message_center/fake_message_center.h"
#include "ui/message_center/notification_blocker.h"
#include "ui/message_center/notification_types.h"
-#include "ui/message_center/notifier_settings.h"
+#include "ui/message_center/notifier_id.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
using base::UTF8ToUTF16;
@@ -130,13 +130,11 @@ const char NotificationListTest::kExtensionId[] = "ext";
TEST_F(NotificationListTest, Basic) {
ASSERT_EQ(0u, notification_list()->NotificationCount(blockers()));
- ASSERT_EQ(0u, notification_list()->UnreadCount(blockers()));
std::string id0 = AddNotification();
EXPECT_EQ(1u, notification_list()->NotificationCount(blockers()));
std::string id1 = AddNotification();
EXPECT_EQ(2u, notification_list()->NotificationCount(blockers()));
- EXPECT_EQ(2u, notification_list()->UnreadCount(blockers()));
EXPECT_TRUE(notification_list()->HasPopupNotifications(blockers()));
EXPECT_TRUE(notification_list()->GetNotificationById(id0));
@@ -152,7 +150,6 @@ TEST_F(NotificationListTest, Basic) {
notification_list()->RemoveNotification(id0);
EXPECT_EQ(1u, notification_list()->NotificationCount(blockers()));
- EXPECT_EQ(1u, notification_list()->UnreadCount(blockers()));
AddNotification();
EXPECT_EQ(2u, notification_list()->NotificationCount(blockers()));
@@ -161,28 +158,13 @@ TEST_F(NotificationListTest, Basic) {
TEST_F(NotificationListTest, MessageCenterVisible) {
AddNotification();
EXPECT_EQ(1u, notification_list()->NotificationCount(blockers()));
- ASSERT_EQ(1u, notification_list()->UnreadCount(blockers()));
ASSERT_EQ(1u, GetPopupCounts());
// Resets the unread count and popup counts.
notification_list()->SetNotificationsShown(blockers(), NULL);
- ASSERT_EQ(0u, notification_list()->UnreadCount(blockers()));
ASSERT_EQ(0u, GetPopupCounts());
}
-TEST_F(NotificationListTest, UnreadCount) {
- std::string id0 = AddNotification();
- std::string id1 = AddNotification();
- ASSERT_EQ(2u, notification_list()->UnreadCount(blockers()));
-
- notification_list()->MarkSinglePopupAsDisplayed(id0);
- EXPECT_EQ(1u, notification_list()->UnreadCount(blockers()));
- notification_list()->MarkSinglePopupAsDisplayed(id0);
- EXPECT_EQ(1u, notification_list()->UnreadCount(blockers()));
- notification_list()->MarkSinglePopupAsDisplayed(id1);
- EXPECT_EQ(0u, notification_list()->UnreadCount(blockers()));
-}
-
TEST_F(NotificationListTest, UpdateNotification) {
std::string id0 = AddNotification();
std::string replaced = id0 + "_replaced";
@@ -300,7 +282,6 @@ TEST_F(NotificationListTest, OldPopupShouldNotBeHidden) {
TEST_F(NotificationListTest, Priority) {
ASSERT_EQ(0u, notification_list()->NotificationCount(blockers()));
- ASSERT_EQ(0u, notification_list()->UnreadCount(blockers()));
// Default priority has the limit on the number of the popups.
for (size_t i = 0; i <= kMaxVisiblePopupNotifications; ++i)
@@ -311,18 +292,15 @@ TEST_F(NotificationListTest, Priority) {
// Low priority: not visible to popups.
notification_list()->SetNotificationsShown(blockers(), NULL);
- EXPECT_EQ(0u, notification_list()->UnreadCount(blockers()));
AddPriorityNotification(LOW_PRIORITY);
EXPECT_EQ(kMaxVisiblePopupNotifications + 2,
notification_list()->NotificationCount(blockers()));
- EXPECT_EQ(1u, notification_list()->UnreadCount(blockers()));
EXPECT_EQ(0u, GetPopupCounts());
// Minimum priority: doesn't update the unread count.
AddPriorityNotification(MIN_PRIORITY);
EXPECT_EQ(kMaxVisiblePopupNotifications + 3,
notification_list()->NotificationCount(blockers()));
- EXPECT_EQ(1u, notification_list()->UnreadCount(blockers()));
EXPECT_EQ(0u, GetPopupCounts());
NotificationList::Notifications notifications =
@@ -344,7 +322,6 @@ TEST_F(NotificationListTest, Priority) {
TEST_F(NotificationListTest, HasPopupsWithPriority) {
ASSERT_EQ(0u, notification_list()->NotificationCount(blockers()));
- ASSERT_EQ(0u, notification_list()->UnreadCount(blockers()));
AddPriorityNotification(MIN_PRIORITY);
AddPriorityNotification(MAX_PRIORITY);
@@ -354,7 +331,6 @@ TEST_F(NotificationListTest, HasPopupsWithPriority) {
TEST_F(NotificationListTest, HasPopupsWithSystemPriority) {
ASSERT_EQ(0u, notification_list()->NotificationCount(blockers()));
- ASSERT_EQ(0u, notification_list()->UnreadCount(blockers()));
std::string normal_id = AddPriorityNotification(DEFAULT_PRIORITY);
std::string system_id = AddNotification();
@@ -549,7 +525,6 @@ TEST_F(NotificationListTest, MarkSinglePopupAsShown) {
notification_list()->MarkSinglePopupAsShown(id2, true);
notification_list()->MarkSinglePopupAsShown(id3, false);
EXPECT_EQ(3u, notification_list()->NotificationCount(blockers()));
- EXPECT_EQ(1u, notification_list()->UnreadCount(blockers()));
EXPECT_EQ(1u, GetPopupCounts());
NotificationList::PopupNotifications popups = GetPopups();
EXPECT_EQ(id1, (*popups.begin())->id());
@@ -614,26 +589,6 @@ TEST_F(NotificationListTest, QuietMode) {
// TODO(mukai): Add test of quiet mode with expiration.
}
-// Verifies that unread_count doesn't become negative.
-TEST_F(NotificationListTest, UnreadCountNoNegative) {
- std::string id = AddNotification();
- EXPECT_EQ(1u, notification_list()->UnreadCount(blockers()));
-
- notification_list()->MarkSinglePopupAsDisplayed(id);
- EXPECT_EQ(0u, notification_list()->UnreadCount(blockers()));
- notification_list()->MarkSinglePopupAsShown(
- id, false /* mark_notification_as_read */);
- EXPECT_EQ(1u, notification_list()->UnreadCount(blockers()));
-
- // Updates the notification and verifies unread_count doesn't change.
- std::unique_ptr<Notification> updated_notification(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, id, UTF8ToUTF16("updated"),
- UTF8ToUTF16("updated"), gfx::Image(), base::string16(), GURL(),
- NotifierId(), RichNotificationData(), NULL));
- notification_list()->AddNotification(std::move(updated_notification));
- EXPECT_EQ(1u, notification_list()->UnreadCount(blockers()));
-}
-
TEST_F(NotificationListTest, TestPushingShownNotification) {
// Create a notification and mark it as shown.
std::string id1;
diff --git a/chromium/ui/message_center/notifier_settings.cc b/chromium/ui/message_center/notifier_id.cc
index e7099fd55cf..6bf32a3352f 100644
--- a/chromium/ui/message_center/notifier_settings.cc
+++ b/chromium/ui/message_center/notifier_id.cc
@@ -2,27 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "ui/message_center/notifier_id.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
-#include "ui/message_center/notifier_settings.h"
namespace message_center {
-NotifierId::NotifierId(NotifierType type,
- const std::string& id)
- : type(type),
- id(id) {
+NotifierId::NotifierId() : type(SYSTEM_COMPONENT) {}
+
+NotifierId::NotifierId(NotifierType type, const std::string& id)
+ : type(type), id(id) {
DCHECK(type != WEB_PAGE);
DCHECK(!id.empty());
}
-NotifierId::NotifierId(const GURL& url)
- : type(WEB_PAGE),
- url(url) {}
-
-NotifierId::NotifierId()
- : type(SYSTEM_COMPONENT) {
-}
+NotifierId::NotifierId(const GURL& url) : type(WEB_PAGE), url(url) {}
NotifierId::NotifierId(const NotifierId& other) = default;
@@ -52,21 +46,4 @@ bool NotifierId::operator<(const NotifierId& other) const {
return id < other.id;
}
-Notifier::Notifier(const NotifierId& notifier_id,
- const base::string16& name,
- bool enabled)
- : notifier_id(notifier_id),
- name(name),
- enabled(enabled) {
-}
-
-Notifier::~Notifier() {
-}
-
-NotifierGroup::NotifierGroup(const base::string16& name,
- const base::string16& login_info)
- : name(name), login_info(login_info) {}
-
-NotifierGroup::~NotifierGroup() {}
-
} // namespace message_center
diff --git a/chromium/ui/message_center/notifier_id.h b/chromium/ui/message_center/notifier_id.h
new file mode 100644
index 00000000000..ac11acd0f48
--- /dev/null
+++ b/chromium/ui/message_center/notifier_id.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2013 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 UI_MESSAGE_CENTER_NOTIFIER_ID_H_
+#define UI_MESSAGE_CENTER_NOTIFIER_ID_H_
+
+#include <stddef.h>
+
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/strings/string16.h"
+#include "ui/gfx/image/image.h"
+#include "ui/message_center/message_center_export.h"
+#include "url/gurl.h"
+
+namespace message_center {
+
+// A struct that identifies the source of notifications. For example, a web page
+// might send multiple notifications but they'd all have the same NotifierId.
+// TODO(estade): move to public directory.
+struct MESSAGE_CENTER_EXPORT NotifierId {
+ // This enum is being used for histogram reporting and the elements should not
+ // be re-ordered.
+ enum NotifierType : int {
+ APPLICATION = 0,
+ ARC_APPLICATION = 1,
+ WEB_PAGE = 2,
+ SYSTEM_COMPONENT = 3,
+ SIZE,
+ };
+
+ // Default constructor needed for generated mojom files and tests.
+ NotifierId();
+
+ // Constructor for non WEB_PAGE type.
+ NotifierId(NotifierType type, const std::string& id);
+
+ // Constructor for WEB_PAGE type.
+ explicit NotifierId(const GURL& url);
+
+ NotifierId(const NotifierId& other);
+
+ bool operator==(const NotifierId& other) const;
+ // Allows NotifierId to be used as a key in std::map.
+ bool operator<(const NotifierId& other) const;
+
+ NotifierType type;
+
+ // The identifier of the app notifier. Empty if it's WEB_PAGE.
+ std::string id;
+
+ // The URL pattern of the notifer.
+ GURL url;
+
+ // The identifier of the profile where the notification is created. This is
+ // used for ChromeOS multi-profile support and can be empty.
+ std::string profile_id;
+};
+
+} // namespace message_center
+
+#endif // UI_MESSAGE_CENTER_NOTIFIER_ID_H_
diff --git a/chromium/ui/message_center/notifier_settings.h b/chromium/ui/message_center/notifier_settings.h
deleted file mode 100644
index 39880de566a..00000000000
--- a/chromium/ui/message_center/notifier_settings.h
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright (c) 2013 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 UI_MESSAGE_CENTER_NOTIFIER_SETTINGS_H_
-#define UI_MESSAGE_CENTER_NOTIFIER_SETTINGS_H_
-
-#include <stddef.h>
-
-#include <string>
-#include <vector>
-
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/strings/string16.h"
-#include "ui/gfx/image/image.h"
-#include "ui/message_center/message_center_export.h"
-#include "url/gurl.h"
-
-class MessageCenterNotificationsTest;
-class MessageCenterTrayBridgeTest;
-
-namespace ash {
-class WebNotificationTrayTest;
-}
-
-namespace message_center {
-namespace test {
-class MessagePopupCollectionTest;
-}
-
-class MessageCenterNotificationManagerTest;
-class Notification;
-class NotifierSettingsDelegate;
-class NotifierSettingsProvider;
-
-// Brings up the settings dialog and returns a weak reference to the delegate,
-// which is typically the view. If the dialog already exists, it is brought to
-// the front, otherwise it is created.
-MESSAGE_CENTER_EXPORT NotifierSettingsDelegate* ShowSettings(
- NotifierSettingsProvider* provider,
- gfx::NativeView context);
-
-// A struct that identifies the source of notifications. For example, a web page
-// might send multiple notifications but they'd all have the same NotifierId.
-// TODO(estade): rename to Notifier.
-struct MESSAGE_CENTER_EXPORT NotifierId {
- // This enum is being used for histogram reporting and the elements should not
- // be re-ordered.
- enum NotifierType : int {
- APPLICATION = 0,
- ARC_APPLICATION = 1,
- WEB_PAGE = 2,
- SYSTEM_COMPONENT = 3,
- SIZE,
- };
-
- // Constructor for non WEB_PAGE type.
- NotifierId(NotifierType type, const std::string& id);
-
- // Constructor for WEB_PAGE type.
- explicit NotifierId(const GURL& url);
-
- NotifierId(const NotifierId& other);
-
- bool operator==(const NotifierId& other) const;
- // Allows NotifierId to be used as a key in std::map.
- bool operator<(const NotifierId& other) const;
-
- NotifierType type;
-
- // The identifier of the app notifier. Empty if it's WEB_PAGE.
- std::string id;
-
- // The URL pattern of the notifer.
- GURL url;
-
- // The identifier of the profile where the notification is created. This is
- // used for ChromeOS multi-profile support and can be empty.
- std::string profile_id;
-
- private:
- friend class MessageCenterNotificationManagerTest;
- friend class MessageCenterTrayTest;
- friend class Notification;
- friend class NotificationControllerTest;
- friend class PopupCollectionTest;
- friend class TrayViewControllerTest;
- friend class ::MessageCenterNotificationsTest;
- friend class ::MessageCenterTrayBridgeTest;
- friend class ash::WebNotificationTrayTest;
- friend class test::MessagePopupCollectionTest;
- FRIEND_TEST_ALL_PREFIXES(PopupControllerTest, Creation);
- FRIEND_TEST_ALL_PREFIXES(NotificationListTest, UnreadCountNoNegative);
- FRIEND_TEST_ALL_PREFIXES(NotificationListTest, TestHasNotificationOfType);
-
- // The default constructor which doesn't specify the notifier. Used for tests.
- NotifierId();
-};
-
-// A struct to hold UI information about notifiers. The data is used by
-// NotifierSettingsView. TODO(estade): rename to NotifierUiData.
-struct MESSAGE_CENTER_EXPORT Notifier {
- Notifier(const NotifierId& notifier_id,
- const base::string16& name,
- bool enabled);
- ~Notifier();
-
- NotifierId notifier_id;
-
- // The human-readable name of the notifier such like the extension name.
- // It can be empty.
- base::string16 name;
-
- // True if the source is allowed to send notifications. True is default.
- bool enabled;
-
- // The icon image of the notifier. The extension icon or favicon.
- gfx::Image icon;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Notifier);
-};
-
-struct MESSAGE_CENTER_EXPORT NotifierGroup {
- NotifierGroup(const base::string16& name, const base::string16& login_info);
- ~NotifierGroup();
-
- // Display name of a notifier group.
- const base::string16 name;
-
- // More display information about the notifier group.
- base::string16 login_info;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(NotifierGroup);
-};
-
-// An observer class implemented by the view of the NotifierSettings to get
-// notified when the controller has changed data.
-class MESSAGE_CENTER_EXPORT NotifierSettingsObserver {
- public:
- // Called when an icon in the controller has been updated.
- virtual void UpdateIconImage(const NotifierId& notifier_id,
- const gfx::Image& icon) = 0;
-
- // Called when any change happens to the set of notifier groups.
- virtual void NotifierGroupChanged() = 0;
-
- // Called when a notifier is enabled or disabled.
- virtual void NotifierEnabledChanged(const NotifierId& notifier_id,
- bool enabled) = 0;
-};
-
-// A class used by NotifierSettingsView to integrate with a setting system
-// for the clients of this module.
-class MESSAGE_CENTER_EXPORT NotifierSettingsProvider {
- public:
- virtual ~NotifierSettingsProvider() {}
-
- // Sets the delegate.
- virtual void AddObserver(NotifierSettingsObserver* observer) = 0;
- virtual void RemoveObserver(NotifierSettingsObserver* observer) = 0;
-
- // Returns the number of notifier groups available.
- virtual size_t GetNotifierGroupCount() const = 0;
-
- // Requests the model for a particular notifier group.
- virtual const message_center::NotifierGroup& GetNotifierGroupAt(
- size_t index) const = 0;
-
- // Returns true if the notifier group at |index| is active.
- virtual bool IsNotifierGroupActiveAt(size_t index) const = 0;
-
- // Informs the settings provider that further requests to GetNotifierList
- // should return notifiers for the specified notifier group.
- virtual void SwitchToNotifierGroup(size_t index) = 0;
-
- // Requests the currently active notifier group.
- virtual const message_center::NotifierGroup& GetActiveNotifierGroup()
- const = 0;
-
- // Provides the current notifier list in |notifiers|.
- virtual void GetNotifierList(
- std::vector<std::unique_ptr<Notifier>>* notifiers) = 0;
-
- // Called when the |enabled| for the given notifier has been changed by user
- // operation.
- virtual void SetNotifierEnabled(const NotifierId& notifier_id,
- bool enabled) = 0;
-
- // Called when the settings window is closed.
- virtual void OnNotifierSettingsClosing() = 0;
-
- // Called to determine if a particular notifier can respond to a request for
- // more information.
- virtual bool NotifierHasAdvancedSettings(const NotifierId& notifier_id)
- const = 0;
-
- // Called upon request for more information about a particular notifier.
- virtual void OnNotifierAdvancedSettingsRequested(
- const NotifierId& notifier_id,
- const std::string* notification_id) = 0;
-};
-
-} // namespace message_center
-
-#endif // UI_MESSAGE_CENTER_NOTIFIER_SETTINGS_H_
diff --git a/chromium/ui/message_center/popup_timers_controller.cc b/chromium/ui/message_center/popup_timers_controller.cc
index 49e5d85c683..359f1049129 100644
--- a/chromium/ui/message_center/popup_timers_controller.cc
+++ b/chromium/ui/message_center/popup_timers_controller.cc
@@ -14,10 +14,20 @@ namespace message_center {
namespace {
base::TimeDelta GetTimeoutForNotification(Notification* notification) {
- if (notification->notifier_id().type == NotifierId::WEB_PAGE ||
- notification->priority() > DEFAULT_PRIORITY) {
+// Web Notifications are given a longer on-screen time on non-Chrome OS
+// platforms as there is no notification center to dismiss them to.
+#if defined(OS_CHROMEOS)
+ const bool use_high_priority_delay =
+ notification->priority() > DEFAULT_PRIORITY;
+#else
+ const bool use_high_priority_delay =
+ notification->priority() > DEFAULT_PRIORITY ||
+ notification->notifier_id().type == NotifierId::WEB_PAGE;
+#endif
+
+ if (use_high_priority_delay)
return base::TimeDelta::FromSeconds(kAutocloseHighPriorityDelaySeconds);
- }
+
return base::TimeDelta::FromSeconds(kAutocloseDefaultDelaySeconds);
}
diff --git a/chromium/ui/message_center/public/cpp/message_center_constants.h b/chromium/ui/message_center/public/cpp/message_center_constants.h
index f07818a0861..cc0489c6a88 100644
--- a/chromium/ui/message_center/public/cpp/message_center_constants.h
+++ b/chromium/ui/message_center/public/cpp/message_center_constants.h
@@ -93,9 +93,9 @@ const SkColor kNotificationDefaultAccentColor = gfx::kChromeIconGrey;
// Not used when --enabled-new-style-notification is set.
const size_t kNotificationMaximumItems = 5;
-// Timing. Web Notifications always use high-priority timings. Given the absence
-// of a notification center on non-Chrome OS platforms, this improves users'
-// ability to interact with the toasts.
+// Timing. Web Notifications always use high-priority timings except on
+// Chrome OS. Given the absence of a notification center on non-Chrome OS
+// platforms, this improves users' ability to interact with the toasts.
const int kAutocloseDefaultDelaySeconds = 8;
const int kAutocloseHighPriorityDelaySeconds = 25;
@@ -127,9 +127,17 @@ const int kContextMessageLineLimit = 1;
// Around notifications ////////////////////////////////////////////////////////
-// DIP dimensions (H = horizontal, V = vertical).
-const int kMarginBetweenItems = 10; // H & V space around & between
- // notifications.
+#if defined(OS_CHROMEOS)
+// Horizontal & vertical thickness of the border around the notifications in the
+// notification list.
+constexpr int kNotificationBorderThickness = 1;
+// Horizontal & vertical space around & between notifications in the
+// notification list.
+constexpr int kMarginBetweenItemsInList = 8;
+#endif
+
+// Horizontal & vertical space around & between popup notifications.
+constexpr int kMarginBetweenPopups = 10;
// Shadow in the tray.
const SkColor kShadowColor = SkColorSetARGB(0.3 * 255, 0, 0, 0);
diff --git a/chromium/ui/message_center/ui_controller.cc b/chromium/ui/message_center/ui_controller.cc
new file mode 100644
index 00000000000..3fd67d1474d
--- /dev/null
+++ b/chromium/ui/message_center/ui_controller.cc
@@ -0,0 +1,201 @@
+// Copyright (c) 2013 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 "ui/message_center/ui_controller.h"
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/models/simple_menu_model.h"
+#include "ui/message_center/message_center.h"
+#include "ui/message_center/message_center_types.h"
+#include "ui/message_center/notification_blocker.h"
+#include "ui/message_center/ui_delegate.h"
+#include "ui/message_center/views/notification_menu_model.h"
+#include "ui/strings/grit/ui_strings.h"
+
+namespace message_center {
+
+UiController::UiController(UiDelegate* delegate)
+ : message_center_(MessageCenter::Get()),
+ message_center_visible_(false),
+ popups_visible_(false),
+ delegate_(delegate) {
+ message_center_->AddObserver(this);
+}
+
+UiController::~UiController() {
+ message_center_->RemoveObserver(this);
+}
+
+bool UiController::ShowMessageCenterBubble(bool show_by_click) {
+ if (message_center_visible_)
+ return true;
+
+ HidePopupBubbleInternal();
+
+ message_center_visible_ = delegate_->ShowMessageCenter(show_by_click);
+ if (message_center_visible_) {
+ message_center_->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER);
+ NotifyUiControllerChanged();
+ }
+ return message_center_visible_;
+}
+
+bool UiController::HideMessageCenterBubble() {
+#if defined(OS_CHROMEOS)
+ // TODO(yoshiki): Move the message center bubble related logic to ash/.
+ hide_empty_message_center_callback_.reset();
+#endif
+
+ if (!message_center_visible_)
+ return false;
+ delegate_->HideMessageCenter();
+ MarkMessageCenterHidden();
+
+ return true;
+}
+
+void UiController::MarkMessageCenterHidden() {
+ if (!message_center_visible_)
+ return;
+ message_center_visible_ = false;
+ message_center_->SetVisibility(message_center::VISIBILITY_TRANSIENT);
+
+ // Some notifications (like system ones) should appear as popups again
+ // after the message center is closed.
+ if (message_center_->HasPopupNotifications()) {
+ ShowPopupBubble();
+ return;
+ }
+
+ NotifyUiControllerChanged();
+}
+
+void UiController::ShowPopupBubble() {
+ if (message_center_visible_)
+ return;
+
+ if (popups_visible_) {
+ NotifyUiControllerChanged();
+ return;
+ }
+
+ if (!message_center_->HasPopupNotifications())
+ return;
+
+ popups_visible_ = delegate_->ShowPopups();
+
+ NotifyUiControllerChanged();
+}
+
+bool UiController::HidePopupBubble() {
+ if (!popups_visible_)
+ return false;
+ HidePopupBubbleInternal();
+ NotifyUiControllerChanged();
+
+ return true;
+}
+
+void UiController::HidePopupBubbleInternal() {
+ if (!popups_visible_)
+ return;
+
+ delegate_->HidePopups();
+ popups_visible_ = false;
+}
+
+void UiController::ShowNotifierSettingsBubble() {
+ if (popups_visible_)
+ HidePopupBubbleInternal();
+
+ message_center_visible_ = delegate_->ShowNotifierSettings();
+ message_center_->SetVisibility(message_center::VISIBILITY_SETTINGS);
+
+ NotifyUiControllerChanged();
+}
+
+void UiController::OnNotificationAdded(const std::string& notification_id) {
+ OnMessageCenterChanged();
+}
+
+void UiController::OnNotificationRemoved(const std::string& notification_id,
+ bool by_user) {
+ OnMessageCenterChanged();
+}
+
+void UiController::OnNotificationUpdated(const std::string& notification_id) {
+ OnMessageCenterChanged();
+}
+
+void UiController::OnNotificationClicked(const std::string& notification_id) {
+ if (popups_visible_)
+ OnMessageCenterChanged();
+}
+
+void UiController::OnNotificationButtonClicked(
+ const std::string& notification_id,
+ int button_index) {
+ if (popups_visible_)
+ OnMessageCenterChanged();
+}
+
+void UiController::OnNotificationSettingsClicked(bool handled) {
+ if (!handled)
+ ShowNotifierSettingsBubble();
+}
+
+void UiController::OnNotificationDisplayed(const std::string& notification_id,
+ const DisplaySource source) {
+ NotifyUiControllerChanged();
+}
+
+void UiController::OnQuietModeChanged(bool in_quiet_mode) {
+ NotifyUiControllerChanged();
+}
+
+void UiController::OnBlockingStateChanged(NotificationBlocker* blocker) {
+ OnMessageCenterChanged();
+}
+
+void UiController::OnMessageCenterChanged() {
+#if defined(OS_CHROMEOS)
+ // TODO(yoshiki): Move the message center bubble related logic to ash/.
+ if (message_center_visible_ && message_center_->NotificationCount() == 0) {
+ if (hide_empty_message_center_callback_)
+ return;
+
+ hide_empty_message_center_callback_ =
+ std::make_unique<base::CancelableClosure>(base::Bind(
+ base::IgnoreResult(&UiController::HideMessageCenterBubble),
+ base::Unretained(this)));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, hide_empty_message_center_callback_->callback());
+ return;
+ }
+
+ // Cancel the callback if necessary.
+ if (hide_empty_message_center_callback_)
+ hide_empty_message_center_callback_.reset();
+#endif
+
+ if (popups_visible_ && !message_center_->HasPopupNotifications())
+ HidePopupBubbleInternal();
+ else if (!popups_visible_ && message_center_->HasPopupNotifications())
+ ShowPopupBubble();
+
+ NotifyUiControllerChanged();
+}
+
+void UiController::NotifyUiControllerChanged() {
+ delegate_->OnMessageCenterContentsChanged();
+}
+
+} // namespace message_center
diff --git a/chromium/ui/message_center/message_center_tray.h b/chromium/ui/message_center/ui_controller.h
index 7377d3bcddf..bbe26caa972 100644
--- a/chromium/ui/message_center/message_center_tray.h
+++ b/chromium/ui/message_center/ui_controller.h
@@ -2,33 +2,30 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_MESSAGE_CENTER_MESSAGE_CENTER_TRAY_H_
-#define UI_MESSAGE_CENTER_MESSAGE_CENTER_TRAY_H_
+#ifndef UI_MESSAGE_CENTER_UI_CONTROLLER_H_
+#define UI_MESSAGE_CENTER_UI_CONTROLLER_H_
+#include "base/cancelable_callback.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/strings/string16.h"
#include "ui/message_center/message_center_export.h"
#include "ui/message_center/message_center_observer.h"
-#include "ui/message_center/message_center_tray_delegate.h"
-#include "ui/message_center/notifier_settings.h"
-
-namespace ui {
-class MenuModel;
-}
+#include "ui/message_center/notifier_id.h"
+#include "ui/message_center/ui_delegate.h"
namespace message_center {
class MessageCenter;
-// Class that observes a MessageCenter. Manages the popup and message center
-// bubbles. Tells the MessageCenterTrayHost when the tray is changed, as well
-// as when bubbles are shown and hidden.
-class MESSAGE_CENTER_EXPORT MessageCenterTray : public MessageCenterObserver {
+// Class that observes a MessageCenter and reacts to changes in the list of
+// notifications. Manages the popup and message center bubbles. Tells the
+// UiDelegate when the tray is changed, as well as when bubbles are shown and
+// hidden.
+class MESSAGE_CENTER_EXPORT UiController : public MessageCenterObserver {
public:
- MessageCenterTray(MessageCenterTrayDelegate* delegate,
- message_center::MessageCenter* message_center);
- ~MessageCenterTray() override;
+ explicit UiController(UiDelegate* delegate);
+ ~UiController() override;
// Shows or updates the message center bubble and hides the popup bubble. Set
// |show_by_click| to true if bubble is shown by mouse or gesture click.
@@ -53,13 +50,9 @@ class MESSAGE_CENTER_EXPORT MessageCenterTray : public MessageCenterObserver {
// Toggles the visibility of the settings view in the message center bubble.
void ShowNotifierSettingsBubble();
- // Creates a model for the context menu for a notification card.
- std::unique_ptr<ui::MenuModel> CreateNotificationMenuModel(
- const Notification& notification);
-
bool message_center_visible() { return message_center_visible_; }
bool popups_visible() { return popups_visible_; }
- MessageCenterTrayDelegate* delegate() { return delegate_; }
+ UiDelegate* delegate() { return delegate_; }
const message_center::MessageCenter* message_center() const {
return message_center_;
}
@@ -81,20 +74,21 @@ class MESSAGE_CENTER_EXPORT MessageCenterTray : public MessageCenterObserver {
private:
void OnMessageCenterChanged();
- void NotifyMessageCenterTrayChanged();
+ void NotifyUiControllerChanged();
void HidePopupBubbleInternal();
- // |message_center_| is a weak pointer that must live longer than
- // MessageCenterTray.
message_center::MessageCenter* message_center_;
- bool message_center_visible_;
- bool popups_visible_;
- // |delegate_| is a weak pointer that must live longer than MessageCenterTray.
- MessageCenterTrayDelegate* delegate_;
+ bool message_center_visible_ = false;
+ bool popups_visible_ = false;
+ UiDelegate* delegate_;
+
+#if defined(OS_CHROMEOS)
+ std::unique_ptr<base::CancelableClosure> hide_empty_message_center_callback_;
+#endif
- DISALLOW_COPY_AND_ASSIGN(MessageCenterTray);
+ DISALLOW_COPY_AND_ASSIGN(UiController);
};
} // namespace message_center
-#endif // UI_MESSAGE_CENTER_MESSAGE_CENTER_TRAY_H_
+#endif // UI_MESSAGE_CENTER_UI_CONTROLLER_H_
diff --git a/chromium/ui/message_center/ui_controller_unittest.cc b/chromium/ui/message_center/ui_controller_unittest.cc
new file mode 100644
index 00000000000..75795f7277e
--- /dev/null
+++ b/chromium/ui/message_center/ui_controller_unittest.cc
@@ -0,0 +1,251 @@
+// Copyright (c) 2013 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 "ui/message_center/ui_controller.h"
+
+#include <utility>
+
+#include "base/macros.h"
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/models/menu_model.h"
+#include "ui/message_center/message_center.h"
+#include "ui/message_center/notification.h"
+#include "ui/message_center/notification_types.h"
+
+using base::ASCIIToUTF16;
+
+namespace message_center {
+namespace {
+
+class TestNotificationDelegate : public message_center::NotificationDelegate {
+ public:
+ TestNotificationDelegate() = default;
+
+ private:
+ ~TestNotificationDelegate() override = default;
+
+ DISALLOW_COPY_AND_ASSIGN(TestNotificationDelegate);
+};
+
+class MockDelegate : public UiDelegate {
+ public:
+ MockDelegate() {}
+ ~MockDelegate() override {}
+ void OnMessageCenterContentsChanged() override {}
+ bool ShowPopups() override { return show_message_center_success_; }
+ void HidePopups() override {}
+ bool ShowMessageCenter(bool show_by_click) override {
+ return show_popups_success_;
+ }
+ void HideMessageCenter() override {}
+ bool ShowNotifierSettings() override { return true; }
+
+ bool show_popups_success_ = true;
+ bool show_message_center_success_ = true;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockDelegate);
+};
+
+} // namespace
+
+class UiControllerTest : public testing::Test {
+ public:
+ UiControllerTest() {}
+ ~UiControllerTest() override {}
+
+ void SetUp() override {
+ MessageCenter::Initialize();
+ delegate_.reset(new MockDelegate);
+ message_center_ = MessageCenter::Get();
+ ui_controller_.reset(new UiController(delegate_.get()));
+ }
+
+ void TearDown() override {
+ ui_controller_.reset();
+ delegate_.reset();
+ message_center_ = NULL;
+ MessageCenter::Shutdown();
+ }
+
+ protected:
+ NotifierId DummyNotifierId() { return NotifierId(); }
+
+ Notification* AddNotification(const std::string& id) {
+ return AddNotification(id, DummyNotifierId());
+ }
+
+ Notification* AddNotification(const std::string& id, NotifierId notifier_id) {
+ std::unique_ptr<Notification> notification(
+ new Notification(message_center::NOTIFICATION_TYPE_SIMPLE, id,
+ ASCIIToUTF16("Test Web Notification"),
+ ASCIIToUTF16("Notification message body."),
+ gfx::Image(), ASCIIToUTF16("www.test.org"), GURL(),
+ notifier_id, message_center::RichNotificationData(),
+ new TestNotificationDelegate()));
+ Notification* notification_ptr = notification.get();
+ message_center_->AddNotification(std::move(notification));
+ return notification_ptr;
+ }
+ std::unique_ptr<MockDelegate> delegate_;
+ std::unique_ptr<UiController> ui_controller_;
+ MessageCenter* message_center_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(UiControllerTest);
+};
+
+TEST_F(UiControllerTest, BasicMessageCenter) {
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ bool shown =
+ ui_controller_->ShowMessageCenterBubble(false /* show_by_click */);
+ EXPECT_TRUE(shown);
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_TRUE(ui_controller_->message_center_visible());
+
+ ui_controller_->HideMessageCenterBubble();
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ ui_controller_->ShowMessageCenterBubble(false /* show_by_click */);
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_TRUE(ui_controller_->message_center_visible());
+
+ ui_controller_->HideMessageCenterBubble();
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+}
+
+TEST_F(UiControllerTest, BasicPopup) {
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ ui_controller_->ShowPopupBubble();
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ AddNotification("BasicPopup");
+
+ ASSERT_TRUE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ ui_controller_->HidePopupBubble();
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+}
+
+TEST_F(UiControllerTest, MessageCenterClosesPopups) {
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ AddNotification("MessageCenterClosesPopups");
+
+ ASSERT_TRUE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ bool shown =
+ ui_controller_->ShowMessageCenterBubble(false /* show_by_click */);
+ EXPECT_TRUE(shown);
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_TRUE(ui_controller_->message_center_visible());
+
+ // The notification is queued if it's added when message center is visible.
+ AddNotification("MessageCenterClosesPopups2");
+
+ ui_controller_->ShowPopupBubble();
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_TRUE(ui_controller_->message_center_visible());
+
+ ui_controller_->HideMessageCenterBubble();
+
+ // There is no queued notification.
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ ui_controller_->ShowMessageCenterBubble(false /* show_by_click */);
+ ui_controller_->HideMessageCenterBubble();
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+}
+
+TEST_F(UiControllerTest, MessageCenterReopenPopupsForSystemPriority) {
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ std::unique_ptr<Notification> notification(new Notification(
+ message_center::NOTIFICATION_TYPE_SIMPLE,
+ "MessageCenterReopnPopupsForSystemPriority",
+ ASCIIToUTF16("Test Web Notification"),
+ ASCIIToUTF16("Notification message body."), gfx::Image(),
+ ASCIIToUTF16("www.test.org"), GURL(), DummyNotifierId(),
+ message_center::RichNotificationData(), NULL /* delegate */));
+ notification->SetSystemPriority();
+ message_center_->AddNotification(std::move(notification));
+
+ ASSERT_TRUE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ bool shown =
+ ui_controller_->ShowMessageCenterBubble(false /* show_by_click */);
+ EXPECT_TRUE(shown);
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_TRUE(ui_controller_->message_center_visible());
+
+ ui_controller_->HideMessageCenterBubble();
+
+ ASSERT_TRUE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+}
+
+TEST_F(UiControllerTest, ShowBubbleFails) {
+ // Now the delegate will signal that it was unable to show a bubble.
+ delegate_->show_popups_success_ = false;
+ delegate_->show_message_center_success_ = false;
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ AddNotification("ShowBubbleFails");
+
+ ui_controller_->ShowPopupBubble();
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ bool shown =
+ ui_controller_->ShowMessageCenterBubble(false /* show_by_click */);
+ EXPECT_FALSE(shown);
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ ui_controller_->HideMessageCenterBubble();
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ ui_controller_->ShowMessageCenterBubble(false /* show_by_click */);
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+
+ ui_controller_->HidePopupBubble();
+
+ ASSERT_FALSE(ui_controller_->popups_visible());
+ ASSERT_FALSE(ui_controller_->message_center_visible());
+}
+
+} // namespace message_center
diff --git a/chromium/ui/message_center/message_center_tray_delegate.h b/chromium/ui/message_center/ui_delegate.h
index 11a13667be7..89d302673ac 100644
--- a/chromium/ui/message_center/message_center_tray_delegate.h
+++ b/chromium/ui/message_center/ui_delegate.h
@@ -2,23 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_MESSAGE_CENTER_MESSAGE_CENTER_TRAY_DELEGATE_H_
-#define UI_MESSAGE_CENTER_MESSAGE_CENTER_TRAY_DELEGATE_H_
+#ifndef UI_MESSAGE_CENTER_UI_DELEGATE_H_
+#define UI_MESSAGE_CENTER_UI_DELEGATE_H_
#include "ui/message_center/message_center_export.h"
namespace message_center {
-class MessageCenterTray;
-
-// A MessageCenterTrayDelegate class is responsible for managing the various UI
-// surfaces that should be displayed when the MessageCenter is changed.
-class MESSAGE_CENTER_EXPORT MessageCenterTrayDelegate {
+// A UiDelegate class is responsible for managing the various UI surfaces
+// (MessageCenter and popups) as notifications are added and updated.
+// Implementations are platform specific.
+class MESSAGE_CENTER_EXPORT UiDelegate {
public:
- virtual ~MessageCenterTrayDelegate() {};
+ virtual ~UiDelegate(){};
// Called whenever a change to the visible UI has occurred.
- virtual void OnMessageCenterTrayChanged() = 0;
+ virtual void OnMessageCenterContentsChanged() = 0;
// Display the popup bubbles for new notifications to the user. Returns true
// if popups were actually displayed to the user.
@@ -38,14 +37,8 @@ class MESSAGE_CENTER_EXPORT MessageCenterTrayDelegate {
// Display the notifier settings as a bubble.
virtual bool ShowNotifierSettings() = 0;
-
- // Show a platform-specific UI that informs the user how to open the message
- // center.
- virtual void DisplayFirstRunBalloon() {}
-
- virtual MessageCenterTray* GetMessageCenterTray() = 0;
};
} // namespace message_center
-#endif // UI_MESSAGE_CENTER_MESSAGE_CENTER_TRAY_DELEGATE_H_
+#endif // UI_MESSAGE_CENTER_UI_DELEGATE_H_
diff --git a/chromium/ui/message_center/views/bounded_label.cc b/chromium/ui/message_center/views/bounded_label.cc
index 64d88e4bf4f..334cc34f830 100644
--- a/chromium/ui/message_center/views/bounded_label.cc
+++ b/chromium/ui/message_center/views/bounded_label.cc
@@ -346,6 +346,19 @@ void BoundedLabel::GetAccessibleNodeData(ui::AXNodeData* node_data) {
label_->GetAccessibleNodeData(node_data);
}
+views::View* BoundedLabel::GetTooltipHandlerForPoint(const gfx::Point& point) {
+ if (GetSizeForWidthAndLines(width(), -1).height() <=
+ GetHeightForWidth(width())) {
+ return nullptr;
+ }
+ return HitTestPoint(point) ? this : nullptr;
+}
+
+bool BoundedLabel::GetTooltipText(const gfx::Point& p,
+ base::string16* tooltip) const {
+ return label_->GetTooltipText(p, tooltip);
+}
+
void BoundedLabel::OnBoundsChanged(const gfx::Rect& previous_bounds) {
label_->SetBoundsRect(bounds());
views::View::OnBoundsChanged(previous_bounds);
diff --git a/chromium/ui/message_center/views/bounded_label.h b/chromium/ui/message_center/views/bounded_label.h
index 8d204cdac19..1ae1a16f581 100644
--- a/chromium/ui/message_center/views/bounded_label.h
+++ b/chromium/ui/message_center/views/bounded_label.h
@@ -58,6 +58,9 @@ class MESSAGE_CENTER_EXPORT BoundedLabel : public views::View {
void OnPaint(gfx::Canvas* canvas) override;
bool CanProcessEventsWithinSubtree() const override;
void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
+ views::View* GetTooltipHandlerForPoint(const gfx::Point& point) override;
+ bool GetTooltipText(const gfx::Point& p,
+ base::string16* tooltip) const override;
protected:
// Overridden from views::View.
diff --git a/chromium/ui/message_center/views/desktop_popup_alignment_delegate.cc b/chromium/ui/message_center/views/desktop_popup_alignment_delegate.cc
index fbfb591b35d..56aa3b95cc6 100644
--- a/chromium/ui/message_center/views/desktop_popup_alignment_delegate.cc
+++ b/chromium/ui/message_center/views/desktop_popup_alignment_delegate.cc
@@ -35,14 +35,13 @@ void DesktopPopupAlignmentDelegate::StartObserving(display::Screen* screen) {
int DesktopPopupAlignmentDelegate::GetToastOriginX(
const gfx::Rect& toast_bounds) const {
if (IsFromLeft())
- return work_area_.x() + kMarginBetweenItems;
- return work_area_.right() - kMarginBetweenItems - toast_bounds.width();
+ return work_area_.x() + kMarginBetweenPopups;
+ return work_area_.right() - kMarginBetweenPopups - toast_bounds.width();
}
int DesktopPopupAlignmentDelegate::GetBaseLine() const {
- return IsTopDown()
- ? work_area_.y() + kMarginBetweenItems
- : work_area_.bottom() - kMarginBetweenItems;
+ return IsTopDown() ? work_area_.y() + kMarginBetweenPopups
+ : work_area_.bottom() - kMarginBetweenPopups;
}
gfx::Rect DesktopPopupAlignmentDelegate::GetWorkArea() const {
diff --git a/chromium/ui/message_center/views/message_popup_collection.cc b/chromium/ui/message_center/views/message_popup_collection.cc
index 989a427dce4..4fa28767e3d 100644
--- a/chromium/ui/message_center/views/message_popup_collection.cc
+++ b/chromium/ui/message_center/views/message_popup_collection.cc
@@ -17,10 +17,10 @@
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/message_center/message_center.h"
-#include "ui/message_center/message_center_tray.h"
#include "ui/message_center/notification.h"
#include "ui/message_center/notification_list.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/message_center/ui_controller.h"
#include "ui/message_center/views/message_view.h"
#include "ui/message_center/views/message_view_context_menu_controller.h"
#include "ui/message_center/views/message_view_factory.h"
@@ -43,13 +43,13 @@ const int kMouseExitedDeferTimeoutMs = 200;
// The margin between messages (and between the anchor unless
// first_item_has_no_margin was specified).
-const int kToastMarginY = kMarginBetweenItems;
+const int kToastMarginY = kMarginBetweenPopups;
} // namespace.
MessagePopupCollection::MessagePopupCollection(
MessageCenter* message_center,
- MessageCenterTray* tray,
+ UiController* tray,
PopupAlignmentDelegate* alignment_delegate)
: message_center_(message_center),
tray_(tray),
@@ -58,7 +58,7 @@ MessagePopupCollection::MessagePopupCollection(
latest_toast_entered_(NULL),
user_is_closing_toasts_by_clicking_(false),
target_top_edge_(0),
- context_menu_controller_(new MessageViewContextMenuController(this)),
+ context_menu_controller_(new MessageViewContextMenuController()),
weak_factory_(this) {
DCHECK(message_center_);
defer_timer_.reset(new base::OneShotTimer);
@@ -103,22 +103,20 @@ void MessagePopupCollection::RemoveNotification(
}
}
-std::unique_ptr<ui::MenuModel> MessagePopupCollection::CreateMenuModel(
- const Notification& notification) {
- return tray_->CreateNotificationMenuModel(notification);
-}
-
-bool MessagePopupCollection::HasClickedListener(
- const std::string& notification_id) {
- return message_center_->HasClickedListener(notification_id);
-}
-
void MessagePopupCollection::ClickOnNotificationButton(
const std::string& notification_id,
int button_index) {
message_center_->ClickOnNotificationButton(notification_id, button_index);
}
+void MessagePopupCollection::ClickOnNotificationButtonWithReply(
+ const std::string& notification_id,
+ int button_index,
+ const base::string16& reply) {
+ message_center_->ClickOnNotificationButtonWithReply(notification_id,
+ button_index, reply);
+}
+
void MessagePopupCollection::ClickOnSettingsButton(
const std::string& notification_id) {
message_center_->ClickOnSettingsButton(notification_id);
@@ -203,11 +201,10 @@ void MessagePopupCollection::UpdateWidgets() {
#endif // defined(OS_CHROMEOS)
view->SetExpanded(true);
- // TODO(yoshiki): Temporary disable context menu on custom notifications.
- // See crbug.com/750307 for detail.
+ // TODO(yoshiki): Temporarily disable context menu on custom (arc)
+ // notifications. See crbug.com/750307 for detail.
if (notification.type() != NOTIFICATION_TYPE_CUSTOM &&
- notification.delegate() &&
- notification.delegate()->ShouldDisplaySettingsButton()) {
+ notification.should_show_settings_button()) {
view->set_context_menu_controller(context_menu_controller_.get());
}
@@ -226,7 +223,7 @@ void MessagePopupCollection::UpdateWidgets() {
// There will be no contents already since this is a new ToastContentsView.
toast->SetContents(view, /*a11y_feedback_for_updates=*/false);
toasts_.push_back(toast);
- view->set_controller(toast);
+ view->set_delegate(toast);
gfx::Size preferred_size = toast->GetPreferredSize();
gfx::Point origin(
diff --git a/chromium/ui/message_center/views/message_popup_collection.h b/chromium/ui/message_center/views/message_popup_collection.h
index cc7de5cc064..e02ea7ed447 100644
--- a/chromium/ui/message_center/views/message_popup_collection.h
+++ b/chromium/ui/message_center/views/message_popup_collection.h
@@ -17,7 +17,7 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/message_center/message_center_export.h"
#include "ui/message_center/message_center_observer.h"
-#include "ui/message_center/views/message_center_controller.h"
+#include "ui/message_center/views/message_view_delegate.h"
#include "ui/message_center/views/toast_contents_view.h"
#include "ui/views/widget/widget_observer.h"
@@ -39,7 +39,7 @@ class MessagePopupCollectionTest;
}
class MessageCenter;
-class MessageCenterTray;
+class UiController;
class MessageViewContextMenuController;
class PopupAlignmentDelegate;
@@ -49,23 +49,23 @@ class PopupAlignmentDelegate;
// contents of each toast are for the message center and layout strategy would
// be slightly different.
class MESSAGE_CENTER_EXPORT MessagePopupCollection
- : public MessageCenterController,
+ : public MessageViewDelegate,
public MessageCenterObserver {
public:
MessagePopupCollection(MessageCenter* message_center,
- MessageCenterTray* tray,
+ UiController* tray,
PopupAlignmentDelegate* alignment_delegate);
~MessagePopupCollection() override;
- // Overridden from MessageCenterController:
+ // Overridden from MessageViewDelegate:
void ClickOnNotification(const std::string& notification_id) override;
void RemoveNotification(const std::string& notification_id,
bool by_user) override;
- std::unique_ptr<ui::MenuModel> CreateMenuModel(
- const Notification& notification) override;
- bool HasClickedListener(const std::string& notification_id) override;
void ClickOnNotificationButton(const std::string& notification_id,
int button_index) override;
+ void ClickOnNotificationButtonWithReply(const std::string& notification_id,
+ int button_index,
+ const base::string16& reply) override;
void ClickOnSettingsButton(const std::string& notification_id) override;
void UpdateNotificationSize(const std::string& notification_id) override;
@@ -147,7 +147,7 @@ class MESSAGE_CENTER_EXPORT MessagePopupCollection
gfx::Rect GetToastRectAt(size_t index) const;
MessageCenter* message_center_;
- MessageCenterTray* tray_;
+ UiController* tray_;
Toasts toasts_;
PopupAlignmentDelegate* alignment_delegate_;
diff --git a/chromium/ui/message_center/views/message_popup_collection_unittest.cc b/chromium/ui/message_center/views/message_popup_collection_unittest.cc
index 8c75aa126eb..f1c48b1fd8f 100644
--- a/chromium/ui/message_center/views/message_popup_collection_unittest.cc
+++ b/chromium/ui/message_center/views/message_popup_collection_unittest.cc
@@ -271,7 +271,7 @@ void MessagePopupCollectionTest::CheckedAnimationDelegate::
auto poorly_aligned = std::adjacent_find(
toasts_->begin(), toasts_->end(),
[](ToastContentsView* top, ToastContentsView* bottom) {
- return ComputeYDistance(*top, *bottom) != kMarginBetweenItems;
+ return ComputeYDistance(*top, *bottom) != kMarginBetweenPopups;
});
if (poorly_aligned != toasts_->end())
error_msg_ = calling_func + " CheckToastsAreAligned: distance between: " +
@@ -279,7 +279,7 @@ void MessagePopupCollectionTest::CheckedAnimationDelegate::
(*std::next(poorly_aligned))->id() + ": " +
std::to_string(ComputeYDistance(**poorly_aligned,
**std::next(poorly_aligned))) +
- " expected: " + std::to_string(kMarginBetweenItems) +
+ " expected: " + std::to_string(kMarginBetweenPopups) +
"\nLayout:\n" + YPositionsToString(*toasts_);
}
diff --git a/chromium/ui/message_center/views/message_view.cc b/chromium/ui/message_center/views/message_view.cc
index 4513fe66590..43e9d7c2671 100644
--- a/chromium/ui/message_center/views/message_view.cc
+++ b/chromium/ui/message_center/views/message_view.cc
@@ -15,7 +15,7 @@
#include "ui/gfx/shadow_value.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
-#include "ui/message_center/views/message_center_controller.h"
+#include "ui/message_center/views/message_view_delegate.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
@@ -29,11 +29,12 @@
namespace {
#if defined(OS_CHROMEOS)
-const int kShadowCornerRadius = 2;
+const int kBorderCorderRadius = 2;
+const SkColor kBorderColor = SkColorSetARGB(0x1F, 0x0, 0x0, 0x0);
#else
const int kShadowCornerRadius = 0;
-#endif
const int kShadowElevation = 2;
+#endif
// Creates a text for spoken feedback from the data contained in the
// notification.
@@ -60,9 +61,9 @@ base::string16 CreateAccessibleName(
namespace message_center {
-MessageView::MessageView(MessageCenterController* controller,
+MessageView::MessageView(MessageViewDelegate* delegate,
const Notification& notification)
- : controller_(controller),
+ : delegate_(delegate),
notification_id_(notification.id()),
slide_out_controller_(this, this) {
SetFocusBehavior(FocusBehavior::ALWAYS);
@@ -92,15 +93,13 @@ void MessageView::UpdateWithNotification(const Notification& notification) {
slide_out_controller_.set_enabled(!GetPinned());
}
-// static
-gfx::Insets MessageView::GetShadowInsets() {
- return -gfx::ShadowValue::GetMargin(
- gfx::ShadowDetails::Get(kShadowElevation, kShadowCornerRadius).values);
-}
-
void MessageView::SetIsNested() {
is_nested_ = true;
+#if defined(OS_CHROMEOS)
+ SetBorder(views::CreateRoundedRectBorder(kNotificationBorderThickness,
+ kBorderCorderRadius, kBorderColor));
+#else
const auto& shadow =
gfx::ShadowDetails::Get(kShadowElevation, kShadowCornerRadius);
gfx::Insets ninebox_insets = gfx::ShadowValue::GetBlurRegion(shadow.values) +
@@ -109,6 +108,7 @@ void MessageView::SetIsNested() {
std::unique_ptr<views::Painter>(views::Painter::CreateImagePainter(
shadow.ninebox_image, ninebox_insets)),
-gfx::ShadowValue::GetMargin(shadow.values)));
+#endif
}
void MessageView::SetExpanded(bool expanded) {
@@ -120,6 +120,14 @@ bool MessageView::IsExpanded() const {
return false;
}
+void MessageView::OnContainerAnimationStarted() {
+ // Not implemented by default.
+}
+
+void MessageView::OnContainerAnimationEnded() {
+ // Not implemented by default.
+}
+
void MessageView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
node_data->role = ui::AX_ROLE_BUTTON;
node_data->AddStringAttribute(
@@ -133,7 +141,7 @@ bool MessageView::OnMousePressed(const ui::MouseEvent& event) {
if (!event.IsOnlyLeftMouseButton())
return false;
- controller_->ClickOnNotification(notification_id_);
+ delegate_->ClickOnNotification(notification_id_);
return true;
}
@@ -142,11 +150,11 @@ bool MessageView::OnKeyPressed(const ui::KeyEvent& event) {
return false;
if (event.key_code() == ui::VKEY_RETURN) {
- controller_->ClickOnNotification(notification_id_);
+ delegate_->ClickOnNotification(notification_id_);
return true;
} else if ((event.key_code() == ui::VKEY_DELETE ||
event.key_code() == ui::VKEY_BACK)) {
- controller_->RemoveNotification(notification_id_, true); // By user.
+ delegate_->RemoveNotification(notification_id_, true); // By user.
return true;
}
@@ -159,7 +167,7 @@ bool MessageView::OnKeyReleased(const ui::KeyEvent& event) {
if (event.flags() != ui::EF_NONE || event.key_code() != ui::VKEY_SPACE)
return false;
- controller_->ClickOnNotification(notification_id_);
+ delegate_->ClickOnNotification(notification_id_);
return true;
}
@@ -211,7 +219,7 @@ void MessageView::OnGestureEvent(ui::GestureEvent* event) {
}
case ui::ET_GESTURE_TAP: {
SetDrawBackgroundAsActive(false);
- controller_->ClickOnNotification(notification_id_);
+ delegate_->ClickOnNotification(notification_id_);
event->SetHandled();
return;
}
@@ -235,7 +243,7 @@ ui::Layer* MessageView::GetSlideOutLayer() {
void MessageView::OnSlideChanged() {}
void MessageView::OnSlideOut() {
- controller_->RemoveNotification(notification_id_, true); // By user.
+ delegate_->RemoveNotification(notification_id_, true); // By user.
}
bool MessageView::GetPinned() const {
@@ -243,11 +251,11 @@ bool MessageView::GetPinned() const {
}
void MessageView::OnCloseButtonPressed() {
- controller_->RemoveNotification(notification_id_, true); // By user.
+ delegate_->RemoveNotification(notification_id_, true); // By user.
}
void MessageView::OnSettingsButtonPressed() {
- controller_->ClickOnSettingsButton(notification_id_);
+ delegate_->ClickOnSettingsButton(notification_id_);
}
void MessageView::SetDrawBackgroundAsActive(bool active) {
diff --git a/chromium/ui/message_center/views/message_view.h b/chromium/ui/message_center/views/message_view.h
index f62ee165e3c..64dfa472632 100644
--- a/chromium/ui/message_center/views/message_view.h
+++ b/chromium/ui/message_center/views/message_view.h
@@ -29,7 +29,7 @@ namespace message_center {
class Notification;
class NotificationControlButtonsView;
-class MessageCenterController;
+class MessageViewDelegate;
// An base class for a notification entry. Contains background and other
// elements shared by derived notification views.
@@ -37,16 +37,12 @@ class MESSAGE_CENTER_EXPORT MessageView
: public views::View,
public views::SlideOutController::Delegate {
public:
- MessageView(MessageCenterController* controller,
- const Notification& notification);
+ MessageView(MessageViewDelegate* delegate, const Notification& notification);
~MessageView() override;
// Updates this view with the new data contained in the notification.
virtual void UpdateWithNotification(const Notification& notification);
- // Returns the insets for the shadow it will have for rich notification.
- static gfx::Insets GetShadowInsets();
-
// Creates a shadow around the notification and changes slide-out behavior.
void SetIsNested();
@@ -58,6 +54,13 @@ class MESSAGE_CENTER_EXPORT MessageView
virtual void SetExpanded(bool expanded);
virtual bool IsExpanded() const;
+ // Invoked when the container view of MessageView (e.g. MessageCenterView in
+ // ash) is starting the animation that possibly hides some part of
+ // the MessageView.
+ // During the animation, MessageView should comply with the Z order in views.
+ virtual void OnContainerAnimationStarted();
+ virtual void OnContainerAnimationEnded();
+
void OnCloseButtonPressed();
void OnSettingsButtonPressed();
@@ -81,9 +84,7 @@ class MESSAGE_CENTER_EXPORT MessageView
void set_scroller(views::ScrollView* scroller) { scroller_ = scroller; }
std::string notification_id() const { return notification_id_; }
- void set_controller(MessageCenterController* controller) {
- controller_ = controller;
- }
+ void set_delegate(MessageViewDelegate* delegate) { delegate_ = delegate; }
#if defined(OS_CHROMEOS)
// By calling this, all notifications are treated as non-pinned forcibly.
@@ -102,10 +103,10 @@ class MESSAGE_CENTER_EXPORT MessageView
views::View* background_view() { return background_view_; }
views::ScrollView* scroller() { return scroller_; }
- MessageCenterController* controller() { return controller_; }
+ MessageViewDelegate* delegate() { return delegate_; }
private:
- MessageCenterController* controller_; // Weak, lives longer then views.
+ MessageViewDelegate* delegate_;
std::string notification_id_;
views::View* background_view_ = nullptr; // Owned by views hierarchy.
views::ScrollView* scroller_ = nullptr;
diff --git a/chromium/ui/message_center/views/message_view_context_menu_controller.cc b/chromium/ui/message_center/views/message_view_context_menu_controller.cc
index 367fcd8d620..fb871b6d6cb 100644
--- a/chromium/ui/message_center/views/message_view_context_menu_controller.cc
+++ b/chromium/ui/message_center/views/message_view_context_menu_controller.cc
@@ -6,21 +6,18 @@
#include "ui/base/models/menu_model.h"
#include "ui/message_center/message_center.h"
-#include "ui/message_center/views/message_center_controller.h"
#include "ui/message_center/views/message_view.h"
+#include "ui/message_center/views/message_view_delegate.h"
+#include "ui/message_center/views/notification_menu_model.h"
#include "ui/views/controls/menu/menu_model_adapter.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/widget/widget.h"
namespace message_center {
-MessageViewContextMenuController::MessageViewContextMenuController(
- MessageCenterController* controller)
- : controller_(controller) {
-}
+MessageViewContextMenuController::MessageViewContextMenuController() = default;
-MessageViewContextMenuController::~MessageViewContextMenuController() {
-}
+MessageViewContextMenuController::~MessageViewContextMenuController() = default;
void MessageViewContextMenuController::ShowContextMenuForView(
views::View* source,
@@ -31,7 +28,7 @@ void MessageViewContextMenuController::ShowContextMenuForView(
Notification* notification =
MessageCenter::Get()->FindVisibleNotificationById(
message_view->notification_id());
- menu_model_ = controller_->CreateMenuModel(*notification);
+ menu_model_ = std::make_unique<NotificationMenuModel>(*notification);
if (!menu_model_ || menu_model_->GetItemCount() == 0)
return;
diff --git a/chromium/ui/message_center/views/message_view_context_menu_controller.h b/chromium/ui/message_center/views/message_view_context_menu_controller.h
index db49a305dd4..49596008f3e 100644
--- a/chromium/ui/message_center/views/message_view_context_menu_controller.h
+++ b/chromium/ui/message_center/views/message_view_context_menu_controller.h
@@ -22,13 +22,11 @@ class MenuRunner;
} // namespace views
namespace message_center {
-class MessageCenterController;
class MESSAGE_CENTER_EXPORT MessageViewContextMenuController
: public views::ContextMenuController {
public:
- explicit MessageViewContextMenuController(
- MessageCenterController* controller);
+ explicit MessageViewContextMenuController();
~MessageViewContextMenuController() override;
private:
@@ -40,8 +38,6 @@ class MESSAGE_CENTER_EXPORT MessageViewContextMenuController
// Callback for MenuModelAdapter
void OnMenuClosed();
- MessageCenterController* controller_;
-
std::unique_ptr<ui::MenuModel> menu_model_;
std::unique_ptr<views::MenuModelAdapter> menu_model_adapter_;
std::unique_ptr<views::MenuRunner> menu_runner_;
diff --git a/chromium/ui/message_center/views/message_center_controller.h b/chromium/ui/message_center/views/message_view_delegate.h
index 544be9cc786..b4bee17b816 100644
--- a/chromium/ui/message_center/views/message_center_controller.h
+++ b/chromium/ui/message_center/views/message_view_delegate.h
@@ -2,32 +2,31 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_MESSAGE_CENTER_VIEWS_MESSAGE_CENTER_CONTROLLER_H_
-#define UI_MESSAGE_CENTER_VIEWS_MESSAGE_CENTER_CONTROLLER_H_
+#ifndef UI_MESSAGE_CENTER_VIEWS_MESSAGE_VIEW_DELEGATE_H_
+#define UI_MESSAGE_CENTER_VIEWS_MESSAGE_VIEW_DELEGATE_H_
#include <memory>
#include <string>
-#include "base/strings/string16.h"
#include "ui/base/models/menu_model.h"
-#include "ui/message_center/notifier_settings.h"
namespace message_center {
// Interface used by views to report clicks and other user actions. The views
// by themselves do not know how to perform those operations, they ask
-// MessageCenterController to do them. Implemented by MessageCenterView and
+// MessageViewDelegate to do them. Implemented by MessageCenterView and
// MessagePopupCollection.
-class MessageCenterController {
+class MessageViewDelegate {
public:
virtual void ClickOnNotification(const std::string& notification_id) = 0;
virtual void RemoveNotification(const std::string& notification_id,
bool by_user) = 0;
- virtual std::unique_ptr<ui::MenuModel> CreateMenuModel(
- const Notification& notification) = 0;
- virtual bool HasClickedListener(const std::string& notification_id) = 0;
virtual void ClickOnNotificationButton(const std::string& notification_id,
int button_index) = 0;
+ virtual void ClickOnNotificationButtonWithReply(
+ const std::string& notification_id,
+ int button_index,
+ const base::string16& reply) = 0;
virtual void ClickOnSettingsButton(const std::string& notification_id) = 0;
// For ArcCustomNotificationView, size changes might come after the
// notification update over Mojo. Provide a method here to notify when
@@ -38,4 +37,4 @@ class MessageCenterController {
} // namespace message_center
-#endif // UI_MESSAGE_CENTER_VIEWS_MESSAGE_CENTER_CONTROLLER_H_
+#endif // UI_MESSAGE_CENTER_VIEWS_MESSAGE_VIEW_DELEGATE_H_
diff --git a/chromium/ui/message_center/views/message_view_factory.cc b/chromium/ui/message_center/views/message_view_factory.cc
index 5e9c400fb27..74465ab5802 100644
--- a/chromium/ui/message_center/views/message_view_factory.cc
+++ b/chromium/ui/message_center/views/message_view_factory.cc
@@ -5,6 +5,7 @@
#include "ui/message_center/views/message_view_factory.h"
#include "base/command_line.h"
+#include "base/lazy_instance.h"
#include "ui/message_center/notification_types.h"
#include "ui/message_center/public/cpp/message_center_switches.h"
#include "ui/message_center/views/notification_view.h"
@@ -16,8 +17,15 @@
namespace message_center {
+namespace {
+
+base::LazyInstance<MessageViewFactory::CustomMessageViewFactoryFunction>::Leaky
+ g_custom_view_factory = LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
+
// static
-MessageView* MessageViewFactory::Create(MessageCenterController* controller,
+MessageView* MessageViewFactory::Create(MessageViewDelegate* controller,
const Notification& notification,
bool top_level) {
MessageView* notification_view = nullptr;
@@ -33,14 +41,10 @@ MessageView* MessageViewFactory::Create(MessageCenterController* controller,
else
notification_view = new NotificationView(controller, notification);
break;
-#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
case NOTIFICATION_TYPE_CUSTOM:
notification_view =
- notification.delegate()
- ->CreateCustomMessageView(controller, notification)
- .release();
+ g_custom_view_factory.Get().Run(controller, notification).release();
break;
-#endif
default:
// If the caller asks for an unrecognized kind of view (entirely possible
// if an application is running on an older version of this code that
@@ -70,4 +74,15 @@ MessageView* MessageViewFactory::Create(MessageCenterController* controller,
return notification_view;
}
+// static
+void MessageViewFactory::SetCustomNotificationViewFactory(
+ const CustomMessageViewFactoryFunction& factory_function) {
+ g_custom_view_factory.Get() = factory_function;
+}
+
+// static
+bool MessageViewFactory::HasCustomNotificationViewFactory() {
+ return !g_custom_view_factory.Get().is_null();
+}
+
} // namespace message_center
diff --git a/chromium/ui/message_center/views/message_view_factory.h b/chromium/ui/message_center/views/message_view_factory.h
index 9ff2251ff54..22d5ac71cdb 100644
--- a/chromium/ui/message_center/views/message_view_factory.h
+++ b/chromium/ui/message_center/views/message_view_factory.h
@@ -7,9 +7,13 @@
#include "ui/message_center/message_center_export.h"
+#include <memory>
+
+#include "base/callback_forward.h"
+
namespace message_center {
-class MessageCenterController;
+class MessageViewDelegate;
class MessageView;
class Notification;
@@ -19,10 +23,28 @@ class Notification;
// notifications on Linux with Aura.
class MESSAGE_CENTER_EXPORT MessageViewFactory {
public:
+ // A function that creates MessageView for a NOTIFICATION_TYPE_CUSTOM
+ // notification.
+ typedef base::Callback<std::unique_ptr<message_center::MessageView>(
+ message_center::MessageViewDelegate*,
+ const message_center::Notification&)>
+ CustomMessageViewFactoryFunction;
+
// |controller| may be NULL, but has to be set before the view is shown.
- static MessageView* Create(MessageCenterController* controller,
+ static MessageView* Create(MessageViewDelegate* controller,
const Notification& notification,
bool top_level);
+
+ // Sets the function that will be invoked to create a custom notification
+ // view. This should be a repeating callback. It's an error to attempt to show
+ // a custom notification without first having called this function. Currently,
+ // only ARC uses custom notifications, so this doesn't need to distinguish
+ // between various sources of custom notification.
+ static void SetCustomNotificationViewFactory(
+ const CustomMessageViewFactoryFunction& factory_function);
+
+ // Returns whether the custom view factory function has already been set.
+ static bool HasCustomNotificationViewFactory();
};
} // namespace message_center
diff --git a/chromium/ui/message_center/views/notification_header_view.cc b/chromium/ui/message_center/views/notification_header_view.cc
index c7dec90a69d..c537e36ccc4 100644
--- a/chromium/ui/message_center/views/notification_header_view.cc
+++ b/chromium/ui/message_center/views/notification_header_view.cc
@@ -189,14 +189,16 @@ NotificationHeaderView::NotificationHeaderView(
DCHECK_EQ(kInnerHeaderHeight, app_icon_view_->GetPreferredSize().height());
app_info_container->AddChildView(app_icon_view_);
- // Font list for text views.
- const gfx::FontList& font_list = GetHeaderTextFontList();
- // The height must be 15px to match with the mock.
+ // Font list for text views. The height must be 15px to match with the mock.
+ gfx::FontList font_list = GetHeaderTextFontList();
DCHECK_EQ(15, font_list.GetHeight());
+ const int font_list_height = font_list.GetHeight();
+
// App name view
app_name_view_ = new views::Label(base::string16());
app_name_view_->SetFontList(font_list);
+ app_name_view_->SetLineHeight(font_list_height);
app_name_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
app_name_view_->SetEnabledColor(accent_color_);
app_name_view_->SetBorder(views::CreateEmptyBorder(kTextViewPadding));
@@ -207,6 +209,7 @@ NotificationHeaderView::NotificationHeaderView(
summary_text_divider_ =
new views::Label(base::WideToUTF16(kNotificationHeaderDivider));
summary_text_divider_->SetFontList(font_list);
+ summary_text_divider_->SetLineHeight(font_list_height);
summary_text_divider_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
summary_text_divider_->SetBorder(views::CreateEmptyBorder(kTextViewPadding));
summary_text_divider_->SetVisible(false);
@@ -217,6 +220,7 @@ NotificationHeaderView::NotificationHeaderView(
// Summary text view
summary_text_view_ = new views::Label(base::string16());
summary_text_view_->SetFontList(font_list);
+ summary_text_view_->SetLineHeight(font_list_height);
summary_text_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
summary_text_view_->SetBorder(views::CreateEmptyBorder(kTextViewPadding));
summary_text_view_->SetVisible(false);
@@ -228,6 +232,7 @@ NotificationHeaderView::NotificationHeaderView(
timestamp_divider_ =
new views::Label(base::WideToUTF16(kNotificationHeaderDivider));
timestamp_divider_->SetFontList(font_list);
+ timestamp_divider_->SetLineHeight(font_list_height);
timestamp_divider_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
timestamp_divider_->SetBorder(views::CreateEmptyBorder(kTextViewPadding));
timestamp_divider_->SetVisible(false);
@@ -238,6 +243,7 @@ NotificationHeaderView::NotificationHeaderView(
// Timestamp view
timestamp_view_ = new views::Label(base::string16());
timestamp_view_->SetFontList(font_list);
+ timestamp_view_->SetLineHeight(font_list_height);
timestamp_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
timestamp_view_->SetBorder(views::CreateEmptyBorder(kTextViewPadding));
timestamp_view_->SetVisible(false);
@@ -348,7 +354,7 @@ bool NotificationHeaderView::IsExpandButtonEnabled() {
}
std::unique_ptr<views::InkDrop> NotificationHeaderView::CreateInkDrop() {
- return base::MakeUnique<views::InkDropStub>();
+ return std::make_unique<views::InkDropStub>();
}
void NotificationHeaderView::UpdateSummaryTextVisibility() {
diff --git a/chromium/ui/message_center/views/notification_menu_model.cc b/chromium/ui/message_center/views/notification_menu_model.cc
new file mode 100644
index 00000000000..de4219d2262
--- /dev/null
+++ b/chromium/ui/message_center/views/notification_menu_model.cc
@@ -0,0 +1,69 @@
+// Copyright 2017 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 "ui/message_center/views/notification_menu_model.h"
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/strings/utf_string_conversions.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/models/simple_menu_model.h"
+#include "ui/message_center/message_center.h"
+#include "ui/strings/grit/ui_strings.h"
+
+namespace message_center {
+
+namespace {
+
+// Menu constants
+const int kTogglePermissionCommand = 0;
+const int kShowSettingsCommand = 1;
+
+} // namespace
+
+NotificationMenuModel::NotificationMenuModel(const Notification& notification)
+ : ui::SimpleMenuModel(this), notification_(notification) {
+ DCHECK(!notification.display_source().empty());
+ AddItem(kTogglePermissionCommand,
+ l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_NOTIFIER_DISABLE,
+ notification.display_source()));
+
+#if defined(OS_CHROMEOS)
+ // Add settings menu item.
+ AddItem(kShowSettingsCommand,
+ l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_SETTINGS));
+#endif
+}
+
+NotificationMenuModel::~NotificationMenuModel() {}
+
+bool NotificationMenuModel::IsCommandIdChecked(int command_id) const {
+ return false;
+}
+
+bool NotificationMenuModel::IsCommandIdEnabled(int command_id) const {
+ // TODO(estade): commands shouldn't always be enabled. For example, a
+ // notification's enabled state might be controlled by policy. See
+ // http://crbug.com/771269
+ return true;
+}
+
+void NotificationMenuModel::ExecuteCommand(int command_id, int event_flags) {
+ switch (command_id) {
+ case kTogglePermissionCommand:
+ notification_.delegate()->DisableNotification();
+ // TODO(estade): this will not close other open notifications from the
+ // same site.
+ MessageCenter::Get()->RemoveNotification(notification_.id(), false);
+ break;
+ case kShowSettingsCommand:
+ MessageCenter::Get()->ClickOnSettingsButton(notification_.id());
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+} // namespace message_center
diff --git a/chromium/ui/message_center/views/notification_menu_model.h b/chromium/ui/message_center/views/notification_menu_model.h
new file mode 100644
index 00000000000..324b9893f46
--- /dev/null
+++ b/chromium/ui/message_center/views/notification_menu_model.h
@@ -0,0 +1,35 @@
+// Copyright 2017 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 UI_MESSAGE_CENTER_NOTIFICATION_MENU_MODEL_H_
+#define UI_MESSAGE_CENTER_NOTIFICATION_MENU_MODEL_H_
+
+#include "base/macros.h"
+#include "ui/base/models/simple_menu_model.h"
+#include "ui/message_center/message_center_export.h"
+#include "ui/message_center/notification.h"
+
+namespace message_center {
+
+// The model of the context menu for a notification card.
+class MESSAGE_CENTER_EXPORT NotificationMenuModel
+ : public ui::SimpleMenuModel,
+ public ui::SimpleMenuModel::Delegate {
+ public:
+ NotificationMenuModel(const Notification& notification);
+ ~NotificationMenuModel() override;
+
+ // Overridden from ui::SimpleMenuModel::Delegate:
+ bool IsCommandIdChecked(int command_id) const override;
+ bool IsCommandIdEnabled(int command_id) const override;
+ void ExecuteCommand(int command_id, int event_flags) override;
+
+ private:
+ Notification notification_;
+ DISALLOW_COPY_AND_ASSIGN(NotificationMenuModel);
+};
+
+} // namespace message_center
+
+#endif // UI_MESSAGE_CENTER_UI_CONTROLLER_H_
diff --git a/chromium/ui/message_center/views/notification_menu_model_unittest.cc b/chromium/ui/message_center/views/notification_menu_model_unittest.cc
new file mode 100644
index 00000000000..1ba2f38bc18
--- /dev/null
+++ b/chromium/ui/message_center/views/notification_menu_model_unittest.cc
@@ -0,0 +1,113 @@
+// Copyright 2017 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 "ui/message_center/views/notification_menu_model.h"
+
+#include <utility>
+
+#include "base/macros.h"
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/models/menu_model.h"
+#include "ui/message_center/message_center.h"
+#include "ui/message_center/notification.h"
+#include "ui/message_center/notification_types.h"
+#include "ui/message_center/ui_controller.h"
+
+namespace message_center {
+namespace {
+
+class TestNotificationDelegate : public message_center::NotificationDelegate {
+ public:
+ TestNotificationDelegate() = default;
+
+ private:
+ ~TestNotificationDelegate() override = default;
+
+ DISALLOW_COPY_AND_ASSIGN(TestNotificationDelegate);
+};
+
+} // namespace
+
+class NotificationMenuModelTest : public testing::Test {
+ public:
+ NotificationMenuModelTest() = default;
+ ~NotificationMenuModelTest() override = default;
+
+ void SetUp() override {
+ MessageCenter::Initialize();
+ message_center_ = MessageCenter::Get();
+ }
+
+ void TearDown() override {
+ message_center_ = NULL;
+ MessageCenter::Shutdown();
+ }
+
+ protected:
+ NotifierId DummyNotifierId() { return NotifierId(); }
+
+ Notification* AddNotification(const std::string& id) {
+ return AddNotification(id, DummyNotifierId());
+ }
+
+ Notification* AddNotification(const std::string& id, NotifierId notifier_id) {
+ std::unique_ptr<Notification> notification(new Notification(
+ message_center::NOTIFICATION_TYPE_SIMPLE, id,
+ base::ASCIIToUTF16("Test Web Notification"),
+ base::ASCIIToUTF16("Notification message body."), gfx::Image(),
+ base::ASCIIToUTF16("www.test.org"), GURL(), notifier_id,
+ message_center::RichNotificationData(),
+ new TestNotificationDelegate()));
+ Notification* notification_ptr = notification.get();
+ message_center_->AddNotification(std::move(notification));
+ return notification_ptr;
+ }
+ MessageCenter* message_center_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NotificationMenuModelTest);
+};
+
+TEST_F(NotificationMenuModelTest, ContextMenuTestWithMessageCenter) {
+ const std::string id1 = "id1";
+ const std::string id2 = "id2";
+ const std::string id3 = "id3";
+ AddNotification(id1);
+
+ base::string16 display_source = base::ASCIIToUTF16("www.test.org");
+ NotifierId notifier_id = DummyNotifierId();
+
+ NotifierId notifier_id2(NotifierId::APPLICATION, "sample-app");
+ std::unique_ptr<Notification> notification = std::make_unique<Notification>(
+ message_center::NOTIFICATION_TYPE_SIMPLE, id2,
+ base::ASCIIToUTF16("Test Web Notification"),
+ base::ASCIIToUTF16("Notification message body."), gfx::Image(),
+ display_source, GURL(), notifier_id2,
+ message_center::RichNotificationData(), new TestNotificationDelegate());
+
+ std::unique_ptr<ui::MenuModel> model(
+ std::make_unique<NotificationMenuModel>(*notification));
+ message_center_->AddNotification(std::move(notification));
+
+ AddNotification(id3);
+#if defined(OS_CHROMEOS)
+ EXPECT_EQ(2, model->GetItemCount());
+
+ // The second item is to open the settings.
+ EXPECT_TRUE(model->IsEnabledAt(0));
+ EXPECT_TRUE(model->IsEnabledAt(1));
+ model->ActivatedAt(1);
+#else
+ EXPECT_EQ(1, model->GetItemCount());
+#endif
+
+ // The first item is to disable notifications from the notifier id. It also
+ // removes the notification.
+ EXPECT_EQ(3u, message_center_->GetVisibleNotifications().size());
+ model->ActivatedAt(0);
+ EXPECT_EQ(2u, message_center_->GetVisibleNotifications().size());
+}
+
+} // namespace message_center
diff --git a/chromium/ui/message_center/views/notification_view.cc b/chromium/ui/message_center/views/notification_view.cc
index 4a2a5de8896..b86b8bf0c07 100644
--- a/chromium/ui/message_center/views/notification_view.cc
+++ b/chromium/ui/message_center/views/notification_view.cc
@@ -28,7 +28,7 @@
#include "ui/message_center/public/cpp/message_center_constants.h"
#include "ui/message_center/views/bounded_label.h"
#include "ui/message_center/views/constants.h"
-#include "ui/message_center/views/message_center_controller.h"
+#include "ui/message_center/views/message_view_delegate.h"
#include "ui/message_center/views/notification_button.h"
#include "ui/message_center/views/notification_control_buttons_view.h"
#include "ui/message_center/views/padded_button.h"
@@ -177,9 +177,9 @@ void NotificationView::CreateOrUpdateViews(const Notification& notification) {
CreateOrUpdateActionButtonViews(notification);
}
-NotificationView::NotificationView(MessageCenterController* controller,
+NotificationView::NotificationView(MessageViewDelegate* delegate,
const Notification& notification)
- : MessageView(controller, notification),
+ : MessageView(delegate, notification),
clickable_(notification.clickable()) {
// Create the top_view_, which collects into a vertical box all content
// at the top of the notification (to the right of the icon) except for the
@@ -330,11 +330,8 @@ void NotificationView::ScrollRectToVisible(const gfx::Rect& rect) {
}
gfx::NativeCursor NotificationView::GetCursor(const ui::MouseEvent& event) {
- // TODO(estade): remove NotificationDelegate::HasClickedListener.
- if (clickable_ || controller()->HasClickedListener(notification_id()))
- return views::GetNativeHandCursor();
-
- return views::View::GetCursor(event);
+ return clickable_ ? views::GetNativeHandCursor()
+ : views::View::GetCursor(event);
}
@@ -368,7 +365,7 @@ void NotificationView::ButtonPressed(views::Button* sender,
// See if the button pressed was an action button.
for (size_t i = 0; i < action_buttons_.size(); ++i) {
if (sender == action_buttons_[i]) {
- controller()->ClickOnNotificationButton(id, i);
+ delegate()->ClickOnNotificationButton(id, i);
return;
}
}
@@ -643,8 +640,7 @@ void NotificationView::CreateOrUpdateActionButtonViews(
void NotificationView::UpdateControlButtonsVisibilityWithNotification(
const Notification& notification) {
control_buttons_view_->ShowSettingsButton(
- notification.delegate() &&
- notification.delegate()->ShouldDisplaySettingsButton());
+ notification.should_show_settings_button());
control_buttons_view_->ShowCloseButton(!GetPinned());
UpdateControlButtonsVisibility();
}
diff --git a/chromium/ui/message_center/views/notification_view.h b/chromium/ui/message_center/views/notification_view.h
index 972a21ff9f4..7ff5b45b266 100644
--- a/chromium/ui/message_center/views/notification_view.h
+++ b/chromium/ui/message_center/views/notification_view.h
@@ -36,7 +36,7 @@ class MESSAGE_CENTER_EXPORT NotificationView
public views::ButtonListener,
public views::ViewTargeterDelegate {
public:
- NotificationView(MessageCenterController* controller,
+ NotificationView(MessageViewDelegate* delegate,
const Notification& notification);
~NotificationView() override;
diff --git a/chromium/ui/message_center/views/notification_view_md.cc b/chromium/ui/message_center/views/notification_view_md.cc
index a896f00173a..529cdef87ba 100644
--- a/chromium/ui/message_center/views/notification_view_md.cc
+++ b/chromium/ui/message_center/views/notification_view_md.cc
@@ -25,7 +25,7 @@
#include "ui/message_center/vector_icons.h"
#include "ui/message_center/views/bounded_label.h"
#include "ui/message_center/views/constants.h"
-#include "ui/message_center/views/message_center_controller.h"
+#include "ui/message_center/views/message_view_delegate.h"
#include "ui/message_center/views/notification_control_buttons_view.h"
#include "ui/message_center/views/notification_header_view.h"
#include "ui/message_center/views/padded_button.h"
@@ -64,6 +64,7 @@ constexpr gfx::Size kLargeImageMinSize(328, 0);
constexpr gfx::Size kLargeImageMaxSize(328, 218);
constexpr gfx::Insets kLeftContentPadding(2, 4, 0, 4);
constexpr gfx::Insets kLeftContentPaddingWithIcon(2, 4, 0, 12);
+constexpr gfx::Insets kNotificationInputPadding(0, 16, 0, 16);
// Background of inline actions area.
const SkColor kActionsRowBackgroundColor = SkColorSetRGB(0xee, 0xee, 0xee);
@@ -81,6 +82,11 @@ const SkColor kLargeImageBackgroundColor = SkColorSetRGB(0xf5, 0xf5, 0xf5);
const SkColor kRegularTextColorMD = SkColorSetRGB(0x21, 0x21, 0x21);
const SkColor kDimTextColorMD = SkColorSetRGB(0x75, 0x75, 0x75);
+// The text color and the background color of inline reply input field.
+const SkColor kInputTextColor = SkColorSetRGB(0xFF, 0xFF, 0xFF);
+const SkColor kInputPlaceholderColor = SkColorSetARGB(0x8A, 0xFF, 0xFF, 0xFF);
+const SkColor kInputBackgroundColor = SkColorSetRGB(0x33, 0x67, 0xD6);
+
// Max number of lines for message_view_.
constexpr int kMaxLinesForMessageView = 1;
constexpr int kMaxLinesForExpandedMessageView = 4;
@@ -102,6 +108,12 @@ constexpr int kMessageViewWidth =
// "Roboto-Regular, 13sp" is specified in the mock.
constexpr int kTextFontSize = 13;
+// In progress notification, if both the title and the message are long, the
+// message would be prioritized and the title would be elided.
+// However, it is not perferable that we completely omit the title, so
+// the ratio of the message width is limited to this value.
+constexpr double kProgressNotificationMessageRatio = 0.7;
+
// FontList for the texts except for the header.
gfx::FontList GetTextFontList() {
gfx::Font default_font;
@@ -197,22 +209,24 @@ void CompactTitleMessageView::OnPaint(gfx::Canvas* canvas) {
const gfx::FontList& font_list = GetTextFontList();
- // Elides title and message. The behavior is based on Android's one.
- // * If the title is too long, only the title is shown.
- // * If the message is too long, the full content of the title is shown,
+ // Elides title and message.
+ // * If the message is too long, the message occupies at most
+ // kProgressNotificationMessageRatio of the width.
+ // * If the title is too long, the full content of the message is shown,
// kCompactTitleMessageViewSpacing is added between them, and the elided
- // message is shown.
+ // title is shown.
// * If they are short enough, the title is left-aligned and the message is
// right-aligned.
- const int original_title_width =
- gfx::Canvas::GetStringWidthF(title, font_list);
- if (original_title_width >= width())
- message.clear();
- title = gfx::ElideText(title, font_list, width(), gfx::ELIDE_TAIL);
- const int title_width = gfx::Canvas::GetStringWidthF(title, font_list);
- const int message_width =
- std::max(0, width() - title_width - kCompactTitleMessageViewSpacing);
- message = gfx::ElideText(message, font_list, message_width, gfx::ELIDE_TAIL);
+ message = gfx::ElideText(
+ message, font_list,
+ title.empty()
+ ? width()
+ : static_cast<int>(kProgressNotificationMessageRatio * width()),
+ gfx::ELIDE_TAIL);
+ const int message_width = gfx::Canvas::GetStringWidthF(message, font_list);
+ const int title_width =
+ std::max(0, width() - message_width - kCompactTitleMessageViewSpacing);
+ title = gfx::ElideText(title, font_list, title_width, gfx::ELIDE_TAIL);
title_view_->SetText(title);
message_view_->SetText(message);
@@ -302,10 +316,14 @@ const char* LargeImageContainerView::GetClassName() const {
// NotificationButtonMD ////////////////////////////////////////////////////////
NotificationButtonMD::NotificationButtonMD(views::ButtonListener* listener,
- const base::string16& text)
+ bool is_inline_reply,
+ const base::string16& label,
+ const base::string16& placeholder)
: views::LabelButton(listener,
- base::i18n::ToUpper(text),
- views::style::CONTEXT_BUTTON_MD) {
+ base::i18n::ToUpper(label),
+ views::style::CONTEXT_BUTTON_MD),
+ is_inline_reply_(is_inline_reply),
+ placeholder_(placeholder) {
SetHorizontalAlignment(gfx::ALIGN_CENTER);
SetInkDropMode(views::LabelButton::InkDropMode::ON);
set_has_ink_drop_action_on_click(true);
@@ -335,6 +353,38 @@ NotificationButtonMD::CreateInkDropHighlight() const {
return highlight;
}
+// NotificationInputMD /////////////////////////////////////////////////////////
+
+NotificationInputMD::NotificationInputMD(NotificationInputDelegate* delegate)
+ : delegate_(delegate), index_(0) {
+ set_controller(this);
+ SetTextColor(kInputTextColor);
+ SetBackgroundColor(kInputBackgroundColor);
+ set_placeholder_text_color(kInputPlaceholderColor);
+ SetBorder(views::CreateEmptyBorder(kNotificationInputPadding));
+}
+
+NotificationInputMD::~NotificationInputMD() = default;
+
+bool NotificationInputMD::HandleKeyEvent(views::Textfield* sender,
+ const ui::KeyEvent& event) {
+ if (event.type() == ui::ET_KEY_PRESSED &&
+ event.key_code() == ui::VKEY_RETURN) {
+ delegate_->OnNotificationInputSubmit(index_, text());
+ return true;
+ }
+ return event.type() == ui::ET_KEY_RELEASED;
+}
+
+void NotificationInputMD::set_placeholder(const base::string16& placeholder) {
+ if (placeholder.empty()) {
+ set_placeholder_text(l10n_util::GetStringUTF16(
+ IDS_MESSAGE_CENTER_NOTIFICATION_INLINE_REPLY_PLACEHOLDER));
+ } else {
+ set_placeholder_text(placeholder);
+ }
+}
+
// ////////////////////////////////////////////////////////////
// NotificationViewMD
// ////////////////////////////////////////////////////////////
@@ -343,19 +393,25 @@ views::View* NotificationViewMD::TargetForRect(views::View* root,
const gfx::Rect& rect) {
CHECK_EQ(root, this);
- // TODO(tdanderson): Modify this function to support rect-based event
+ // TODO(tetsui): Modify this function to support rect-based event
// targeting. Using the center point of |rect| preserves this function's
// expected behavior for the time being.
gfx::Point point = rect.CenterPoint();
// Want to return this for underlying views, otherwise GetCursor is not
// called. But buttons are exceptions, they'll have their own event handlings.
- std::vector<views::View*> buttons(action_buttons_.begin(),
- action_buttons_.end());
+ std::vector<views::View*> buttons;
if (header_row_->expand_button())
buttons.push_back(header_row_->expand_button());
buttons.push_back(header_row_);
+ if (action_buttons_row_->visible()) {
+ buttons.insert(buttons.end(), action_buttons_.begin(),
+ action_buttons_.end());
+ }
+ if (inline_reply_->visible())
+ buttons.push_back(inline_reply_);
+
for (size_t i = 0; i < buttons.size(); ++i) {
gfx::Point point_in_child = point;
ConvertPointToTarget(this, buttons[i], &point_in_child);
@@ -383,7 +439,7 @@ void NotificationViewMD::CreateOrUpdateViews(const Notification& notification) {
CreateOrUpdateActionButtonViews(notification);
}
-NotificationViewMD::NotificationViewMD(MessageCenterController* controller,
+NotificationViewMD::NotificationViewMD(MessageViewDelegate* controller,
const Notification& notification)
: MessageView(controller, notification),
clickable_(notification.clickable()) {
@@ -421,15 +477,27 @@ NotificationViewMD::NotificationViewMD(MessageCenterController* controller,
right_content_->SetLayoutManager(new views::FillLayout());
content_row_->AddChildView(right_content_);
- // |action_row_| contains inline action button.
+ // |action_row_| contains inline action buttons and inline textfield.
actions_row_ = new views::View();
- actions_row_->SetLayoutManager(
+ actions_row_->SetVisible(false);
+ actions_row_->SetLayoutManager(new views::FillLayout());
+ AddChildView(actions_row_);
+
+ // |action_buttons_row_| contains inline action buttons.
+ action_buttons_row_ = new views::View();
+ action_buttons_row_->SetLayoutManager(
new views::BoxLayout(views::BoxLayout::kHorizontal, kActionsRowPadding,
kActionsRowHorizontalSpacing));
- actions_row_->SetBackground(
+ action_buttons_row_->SetBackground(
views::CreateSolidBackground(kActionsRowBackgroundColor));
- actions_row_->SetVisible(false);
- AddChildView(actions_row_);
+ action_buttons_row_->SetVisible(false);
+ actions_row_->AddChildView(action_buttons_row_);
+
+ // |inline_reply_| is a textfield for inline reply.
+ inline_reply_ = new NotificationInputMD(this);
+ inline_reply_->SetVisible(false);
+
+ actions_row_->AddChildView(inline_reply_);
CreateOrUpdateViews(notification);
UpdateControlButtonsVisibilityWithNotification(notification);
@@ -473,10 +541,20 @@ void NotificationViewMD::ScrollRectToVisible(const gfx::Rect& rect) {
}
gfx::NativeCursor NotificationViewMD::GetCursor(const ui::MouseEvent& event) {
- if (clickable_ || controller()->HasClickedListener(notification_id()))
- return views::GetNativeHandCursor();
+ // Do not change the cursor on a notification that isn't clickable.
+ if (!clickable_)
+ return views::View::GetCursor(event);
+
+ // Do not change the cursor on the actions row.
+ if (expanded_) {
+ DCHECK(actions_row_);
+ gfx::Point point_in_child = event.location();
+ ConvertPointToTarget(this, actions_row_, &point_in_child);
+ if (actions_row_->HitTestPoint(point_in_child))
+ return views::View::GetCursor(event);
+ }
- return views::View::GetCursor(event);
+ return views::GetNativeHandCursor();
}
void NotificationViewMD::OnMouseEntered(const ui::MouseEvent& event) {
@@ -489,6 +567,22 @@ void NotificationViewMD::OnMouseExited(const ui::MouseEvent& event) {
UpdateControlButtonsVisibility();
}
+bool NotificationViewMD::OnMousePressed(const ui::MouseEvent& event) {
+ if (!event.IsOnlyLeftMouseButton())
+ return false;
+
+ // Ignore click of actions row outside action buttons.
+ if (expanded_) {
+ DCHECK(actions_row_);
+ gfx::Point point_in_child = event.location();
+ ConvertPointToTarget(this, actions_row_, &point_in_child);
+ if (actions_row_->HitTestPoint(point_in_child))
+ return true;
+ }
+
+ return MessageView::OnMousePressed(event);
+}
+
void NotificationViewMD::UpdateWithNotification(
const Notification& notification) {
MessageView::UpdateWithNotification(notification);
@@ -503,8 +597,7 @@ void NotificationViewMD::UpdateWithNotification(
void NotificationViewMD::UpdateControlButtonsVisibilityWithNotification(
const Notification& notification) {
control_buttons_view_->ShowSettingsButton(
- notification.delegate() &&
- notification.delegate()->ShouldDisplaySettingsButton());
+ notification.should_show_settings_button());
control_buttons_view_->ShowCloseButton(!GetPinned());
UpdateControlButtonsVisibility();
}
@@ -527,13 +620,28 @@ void NotificationViewMD::ButtonPressed(views::Button* sender,
// See if the button pressed was an action button.
for (size_t i = 0; i < action_buttons_.size(); ++i) {
- if (sender == action_buttons_[i]) {
- controller()->ClickOnNotificationButton(id, i);
- return;
+ if (sender != action_buttons_[i])
+ continue;
+ if (action_buttons_[i]->is_inline_reply()) {
+ inline_reply_->set_index(i);
+ inline_reply_->set_placeholder(action_buttons_[i]->placeholder());
+ inline_reply_->SetVisible(true);
+ action_buttons_row_->SetVisible(false);
+ Layout();
+ SchedulePaint();
+ } else {
+ delegate()->ClickOnNotificationButton(id, i);
}
+ return;
}
}
+void NotificationViewMD::OnNotificationInputSubmit(size_t index,
+ const base::string16& text) {
+ delegate()->ClickOnNotificationButtonWithReply(notification_id(), index,
+ text);
+}
+
bool NotificationViewMD::IsCloseButtonFocused() const {
return control_buttons_view_->IsCloseButtonFocused();
}
@@ -801,10 +909,12 @@ void NotificationViewMD::CreateOrUpdateActionButtonViews(
for (size_t i = 0; i < buttons.size(); ++i) {
ButtonInfo button_info = buttons[i];
if (new_buttons) {
- NotificationButtonMD* button =
- new NotificationButtonMD(this, button_info.title);
+ bool is_inline_reply =
+ button_info.type == message_center::ButtonType::TEXT;
+ NotificationButtonMD* button = new NotificationButtonMD(
+ this, is_inline_reply, button_info.title, button_info.placeholder);
action_buttons_.push_back(button);
- actions_row_->AddChildView(button);
+ action_buttons_row_->AddChildView(button);
} else {
action_buttons_[i]->SetText(button_info.title);
action_buttons_[i]->SchedulePaint();
@@ -839,7 +949,7 @@ bool NotificationViewMD::IsExpandable() {
return true;
}
// Expandable if there is at least one inline action.
- if (actions_row_->has_children())
+ if (action_buttons_row_->has_children())
return true;
// Expandable if the notification has image.
@@ -867,7 +977,13 @@ void NotificationViewMD::UpdateViewForExpandedState(bool expanded) {
}
if (image_container_view_)
image_container_view_->SetVisible(expanded);
- actions_row_->SetVisible(expanded && actions_row_->has_children());
+
+ actions_row_->SetVisible(expanded && (action_buttons_row_->has_children()));
+ if (!expanded) {
+ action_buttons_row_->SetVisible(true);
+ inline_reply_->SetVisible(false);
+ }
+
for (size_t i = kMaxLinesForMessageView; i < item_views_.size(); ++i) {
item_views_[i]->SetVisible(expanded);
}
@@ -924,8 +1040,8 @@ void NotificationViewMD::SetExpanded(bool expanded) {
UpdateViewForExpandedState(expanded_);
content_row_->InvalidateLayout();
- if (controller())
- controller()->UpdateNotificationSize(notification_id());
+ if (delegate())
+ delegate()->UpdateNotificationSize(notification_id());
}
void NotificationViewMD::Activate() {
diff --git a/chromium/ui/message_center/views/notification_view_md.h b/chromium/ui/message_center/views/notification_view_md.h
index b4240094bc9..cf2ff5d0ba3 100644
--- a/chromium/ui/message_center/views/notification_view_md.h
+++ b/chromium/ui/message_center/views/notification_view_md.h
@@ -13,6 +13,8 @@
#include "ui/message_center/views/message_view.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/label_button.h"
+#include "ui/views/controls/textfield/textfield.h"
+#include "ui/views/controls/textfield/textfield_controller.h"
#include "ui/views/view_targeter_delegate.h"
namespace views {
@@ -103,8 +105,15 @@ class LargeImageContainerView : public views::View {
// This button capitalizes the given label string.
class NotificationButtonMD : public views::LabelButton {
public:
+ // |is_inline_reply| is true when the notification action takes text as the
+ // return value i.e. the notification action is inline reply.
+ // The input field would be shown when the button is clicked.
+ // |placeholder| is placeholder text shown on the input field. Only used when
+ // |is_inline_reply| is true.
NotificationButtonMD(views::ButtonListener* listener,
- const base::string16& text);
+ bool is_inline_reply,
+ const base::string16& label,
+ const base::string16& placeholder);
~NotificationButtonMD() override;
void SetText(const base::string16& text) override;
@@ -115,20 +124,56 @@ class NotificationButtonMD : public views::LabelButton {
SkColor enabled_color_for_testing() { return label()->enabled_color(); }
+ bool is_inline_reply() const { return is_inline_reply_; }
+ const base::string16& placeholder() const { return placeholder_; }
+
private:
+ const bool is_inline_reply_;
+ const base::string16 placeholder_;
+
DISALLOW_COPY_AND_ASSIGN(NotificationButtonMD);
};
+class NotificationInputDelegate {
+ public:
+ virtual void OnNotificationInputSubmit(size_t index,
+ const base::string16& text) = 0;
+ virtual ~NotificationInputDelegate() = default;
+};
+
+class NotificationInputMD : public views::Textfield,
+ public views::TextfieldController {
+ public:
+ NotificationInputMD(NotificationInputDelegate* delegate);
+ ~NotificationInputMD() override;
+
+ bool HandleKeyEvent(views::Textfield* sender,
+ const ui::KeyEvent& key_event) override;
+
+ void set_index(size_t index) { index_ = index; }
+ void set_placeholder(const base::string16& placeholder);
+
+ private:
+ NotificationInputDelegate* const delegate_;
+
+ // |index_| is the notification action index that should be passed as the
+ // argument of MessageViewDelegate::ClickOnNotificationButtonWithReply.
+ size_t index_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(NotificationInputMD);
+};
+
// View that displays all current types of notification (web, basic, image, and
// list) except the custom notification. Future notification types may be
// handled by other classes, in which case instances of those classes would be
// returned by the Create() factory method below.
class MESSAGE_CENTER_EXPORT NotificationViewMD
: public MessageView,
+ public NotificationInputDelegate,
public views::ButtonListener,
public views::ViewTargeterDelegate {
public:
- NotificationViewMD(MessageCenterController* controller,
+ NotificationViewMD(MessageViewDelegate* controller,
const Notification& notification);
~NotificationViewMD() override;
@@ -141,6 +186,7 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD
gfx::NativeCursor GetCursor(const ui::MouseEvent& event) override;
void OnMouseEntered(const ui::MouseEvent& event) override;
void OnMouseExited(const ui::MouseEvent& event) override;
+ bool OnMousePressed(const ui::MouseEvent& event) override;
// Overridden from MessageView:
void UpdateWithNotification(const Notification& notification) override;
@@ -152,6 +198,10 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD
bool IsExpanded() const override;
void SetExpanded(bool expanded) override;
+ // Overridden from NotificationInputDelegate:
+ void OnNotificationInputSubmit(size_t index,
+ const base::string16& text) override;
+
// views::ViewTargeterDelegate:
views::View* TargetForRect(views::View* root, const gfx::Rect& rect) override;
@@ -160,6 +210,8 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD
FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, TestIconSizing);
FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, UpdateButtonsStateTest);
FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, UpdateButtonCountTest);
+ FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, TestActionButtonClick);
+ FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, TestInlineReply);
FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, ExpandLongMessage);
FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, TestAccentColor);
FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, UseImageAsIcon);
@@ -221,6 +273,8 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD
std::vector<ItemView*> item_views_;
views::ProgressBar* progress_bar_view_ = nullptr;
CompactTitleMessageView* compact_title_message_view_ = nullptr;
+ views::View* action_buttons_row_ = nullptr;
+ NotificationInputMD* inline_reply_ = nullptr;
std::unique_ptr<ui::EventHandler> click_activator_;
diff --git a/chromium/ui/message_center/views/notification_view_md_unittest.cc b/chromium/ui/message_center/views/notification_view_md_unittest.cc
index 1ef5ecadea3..6ebc86921a1 100644
--- a/chromium/ui/message_center/views/notification_view_md_unittest.cc
+++ b/chromium/ui/message_center/views/notification_view_md_unittest.cc
@@ -15,7 +15,7 @@
#include "ui/gfx/canvas.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
#include "ui/message_center/views/bounded_label.h"
-#include "ui/message_center/views/message_center_controller.h"
+#include "ui/message_center/views/message_view_delegate.h"
#include "ui/message_center/views/notification_control_buttons_view.h"
#include "ui/message_center/views/notification_header_view.h"
#include "ui/message_center/views/padded_button.h"
@@ -33,7 +33,7 @@ namespace message_center {
static const SkColor kBitmapColor = SK_ColorGREEN;
class NotificationViewMDTest : public views::ViewsTestBase,
- public MessageCenterController {
+ public MessageViewDelegate {
public:
NotificationViewMDTest();
~NotificationViewMDTest() override;
@@ -42,15 +42,15 @@ class NotificationViewMDTest : public views::ViewsTestBase,
void SetUp() override;
void TearDown() override;
- // Overridden from MessageCenterController:
+ // Overridden from MessageViewDelegate:
void ClickOnNotification(const std::string& notification_id) override;
void RemoveNotification(const std::string& notification_id,
bool by_user) override;
- std::unique_ptr<ui::MenuModel> CreateMenuModel(
- const Notification& notification) override;
- bool HasClickedListener(const std::string& notification_id) override;
void ClickOnNotificationButton(const std::string& notification_id,
int button_index) override;
+ void ClickOnNotificationButtonWithReply(const std::string& notification_id,
+ int button_index,
+ const base::string16& reply) override;
void ClickOnSettingsButton(const std::string& notification_id) override;
void UpdateNotificationSize(const std::string& notification_id) override;
@@ -81,6 +81,11 @@ class NotificationViewMDTest : public views::ViewsTestBase,
void ScrollBy(int dx);
views::View* GetCloseButton();
+ bool expecting_button_click_ = false;
+ bool expecting_reply_submission_ = false;
+ int clicked_button_index_ = -1;
+ base::string16 submitted_reply_string_;
+
private:
std::set<std::string> removed_ids_;
@@ -123,6 +128,13 @@ void NotificationViewMDTest::SetUp() {
widget_->SetContentsView(notification_view_.get());
widget_->SetSize(notification_view_->GetPreferredSize());
widget_->Show();
+ widget_->widget_delegate()->set_can_activate(true);
+ widget_->Activate();
+
+ expecting_button_click_ = false;
+ expecting_reply_submission_ = false;
+ clicked_button_index_ = -1;
+ submitted_reply_string_.clear();
}
void NotificationViewMDTest::TearDown() {
@@ -143,23 +155,25 @@ void NotificationViewMDTest::RemoveNotification(
removed_ids_.insert(notification_id);
}
-std::unique_ptr<ui::MenuModel> NotificationViewMDTest::CreateMenuModel(
- const Notification& notification) {
- // For this test, this method should not be invoked.
- NOTREACHED();
- return nullptr;
-}
-
-bool NotificationViewMDTest::HasClickedListener(
- const std::string& notification_id) {
- return true;
-}
-
void NotificationViewMDTest::ClickOnNotificationButton(
const std::string& notification_id,
int button_index) {
- // For this test, this method should not be invoked.
- NOTREACHED();
+ if (!expecting_button_click_) {
+ ADD_FAILURE() << "ClickOnNotificationButton should not be invoked.";
+ }
+ clicked_button_index_ = button_index;
+}
+
+void NotificationViewMDTest::ClickOnNotificationButtonWithReply(
+ const std::string& notification_id,
+ int button_index,
+ const base::string16& reply) {
+ if (!expecting_reply_submission_) {
+ ADD_FAILURE()
+ << "ClickOnNotificationButtonWithReply should not be invoked.";
+ }
+ clicked_button_index_ = button_index;
+ submitted_reply_string_ = reply;
}
void NotificationViewMDTest::ClickOnSettingsButton(
@@ -424,6 +438,83 @@ TEST_F(NotificationViewMDTest, UpdateButtonCountTest) {
notification_view()->action_buttons_[0]->state());
}
+TEST_F(NotificationViewMDTest, TestActionButtonClick) {
+ expecting_button_click_ = true;
+
+ notification()->set_buttons(CreateButtons(2));
+ notification_view()->UpdateWithNotification(*notification());
+ widget()->Show();
+
+ ui::test::EventGenerator generator(widget()->GetNativeWindow());
+
+ // Action buttons are hidden by collapsed state.
+ if (!notification_view()->expanded_)
+ notification_view()->ToggleExpanded();
+ EXPECT_TRUE(notification_view()->actions_row_->visible());
+
+ // Now construct a mouse click event 1 pixel inside the boundary of the action
+ // button.
+ gfx::Point cursor_location(1, 1);
+ views::View::ConvertPointToScreen(notification_view()->action_buttons_[1],
+ &cursor_location);
+ generator.MoveMouseTo(cursor_location);
+ generator.ClickLeftButton();
+
+ EXPECT_EQ(1, clicked_button_index_);
+}
+
+TEST_F(NotificationViewMDTest, TestInlineReply) {
+ expecting_reply_submission_ = true;
+
+ std::vector<ButtonInfo> buttons = CreateButtons(2);
+ buttons[1].type = ButtonType::TEXT;
+ notification()->set_buttons(buttons);
+ notification_view()->UpdateWithNotification(*notification());
+ widget()->Show();
+
+ ui::test::EventGenerator generator(widget()->GetNativeWindow());
+
+ // Action buttons are hidden by collapsed state.
+ if (!notification_view()->expanded_)
+ notification_view()->ToggleExpanded();
+ EXPECT_TRUE(notification_view()->actions_row_->visible());
+
+ // Now construct a mouse click event 1 pixel inside the boundary of the action
+ // button.
+ gfx::Point cursor_location(1, 1);
+ views::View::ConvertPointToScreen(notification_view()->action_buttons_[1],
+ &cursor_location);
+ generator.MoveMouseTo(cursor_location);
+ generator.ClickLeftButton();
+
+ // Nothing should be submitted at this point.
+ EXPECT_EQ(-1, clicked_button_index_);
+
+ // Toggling should hide the inline textfield.
+ EXPECT_TRUE(notification_view()->inline_reply_->visible());
+ notification_view()->ToggleExpanded();
+ notification_view()->ToggleExpanded();
+ EXPECT_FALSE(notification_view()->inline_reply_->visible());
+
+ // Click the button again and focus on the inline textfield.
+ generator.ClickLeftButton();
+ generator.ClickLeftButton();
+ EXPECT_TRUE(notification_view()->inline_reply_->visible());
+ EXPECT_TRUE(notification_view()->inline_reply_->HasFocus());
+
+ // Type the text and submit.
+ ui::KeyboardCode keycodes[] = {ui::VKEY_T, ui::VKEY_E, ui::VKEY_S, ui::VKEY_T,
+ ui::VKEY_RETURN};
+
+ for (ui::KeyboardCode keycode : keycodes) {
+ generator.PressKey(keycode, ui::EF_NONE);
+ generator.ReleaseKey(keycode, ui::EF_NONE);
+ }
+
+ EXPECT_EQ(1, clicked_button_index_);
+ EXPECT_EQ(base::ASCIIToUTF16("test"), submitted_reply_string_);
+}
+
TEST_F(NotificationViewMDTest, SlideOut) {
ui::ScopedAnimationDurationScaleMode zero_duration_scope(
ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
diff --git a/chromium/ui/message_center/views/notification_view_unittest.cc b/chromium/ui/message_center/views/notification_view_unittest.cc
index d11904f7a74..a394a89d6d7 100644
--- a/chromium/ui/message_center/views/notification_view_unittest.cc
+++ b/chromium/ui/message_center/views/notification_view_unittest.cc
@@ -27,7 +27,7 @@
#include "ui/message_center/notification_list.h"
#include "ui/message_center/notification_types.h"
#include "ui/message_center/views/constants.h"
-#include "ui/message_center/views/message_center_controller.h"
+#include "ui/message_center/views/message_view_delegate.h"
#include "ui/message_center/views/message_view_factory.h"
#include "ui/message_center/views/notification_button.h"
#include "ui/message_center/views/notification_control_buttons_view.h"
@@ -45,19 +45,10 @@
namespace message_center {
-// A test delegate used for tests that deal with the notification settings
-// button.
-class NotificationSettingsDelegate : public NotificationDelegate {
- bool ShouldDisplaySettingsButton() override { return true; }
-
- private:
- ~NotificationSettingsDelegate() override {}
-};
-
/* Test fixture ***************************************************************/
class NotificationViewTest : public views::ViewsTestBase,
- public MessageCenterController {
+ public MessageViewDelegate {
public:
NotificationViewTest();
~NotificationViewTest() override;
@@ -72,15 +63,15 @@ class NotificationViewTest : public views::ViewsTestBase,
Notification* notification() { return notification_.get(); }
RichNotificationData* data() { return data_.get(); }
- // Overridden from MessageCenterController:
+ // Overridden from MessageViewDelegate:
void ClickOnNotification(const std::string& notification_id) override;
void RemoveNotification(const std::string& notification_id,
bool by_user) override;
- std::unique_ptr<ui::MenuModel> CreateMenuModel(
- const Notification& notification) override;
- bool HasClickedListener(const std::string& notification_id) override;
void ClickOnNotificationButton(const std::string& notification_id,
int button_index) override;
+ void ClickOnNotificationButtonWithReply(const std::string& notification_id,
+ int button_index,
+ const base::string16& reply) override;
void ClickOnSettingsButton(const std::string& notification_id) override;
void UpdateNotificationSize(const std::string& notification_id) override;
@@ -286,21 +277,17 @@ void NotificationViewTest::RemoveNotification(
removed_ids_.insert(notification_id);
}
-std::unique_ptr<ui::MenuModel> NotificationViewTest::CreateMenuModel(
- const Notification& notification) {
+void NotificationViewTest::ClickOnNotificationButton(
+ const std::string& notification_id,
+ int button_index) {
// For this test, this method should not be invoked.
NOTREACHED();
- return nullptr;
-}
-
-bool NotificationViewTest::HasClickedListener(
- const std::string& notification_id) {
- return true;
}
-void NotificationViewTest::ClickOnNotificationButton(
+void NotificationViewTest::ClickOnNotificationButtonWithReply(
const std::string& notification_id,
- int button_index) {
+ int button_index,
+ const base::string16& reply) {
// For this test, this method should not be invoked.
NOTREACHED();
}
@@ -345,15 +332,13 @@ TEST_F(NotificationViewTest, CreateOrUpdateTest) {
}
TEST_F(NotificationViewTest, CreateOrUpdateTestSettingsButton) {
- scoped_refptr<NotificationSettingsDelegate> delegate =
- new NotificationSettingsDelegate();
- Notification notf(NOTIFICATION_TYPE_BASE_FORMAT,
- std::string("notification id"), base::UTF8ToUTF16("title"),
- base::UTF8ToUTF16("message"), CreateTestImage(80, 80),
- base::UTF8ToUTF16("display source"),
- GURL("https://hello.com"),
- NotifierId(NotifierId::APPLICATION, "extension_id"),
- *data(), delegate.get());
+ data()->settings_button_handler = SettingsButtonHandler::TRAY;
+ Notification notf(
+ NOTIFICATION_TYPE_BASE_FORMAT, std::string("notification id"),
+ base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"),
+ CreateTestImage(80, 80), base::UTF8ToUTF16("display source"),
+ GURL("https://hello.com"),
+ NotifierId(NotifierId::APPLICATION, "extension_id"), *data(), nullptr);
notification_view()->UpdateWithNotification(notf);
EXPECT_TRUE(NULL != notification_view()->title_view_);
@@ -555,15 +540,13 @@ TEST_F(NotificationViewTest, UpdateButtonCountTest) {
}
TEST_F(NotificationViewTest, SettingsButtonTest) {
- scoped_refptr<NotificationSettingsDelegate> delegate =
- new NotificationSettingsDelegate();
- Notification notf(NOTIFICATION_TYPE_BASE_FORMAT,
- std::string("notification id"), base::UTF8ToUTF16("title"),
- base::UTF8ToUTF16("message"), CreateTestImage(80, 80),
- base::UTF8ToUTF16("display source"),
- GURL("https://hello.com"),
- NotifierId(NotifierId::APPLICATION, "extension_id"),
- *data(), delegate.get());
+ data()->settings_button_handler = SettingsButtonHandler::TRAY;
+ Notification notf(
+ NOTIFICATION_TYPE_BASE_FORMAT, std::string("notification id"),
+ base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"),
+ CreateTestImage(80, 80), base::UTF8ToUTF16("display source"),
+ GURL("https://hello.com"),
+ NotifierId(NotifierId::APPLICATION, "extension_id"), *data(), nullptr);
notification_view()->UpdateWithNotification(notf);
widget()->Show();
diff --git a/chromium/ui/message_center/views/toast_contents_view.cc b/chromium/ui/message_center/views/toast_contents_view.cc
index cc6138b2ad3..d8a2cf67842 100644
--- a/chromium/ui/message_center/views/toast_contents_view.cc
+++ b/chromium/ui/message_center/views/toast_contents_view.cc
@@ -357,21 +357,6 @@ void ToastContentsView::RemoveNotification(
collection_->RemoveNotification(notification_id, by_user);
}
-std::unique_ptr<ui::MenuModel> ToastContentsView::CreateMenuModel(
- const Notification& notification) {
- // Should not reach, the context menu should be handled in
- // MessagePopupCollection.
- NOTREACHED();
- return nullptr;
-}
-
-bool ToastContentsView::HasClickedListener(
- const std::string& notification_id) {
- if (!collection_)
- return false;
- return collection_->HasClickedListener(notification_id);
-}
-
void ToastContentsView::ClickOnNotificationButton(
const std::string& notification_id,
int button_index) {
@@ -379,6 +364,15 @@ void ToastContentsView::ClickOnNotificationButton(
collection_->ClickOnNotificationButton(notification_id, button_index);
}
+void ToastContentsView::ClickOnNotificationButtonWithReply(
+ const std::string& notification_id,
+ int button_index,
+ const base::string16& reply) {
+ if (collection_)
+ collection_->ClickOnNotificationButtonWithReply(notification_id,
+ button_index, reply);
+}
+
void ToastContentsView::CreateWidget(
PopupAlignmentDelegate* alignment_delegate) {
views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
diff --git a/chromium/ui/message_center/views/toast_contents_view.h b/chromium/ui/message_center/views/toast_contents_view.h
index 4cd4ce0f28b..441c9d3f3fc 100644
--- a/chromium/ui/message_center/views/toast_contents_view.h
+++ b/chromium/ui/message_center/views/toast_contents_view.h
@@ -13,7 +13,7 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/message_center/message_center_export.h"
-#include "ui/message_center/views/message_center_controller.h"
+#include "ui/message_center/views/message_view_delegate.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/widget/widget_observer.h"
@@ -37,14 +37,14 @@ class MessageView;
class Notification;
class PopupAlignmentDelegate;
-// The widget host for a popup. Also implements MessageCenterController
+// The widget host for a popup. Also implements MessageViewDelegate
// which delegates over to MessagePopupCollection, but takes care about
// checking the weakref since MessagePopupCollection may disappear before
// widget/views are closed/destructed.
class MESSAGE_CENTER_EXPORT ToastContentsView
: public views::WidgetDelegateView,
public views::WidgetObserver,
- public MessageCenterController,
+ public MessageViewDelegate,
public gfx::AnimationDelegate {
public:
static const char kViewClassName[];
@@ -93,15 +93,15 @@ class MESSAGE_CENTER_EXPORT ToastContentsView
private:
friend class test::MessagePopupCollectionTest;
- // Overridden from MessageCenterController:
+ // Overridden from MessageViewDelegate:
void ClickOnNotification(const std::string& notification_id) override;
void RemoveNotification(const std::string& notification_id,
bool by_user) override;
- std::unique_ptr<ui::MenuModel> CreateMenuModel(
- const Notification& notification) override;
- bool HasClickedListener(const std::string& notification_id) override;
void ClickOnNotificationButton(const std::string& notification_id,
int button_index) override;
+ void ClickOnNotificationButtonWithReply(const std::string& notification_id,
+ int button_index,
+ const base::string16& reply) override;
void ClickOnSettingsButton(const std::string& notification_id) override;
void UpdateNotificationSize(const std::string& notification_id) override;