Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Unified Diff: ui/views/widget/widget_unittest.cc

Issue 2834943002: Don't allow a widget to send close notifications more than once. (Closed)
Patch Set: sky review Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/widget/widget.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/widget/widget_unittest.cc
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc
index 52845e5ed925fc9141065f1f52e2ac2e7a8ccfc2..fe51c6f0e0acaa603e2e2729994e0d3907ffe58a 100644
--- a/ui/views/widget/widget_unittest.cc
+++ b/ui/views/widget/widget_unittest.cc
@@ -738,6 +738,8 @@ class WidgetObserverTest : public WidgetTest, public WidgetObserver {
void OnWidgetDestroying(Widget* widget) override {
if (active_ == widget)
active_ = nullptr;
+ if (widget_activated_ == widget)
+ widget_activated_ = nullptr;
widget_closed_ = widget;
}
@@ -808,11 +810,10 @@ class WidgetObserverTest : public WidgetTest, public WidgetObserver {
Widget* widget_to_close_on_hide_;
};
-TEST_F(WidgetObserverTest, DISABLED_ActivationChange) {
+TEST_F(WidgetObserverTest, ActivationChange) {
WidgetAutoclosePtr toplevel(CreateTopLevelPlatformWidget());
-
- Widget* toplevel1 = NewWidget();
- Widget* toplevel2 = NewWidget();
+ WidgetAutoclosePtr toplevel1(NewWidget());
+ WidgetAutoclosePtr toplevel2(NewWidget());
toplevel1->Show();
toplevel2->Show();
@@ -822,20 +823,82 @@ TEST_F(WidgetObserverTest, DISABLED_ActivationChange) {
toplevel1->Activate();
RunPendingMessages();
- EXPECT_EQ(toplevel1, widget_activated());
+ EXPECT_EQ(toplevel1.get(), widget_activated());
toplevel2->Activate();
RunPendingMessages();
- EXPECT_EQ(toplevel1, widget_deactivated());
- EXPECT_EQ(toplevel2, widget_activated());
- EXPECT_EQ(toplevel2, active());
+ EXPECT_EQ(toplevel1.get(), widget_deactivated());
+ EXPECT_EQ(toplevel2.get(), widget_activated());
+ EXPECT_EQ(toplevel2.get(), active());
}
-TEST_F(WidgetObserverTest, DISABLED_VisibilityChange) {
- WidgetAutoclosePtr toplevel(CreateTopLevelPlatformWidget());
+namespace {
+
+// This class simulates a focus manager that moves focus to a second widget when
+// the first one is closed. It simulates a situation where a sequence of widget
+// observers might try to call Widget::Close in response to a OnWidgetClosing().
+class WidgetActivationForwarder : public TestWidgetObserver {
+ public:
+ WidgetActivationForwarder(Widget* current_active_widget,
+ Widget* widget_to_activate)
+ : TestWidgetObserver(current_active_widget),
+ widget_to_activate_(widget_to_activate) {}
+
+ ~WidgetActivationForwarder() override {}
+
+ private:
+ // WidgetObserver overrides:
+ void OnWidgetClosing(Widget* widget) override {
+ widget->OnNativeWidgetActivationChanged(false);
+ widget_to_activate_->Activate();
+ }
+ void OnWidgetActivationChanged(Widget* widget, bool active) override {
+ if (!active)
+ widget->Close();
+ }
+
+ Widget* widget_to_activate_;
+
+ DISALLOW_COPY_AND_ASSIGN(WidgetActivationForwarder);
+};
+
+// This class observes a widget and counts the number of times OnWidgetClosing
+// is called.
+class WidgetCloseCounter : public TestWidgetObserver {
+ public:
+ explicit WidgetCloseCounter(Widget* widget) : TestWidgetObserver(widget) {}
+
+ ~WidgetCloseCounter() override {}
+
+ int close_count() const { return close_count_; }
+
+ private:
+ // WidgetObserver overrides:
+ void OnWidgetClosing(Widget* widget) override { close_count_++; }
+
+ int close_count_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(WidgetCloseCounter);
+};
- Widget* child1 = NewWidget();
- Widget* child2 = NewWidget();
+} // namespace
+
+// Makes sure close notifications aren't sent more than once when a Widget is
+// shutting down. Test for crbug.com/714334
+TEST_F(WidgetObserverTest, CloseReentrancy) {
+ Widget* widget1 = CreateTopLevelPlatformWidget();
+ Widget* widget2 = CreateTopLevelPlatformWidget();
+ WidgetCloseCounter counter(widget1);
+ WidgetActivationForwarder focus_manager(widget1, widget2);
+ widget1->Close();
+ EXPECT_EQ(1, counter.close_count());
+ widget2->Close();
+}
+
+TEST_F(WidgetObserverTest, VisibilityChange) {
+ WidgetAutoclosePtr toplevel(CreateTopLevelPlatformWidget());
+ WidgetAutoclosePtr child1(NewWidget());
+ WidgetAutoclosePtr child2(NewWidget());
toplevel->Show();
child1->Show();
@@ -844,16 +907,16 @@ TEST_F(WidgetObserverTest, DISABLED_VisibilityChange) {
reset();
child1->Hide();
- EXPECT_EQ(child1, widget_hidden());
+ EXPECT_EQ(child1.get(), widget_hidden());
child2->Hide();
- EXPECT_EQ(child2, widget_hidden());
+ EXPECT_EQ(child2.get(), widget_hidden());
child1->Show();
- EXPECT_EQ(child1, widget_shown());
+ EXPECT_EQ(child1.get(), widget_shown());
child2->Show();
- EXPECT_EQ(child2, widget_shown());
+ EXPECT_EQ(child2.get(), widget_shown());
}
TEST_F(WidgetObserverTest, DestroyBubble) {
« no previous file with comments | « ui/views/widget/widget.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698