OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <algorithm> | 5 #include <algorithm> |
| 6 #include <memory> |
6 #include <set> | 7 #include <set> |
7 | 8 |
8 #include "base/bind.h" | 9 #include "base/bind.h" |
9 #include "base/macros.h" | 10 #include "base/macros.h" |
10 #include "base/memory/scoped_ptr.h" | |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
14 #include "build/build_config.h" | 14 #include "build/build_config.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
16 #include "ui/base/hit_test.h" | 16 #include "ui/base/hit_test.h" |
17 #include "ui/compositor/layer_animation_observer.h" | 17 #include "ui/compositor/layer_animation_observer.h" |
18 #include "ui/compositor/scoped_animation_duration_scale_mode.h" | 18 #include "ui/compositor/scoped_animation_duration_scale_mode.h" |
19 #include "ui/compositor/scoped_layer_animation_settings.h" | 19 #include "ui/compositor/scoped_layer_animation_settings.h" |
20 #include "ui/events/event_utils.h" | 20 #include "ui/events/event_utils.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 | 54 |
55 // TODO(tdanderson): This utility function is used in different unittest | 55 // TODO(tdanderson): This utility function is used in different unittest |
56 // files. Move to a common location to avoid | 56 // files. Move to a common location to avoid |
57 // repeated code. | 57 // repeated code. |
58 gfx::Point ConvertPointFromWidgetToView(View* view, const gfx::Point& p) { | 58 gfx::Point ConvertPointFromWidgetToView(View* view, const gfx::Point& p) { |
59 gfx::Point tmp(p); | 59 gfx::Point tmp(p); |
60 View::ConvertPointToTarget(view->GetWidget()->GetRootView(), view, &tmp); | 60 View::ConvertPointToTarget(view->GetWidget()->GetRootView(), view, &tmp); |
61 return tmp; | 61 return tmp; |
62 } | 62 } |
63 | 63 |
64 // This class can be used as a deleter for scoped_ptr<Widget> | 64 // This class can be used as a deleter for std::unique_ptr<Widget> |
65 // to call function Widget::CloseNow automatically. | 65 // to call function Widget::CloseNow automatically. |
66 struct WidgetCloser { | 66 struct WidgetCloser { |
67 inline void operator()(Widget* widget) const { widget->CloseNow(); } | 67 inline void operator()(Widget* widget) const { widget->CloseNow(); } |
68 }; | 68 }; |
69 | 69 |
70 using WidgetAutoclosePtr = scoped_ptr<Widget, WidgetCloser>; | 70 using WidgetAutoclosePtr = std::unique_ptr<Widget, WidgetCloser>; |
71 | 71 |
72 } // namespace | 72 } // namespace |
73 | 73 |
74 // A view that keeps track of the events it receives, and consumes all scroll | 74 // A view that keeps track of the events it receives, and consumes all scroll |
75 // gesture events and ui::ET_SCROLL events. | 75 // gesture events and ui::ET_SCROLL events. |
76 class ScrollableEventCountView : public EventCountView { | 76 class ScrollableEventCountView : public EventCountView { |
77 public: | 77 public: |
78 ScrollableEventCountView() {} | 78 ScrollableEventCountView() {} |
79 ~ScrollableEventCountView() override {} | 79 ~ScrollableEventCountView() override {} |
80 | 80 |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 DISALLOW_COPY_AND_ASSIGN(OwnershipTestWidget); | 372 DISALLOW_COPY_AND_ASSIGN(OwnershipTestWidget); |
373 }; | 373 }; |
374 | 374 |
375 // TODO(sky): add coverage of ownership for the desktop variants. | 375 // TODO(sky): add coverage of ownership for the desktop variants. |
376 | 376 |
377 // Widget owns its NativeWidget, part 1: NativeWidget is a platform-native | 377 // Widget owns its NativeWidget, part 1: NativeWidget is a platform-native |
378 // widget. | 378 // widget. |
379 TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) { | 379 TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) { |
380 OwnershipTestState state; | 380 OwnershipTestState state; |
381 | 381 |
382 scoped_ptr<Widget> widget(new OwnershipTestWidget(&state)); | 382 std::unique_ptr<Widget> widget(new OwnershipTestWidget(&state)); |
383 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | 383 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
384 params.native_widget = CreatePlatformNativeWidgetImpl( | 384 params.native_widget = CreatePlatformNativeWidgetImpl( |
385 params, widget.get(), kStubCapture, &state.native_widget_deleted); | 385 params, widget.get(), kStubCapture, &state.native_widget_deleted); |
386 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 386 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
387 widget->Init(params); | 387 widget->Init(params); |
388 | 388 |
389 // Now delete the Widget, which should delete the NativeWidget. | 389 // Now delete the Widget, which should delete the NativeWidget. |
390 widget.reset(); | 390 widget.reset(); |
391 | 391 |
392 EXPECT_TRUE(state.widget_deleted); | 392 EXPECT_TRUE(state.widget_deleted); |
393 EXPECT_TRUE(state.native_widget_deleted); | 393 EXPECT_TRUE(state.native_widget_deleted); |
394 | 394 |
395 // TODO(beng): write test for this ownership scenario and the NativeWidget | 395 // TODO(beng): write test for this ownership scenario and the NativeWidget |
396 // being deleted out from under the Widget. | 396 // being deleted out from under the Widget. |
397 } | 397 } |
398 | 398 |
399 // Widget owns its NativeWidget, part 2: NativeWidget is a NativeWidget. | 399 // Widget owns its NativeWidget, part 2: NativeWidget is a NativeWidget. |
400 TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsViewsNativeWidget) { | 400 TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsViewsNativeWidget) { |
401 OwnershipTestState state; | 401 OwnershipTestState state; |
402 | 402 |
403 scoped_ptr<Widget> widget(new OwnershipTestWidget(&state)); | 403 std::unique_ptr<Widget> widget(new OwnershipTestWidget(&state)); |
404 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | 404 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
405 params.native_widget = CreatePlatformNativeWidgetImpl( | 405 params.native_widget = CreatePlatformNativeWidgetImpl( |
406 params, widget.get(), kStubCapture, &state.native_widget_deleted); | 406 params, widget.get(), kStubCapture, &state.native_widget_deleted); |
407 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 407 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
408 widget->Init(params); | 408 widget->Init(params); |
409 | 409 |
410 // Now delete the Widget, which should delete the NativeWidget. | 410 // Now delete the Widget, which should delete the NativeWidget. |
411 widget.reset(); | 411 widget.reset(); |
412 | 412 |
413 EXPECT_TRUE(state.widget_deleted); | 413 EXPECT_TRUE(state.widget_deleted); |
414 EXPECT_TRUE(state.native_widget_deleted); | 414 EXPECT_TRUE(state.native_widget_deleted); |
415 | 415 |
416 // TODO(beng): write test for this ownership scenario and the NativeWidget | 416 // TODO(beng): write test for this ownership scenario and the NativeWidget |
417 // being deleted out from under the Widget. | 417 // being deleted out from under the Widget. |
418 } | 418 } |
419 | 419 |
420 // Widget owns its NativeWidget, part 3: NativeWidget is a NativeWidget, | 420 // Widget owns its NativeWidget, part 3: NativeWidget is a NativeWidget, |
421 // destroy the parent view. | 421 // destroy the parent view. |
422 TEST_F(WidgetOwnershipTest, | 422 TEST_F(WidgetOwnershipTest, |
423 Ownership_WidgetOwnsViewsNativeWidget_DestroyParentView) { | 423 Ownership_WidgetOwnsViewsNativeWidget_DestroyParentView) { |
424 OwnershipTestState state; | 424 OwnershipTestState state; |
425 | 425 |
426 Widget* toplevel = CreateTopLevelPlatformWidget(); | 426 Widget* toplevel = CreateTopLevelPlatformWidget(); |
427 | 427 |
428 scoped_ptr<Widget> widget(new OwnershipTestWidget(&state)); | 428 std::unique_ptr<Widget> widget(new OwnershipTestWidget(&state)); |
429 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | 429 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
430 params.parent = toplevel->GetNativeView(); | 430 params.parent = toplevel->GetNativeView(); |
431 params.native_widget = CreatePlatformNativeWidgetImpl( | 431 params.native_widget = CreatePlatformNativeWidgetImpl( |
432 params, widget.get(), kStubCapture, &state.native_widget_deleted); | 432 params, widget.get(), kStubCapture, &state.native_widget_deleted); |
433 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 433 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
434 widget->Init(params); | 434 widget->Init(params); |
435 | 435 |
436 // Now close the toplevel, which deletes the view hierarchy. | 436 // Now close the toplevel, which deletes the view hierarchy. |
437 toplevel->CloseNow(); | 437 toplevel->CloseNow(); |
438 | 438 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 EXPECT_TRUE(state.native_widget_deleted); | 564 EXPECT_TRUE(state.native_widget_deleted); |
565 } | 565 } |
566 | 566 |
567 // Widget owns its NativeWidget and has a WidgetDelegateView as its contents. | 567 // Widget owns its NativeWidget and has a WidgetDelegateView as its contents. |
568 TEST_F(WidgetOwnershipTest, | 568 TEST_F(WidgetOwnershipTest, |
569 Ownership_WidgetOwnsNativeWidgetWithWithWidgetDelegateView) { | 569 Ownership_WidgetOwnsNativeWidgetWithWithWidgetDelegateView) { |
570 OwnershipTestState state; | 570 OwnershipTestState state; |
571 | 571 |
572 WidgetDelegateView* delegate_view = new WidgetDelegateView; | 572 WidgetDelegateView* delegate_view = new WidgetDelegateView; |
573 | 573 |
574 scoped_ptr<Widget> widget(new OwnershipTestWidget(&state)); | 574 std::unique_ptr<Widget> widget(new OwnershipTestWidget(&state)); |
575 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | 575 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
576 params.native_widget = CreatePlatformNativeWidgetImpl( | 576 params.native_widget = CreatePlatformNativeWidgetImpl( |
577 params, widget.get(), kStubCapture, &state.native_widget_deleted); | 577 params, widget.get(), kStubCapture, &state.native_widget_deleted); |
578 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 578 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
579 params.delegate = delegate_view; | 579 params.delegate = delegate_view; |
580 widget->Init(params); | 580 widget->Init(params); |
581 widget->SetContentsView(delegate_view); | 581 widget->SetContentsView(delegate_view); |
582 | 582 |
583 // Now delete the Widget. There should be no crash or use-after-free. | 583 // Now delete the Widget. There should be no crash or use-after-free. |
584 widget.reset(); | 584 widget.reset(); |
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1527 EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_END)); | 1527 EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_END)); |
1528 } | 1528 } |
1529 } | 1529 } |
1530 | 1530 |
1531 // Tests that event-handlers installed on the RootView get triggered correctly. | 1531 // Tests that event-handlers installed on the RootView get triggered correctly. |
1532 // TODO(tdanderson): Clean up this test as part of crbug.com/355680. | 1532 // TODO(tdanderson): Clean up this test as part of crbug.com/355680. |
1533 TEST_F(WidgetTest, EventHandlersOnRootView) { | 1533 TEST_F(WidgetTest, EventHandlersOnRootView) { |
1534 WidgetAutoclosePtr widget(CreateTopLevelNativeWidget()); | 1534 WidgetAutoclosePtr widget(CreateTopLevelNativeWidget()); |
1535 View* root_view = widget->GetRootView(); | 1535 View* root_view = widget->GetRootView(); |
1536 | 1536 |
1537 scoped_ptr<EventCountView> view(new EventCountView()); | 1537 std::unique_ptr<EventCountView> view(new EventCountView()); |
1538 view->set_owned_by_client(); | 1538 view->set_owned_by_client(); |
1539 view->SetBounds(0, 0, 20, 20); | 1539 view->SetBounds(0, 0, 20, 20); |
1540 root_view->AddChildView(view.get()); | 1540 root_view->AddChildView(view.get()); |
1541 | 1541 |
1542 EventCountHandler h1; | 1542 EventCountHandler h1; |
1543 root_view->AddPreTargetHandler(&h1); | 1543 root_view->AddPreTargetHandler(&h1); |
1544 | 1544 |
1545 EventCountHandler h2; | 1545 EventCountHandler h2; |
1546 root_view->AddPostTargetHandler(&h2); | 1546 root_view->AddPostTargetHandler(&h2); |
1547 | 1547 |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1717 widget->Show(); | 1717 widget->Show(); |
1718 widget->SetSize(gfx::Size(300, 300)); | 1718 widget->SetSize(gfx::Size(300, 300)); |
1719 | 1719 |
1720 EventCountView* event_count_view = new EventCountView(); | 1720 EventCountView* event_count_view = new EventCountView(); |
1721 event_count_view->SetBounds(0, 0, 300, 300); | 1721 event_count_view->SetBounds(0, 0, 300, 300); |
1722 widget->GetRootView()->AddChildView(event_count_view); | 1722 widget->GetRootView()->AddChildView(event_count_view); |
1723 | 1723 |
1724 MousePressEventConsumer consumer; | 1724 MousePressEventConsumer consumer; |
1725 event_count_view->AddPostTargetHandler(&consumer); | 1725 event_count_view->AddPostTargetHandler(&consumer); |
1726 | 1726 |
1727 scoped_ptr<ui::test::EventGenerator> generator(new ui::test::EventGenerator( | 1727 std::unique_ptr<ui::test::EventGenerator> generator( |
1728 IsMus() ? widget->GetNativeWindow() : GetContext(), | 1728 new ui::test::EventGenerator( |
1729 widget->GetNativeWindow())); | 1729 IsMus() ? widget->GetNativeWindow() : GetContext(), |
| 1730 widget->GetNativeWindow())); |
1730 generator->PressTouch(); | 1731 generator->PressTouch(); |
1731 generator->ClickLeftButton(); | 1732 generator->ClickLeftButton(); |
1732 | 1733 |
1733 EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_PRESSED)); | 1734 EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_PRESSED)); |
1734 EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_RELEASED)); | 1735 EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_RELEASED)); |
1735 | 1736 |
1736 // For mus it's important we destroy the widget before the EventGenerator. | 1737 // For mus it's important we destroy the widget before the EventGenerator. |
1737 widget->CloseNow(); | 1738 widget->CloseNow(); |
1738 } | 1739 } |
1739 | 1740 |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1989 EXPECT_TRUE(destroyed); | 1990 EXPECT_TRUE(destroyed); |
1990 // Close() should destroy the widget. If not we'll cleanup to avoid leaks. | 1991 // Close() should destroy the widget. If not we'll cleanup to avoid leaks. |
1991 if (!destroyed) { | 1992 if (!destroyed) { |
1992 widget->Detach(); | 1993 widget->Detach(); |
1993 widget->CloseNow(); | 1994 widget->CloseNow(); |
1994 } | 1995 } |
1995 } | 1996 } |
1996 | 1997 |
1997 // Tests that killing a widget while animating it does not crash. | 1998 // Tests that killing a widget while animating it does not crash. |
1998 TEST_F(WidgetTest, CloseWidgetWhileAnimating) { | 1999 TEST_F(WidgetTest, CloseWidgetWhileAnimating) { |
1999 scoped_ptr<Widget> widget(new Widget); | 2000 std::unique_ptr<Widget> widget(new Widget); |
2000 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | 2001 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
2001 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 2002 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
2002 params.bounds = gfx::Rect(50, 50, 250, 250); | 2003 params.bounds = gfx::Rect(50, 50, 250, 250); |
2003 widget->Init(params); | 2004 widget->Init(params); |
2004 AnimationEndObserver animation_observer; | 2005 AnimationEndObserver animation_observer; |
2005 WidgetBoundsObserver widget_observer; | 2006 WidgetBoundsObserver widget_observer; |
2006 gfx::Rect bounds(100, 100, 50, 50); | 2007 gfx::Rect bounds(100, 100, 50, 50); |
2007 { | 2008 { |
2008 // Normal animations for tests have ZERO_DURATION, make sure we are actually | 2009 // Normal animations for tests have ZERO_DURATION, make sure we are actually |
2009 // animating the movement. | 2010 // animating the movement. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2051 base::RunLoop().RunUntilIdle(); | 2052 base::RunLoop().RunUntilIdle(); |
2052 // Broken on Linux. See http://crbug.com/515379. | 2053 // Broken on Linux. See http://crbug.com/515379. |
2053 #if !defined(OS_LINUX) || defined(OS_CHROMEOS) | 2054 #if !defined(OS_LINUX) || defined(OS_CHROMEOS) |
2054 EXPECT_EQ(screen_rect, observer.bounds()); | 2055 EXPECT_EQ(screen_rect, observer.bounds()); |
2055 #endif | 2056 #endif |
2056 } | 2057 } |
2057 | 2058 |
2058 // Tests that we do not crash when a Widget is destroyed by going out of | 2059 // Tests that we do not crash when a Widget is destroyed by going out of |
2059 // scope (as opposed to being explicitly deleted by its NativeWidget). | 2060 // scope (as opposed to being explicitly deleted by its NativeWidget). |
2060 TEST_F(WidgetTest, NoCrashOnWidgetDelete) { | 2061 TEST_F(WidgetTest, NoCrashOnWidgetDelete) { |
2061 scoped_ptr<Widget> widget(new Widget); | 2062 std::unique_ptr<Widget> widget(new Widget); |
2062 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | 2063 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
2063 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 2064 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
2064 widget->Init(params); | 2065 widget->Init(params); |
2065 } | 2066 } |
2066 | 2067 |
2067 // Tests that we do not crash when a Widget is destroyed before it finishes | 2068 // Tests that we do not crash when a Widget is destroyed before it finishes |
2068 // processing of pending input events in the message loop. | 2069 // processing of pending input events in the message loop. |
2069 TEST_F(WidgetTest, NoCrashOnWidgetDeleteWithPendingEvents) { | 2070 TEST_F(WidgetTest, NoCrashOnWidgetDeleteWithPendingEvents) { |
2070 scoped_ptr<Widget> widget(new Widget); | 2071 std::unique_ptr<Widget> widget(new Widget); |
2071 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); | 2072 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); |
2072 params.bounds = gfx::Rect(0, 0, 200, 200); | 2073 params.bounds = gfx::Rect(0, 0, 200, 200); |
2073 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 2074 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
2074 widget->Init(params); | 2075 widget->Init(params); |
2075 widget->Show(); | 2076 widget->Show(); |
2076 | 2077 |
2077 ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow()); | 2078 ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow()); |
2078 generator.MoveMouseTo(10, 10); | 2079 generator.MoveMouseTo(10, 10); |
2079 | 2080 |
2080 // No touch on desktop Mac. Tracked in http://crbug.com/445520. | 2081 // No touch on desktop Mac. Tracked in http://crbug.com/445520. |
(...skipping 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3501 // Moving the child to a different widget should call the removals observer. | 3502 // Moving the child to a different widget should call the removals observer. |
3502 WidgetAutoclosePtr widget2(CreateTopLevelPlatformWidget()); | 3503 WidgetAutoclosePtr widget2(CreateTopLevelPlatformWidget()); |
3503 widget2->client_view()->AddChildView(child); | 3504 widget2->client_view()->AddChildView(child); |
3504 EXPECT_TRUE(removals_observer.DidRemoveView(child)); | 3505 EXPECT_TRUE(removals_observer.DidRemoveView(child)); |
3505 | 3506 |
3506 widget->RemoveRemovalsObserver(&removals_observer); | 3507 widget->RemoveRemovalsObserver(&removals_observer); |
3507 } | 3508 } |
3508 | 3509 |
3509 } // namespace test | 3510 } // namespace test |
3510 } // namespace views | 3511 } // namespace views |
OLD | NEW |