Index: ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc |
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc |
index b314667bede10ff6e5f42e979d5a1936942d47c3..17624549831ce4f53699002ce782c42b9362f2e4 100644 |
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc |
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc |
@@ -229,4 +229,163 @@ TEST_F(DesktopNativeWidgetAuraTest, WidgetCanBeDestroyedFromNestedLoop) { |
run_loop.Run(); |
} |
+// This class provides functionality to create fullscreen and top level popup |
+// windows. It additionally tests whether the destruction of these windows |
+// occurs correctly in desktop AURA without crashing. |
+// It provides facilities to test the following cases:- |
+// 1. Child window destroyed which should lead to the destruction of the |
+// parent. |
+// 2. Parent window destroyed which should lead to the child being destroyed. |
+class DesktopAuraTopLevelWindowTest |
+ : public views::TestViewsDelegate, |
+ public aura::WindowObserver { |
+ public: |
+ DesktopAuraTopLevelWindowTest() |
+ : top_level_widget_(NULL), |
+ owned_window_(NULL), |
+ owner_destroyed_(false), |
+ owned_window_destroyed_(false) {} |
+ |
+ virtual ~DesktopAuraTopLevelWindowTest() { |
+ EXPECT_TRUE(owner_destroyed_); |
+ EXPECT_TRUE(owned_window_destroyed_); |
+ top_level_widget_ = NULL; |
+ owned_window_ = NULL; |
+ } |
+ |
+ // views::TestViewsDelegate overrides. |
+ virtual void OnBeforeWidgetInit( |
+ Widget::InitParams* params, |
+ internal::NativeWidgetDelegate* delegate) OVERRIDE { |
+ if (!params->native_widget) |
+ params->native_widget = new views::DesktopNativeWidgetAura(delegate); |
+ } |
+ |
+ void CreateTopLevelWindow(const gfx::Rect& bounds, bool fullscreen) { |
+ Widget::InitParams init_params; |
+ init_params.type = Widget::InitParams::TYPE_WINDOW; |
+ init_params.bounds = bounds; |
+ init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
+ init_params.layer_type = aura::WINDOW_LAYER_NOT_DRAWN; |
+ init_params.accept_events = fullscreen; |
+ |
+ widget_.Init(init_params); |
+ |
+ owned_window_ = new aura::Window(&child_window_delegate_); |
+ owned_window_->SetType(ui::wm::WINDOW_TYPE_NORMAL); |
+ owned_window_->SetName("TestTopLevelWindow"); |
+ if (fullscreen) { |
+ owned_window_->SetProperty(aura::client::kShowStateKey, |
+ ui::SHOW_STATE_FULLSCREEN); |
+ } else { |
+ owned_window_->SetType(ui::wm::WINDOW_TYPE_MENU); |
+ } |
+ owned_window_->Init(aura::WINDOW_LAYER_TEXTURED); |
+ aura::client::ParentWindowWithContext( |
+ owned_window_, |
+ widget_.GetNativeView()->GetRootWindow(), |
+ gfx::Rect(0, 0, 1900, 1600)); |
+ owned_window_->Show(); |
+ owned_window_->AddObserver(this); |
+ |
+ ASSERT_TRUE(owned_window_->parent() != NULL); |
+ owned_window_->parent()->AddObserver(this); |
+ |
+ top_level_widget_ = |
+ views::Widget::GetWidgetForNativeView(owned_window_->parent()); |
+ ASSERT_TRUE(top_level_widget_ != NULL); |
+ } |
+ |
+ void DestroyOwnedWindow() { |
+ ASSERT_TRUE(owned_window_ != NULL); |
+ delete owned_window_; |
+ } |
+ |
+ void DestroyOwnerWindow() { |
+ ASSERT_TRUE(top_level_widget_ != NULL); |
+ top_level_widget_->CloseNow(); |
+ } |
+ |
+ virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { |
+ window->RemoveObserver(this); |
+ if (window == owned_window_) { |
+ owned_window_destroyed_ = true; |
+ } else if (window == top_level_widget_->GetNativeView()) { |
+ owner_destroyed_ = true; |
+ } else { |
+ ADD_FAILURE() << "Unexpected window destroyed callback: " << window; |
+ } |
+ } |
+ |
+ aura::Window* owned_window() { |
+ return owned_window_; |
+ } |
+ |
+ views::Widget* top_level_widget() { |
+ return top_level_widget_; |
+ } |
+ |
+ private: |
+ views::Widget widget_; |
+ views::Widget* top_level_widget_; |
+ aura::Window* owned_window_; |
+ bool owner_destroyed_; |
+ bool owned_window_destroyed_; |
+ aura::test::TestWindowDelegate child_window_delegate_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(DesktopAuraTopLevelWindowTest); |
+}; |
+ |
+TEST_F(WidgetTest, DesktopAuraFullscreenWindowDestroyedBeforeOwnerTest) { |
+ ViewsDelegate::views_delegate = NULL; |
+ DesktopAuraTopLevelWindowTest fullscreen_window; |
+ ASSERT_NO_FATAL_FAILURE(fullscreen_window.CreateTopLevelWindow( |
+ gfx::Rect(0, 0, 200, 200), true)); |
+ |
+ RunPendingMessages(); |
+ ASSERT_NO_FATAL_FAILURE(fullscreen_window.DestroyOwnedWindow()); |
+ RunPendingMessages(); |
+} |
+ |
+TEST_F(WidgetTest, DesktopAuraFullscreenWindowOwnerDestroyed) { |
+ ViewsDelegate::views_delegate = NULL; |
+ |
+ DesktopAuraTopLevelWindowTest fullscreen_window; |
+ ASSERT_NO_FATAL_FAILURE(fullscreen_window.CreateTopLevelWindow( |
+ gfx::Rect(0, 0, 200, 200), true)); |
+ |
+ RunPendingMessages(); |
+ ASSERT_NO_FATAL_FAILURE(fullscreen_window.DestroyOwnerWindow()); |
+ RunPendingMessages(); |
+} |
+ |
+TEST_F(WidgetTest, DesktopAuraTopLevelOwnedPopupTest) { |
+ ViewsDelegate::views_delegate = NULL; |
+ DesktopAuraTopLevelWindowTest popup_window; |
+ ASSERT_NO_FATAL_FAILURE(popup_window.CreateTopLevelWindow( |
+ gfx::Rect(0, 0, 200, 200), false)); |
+ |
+ RunPendingMessages(); |
+ ASSERT_NO_FATAL_FAILURE(popup_window.DestroyOwnedWindow()); |
+ RunPendingMessages(); |
+} |
+ |
+// This test validates that when a top level owned popup Aura window is |
+// resized, the widget is resized as well. |
+TEST_F(WidgetTest, DesktopAuraTopLevelOwnedPopupResizeTest) { |
+ ViewsDelegate::views_delegate = NULL; |
+ DesktopAuraTopLevelWindowTest popup_window; |
+ ASSERT_NO_FATAL_FAILURE(popup_window.CreateTopLevelWindow( |
+ gfx::Rect(0, 0, 200, 200), false)); |
+ |
+ gfx::Rect new_size(0, 0, 400, 400); |
+ popup_window.owned_window()->SetBounds(new_size); |
+ |
+ EXPECT_EQ(popup_window.top_level_widget()->GetNativeView()->bounds().size(), |
+ new_size.size()); |
+ RunPendingMessages(); |
+ ASSERT_NO_FATAL_FAILURE(popup_window.DestroyOwnedWindow()); |
+ RunPendingMessages(); |
+} |
+ |
} // namespace views |