diff options
Diffstat (limited to 'chromium/ash/wm/frame_painter_unittest.cc')
-rw-r--r-- | chromium/ash/wm/frame_painter_unittest.cc | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/chromium/ash/wm/frame_painter_unittest.cc b/chromium/ash/wm/frame_painter_unittest.cc index ee9313fcf10..5826be6787d 100644 --- a/chromium/ash/wm/frame_painter_unittest.cc +++ b/chromium/ash/wm/frame_painter_unittest.cc @@ -12,6 +12,7 @@ #include "ash/wm/window_properties.h" #include "ash/wm/window_util.h" #include "base/memory/scoped_ptr.h" +#include "base/message_loop/message_loop.h" #include "grit/ash_resources.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/client/aura_constants.h" @@ -25,6 +26,7 @@ #include "ui/views/controls/button/image_button.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" +#include "ui/views/widget/widget_observer.h" #include "ui/views/window/non_client_view.h" using ash::FramePainter; @@ -148,6 +150,33 @@ FramePainter* CreateTestPainter(Widget* widget) { return painter; } +// Self-owned manager of the frame painter which deletes the painter and itself +// when its widget is closed. +class FramePainterOwner : views::WidgetObserver { + public: + explicit FramePainterOwner(Widget* widget) + : frame_painter_(CreateTestPainter(widget)) { + widget->AddObserver(this); + } + + virtual ~FramePainterOwner() {} + + FramePainter* frame_painter() { return frame_painter_.get(); } + + private: + virtual void OnWidgetDestroying(Widget* widget) OVERRIDE { + widget->RemoveObserver(this); + // Do not delete directly here, since the task of FramePainter causing + // the crash of crbug.com/273310 may run after this class handles this + // event. + base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); + } + + scoped_ptr<FramePainter> frame_painter_; + + DISALLOW_COPY_AND_ASSIGN(FramePainterOwner); +}; + } // namespace namespace ash { @@ -690,4 +719,33 @@ TEST_F(FramePainterTest, ChildWindowVisibility) { 0)); } +TEST_F(FramePainterTest, NoCrashShutdownWithAlwaysOnTopWindow) { + // Create normal window and an always-on-top window, and leave it as is + // and finish the test, then verify it doesn't cause a crash. See + // crbug.com/273310. Note that those widgets will be deleted at + // RootWindowController::CloseChildWindows(), so this code is memory-safe. + Widget* w1 = new Widget; + Widget::InitParams params1; + params1.context = CurrentContext(); + w1->Init(params1); + FramePainterOwner* o1 = new FramePainterOwner(w1); + FramePainter* p1 = o1->frame_painter(); + w1->SetBounds(gfx::Rect(0, 0, 100, 100)); + w1->Show(); + EXPECT_TRUE(p1->UseSoloWindowHeader()); + + Widget* w2 = new Widget; + Widget::InitParams params2; + params2.context = CurrentContext(); + params2.keep_on_top = true; + w2->Init(params2); + FramePainterOwner* o2 = new FramePainterOwner(w2); + FramePainter* p2 = o2->frame_painter(); + w2->Show(); + EXPECT_FALSE(p1->UseSoloWindowHeader()); + EXPECT_FALSE(p2->UseSoloWindowHeader()); + + // Exit with no resource release. They'll be released at shutdown. +} + } // namespace ash |