OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" | 5 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "ui/aura/client/cursor_client.h" | 8 #include "ui/aura/client/cursor_client.h" |
9 #include "ui/aura/test/test_window_delegate.h" | 9 #include "ui/aura/test/test_window_delegate.h" |
10 #include "ui/aura/window.h" | 10 #include "ui/aura/window.h" |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 // |RunWithDispatcher()| below. | 222 // |RunWithDispatcher()| below. |
223 aura::client::DispatcherRunLoop run_loop(client, NULL); | 223 aura::client::DispatcherRunLoop run_loop(client, NULL); |
224 base::Closure quit_runloop = run_loop.QuitClosure(); | 224 base::Closure quit_runloop = run_loop.QuitClosure(); |
225 message_loop()->PostTask(FROM_HERE, | 225 message_loop()->PostTask(FROM_HERE, |
226 base::Bind(&QuitNestedLoopAndCloseWidget, | 226 base::Bind(&QuitNestedLoopAndCloseWidget, |
227 base::Passed(&widget), | 227 base::Passed(&widget), |
228 base::Unretained(&quit_runloop))); | 228 base::Unretained(&quit_runloop))); |
229 run_loop.Run(); | 229 run_loop.Run(); |
230 } | 230 } |
231 | 231 |
| 232 // This class provides functionality to create fullscreen and top level popup |
| 233 // windows. It additionally tests whether the destruction of these windows |
| 234 // occurs correctly in desktop AURA without crashing. |
| 235 // It provides facilities to test the following cases:- |
| 236 // 1. Child window destroyed which should lead to the destruction of the |
| 237 // parent. |
| 238 // 2. Parent window destroyed which should lead to the child being destroyed. |
| 239 class DesktopAuraTopLevelWindowTest |
| 240 : public views::TestViewsDelegate, |
| 241 public aura::WindowObserver { |
| 242 public: |
| 243 DesktopAuraTopLevelWindowTest() |
| 244 : top_level_widget_(NULL), |
| 245 owned_window_(NULL), |
| 246 owner_destroyed_(false), |
| 247 owned_window_destroyed_(false) {} |
| 248 |
| 249 virtual ~DesktopAuraTopLevelWindowTest() { |
| 250 EXPECT_TRUE(owner_destroyed_); |
| 251 EXPECT_TRUE(owned_window_destroyed_); |
| 252 top_level_widget_ = NULL; |
| 253 owned_window_ = NULL; |
| 254 } |
| 255 |
| 256 // views::TestViewsDelegate overrides. |
| 257 virtual void OnBeforeWidgetInit( |
| 258 Widget::InitParams* params, |
| 259 internal::NativeWidgetDelegate* delegate) OVERRIDE { |
| 260 if (!params->native_widget) |
| 261 params->native_widget = new views::DesktopNativeWidgetAura(delegate); |
| 262 } |
| 263 |
| 264 void CreateTopLevelWindow(const gfx::Rect& bounds, bool fullscreen) { |
| 265 Widget::InitParams init_params; |
| 266 init_params.type = Widget::InitParams::TYPE_WINDOW; |
| 267 init_params.bounds = bounds; |
| 268 init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 269 init_params.layer_type = aura::WINDOW_LAYER_NOT_DRAWN; |
| 270 init_params.accept_events = fullscreen; |
| 271 |
| 272 widget_.Init(init_params); |
| 273 |
| 274 owned_window_ = new aura::Window(&child_window_delegate_); |
| 275 owned_window_->SetType(ui::wm::WINDOW_TYPE_NORMAL); |
| 276 owned_window_->SetName("TestTopLevelWindow"); |
| 277 if (fullscreen) { |
| 278 owned_window_->SetProperty(aura::client::kShowStateKey, |
| 279 ui::SHOW_STATE_FULLSCREEN); |
| 280 } else { |
| 281 owned_window_->SetType(ui::wm::WINDOW_TYPE_MENU); |
| 282 } |
| 283 owned_window_->Init(aura::WINDOW_LAYER_TEXTURED); |
| 284 aura::client::ParentWindowWithContext( |
| 285 owned_window_, |
| 286 widget_.GetNativeView()->GetRootWindow(), |
| 287 gfx::Rect(0, 0, 1900, 1600)); |
| 288 owned_window_->Show(); |
| 289 owned_window_->AddObserver(this); |
| 290 |
| 291 ASSERT_TRUE(owned_window_->parent() != NULL); |
| 292 owned_window_->parent()->AddObserver(this); |
| 293 |
| 294 top_level_widget_ = |
| 295 views::Widget::GetWidgetForNativeView(owned_window_->parent()); |
| 296 ASSERT_TRUE(top_level_widget_ != NULL); |
| 297 } |
| 298 |
| 299 void DestroyOwnedWindow() { |
| 300 ASSERT_TRUE(owned_window_ != NULL); |
| 301 delete owned_window_; |
| 302 } |
| 303 |
| 304 void DestroyOwnerWindow() { |
| 305 ASSERT_TRUE(top_level_widget_ != NULL); |
| 306 top_level_widget_->CloseNow(); |
| 307 } |
| 308 |
| 309 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { |
| 310 window->RemoveObserver(this); |
| 311 if (window == owned_window_) { |
| 312 owned_window_destroyed_ = true; |
| 313 } else if (window == top_level_widget_->GetNativeView()) { |
| 314 owner_destroyed_ = true; |
| 315 } else { |
| 316 ADD_FAILURE() << "Unexpected window destroyed callback: " << window; |
| 317 } |
| 318 } |
| 319 |
| 320 aura::Window* owned_window() { |
| 321 return owned_window_; |
| 322 } |
| 323 |
| 324 views::Widget* top_level_widget() { |
| 325 return top_level_widget_; |
| 326 } |
| 327 |
| 328 private: |
| 329 views::Widget widget_; |
| 330 views::Widget* top_level_widget_; |
| 331 aura::Window* owned_window_; |
| 332 bool owner_destroyed_; |
| 333 bool owned_window_destroyed_; |
| 334 aura::test::TestWindowDelegate child_window_delegate_; |
| 335 |
| 336 DISALLOW_COPY_AND_ASSIGN(DesktopAuraTopLevelWindowTest); |
| 337 }; |
| 338 |
| 339 TEST_F(WidgetTest, DesktopAuraFullscreenWindowDestroyedBeforeOwnerTest) { |
| 340 ViewsDelegate::views_delegate = NULL; |
| 341 DesktopAuraTopLevelWindowTest fullscreen_window; |
| 342 ASSERT_NO_FATAL_FAILURE(fullscreen_window.CreateTopLevelWindow( |
| 343 gfx::Rect(0, 0, 200, 200), true)); |
| 344 |
| 345 RunPendingMessages(); |
| 346 ASSERT_NO_FATAL_FAILURE(fullscreen_window.DestroyOwnedWindow()); |
| 347 RunPendingMessages(); |
| 348 } |
| 349 |
| 350 TEST_F(WidgetTest, DesktopAuraFullscreenWindowOwnerDestroyed) { |
| 351 ViewsDelegate::views_delegate = NULL; |
| 352 |
| 353 DesktopAuraTopLevelWindowTest fullscreen_window; |
| 354 ASSERT_NO_FATAL_FAILURE(fullscreen_window.CreateTopLevelWindow( |
| 355 gfx::Rect(0, 0, 200, 200), true)); |
| 356 |
| 357 RunPendingMessages(); |
| 358 ASSERT_NO_FATAL_FAILURE(fullscreen_window.DestroyOwnerWindow()); |
| 359 RunPendingMessages(); |
| 360 } |
| 361 |
| 362 TEST_F(WidgetTest, DesktopAuraTopLevelOwnedPopupTest) { |
| 363 ViewsDelegate::views_delegate = NULL; |
| 364 DesktopAuraTopLevelWindowTest popup_window; |
| 365 ASSERT_NO_FATAL_FAILURE(popup_window.CreateTopLevelWindow( |
| 366 gfx::Rect(0, 0, 200, 200), false)); |
| 367 |
| 368 RunPendingMessages(); |
| 369 ASSERT_NO_FATAL_FAILURE(popup_window.DestroyOwnedWindow()); |
| 370 RunPendingMessages(); |
| 371 } |
| 372 |
| 373 // This test validates that when a top level owned popup Aura window is |
| 374 // resized, the widget is resized as well. |
| 375 TEST_F(WidgetTest, DesktopAuraTopLevelOwnedPopupResizeTest) { |
| 376 ViewsDelegate::views_delegate = NULL; |
| 377 DesktopAuraTopLevelWindowTest popup_window; |
| 378 ASSERT_NO_FATAL_FAILURE(popup_window.CreateTopLevelWindow( |
| 379 gfx::Rect(0, 0, 200, 200), false)); |
| 380 |
| 381 gfx::Rect new_size(0, 0, 400, 400); |
| 382 popup_window.owned_window()->SetBounds(new_size); |
| 383 |
| 384 EXPECT_EQ(popup_window.top_level_widget()->GetNativeView()->bounds().size(), |
| 385 new_size.size()); |
| 386 RunPendingMessages(); |
| 387 ASSERT_NO_FATAL_FAILURE(popup_window.DestroyOwnedWindow()); |
| 388 RunPendingMessages(); |
| 389 } |
| 390 |
232 } // namespace views | 391 } // namespace views |
OLD | NEW |