diff options
author | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-14 01:28:54 +0000 |
---|---|---|
committer | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-14 01:28:54 +0000 |
commit | 3ccbef3e6d7388eebe4e212f7f7813fb992314fe (patch) | |
tree | 7d4a326c0c4d1a7d190f627e4493b4af59356ece | |
parent | 6728c8f3deaf67e492054296f3f840400b9e4e04 (diff) | |
download | chromium_src-3ccbef3e6d7388eebe4e212f7f7813fb992314fe.zip chromium_src-3ccbef3e6d7388eebe4e212f7f7813fb992314fe.tar.gz chromium_src-3ccbef3e6d7388eebe4e212f7f7813fb992314fe.tar.bz2 |
Fix crash on signing out with exit warning bubble open.
Make ExitWarningHandler really own its bubble widget so that the widget
will not be released before destructing ExitWarningHandler, which could
happen when shutting down ash while the bubble is visible.
BUG=272368
Review URL: https://chromiumcodereview.appspot.com/23122003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@217429 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/accelerators/accelerator_controller_unittest.cc | 30 | ||||
-rw-r--r-- | ash/accelerators/exit_warning_handler.cc | 11 | ||||
-rw-r--r-- | ash/accelerators/exit_warning_handler.h | 3 |
3 files changed, 28 insertions, 16 deletions
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc index fe9f518..4c00f72 100644 --- a/ash/accelerators/accelerator_controller_unittest.cc +++ b/ash/accelerators/accelerator_controller_unittest.cc @@ -35,8 +35,8 @@ namespace { class TestTarget : public ui::AcceleratorTarget { public: - TestTarget() : accelerator_pressed_count_(0) {}; - virtual ~TestTarget() {}; + TestTarget() : accelerator_pressed_count_(0) {} + virtual ~TestTarget() {} int accelerator_pressed_count() const { return accelerator_pressed_count_; @@ -298,8 +298,8 @@ bool TestTarget::CanHandleAccelerators() const { class AcceleratorControllerTest : public test::AshTestBase { public: - AcceleratorControllerTest() {}; - virtual ~AcceleratorControllerTest() {}; + AcceleratorControllerTest() {} + virtual ~AcceleratorControllerTest() {} protected: void EnableInternalDisplay() { @@ -360,7 +360,7 @@ TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestDoublePress) { EXPECT_FALSE(ProcessWithContext(release)); EXPECT_FALSE(is_idle(ewh)); EXPECT_TRUE(is_ui_shown(ewh)); - EXPECT_TRUE(ProcessWithContext(press)); // second press before timer. + EXPECT_TRUE(ProcessWithContext(press)); // second press before timer. EXPECT_FALSE(ProcessWithContext(release)); SimulateTimerExpired(ewh); EXPECT_TRUE(is_exiting(ewh)); @@ -387,6 +387,20 @@ TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestSinglePress) { EXPECT_FALSE(is_ui_shown(ewh)); Reset(ewh); } + +// Shutdown ash with exit warning bubble open should not crash. +TEST_F(AcceleratorControllerTest, LingeringExitWarningBubble) { + ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest(); + ASSERT_TRUE(!!ewh); + StubForTest(ewh); + + // Trigger once to show the bubble. + ewh->HandleAccelerator(); + EXPECT_FALSE(is_idle(ewh)); + EXPECT_TRUE(is_ui_shown(ewh)); + + // Exit ash and there should be no crash +} #endif // !defined(OS_WIN) TEST_F(AcceleratorControllerTest, Register) { @@ -908,8 +922,8 @@ TEST_F(AcceleratorControllerTest, GlobalAccelerators) { // ToggleDesktopFullScreen (not implemented yet on Linux) EXPECT_TRUE(ProcessWithContext( ui::Accelerator(ui::VKEY_F11, ui::EF_CONTROL_DOWN))); -#endif // OS_LINUX -#endif // !NDEBUG +#endif // OS_LINUX +#endif // !NDEBUG #if !defined(OS_WIN) // Exit @@ -1234,7 +1248,7 @@ TEST_F(AcceleratorControllerTest, DisallowedAtModalWindow) { EXPECT_EQ(2, delegate->handle_take_screenshot_count()); EXPECT_TRUE(ProcessWithContext( ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, - ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN))); + ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN))); EXPECT_EQ(2, delegate->handle_take_screenshot_count()); } // Brightness diff --git a/ash/accelerators/exit_warning_handler.cc b/ash/accelerators/exit_warning_handler.cc index 767b266..6612fc8 100644 --- a/ash/accelerators/exit_warning_handler.cc +++ b/ash/accelerators/exit_warning_handler.cc @@ -100,11 +100,10 @@ class ExitWarningWidgetDelegateView : public views::WidgetDelegateView { DISALLOW_COPY_AND_ASSIGN(ExitWarningWidgetDelegateView); }; -} // namespace +} // namespace ExitWarningHandler::ExitWarningHandler() : state_(IDLE), - widget_(NULL), stub_timer_for_test_(false) { } @@ -169,6 +168,7 @@ void ExitWarningHandler::Show() { views::Widget::InitParams params; params.type = views::Widget::InitParams::TYPE_POPUP; params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; params.accept_events = false; params.can_activate = false; params.keep_on_top = true; @@ -178,7 +178,7 @@ void ExitWarningHandler::Show() { params.parent = Shell::GetContainer( root_window, internal::kShellWindowId_SettingBubbleContainer); - widget_ = new views::Widget; + widget_.reset(new views::Widget); widget_->Init(params); widget_->SetContentsView(delegate); widget_->GetNativeView()->SetName("ExitWarningWindow"); @@ -188,10 +188,7 @@ void ExitWarningHandler::Show() { } void ExitWarningHandler::Hide() { - if (!widget_) - return; - widget_->Close(); - widget_ = NULL; + widget_.reset(); } } // namespace ash diff --git a/ash/accelerators/exit_warning_handler.h b/ash/accelerators/exit_warning_handler.h index b303d84..b99681c 100644 --- a/ash/accelerators/exit_warning_handler.h +++ b/ash/accelerators/exit_warning_handler.h @@ -6,6 +6,7 @@ #define ASH_ACCELERATORS_EXIT_WARNING_HANDLER_H_ #include "ash/ash_export.h" +#include "base/memory/scoped_ptr.h" #include "base/timer/timer.h" #include "ui/base/accelerators/accelerator.h" @@ -71,7 +72,7 @@ class ASH_EXPORT ExitWarningHandler { void Hide(); State state_; - views::Widget* widget_; // owned by |this|. + scoped_ptr<views::Widget> widget_; base::OneShotTimer<ExitWarningHandler> timer_; // Flag to suppress starting the timer for testing. For test we call |