summaryrefslogtreecommitdiff
path: root/chromium/ui/message_center
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/message_center')
-rw-r--r--chromium/ui/message_center/views/message_popup_view.cc4
-rw-r--r--chromium/ui/message_center/views/notification_view_md.cc18
-rw-r--r--chromium/ui/message_center/views/notification_view_md.h2
-rw-r--r--chromium/ui/message_center/views/notification_view_md_unittest.cc31
4 files changed, 51 insertions, 4 deletions
diff --git a/chromium/ui/message_center/views/message_popup_view.cc b/chromium/ui/message_center/views/message_popup_view.cc
index dc37ecaee14..a4e333c54c4 100644
--- a/chromium/ui/message_center/views/message_popup_view.cc
+++ b/chromium/ui/message_center/views/message_popup_view.cc
@@ -113,11 +113,11 @@ void MessagePopupView::AutoCollapse() {
void MessagePopupView::Show() {
views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
+ params.keep_on_top = true;
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
// Make the widget explicitly activatable as TYPE_POPUP is not activatable by
// default but we need focus for the inline reply textarea.
params.activatable = views::Widget::InitParams::ACTIVATABLE_YES;
- params.keep_on_top = true;
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
params.opacity = views::Widget::InitParams::OPAQUE_WINDOW;
#else
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
diff --git a/chromium/ui/message_center/views/notification_view_md.cc b/chromium/ui/message_center/views/notification_view_md.cc
index a81e70dd50e..5349bc34e5b 100644
--- a/chromium/ui/message_center/views/notification_view_md.cc
+++ b/chromium/ui/message_center/views/notification_view_md.cc
@@ -715,7 +715,12 @@ void NotificationViewMD::ButtonPressed(views::Button* sender,
if (sender == header_row_) {
if (IsExpandable() && content_row_->visible()) {
SetManuallyExpandedOrCollapsed(true);
+ auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
ToggleExpanded();
+ // Check |this| is valid before continuing, because ToggleExpanded() might
+ // cause |this| to be deleted.
+ if (!weak_ptr)
+ return;
Layout();
SchedulePaint();
}
@@ -1216,6 +1221,8 @@ void NotificationViewMD::UpdateViewForExpandedState(bool expanded) {
}
void NotificationViewMD::ToggleInlineSettings(const ui::Event& event) {
+ if (!settings_row_)
+ return;
bool inline_settings_visible = !settings_row_->visible();
bool disable_notification =
settings_row_->visible() && block_all_button_->checked();
@@ -1229,7 +1236,16 @@ void NotificationViewMD::ToggleInlineSettings(const ui::Event& event) {
dont_block_button_->SetChecked(true);
SetSettingMode(inline_settings_visible);
- SetExpanded(!inline_settings_visible);
+
+ // Grab a weak pointer before calling SetExpanded() as it might cause |this|
+ // to be deleted.
+ {
+ auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
+ SetExpanded(!inline_settings_visible);
+ if (!weak_ptr)
+ return;
+ }
+
PreferredSizeChanged();
if (inline_settings_visible)
diff --git a/chromium/ui/message_center/views/notification_view_md.h b/chromium/ui/message_center/views/notification_view_md.h
index cc16a88d3b6..ef732236360 100644
--- a/chromium/ui/message_center/views/notification_view_md.h
+++ b/chromium/ui/message_center/views/notification_view_md.h
@@ -325,6 +325,8 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD
base::TimeTicks last_mouse_pressed_timestamp_;
+ base::WeakPtrFactory<NotificationViewMD> weak_ptr_factory_{this};
+
DISALLOW_COPY_AND_ASSIGN(NotificationViewMD);
};
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 248c85270b9..37baaff9219 100644
--- a/chromium/ui/message_center/views/notification_view_md_unittest.cc
+++ b/chromium/ui/message_center/views/notification_view_md_unittest.cc
@@ -139,6 +139,11 @@ class NotificationViewMDTest
void InkDropAnimationStarted() override;
void InkDropRippleAnimationEnded(views::InkDropState ink_drop_state) override;
+ void set_delete_on_preferred_size_changed(
+ bool delete_on_preferred_size_changed) {
+ delete_on_preferred_size_changed_ = delete_on_preferred_size_changed;
+ }
+
void set_delete_on_notification_removed(bool delete_on_notification_removed) {
delete_on_notification_removed_ = delete_on_notification_removed;
}
@@ -165,6 +170,7 @@ class NotificationViewMDTest
views::View* GetCloseButton();
bool ink_drop_stopped_ = false;
+ bool delete_on_preferred_size_changed_ = false;
bool delete_on_notification_removed_ = false;
std::set<std::string> removed_ids_;
scoped_refptr<NotificationTestDelegate> delegate_;
@@ -211,7 +217,8 @@ void NotificationViewMDTest::SetUp() {
void NotificationViewMDTest::TearDown() {
MessageCenter::Get()->RemoveObserver(this);
- DCHECK(notification_view_ || delete_on_notification_removed_);
+ DCHECK(notification_view_ || delete_on_preferred_size_changed_ ||
+ delete_on_notification_removed_);
if (notification_view_) {
notification_view_->SetInkDropMode(MessageView::InkDropMode::OFF);
notification_view_->RemoveObserver(this);
@@ -225,6 +232,11 @@ void NotificationViewMDTest::TearDown() {
void NotificationViewMDTest::OnViewPreferredSizeChanged(
views::View* observed_view) {
EXPECT_EQ(observed_view, notification_view());
+ if (delete_on_preferred_size_changed_) {
+ widget()->CloseNow();
+ notification_view_.reset();
+ return;
+ }
widget()->SetSize(notification_view()->GetPreferredSize());
}
@@ -1198,6 +1210,23 @@ TEST_F(NotificationViewMDTest, TestClickExpanded) {
EXPECT_TRUE(delegate_->clicked());
}
+TEST_F(NotificationViewMDTest, TestDeleteOnToggleExpanded) {
+ std::unique_ptr<Notification> notification = CreateSimpleNotification();
+ notification->set_type(NotificationType::NOTIFICATION_TYPE_SIMPLE);
+ notification->set_title(base::string16());
+ notification->set_message(base::ASCIIToUTF16(
+ "consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore "
+ "et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud "
+ "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."));
+ UpdateNotificationViews(*notification);
+ EXPECT_FALSE(notification_view()->expanded_);
+
+ // The view can be deleted by PreferredSizeChanged(). https://crbug.com/918933
+ set_delete_on_preferred_size_changed(true);
+ notification_view()->ButtonPressed(notification_view()->header_row_,
+ DummyEvent());
+}
+
TEST_F(NotificationViewMDTest, TestDeleteOnDisableNotification) {
std::unique_ptr<Notification> notification = CreateSimpleNotification();
notification->set_type(NOTIFICATION_TYPE_SIMPLE);