Home | History | Annotate | Download | only in widget
      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
      3 // found in the LICENSE file.
      4 
      5 #include <algorithm>
      6 #include <set>
      7 
      8 #include "base/basictypes.h"
      9 #include "base/bind.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "base/message_loop/message_loop.h"
     12 #include "base/run_loop.h"
     13 #include "base/strings/utf_string_conversions.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 #include "ui/base/hit_test.h"
     16 #include "ui/events/event_utils.h"
     17 #include "ui/gfx/native_widget_types.h"
     18 #include "ui/gfx/point.h"
     19 #include "ui/views/bubble/bubble_delegate.h"
     20 #include "ui/views/controls/textfield/textfield.h"
     21 #include "ui/views/test/test_views_delegate.h"
     22 #include "ui/views/test/widget_test.h"
     23 #include "ui/views/views_delegate.h"
     24 #include "ui/views/widget/native_widget_delegate.h"
     25 #include "ui/views/widget/root_view.h"
     26 #include "ui/views/window/dialog_delegate.h"
     27 #include "ui/views/window/native_frame_view.h"
     28 
     29 #if defined(USE_AURA)
     30 #include "ui/aura/client/aura_constants.h"
     31 #include "ui/aura/client/window_tree_client.h"
     32 #include "ui/aura/root_window.h"
     33 #include "ui/aura/test/test_window_delegate.h"
     34 #include "ui/aura/window.h"
     35 #include "ui/views/widget/native_widget_aura.h"
     36 #if !defined(OS_CHROMEOS)
     37 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
     38 #endif
     39 #elif defined(OS_WIN)
     40 #include "ui/views/widget/native_widget_win.h"
     41 #endif
     42 
     43 #if defined(OS_WIN)
     44 #include "ui/views/win/hwnd_util.h"
     45 #endif
     46 
     47 namespace views {
     48 namespace test {
     49 
     50 // A view that keeps track of the events it receives, but consumes no events.
     51 class EventCountView : public View {
     52  public:
     53   EventCountView() {}
     54   virtual ~EventCountView() {}
     55 
     56   int GetEventCount(ui::EventType type) {
     57     return event_count_[type];
     58   }
     59 
     60   void ResetCounts() {
     61     event_count_.clear();
     62   }
     63 
     64  protected:
     65   // Overridden from ui::EventHandler:
     66   virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
     67     RecordEvent(*event);
     68   }
     69   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
     70     RecordEvent(*event);
     71   }
     72   virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
     73     RecordEvent(*event);
     74   }
     75   virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
     76     RecordEvent(*event);
     77   }
     78   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
     79     RecordEvent(*event);
     80   }
     81 
     82  private:
     83   void RecordEvent(const ui::Event& event) {
     84     ++event_count_[event.type()];
     85   }
     86 
     87   std::map<ui::EventType, int> event_count_;
     88 
     89   DISALLOW_COPY_AND_ASSIGN(EventCountView);
     90 };
     91 
     92 // A view that keeps track of the events it receives, and consumes all scroll
     93 // gesture events.
     94 class ScrollableEventCountView : public EventCountView {
     95  public:
     96   ScrollableEventCountView() {}
     97   virtual ~ScrollableEventCountView() {}
     98 
     99  private:
    100   // Overridden from ui::EventHandler:
    101   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
    102     EventCountView::OnGestureEvent(event);
    103     switch (event->type()) {
    104       case ui::ET_GESTURE_SCROLL_BEGIN:
    105       case ui::ET_GESTURE_SCROLL_UPDATE:
    106       case ui::ET_GESTURE_SCROLL_END:
    107       case ui::ET_SCROLL_FLING_START:
    108         event->SetHandled();
    109         break;
    110       default:
    111         break;
    112     }
    113   }
    114 
    115   DISALLOW_COPY_AND_ASSIGN(ScrollableEventCountView);
    116 };
    117 
    118 // A view that implements GetMinimumSize.
    119 class MinimumSizeFrameView : public NativeFrameView {
    120  public:
    121   explicit MinimumSizeFrameView(Widget* frame): NativeFrameView(frame) {}
    122   virtual ~MinimumSizeFrameView() {}
    123 
    124  private:
    125   // Overridden from View:
    126   virtual gfx::Size GetMinimumSize() OVERRIDE {
    127     return gfx::Size(300, 400);
    128   }
    129 
    130   DISALLOW_COPY_AND_ASSIGN(MinimumSizeFrameView);
    131 };
    132 
    133 // An event handler that simply keeps a count of the different types of events
    134 // it receives.
    135 class EventCountHandler : public ui::EventHandler {
    136  public:
    137   EventCountHandler() {}
    138   virtual ~EventCountHandler() {}
    139 
    140   int GetEventCount(ui::EventType type) {
    141     return event_count_[type];
    142   }
    143 
    144   void ResetCounts() {
    145     event_count_.clear();
    146   }
    147 
    148  protected:
    149   // Overridden from ui::EventHandler:
    150   virtual void OnEvent(ui::Event* event) OVERRIDE {
    151     RecordEvent(*event);
    152     ui::EventHandler::OnEvent(event);
    153   }
    154 
    155  private:
    156   void RecordEvent(const ui::Event& event) {
    157     ++event_count_[event.type()];
    158   }
    159 
    160   std::map<ui::EventType, int> event_count_;
    161 
    162   DISALLOW_COPY_AND_ASSIGN(EventCountHandler);
    163 };
    164 
    165 ui::WindowShowState GetWidgetShowState(const Widget* widget) {
    166   // Use IsMaximized/IsMinimized/IsFullScreen instead of GetWindowPlacement
    167   // because the former is implemented on all platforms but the latter is not.
    168   return widget->IsFullscreen() ? ui::SHOW_STATE_FULLSCREEN :
    169       widget->IsMaximized() ? ui::SHOW_STATE_MAXIMIZED :
    170       widget->IsMinimized() ? ui::SHOW_STATE_MINIMIZED :
    171                               ui::SHOW_STATE_NORMAL;
    172 }
    173 
    174 TEST_F(WidgetTest, WidgetInitParams) {
    175   ASSERT_FALSE(views_delegate().UseTransparentWindows());
    176 
    177   // Widgets are not transparent by default.
    178   Widget::InitParams init1;
    179   EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init1.opacity);
    180 
    181   // Non-window widgets are not transparent either.
    182   Widget::InitParams init2(Widget::InitParams::TYPE_MENU);
    183   EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init2.opacity);
    184 
    185   // A ViewsDelegate can set windows transparent by default.
    186   views_delegate().SetUseTransparentWindows(true);
    187   Widget::InitParams init3;
    188   EXPECT_EQ(Widget::InitParams::TRANSLUCENT_WINDOW, init3.opacity);
    189 
    190   // Non-window widgets stay opaque.
    191   Widget::InitParams init4(Widget::InitParams::TYPE_MENU);
    192   EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init4.opacity);
    193 }
    194 
    195 ////////////////////////////////////////////////////////////////////////////////
    196 // Widget::GetTopLevelWidget tests.
    197 
    198 TEST_F(WidgetTest, GetTopLevelWidget_Native) {
    199   // Create a hierarchy of native widgets.
    200   Widget* toplevel = CreateTopLevelPlatformWidget();
    201   gfx::NativeView parent = toplevel->GetNativeView();
    202   Widget* child = CreateChildPlatformWidget(parent);
    203 
    204   EXPECT_EQ(toplevel, toplevel->GetTopLevelWidget());
    205   EXPECT_EQ(toplevel, child->GetTopLevelWidget());
    206 
    207   toplevel->CloseNow();
    208   // |child| should be automatically destroyed with |toplevel|.
    209 }
    210 
    211 // Test if a focus manager and an inputmethod work without CHECK failure
    212 // when window activation changes.
    213 TEST_F(WidgetTest, ChangeActivation) {
    214   Widget* top1 = CreateTopLevelPlatformWidget();
    215   // CreateInputMethod before activated
    216   top1->GetInputMethod();
    217   top1->Show();
    218   RunPendingMessages();
    219 
    220   Widget* top2 = CreateTopLevelPlatformWidget();
    221   top2->Show();
    222   RunPendingMessages();
    223 
    224   top1->Activate();
    225   RunPendingMessages();
    226 
    227   // Create InputMethod after deactivated.
    228   top2->GetInputMethod();
    229   top2->Activate();
    230   RunPendingMessages();
    231 
    232   top1->Activate();
    233   RunPendingMessages();
    234 
    235   top1->CloseNow();
    236   top2->CloseNow();
    237 }
    238 
    239 // Tests visibility of child widgets.
    240 TEST_F(WidgetTest, Visibility) {
    241   Widget* toplevel = CreateTopLevelPlatformWidget();
    242   gfx::NativeView parent = toplevel->GetNativeView();
    243   Widget* child = CreateChildPlatformWidget(parent);
    244 
    245   EXPECT_FALSE(toplevel->IsVisible());
    246   EXPECT_FALSE(child->IsVisible());
    247 
    248   child->Show();
    249 
    250   EXPECT_FALSE(toplevel->IsVisible());
    251   EXPECT_FALSE(child->IsVisible());
    252 
    253   toplevel->Show();
    254 
    255   EXPECT_TRUE(toplevel->IsVisible());
    256   EXPECT_TRUE(child->IsVisible());
    257 
    258   toplevel->CloseNow();
    259   // |child| should be automatically destroyed with |toplevel|.
    260 }
    261 
    262 #if defined(OS_WIN) && !defined(USE_AURA)
    263 // On Windows, it is possible to have child window that are TYPE_POPUP.  Unlike
    264 // regular child windows, these should be created as hidden and must be shown
    265 // explicitly.
    266 TEST_F(WidgetTest, Visibility_ChildPopup) {
    267   Widget* toplevel = CreateTopLevelPlatformWidget();
    268   Widget* child_popup = CreateChildPopupPlatformWidget(
    269       toplevel->GetNativeView());
    270 
    271   EXPECT_FALSE(toplevel->IsVisible());
    272   EXPECT_FALSE(child_popup->IsVisible());
    273 
    274   toplevel->Show();
    275 
    276   EXPECT_TRUE(toplevel->IsVisible());
    277   EXPECT_FALSE(child_popup->IsVisible());
    278 
    279   child_popup->Show();
    280 
    281   EXPECT_TRUE(child_popup->IsVisible());
    282 
    283   toplevel->CloseNow();
    284   // |child_popup| should be automatically destroyed with |toplevel|.
    285 }
    286 #endif
    287 
    288 ////////////////////////////////////////////////////////////////////////////////
    289 // Widget ownership tests.
    290 //
    291 // Tests various permutations of Widget ownership specified in the
    292 // InitParams::Ownership param.
    293 
    294 // A WidgetTest that supplies a toplevel widget for NativeWidget to parent to.
    295 class WidgetOwnershipTest : public WidgetTest {
    296  public:
    297   WidgetOwnershipTest() {}
    298   virtual ~WidgetOwnershipTest() {}
    299 
    300   virtual void SetUp() {
    301     WidgetTest::SetUp();
    302     desktop_widget_ = CreateTopLevelPlatformWidget();
    303   }
    304 
    305   virtual void TearDown() {
    306     desktop_widget_->CloseNow();
    307     WidgetTest::TearDown();
    308   }
    309 
    310  private:
    311   Widget* desktop_widget_;
    312 
    313   DISALLOW_COPY_AND_ASSIGN(WidgetOwnershipTest);
    314 };
    315 
    316 // A bag of state to monitor destructions.
    317 struct OwnershipTestState {
    318   OwnershipTestState() : widget_deleted(false), native_widget_deleted(false) {}
    319 
    320   bool widget_deleted;
    321   bool native_widget_deleted;
    322 };
    323 
    324 // A platform NativeWidget subclass that updates a bag of state when it is
    325 // destroyed.
    326 class OwnershipTestNativeWidget : public NativeWidgetPlatform {
    327  public:
    328   OwnershipTestNativeWidget(internal::NativeWidgetDelegate* delegate,
    329                             OwnershipTestState* state)
    330       : NativeWidgetPlatform(delegate),
    331         state_(state) {
    332   }
    333   virtual ~OwnershipTestNativeWidget() {
    334     state_->native_widget_deleted = true;
    335   }
    336 
    337  private:
    338   OwnershipTestState* state_;
    339 
    340   DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidget);
    341 };
    342 
    343 // A views NativeWidget subclass that updates a bag of state when it is
    344 // destroyed.
    345 class OwnershipTestNativeWidgetPlatform : public NativeWidgetPlatformForTest {
    346  public:
    347   OwnershipTestNativeWidgetPlatform(internal::NativeWidgetDelegate* delegate,
    348                                     OwnershipTestState* state)
    349       : NativeWidgetPlatformForTest(delegate),
    350         state_(state) {
    351   }
    352   virtual ~OwnershipTestNativeWidgetPlatform() {
    353     state_->native_widget_deleted = true;
    354   }
    355 
    356  private:
    357   OwnershipTestState* state_;
    358 
    359   DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidgetPlatform);
    360 };
    361 
    362 // A Widget subclass that updates a bag of state when it is destroyed.
    363 class OwnershipTestWidget : public Widget {
    364  public:
    365   explicit OwnershipTestWidget(OwnershipTestState* state) : state_(state) {}
    366   virtual ~OwnershipTestWidget() {
    367     state_->widget_deleted = true;
    368   }
    369 
    370  private:
    371   OwnershipTestState* state_;
    372 
    373   DISALLOW_COPY_AND_ASSIGN(OwnershipTestWidget);
    374 };
    375 
    376 // Widget owns its NativeWidget, part 1: NativeWidget is a platform-native
    377 // widget.
    378 TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) {
    379   OwnershipTestState state;
    380 
    381   scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
    382   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    383   params.native_widget =
    384       new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
    385   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    386   widget->Init(params);
    387 
    388   // Now delete the Widget, which should delete the NativeWidget.
    389   widget.reset();
    390 
    391   EXPECT_TRUE(state.widget_deleted);
    392   EXPECT_TRUE(state.native_widget_deleted);
    393 
    394   // TODO(beng): write test for this ownership scenario and the NativeWidget
    395   //             being deleted out from under the Widget.
    396 }
    397 
    398 // Widget owns its NativeWidget, part 2: NativeWidget is a NativeWidget.
    399 TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsViewsNativeWidget) {
    400   OwnershipTestState state;
    401 
    402   scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
    403   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    404   params.native_widget =
    405       new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
    406   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    407   widget->Init(params);
    408 
    409   // Now delete the Widget, which should delete the NativeWidget.
    410   widget.reset();
    411 
    412   EXPECT_TRUE(state.widget_deleted);
    413   EXPECT_TRUE(state.native_widget_deleted);
    414 
    415   // TODO(beng): write test for this ownership scenario and the NativeWidget
    416   //             being deleted out from under the Widget.
    417 }
    418 
    419 // Widget owns its NativeWidget, part 3: NativeWidget is a NativeWidget,
    420 // destroy the parent view.
    421 TEST_F(WidgetOwnershipTest,
    422        Ownership_WidgetOwnsViewsNativeWidget_DestroyParentView) {
    423   OwnershipTestState state;
    424 
    425   Widget* toplevel = CreateTopLevelPlatformWidget();
    426 
    427   scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
    428   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    429   params.native_widget =
    430       new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
    431   params.parent = toplevel->GetNativeView();
    432   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    433   widget->Init(params);
    434 
    435   // Now close the toplevel, which deletes the view hierarchy.
    436   toplevel->CloseNow();
    437 
    438   RunPendingMessages();
    439 
    440   // This shouldn't delete the widget because it shouldn't be deleted
    441   // from the native side.
    442   EXPECT_FALSE(state.widget_deleted);
    443   EXPECT_FALSE(state.native_widget_deleted);
    444 
    445   // Now delete it explicitly.
    446   widget.reset();
    447 
    448   EXPECT_TRUE(state.widget_deleted);
    449   EXPECT_TRUE(state.native_widget_deleted);
    450 }
    451 
    452 // NativeWidget owns its Widget, part 1: NativeWidget is a platform-native
    453 // widget.
    454 TEST_F(WidgetOwnershipTest, Ownership_PlatformNativeWidgetOwnsWidget) {
    455   OwnershipTestState state;
    456 
    457   Widget* widget = new OwnershipTestWidget(&state);
    458   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    459   params.native_widget =
    460       new OwnershipTestNativeWidgetPlatform(widget, &state);
    461   widget->Init(params);
    462 
    463   // Now destroy the native widget.
    464   widget->CloseNow();
    465 
    466   EXPECT_TRUE(state.widget_deleted);
    467   EXPECT_TRUE(state.native_widget_deleted);
    468 }
    469 
    470 // NativeWidget owns its Widget, part 2: NativeWidget is a NativeWidget.
    471 TEST_F(WidgetOwnershipTest, Ownership_ViewsNativeWidgetOwnsWidget) {
    472   OwnershipTestState state;
    473 
    474   Widget* toplevel = CreateTopLevelPlatformWidget();
    475 
    476   Widget* widget = new OwnershipTestWidget(&state);
    477   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    478   params.native_widget =
    479       new OwnershipTestNativeWidgetPlatform(widget, &state);
    480   params.parent = toplevel->GetNativeView();
    481   widget->Init(params);
    482 
    483   // Now destroy the native widget. This is achieved by closing the toplevel.
    484   toplevel->CloseNow();
    485 
    486   // The NativeWidget won't be deleted until after a return to the message loop
    487   // so we have to run pending messages before testing the destruction status.
    488   RunPendingMessages();
    489 
    490   EXPECT_TRUE(state.widget_deleted);
    491   EXPECT_TRUE(state.native_widget_deleted);
    492 }
    493 
    494 // NativeWidget owns its Widget, part 3: NativeWidget is a platform-native
    495 // widget, destroyed out from under it by the OS.
    496 TEST_F(WidgetOwnershipTest,
    497        Ownership_PlatformNativeWidgetOwnsWidget_NativeDestroy) {
    498   OwnershipTestState state;
    499 
    500   Widget* widget = new OwnershipTestWidget(&state);
    501   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    502   params.native_widget =
    503       new OwnershipTestNativeWidgetPlatform(widget, &state);
    504   widget->Init(params);
    505 
    506   // Now simulate a destroy of the platform native widget from the OS:
    507 #if defined(USE_AURA)
    508   delete widget->GetNativeView();
    509 #elif defined(OS_WIN)
    510   DestroyWindow(widget->GetNativeView());
    511 #endif
    512 
    513   EXPECT_TRUE(state.widget_deleted);
    514   EXPECT_TRUE(state.native_widget_deleted);
    515 }
    516 
    517 // NativeWidget owns its Widget, part 4: NativeWidget is a NativeWidget,
    518 // destroyed by the view hierarchy that contains it.
    519 TEST_F(WidgetOwnershipTest,
    520        Ownership_ViewsNativeWidgetOwnsWidget_NativeDestroy) {
    521   OwnershipTestState state;
    522 
    523   Widget* toplevel = CreateTopLevelPlatformWidget();
    524 
    525   Widget* widget = new OwnershipTestWidget(&state);
    526   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    527   params.native_widget =
    528       new OwnershipTestNativeWidgetPlatform(widget, &state);
    529   params.parent = toplevel->GetNativeView();
    530   widget->Init(params);
    531 
    532   // Destroy the widget (achieved by closing the toplevel).
    533   toplevel->CloseNow();
    534 
    535   // The NativeWidget won't be deleted until after a return to the message loop
    536   // so we have to run pending messages before testing the destruction status.
    537   RunPendingMessages();
    538 
    539   EXPECT_TRUE(state.widget_deleted);
    540   EXPECT_TRUE(state.native_widget_deleted);
    541 }
    542 
    543 // NativeWidget owns its Widget, part 5: NativeWidget is a NativeWidget,
    544 // we close it directly.
    545 TEST_F(WidgetOwnershipTest,
    546        Ownership_ViewsNativeWidgetOwnsWidget_Close) {
    547   OwnershipTestState state;
    548 
    549   Widget* toplevel = CreateTopLevelPlatformWidget();
    550 
    551   Widget* widget = new OwnershipTestWidget(&state);
    552   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    553   params.native_widget =
    554       new OwnershipTestNativeWidgetPlatform(widget, &state);
    555   params.parent = toplevel->GetNativeView();
    556   widget->Init(params);
    557 
    558   // Destroy the widget.
    559   widget->Close();
    560   toplevel->CloseNow();
    561 
    562   // The NativeWidget won't be deleted until after a return to the message loop
    563   // so we have to run pending messages before testing the destruction status.
    564   RunPendingMessages();
    565 
    566   EXPECT_TRUE(state.widget_deleted);
    567   EXPECT_TRUE(state.native_widget_deleted);
    568 }
    569 
    570 // Widget owns its NativeWidget and has a WidgetDelegateView as its contents.
    571 TEST_F(WidgetOwnershipTest,
    572        Ownership_WidgetOwnsNativeWidgetWithWithWidgetDelegateView) {
    573   OwnershipTestState state;
    574 
    575   WidgetDelegateView* delegate_view = new WidgetDelegateView;
    576 
    577   scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
    578   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    579   params.native_widget =
    580       new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
    581   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    582   params.delegate = delegate_view;
    583   widget->Init(params);
    584   widget->SetContentsView(delegate_view);
    585 
    586   // Now delete the Widget. There should be no crash or use-after-free.
    587   widget.reset();
    588 
    589   EXPECT_TRUE(state.widget_deleted);
    590   EXPECT_TRUE(state.native_widget_deleted);
    591 }
    592 
    593 ////////////////////////////////////////////////////////////////////////////////
    594 // Test to verify using various Widget methods doesn't crash when the underlying
    595 // NativeView is destroyed.
    596 //
    597 class WidgetWithDestroyedNativeViewTest : public ViewsTestBase {
    598  public:
    599   WidgetWithDestroyedNativeViewTest() {}
    600   virtual ~WidgetWithDestroyedNativeViewTest() {}
    601 
    602   void InvokeWidgetMethods(Widget* widget) {
    603     widget->GetNativeView();
    604     widget->GetNativeWindow();
    605     ui::Accelerator accelerator;
    606     widget->GetAccelerator(0, &accelerator);
    607     widget->GetTopLevelWidget();
    608     widget->GetWindowBoundsInScreen();
    609     widget->GetClientAreaBoundsInScreen();
    610     widget->SetBounds(gfx::Rect(0, 0, 100, 80));
    611     widget->SetSize(gfx::Size(10, 11));
    612     widget->SetBoundsConstrained(gfx::Rect(0, 0, 120, 140));
    613     widget->SetVisibilityChangedAnimationsEnabled(false);
    614     widget->StackAtTop();
    615     widget->IsClosed();
    616     widget->Close();
    617     widget->Show();
    618     widget->Hide();
    619     widget->Activate();
    620     widget->Deactivate();
    621     widget->IsActive();
    622     widget->DisableInactiveRendering();
    623     widget->SetAlwaysOnTop(true);
    624     widget->IsAlwaysOnTop();
    625     widget->Maximize();
    626     widget->Minimize();
    627     widget->Restore();
    628     widget->IsMaximized();
    629     widget->IsFullscreen();
    630     widget->SetOpacity(0);
    631     widget->SetUseDragFrame(true);
    632     widget->FlashFrame(true);
    633     widget->IsVisible();
    634     widget->GetThemeProvider();
    635     widget->GetNativeTheme();
    636     widget->GetFocusManager();
    637     widget->GetInputMethod();
    638     widget->SchedulePaintInRect(gfx::Rect(0, 0, 1, 2));
    639     widget->IsMouseEventsEnabled();
    640     widget->SetNativeWindowProperty("xx", widget);
    641     widget->GetNativeWindowProperty("xx");
    642     widget->GetFocusTraversable();
    643     widget->GetLayer();
    644     widget->ReorderNativeViews();
    645     widget->SetCapture(widget->GetRootView());
    646     widget->ReleaseCapture();
    647     widget->HasCapture();
    648     widget->GetWorkAreaBoundsInScreen();
    649     // These three crash with NativeWidgetWin, so I'm assuming we don't need
    650     // them to work for the other NativeWidget impls.
    651     // widget->CenterWindow(gfx::Size(50, 60));
    652     // widget->GetRestoredBounds();
    653     // widget->ShowInactive();
    654   }
    655 
    656  private:
    657   DISALLOW_COPY_AND_ASSIGN(WidgetWithDestroyedNativeViewTest);
    658 };
    659 
    660 TEST_F(WidgetWithDestroyedNativeViewTest, Test) {
    661   {
    662     Widget widget;
    663     Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    664     params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    665     widget.Init(params);
    666     widget.Show();
    667 
    668     widget.native_widget_private()->CloseNow();
    669     InvokeWidgetMethods(&widget);
    670   }
    671 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
    672   {
    673     Widget widget;
    674     Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    675     params.native_widget = new DesktopNativeWidgetAura(&widget);
    676     params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    677     widget.Init(params);
    678     widget.Show();
    679 
    680     widget.native_widget_private()->CloseNow();
    681     InvokeWidgetMethods(&widget);
    682   }
    683 #endif
    684 }
    685 
    686 ////////////////////////////////////////////////////////////////////////////////
    687 // Widget observer tests.
    688 //
    689 
    690 class WidgetObserverTest : public WidgetTest, public WidgetObserver {
    691  public:
    692   WidgetObserverTest()
    693       : active_(NULL),
    694         widget_closed_(NULL),
    695         widget_activated_(NULL),
    696         widget_shown_(NULL),
    697         widget_hidden_(NULL),
    698         widget_bounds_changed_(NULL) {
    699   }
    700 
    701   virtual ~WidgetObserverTest() {}
    702 
    703   // Overridden from WidgetObserver:
    704   virtual void OnWidgetDestroying(Widget* widget) OVERRIDE {
    705     if (active_ == widget)
    706       active_ = NULL;
    707     widget_closed_ = widget;
    708   }
    709 
    710   virtual void OnWidgetActivationChanged(Widget* widget,
    711                                          bool active) OVERRIDE {
    712     if (active) {
    713       if (widget_activated_)
    714         widget_activated_->Deactivate();
    715       widget_activated_ = widget;
    716       active_ = widget;
    717     } else {
    718       if (widget_activated_ == widget)
    719         widget_activated_ = NULL;
    720       widget_deactivated_ = widget;
    721     }
    722   }
    723 
    724   virtual void OnWidgetVisibilityChanged(Widget* widget,
    725                                          bool visible) OVERRIDE {
    726     if (visible)
    727       widget_shown_ = widget;
    728     else
    729       widget_hidden_ = widget;
    730   }
    731 
    732   virtual void OnWidgetBoundsChanged(Widget* widget,
    733                                      const gfx::Rect& new_bounds) OVERRIDE {
    734     widget_bounds_changed_ = widget;
    735   }
    736 
    737   void reset() {
    738     active_ = NULL;
    739     widget_closed_ = NULL;
    740     widget_activated_ = NULL;
    741     widget_deactivated_ = NULL;
    742     widget_shown_ = NULL;
    743     widget_hidden_ = NULL;
    744     widget_bounds_changed_ = NULL;
    745   }
    746 
    747   Widget* NewWidget() {
    748     Widget* widget = CreateTopLevelNativeWidget();
    749     widget->AddObserver(this);
    750     return widget;
    751   }
    752 
    753   const Widget* active() const { return active_; }
    754   const Widget* widget_closed() const { return widget_closed_; }
    755   const Widget* widget_activated() const { return widget_activated_; }
    756   const Widget* widget_deactivated() const { return widget_deactivated_; }
    757   const Widget* widget_shown() const { return widget_shown_; }
    758   const Widget* widget_hidden() const { return widget_hidden_; }
    759   const Widget* widget_bounds_changed() const { return widget_bounds_changed_; }
    760 
    761  private:
    762   Widget* active_;
    763 
    764   Widget* widget_closed_;
    765   Widget* widget_activated_;
    766   Widget* widget_deactivated_;
    767   Widget* widget_shown_;
    768   Widget* widget_hidden_;
    769   Widget* widget_bounds_changed_;
    770 };
    771 
    772 TEST_F(WidgetObserverTest, DISABLED_ActivationChange) {
    773   Widget* toplevel = CreateTopLevelPlatformWidget();
    774 
    775   Widget* toplevel1 = NewWidget();
    776   Widget* toplevel2 = NewWidget();
    777 
    778   toplevel1->Show();
    779   toplevel2->Show();
    780 
    781   reset();
    782 
    783   toplevel1->Activate();
    784 
    785   RunPendingMessages();
    786   EXPECT_EQ(toplevel1, widget_activated());
    787 
    788   toplevel2->Activate();
    789   RunPendingMessages();
    790   EXPECT_EQ(toplevel1, widget_deactivated());
    791   EXPECT_EQ(toplevel2, widget_activated());
    792   EXPECT_EQ(toplevel2, active());
    793 
    794   toplevel->CloseNow();
    795 }
    796 
    797 TEST_F(WidgetObserverTest, DISABLED_VisibilityChange) {
    798   Widget* toplevel = CreateTopLevelPlatformWidget();
    799 
    800   Widget* child1 = NewWidget();
    801   Widget* child2 = NewWidget();
    802 
    803   toplevel->Show();
    804   child1->Show();
    805   child2->Show();
    806 
    807   reset();
    808 
    809   child1->Hide();
    810   EXPECT_EQ(child1, widget_hidden());
    811 
    812   child2->Hide();
    813   EXPECT_EQ(child2, widget_hidden());
    814 
    815   child1->Show();
    816   EXPECT_EQ(child1, widget_shown());
    817 
    818   child2->Show();
    819   EXPECT_EQ(child2, widget_shown());
    820 
    821   toplevel->CloseNow();
    822 }
    823 
    824 TEST_F(WidgetObserverTest, DestroyBubble) {
    825   Widget* anchor = CreateTopLevelPlatformWidget();
    826   anchor->Show();
    827 
    828   BubbleDelegateView* bubble_delegate =
    829       new BubbleDelegateView(anchor->client_view(), BubbleBorder::NONE);
    830   Widget* bubble_widget(BubbleDelegateView::CreateBubble(bubble_delegate));
    831   bubble_widget->Show();
    832   bubble_widget->CloseNow();
    833 
    834   anchor->Hide();
    835   anchor->CloseNow();
    836 }
    837 
    838 TEST_F(WidgetObserverTest, WidgetBoundsChanged) {
    839   Widget* child1 = NewWidget();
    840   Widget* child2 = NewWidget();
    841 
    842   child1->OnNativeWidgetMove();
    843   EXPECT_EQ(child1, widget_bounds_changed());
    844 
    845   child2->OnNativeWidgetMove();
    846   EXPECT_EQ(child2, widget_bounds_changed());
    847 
    848   child1->OnNativeWidgetSizeChanged(gfx::Size());
    849   EXPECT_EQ(child1, widget_bounds_changed());
    850 
    851   child2->OnNativeWidgetSizeChanged(gfx::Size());
    852   EXPECT_EQ(child2, widget_bounds_changed());
    853 }
    854 
    855 #if !defined(USE_AURA) && defined(OS_WIN)
    856 // Aura needs shell to maximize/fullscreen window.
    857 // NativeWidgetGtk doesn't implement GetRestoredBounds.
    858 TEST_F(WidgetTest, GetRestoredBounds) {
    859   Widget* toplevel = CreateTopLevelPlatformWidget();
    860   EXPECT_EQ(toplevel->GetWindowBoundsInScreen().ToString(),
    861             toplevel->GetRestoredBounds().ToString());
    862   toplevel->Show();
    863   toplevel->Maximize();
    864   RunPendingMessages();
    865   EXPECT_NE(toplevel->GetWindowBoundsInScreen().ToString(),
    866             toplevel->GetRestoredBounds().ToString());
    867   EXPECT_GT(toplevel->GetRestoredBounds().width(), 0);
    868   EXPECT_GT(toplevel->GetRestoredBounds().height(), 0);
    869 
    870   toplevel->Restore();
    871   RunPendingMessages();
    872   EXPECT_EQ(toplevel->GetWindowBoundsInScreen().ToString(),
    873             toplevel->GetRestoredBounds().ToString());
    874 
    875   toplevel->SetFullscreen(true);
    876   RunPendingMessages();
    877   EXPECT_NE(toplevel->GetWindowBoundsInScreen().ToString(),
    878             toplevel->GetRestoredBounds().ToString());
    879   EXPECT_GT(toplevel->GetRestoredBounds().width(), 0);
    880   EXPECT_GT(toplevel->GetRestoredBounds().height(), 0);
    881 }
    882 #endif
    883 
    884 // Test that window state is not changed after getting out of full screen.
    885 TEST_F(WidgetTest, ExitFullscreenRestoreState) {
    886   Widget* toplevel = CreateTopLevelPlatformWidget();
    887 
    888   toplevel->Show();
    889   RunPendingMessages();
    890 
    891   // This should be a normal state window.
    892   EXPECT_EQ(ui::SHOW_STATE_NORMAL, GetWidgetShowState(toplevel));
    893 
    894   toplevel->SetFullscreen(true);
    895   while (GetWidgetShowState(toplevel) != ui::SHOW_STATE_FULLSCREEN)
    896     RunPendingMessages();
    897   toplevel->SetFullscreen(false);
    898   while (GetWidgetShowState(toplevel) == ui::SHOW_STATE_FULLSCREEN)
    899     RunPendingMessages();
    900 
    901   // And it should still be in normal state after getting out of full screen.
    902   EXPECT_EQ(ui::SHOW_STATE_NORMAL, GetWidgetShowState(toplevel));
    903 
    904   // Now, make it maximized.
    905   toplevel->Maximize();
    906   while (GetWidgetShowState(toplevel) != ui::SHOW_STATE_MAXIMIZED)
    907     RunPendingMessages();
    908 
    909   toplevel->SetFullscreen(true);
    910   while (GetWidgetShowState(toplevel) != ui::SHOW_STATE_FULLSCREEN)
    911     RunPendingMessages();
    912   toplevel->SetFullscreen(false);
    913   while (GetWidgetShowState(toplevel) == ui::SHOW_STATE_FULLSCREEN)
    914     RunPendingMessages();
    915 
    916   // And it stays maximized after getting out of full screen.
    917   EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, GetWidgetShowState(toplevel));
    918 
    919   // Clean up.
    920   toplevel->Close();
    921   RunPendingMessages();
    922 }
    923 
    924 #if defined(USE_AURA)
    925 // The key-event propagation from Widget happens differently on aura and
    926 // non-aura systems because of the difference in IME. So this test works only on
    927 // aura.
    928 TEST_F(WidgetTest, KeyboardInputEvent) {
    929   Widget* toplevel = CreateTopLevelPlatformWidget();
    930   View* container = toplevel->client_view();
    931 
    932   Textfield* textfield = new Textfield();
    933   textfield->SetText(ASCIIToUTF16("some text"));
    934   container->AddChildView(textfield);
    935   toplevel->Show();
    936   textfield->RequestFocus();
    937 
    938   // The press gets handled. The release doesn't have an effect.
    939   ui::KeyEvent backspace_p(ui::ET_KEY_PRESSED, ui::VKEY_DELETE, 0, false);
    940   toplevel->OnKeyEvent(&backspace_p);
    941   EXPECT_TRUE(backspace_p.stopped_propagation());
    942   ui::KeyEvent backspace_r(ui::ET_KEY_RELEASED, ui::VKEY_DELETE, 0, false);
    943   toplevel->OnKeyEvent(&backspace_r);
    944   EXPECT_FALSE(backspace_r.handled());
    945 
    946   toplevel->Close();
    947 }
    948 
    949 // Verifies bubbles result in a focus lost when shown.
    950 // TODO(msw): this tests relies on focus, it needs to be in
    951 // interactive_ui_tests.
    952 TEST_F(WidgetTest, DISABLED_FocusChangesOnBubble) {
    953   // Create a widget, show and activate it and focus the contents view.
    954   View* contents_view = new View;
    955   contents_view->SetFocusable(true);
    956   Widget widget;
    957   Widget::InitParams init_params =
    958       CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
    959   init_params.bounds = gfx::Rect(0, 0, 200, 200);
    960   init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    961 #if !defined(OS_CHROMEOS)
    962   init_params.native_widget = new DesktopNativeWidgetAura(&widget);
    963 #endif
    964   widget.Init(init_params);
    965   widget.SetContentsView(contents_view);
    966   widget.Show();
    967   widget.Activate();
    968   contents_view->RequestFocus();
    969   EXPECT_TRUE(contents_view->HasFocus());
    970 
    971   // Show a bubble.
    972   BubbleDelegateView* bubble_delegate_view =
    973       new BubbleDelegateView(contents_view, BubbleBorder::TOP_LEFT);
    974   bubble_delegate_view->SetFocusable(true);
    975   BubbleDelegateView::CreateBubble(bubble_delegate_view)->Show();
    976   bubble_delegate_view->RequestFocus();
    977 
    978   // |contents_view_| should no longer have focus.
    979   EXPECT_FALSE(contents_view->HasFocus());
    980   EXPECT_TRUE(bubble_delegate_view->HasFocus());
    981 
    982   bubble_delegate_view->GetWidget()->CloseNow();
    983 
    984   // Closing the bubble should result in focus going back to the contents view.
    985   EXPECT_TRUE(contents_view->HasFocus());
    986 }
    987 
    988 // Desktop native widget Aura tests are for non Chrome OS platforms.
    989 #if !defined(OS_CHROMEOS)
    990 // Test to ensure that after minimize, view width is set to zero.
    991 TEST_F(WidgetTest, TestViewWidthAfterMinimizingWidget) {
    992   // Create a widget.
    993   Widget widget;
    994   Widget::InitParams init_params =
    995       CreateParams(Widget::InitParams::TYPE_WINDOW);
    996   init_params.show_state = ui::SHOW_STATE_NORMAL;
    997   gfx::Rect initial_bounds(0, 0, 300, 400);
    998   init_params.bounds = initial_bounds;
    999   init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1000   init_params.native_widget = new DesktopNativeWidgetAura(&widget);
   1001   widget.Init(init_params);
   1002   NonClientView* non_client_view = widget.non_client_view();
   1003   NonClientFrameView* frame_view = new MinimumSizeFrameView(&widget);
   1004   non_client_view->SetFrameView(frame_view);
   1005   widget.Show();
   1006   widget.Minimize();
   1007   EXPECT_EQ(0, frame_view->width());
   1008 }
   1009 
   1010 // This class validates whether paints are received for a visible Widget.
   1011 // To achieve this it overrides the Show and Close methods on the Widget class
   1012 // and sets state whether subsequent paints are expected.
   1013 class DesktopAuraTestValidPaintWidget : public views::Widget {
   1014  public:
   1015   DesktopAuraTestValidPaintWidget()
   1016     : expect_paint_(true),
   1017       received_paint_while_hidden_(false) {
   1018   }
   1019 
   1020   virtual ~DesktopAuraTestValidPaintWidget() {
   1021   }
   1022 
   1023   virtual void Show() OVERRIDE {
   1024     expect_paint_ = true;
   1025     views::Widget::Show();
   1026   }
   1027 
   1028   virtual void Close() OVERRIDE {
   1029     expect_paint_ = false;
   1030     views::Widget::Close();
   1031   }
   1032 
   1033   void Hide() {
   1034     expect_paint_ = false;
   1035     views::Widget::Hide();
   1036   }
   1037 
   1038   virtual void OnNativeWidgetPaint(gfx::Canvas* canvas) OVERRIDE {
   1039     EXPECT_TRUE(expect_paint_);
   1040     if (!expect_paint_)
   1041       received_paint_while_hidden_ = true;
   1042     views::Widget::OnNativeWidgetPaint(canvas);
   1043   }
   1044 
   1045   bool received_paint_while_hidden() const {
   1046     return received_paint_while_hidden_;
   1047   }
   1048 
   1049  private:
   1050   bool expect_paint_;
   1051   bool received_paint_while_hidden_;
   1052 };
   1053 
   1054 TEST_F(WidgetTest, DesktopNativeWidgetAuraNoPaintAfterCloseTest) {
   1055   View* contents_view = new View;
   1056   contents_view->SetFocusable(true);
   1057   DesktopAuraTestValidPaintWidget widget;
   1058   Widget::InitParams init_params =
   1059       CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
   1060   init_params.bounds = gfx::Rect(0, 0, 200, 200);
   1061   init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1062   init_params.native_widget = new DesktopNativeWidgetAura(&widget);
   1063   widget.Init(init_params);
   1064   widget.SetContentsView(contents_view);
   1065   widget.Show();
   1066   widget.Activate();
   1067   RunPendingMessages();
   1068   widget.SchedulePaintInRect(init_params.bounds);
   1069   widget.Close();
   1070   RunPendingMessages();
   1071   EXPECT_FALSE(widget.received_paint_while_hidden());
   1072 }
   1073 
   1074 TEST_F(WidgetTest, DesktopNativeWidgetAuraNoPaintAfterHideTest) {
   1075   View* contents_view = new View;
   1076   contents_view->SetFocusable(true);
   1077   DesktopAuraTestValidPaintWidget widget;
   1078   Widget::InitParams init_params =
   1079       CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
   1080   init_params.bounds = gfx::Rect(0, 0, 200, 200);
   1081   init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1082   init_params.native_widget = new DesktopNativeWidgetAura(&widget);
   1083   widget.Init(init_params);
   1084   widget.SetContentsView(contents_view);
   1085   widget.Show();
   1086   widget.Activate();
   1087   RunPendingMessages();
   1088   widget.SchedulePaintInRect(init_params.bounds);
   1089   widget.Hide();
   1090   RunPendingMessages();
   1091   EXPECT_FALSE(widget.received_paint_while_hidden());
   1092   widget.Close();
   1093 }
   1094 
   1095 // This class provides functionality to create fullscreen and top level popup
   1096 // windows. It additionally tests whether the destruction of these windows
   1097 // occurs correctly in desktop AURA without crashing.
   1098 // It provides facilities to test the following cases:-
   1099 // 1. Child window destroyed which should lead to the destruction of the
   1100 //    parent.
   1101 // 2. Parent window destroyed which should lead to the child being destroyed.
   1102 class DesktopAuraTopLevelWindowTest
   1103     : public views::TestViewsDelegate,
   1104       public aura::WindowObserver {
   1105  public:
   1106   DesktopAuraTopLevelWindowTest()
   1107       : top_level_widget_(NULL),
   1108         owned_window_(NULL),
   1109         owner_destroyed_(false),
   1110         owned_window_destroyed_(false) {}
   1111 
   1112   virtual ~DesktopAuraTopLevelWindowTest() {
   1113     EXPECT_TRUE(owner_destroyed_);
   1114     EXPECT_TRUE(owned_window_destroyed_);
   1115     top_level_widget_ = NULL;
   1116     owned_window_ = NULL;
   1117   }
   1118 
   1119   // views::TestViewsDelegate overrides.
   1120   virtual void OnBeforeWidgetInit(
   1121       Widget::InitParams* params,
   1122       internal::NativeWidgetDelegate* delegate) OVERRIDE {
   1123     if (!params->native_widget)
   1124       params->native_widget = new views::DesktopNativeWidgetAura(delegate);
   1125   }
   1126 
   1127   void CreateTopLevelWindow(const gfx::Rect& bounds, bool fullscreen) {
   1128     Widget::InitParams init_params;
   1129     init_params.type = Widget::InitParams::TYPE_WINDOW;
   1130     init_params.bounds = bounds;
   1131     init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1132     init_params.layer_type = ui::LAYER_NOT_DRAWN;
   1133     init_params.accept_events = fullscreen;
   1134 
   1135     widget_.Init(init_params);
   1136 
   1137     owned_window_ = new aura::Window(&child_window_delegate_);
   1138     owned_window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
   1139     owned_window_->SetName("TestTopLevelWindow");
   1140     if (fullscreen) {
   1141       owned_window_->SetProperty(aura::client::kShowStateKey,
   1142                                  ui::SHOW_STATE_FULLSCREEN);
   1143     } else {
   1144       owned_window_->SetType(aura::client::WINDOW_TYPE_MENU);
   1145     }
   1146     owned_window_->Init(ui::LAYER_TEXTURED);
   1147     aura::client::ParentWindowWithContext(
   1148         owned_window_,
   1149         widget_.GetNativeView()->GetRootWindow(),
   1150         gfx::Rect(0, 0, 1900, 1600));
   1151     owned_window_->Show();
   1152     owned_window_->AddObserver(this);
   1153 
   1154     ASSERT_TRUE(owned_window_->parent() != NULL);
   1155     owned_window_->parent()->AddObserver(this);
   1156 
   1157     top_level_widget_ =
   1158         views::Widget::GetWidgetForNativeView(owned_window_->parent());
   1159     ASSERT_TRUE(top_level_widget_ != NULL);
   1160   }
   1161 
   1162   void DestroyOwnedWindow() {
   1163     ASSERT_TRUE(owned_window_ != NULL);
   1164     delete owned_window_;
   1165   }
   1166 
   1167   void DestroyOwnerWindow() {
   1168     ASSERT_TRUE(top_level_widget_ != NULL);
   1169     top_level_widget_->CloseNow();
   1170   }
   1171 
   1172   virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
   1173     window->RemoveObserver(this);
   1174     if (window == owned_window_) {
   1175       owned_window_destroyed_ = true;
   1176     } else if (window == top_level_widget_->GetNativeView()) {
   1177       owner_destroyed_ = true;
   1178     } else {
   1179       ADD_FAILURE() << "Unexpected window destroyed callback: " << window;
   1180     }
   1181   }
   1182 
   1183   aura::Window* owned_window() {
   1184     return owned_window_;
   1185   }
   1186 
   1187   views::Widget* top_level_widget() {
   1188     return top_level_widget_;
   1189   }
   1190 
   1191  private:
   1192   views::Widget widget_;
   1193   views::Widget* top_level_widget_;
   1194   aura::Window* owned_window_;
   1195   bool owner_destroyed_;
   1196   bool owned_window_destroyed_;
   1197   aura::test::TestWindowDelegate child_window_delegate_;
   1198 
   1199   DISALLOW_COPY_AND_ASSIGN(DesktopAuraTopLevelWindowTest);
   1200 };
   1201 
   1202 TEST_F(WidgetTest, DesktopAuraFullscreenWindowDestroyedBeforeOwnerTest) {
   1203   ViewsDelegate::views_delegate = NULL;
   1204   DesktopAuraTopLevelWindowTest fullscreen_window;
   1205   ASSERT_NO_FATAL_FAILURE(fullscreen_window.CreateTopLevelWindow(
   1206       gfx::Rect(0, 0, 200, 200), true));
   1207 
   1208   RunPendingMessages();
   1209   ASSERT_NO_FATAL_FAILURE(fullscreen_window.DestroyOwnedWindow());
   1210   RunPendingMessages();
   1211 }
   1212 
   1213 TEST_F(WidgetTest, DesktopAuraFullscreenWindowOwnerDestroyed) {
   1214   ViewsDelegate::views_delegate = NULL;
   1215 
   1216   DesktopAuraTopLevelWindowTest fullscreen_window;
   1217   ASSERT_NO_FATAL_FAILURE(fullscreen_window.CreateTopLevelWindow(
   1218       gfx::Rect(0, 0, 200, 200), true));
   1219 
   1220   RunPendingMessages();
   1221   ASSERT_NO_FATAL_FAILURE(fullscreen_window.DestroyOwnerWindow());
   1222   RunPendingMessages();
   1223 }
   1224 
   1225 TEST_F(WidgetTest, DesktopAuraTopLevelOwnedPopupTest) {
   1226   ViewsDelegate::views_delegate = NULL;
   1227   DesktopAuraTopLevelWindowTest popup_window;
   1228   ASSERT_NO_FATAL_FAILURE(popup_window.CreateTopLevelWindow(
   1229       gfx::Rect(0, 0, 200, 200), false));
   1230 
   1231   RunPendingMessages();
   1232   ASSERT_NO_FATAL_FAILURE(popup_window.DestroyOwnedWindow());
   1233   RunPendingMessages();
   1234 }
   1235 
   1236 #if defined(OS_WIN)
   1237 // TODO(ananta)
   1238 // Fix this test to work on Linux Aura. Need to implement the
   1239 // views::DesktopRootWindowHostX11::SetSize function
   1240 // This test validates that when a top level owned popup Aura window is
   1241 // resized, the widget is resized as well.
   1242 TEST_F(WidgetTest, DesktopAuraTopLevelOwnedPopupResizeTest) {
   1243   ViewsDelegate::views_delegate = NULL;
   1244   DesktopAuraTopLevelWindowTest popup_window;
   1245   ASSERT_NO_FATAL_FAILURE(popup_window.CreateTopLevelWindow(
   1246       gfx::Rect(0, 0, 200, 200), false));
   1247 
   1248   gfx::Rect new_size(0, 0, 400, 400);
   1249   popup_window.owned_window()->SetBounds(new_size);
   1250 
   1251   EXPECT_EQ(popup_window.top_level_widget()->GetNativeView()->bounds().size(),
   1252             new_size.size());
   1253   RunPendingMessages();
   1254   ASSERT_NO_FATAL_FAILURE(popup_window.DestroyOwnedWindow());
   1255   RunPendingMessages();
   1256 }
   1257 #endif
   1258 
   1259 // Test to ensure that the aura Window's visiblity state is set to visible if
   1260 // the underlying widget is hidden and then shown.
   1261 TEST_F(WidgetTest, TestWindowVisibilityAfterHide) {
   1262   // Create a widget.
   1263   Widget widget;
   1264   Widget::InitParams init_params =
   1265       CreateParams(Widget::InitParams::TYPE_WINDOW);
   1266   init_params.show_state = ui::SHOW_STATE_NORMAL;
   1267   gfx::Rect initial_bounds(0, 0, 300, 400);
   1268   init_params.bounds = initial_bounds;
   1269   init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1270   init_params.native_widget = new DesktopNativeWidgetAura(&widget);
   1271   widget.Init(init_params);
   1272   NonClientView* non_client_view = widget.non_client_view();
   1273   NonClientFrameView* frame_view = new MinimumSizeFrameView(&widget);
   1274   non_client_view->SetFrameView(frame_view);
   1275 
   1276   widget.Hide();
   1277   EXPECT_FALSE(widget.GetNativeView()->IsVisible());
   1278   widget.Show();
   1279   EXPECT_TRUE(widget.GetNativeView()->IsVisible());
   1280 }
   1281 
   1282 // The following code verifies we can correctly destroy a Widget from a mouse
   1283 // enter/exit. We could test move/drag/enter/exit but in general we don't run
   1284 // nested message loops from such events, nor has the code ever really dealt
   1285 // with this situation.
   1286 
   1287 // Class that closes the widget (which ends up deleting it immediately) when the
   1288 // appropriate event is received.
   1289 class CloseWidgetView : public View {
   1290  public:
   1291   explicit CloseWidgetView(ui::EventType event_type)
   1292       : event_type_(event_type) {
   1293   }
   1294 
   1295   // View overrides:
   1296   virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
   1297     if (!CloseWidget(event))
   1298       View::OnMousePressed(event);
   1299     return true;
   1300   }
   1301   virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE {
   1302     if (!CloseWidget(event))
   1303       View::OnMouseDragged(event);
   1304     return true;
   1305   }
   1306   virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE {
   1307     if (!CloseWidget(event))
   1308       View::OnMouseReleased(event);
   1309   }
   1310   virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE {
   1311     if (!CloseWidget(event))
   1312       View::OnMouseMoved(event);
   1313   }
   1314   virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE {
   1315     if (!CloseWidget(event))
   1316       View::OnMouseEntered(event);
   1317   }
   1318 
   1319  private:
   1320   bool CloseWidget(const ui::LocatedEvent& event) {
   1321     if (event.type() == event_type_) {
   1322       // Go through NativeWidgetPrivate to simulate what happens if the OS
   1323       // deletes the NativeWindow out from under us.
   1324       GetWidget()->native_widget_private()->CloseNow();
   1325       return true;
   1326     }
   1327     return false;
   1328   }
   1329 
   1330   const ui::EventType event_type_;
   1331 
   1332   DISALLOW_COPY_AND_ASSIGN(CloseWidgetView);
   1333 };
   1334 
   1335 // Generates two moves (first generates enter, second real move), a press, drag
   1336 // and release stopping at |last_event_type|.
   1337 void GenerateMouseEvents(Widget* widget, ui::EventType last_event_type) {
   1338   const gfx::Rect screen_bounds(widget->GetWindowBoundsInScreen());
   1339   ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, screen_bounds.CenterPoint(),
   1340                             screen_bounds.CenterPoint(), 0);
   1341   aura::RootWindowHostDelegate* rwhd =
   1342       widget->GetNativeWindow()->GetDispatcher()->AsRootWindowHostDelegate();
   1343   rwhd->OnHostMouseEvent(&move_event);
   1344   if (last_event_type == ui::ET_MOUSE_ENTERED)
   1345     return;
   1346   rwhd->OnHostMouseEvent(&move_event);
   1347   if (last_event_type == ui::ET_MOUSE_MOVED)
   1348     return;
   1349 
   1350   ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, screen_bounds.CenterPoint(),
   1351                              screen_bounds.CenterPoint(), 0);
   1352   rwhd->OnHostMouseEvent(&press_event);
   1353   if (last_event_type == ui::ET_MOUSE_PRESSED)
   1354     return;
   1355 
   1356   gfx::Point end_point(screen_bounds.CenterPoint());
   1357   end_point.Offset(1, 1);
   1358   ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, end_point, end_point, 0);
   1359   rwhd->OnHostMouseEvent(&drag_event);
   1360   if (last_event_type == ui::ET_MOUSE_DRAGGED)
   1361     return;
   1362 
   1363   ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, end_point, end_point, 0);
   1364   rwhd->OnHostMouseEvent(&release_event);
   1365 }
   1366 
   1367 // Creates a widget and invokes GenerateMouseEvents() with |last_event_type|.
   1368 void RunCloseWidgetDuringDispatchTest(WidgetTest* test,
   1369                                       ui::EventType last_event_type) {
   1370   // |widget| is deleted by CloseWidgetView.
   1371   Widget* widget = new Widget;
   1372   Widget::InitParams params =
   1373       test->CreateParams(Widget::InitParams::TYPE_POPUP);
   1374   params.native_widget = new DesktopNativeWidgetAura(widget);
   1375   params.bounds = gfx::Rect(0, 0, 50, 100);
   1376   widget->Init(params);
   1377   widget->SetContentsView(new CloseWidgetView(last_event_type));
   1378   widget->Show();
   1379   GenerateMouseEvents(widget, last_event_type);
   1380 }
   1381 
   1382 // Verifies deleting the widget from a mouse pressed event doesn't crash.
   1383 TEST_F(WidgetTest, CloseWidgetDuringMousePress) {
   1384   RunCloseWidgetDuringDispatchTest(this, ui::ET_MOUSE_PRESSED);
   1385 }
   1386 
   1387 // Verifies deleting the widget from a mouse released event doesn't crash.
   1388 TEST_F(WidgetTest, CloseWidgetDuringMouseReleased) {
   1389   RunCloseWidgetDuringDispatchTest(this, ui::ET_MOUSE_RELEASED);
   1390 }
   1391 
   1392 #endif  // !defined(OS_CHROMEOS)
   1393 
   1394 // Tests that wheel events generated from scroll events are targetted to the
   1395 // views under the cursor when the focused view does not processed them.
   1396 TEST_F(WidgetTest, WheelEventsFromScrollEventTarget) {
   1397   EventCountView* cursor_view = new EventCountView;
   1398   cursor_view->SetBounds(60, 0, 50, 40);
   1399 
   1400   Widget* widget = CreateTopLevelPlatformWidget();
   1401   widget->GetRootView()->AddChildView(cursor_view);
   1402 
   1403   // Generate a scroll event on the cursor view.
   1404   ui::ScrollEvent scroll(ui::ET_SCROLL,
   1405                          gfx::Point(65, 5),
   1406                          ui::EventTimeForNow(),
   1407                          0,
   1408                          0, 20,
   1409                          0, 20,
   1410                          2);
   1411   widget->OnScrollEvent(&scroll);
   1412 
   1413   EXPECT_EQ(1, cursor_view->GetEventCount(ui::ET_SCROLL));
   1414   EXPECT_EQ(1, cursor_view->GetEventCount(ui::ET_MOUSEWHEEL));
   1415 
   1416   cursor_view->ResetCounts();
   1417 
   1418   ui::ScrollEvent scroll2(ui::ET_SCROLL,
   1419                           gfx::Point(5, 5),
   1420                           ui::EventTimeForNow(),
   1421                           0,
   1422                           0, 20,
   1423                           0, 20,
   1424                           2);
   1425   widget->OnScrollEvent(&scroll2);
   1426 
   1427   EXPECT_EQ(0, cursor_view->GetEventCount(ui::ET_SCROLL));
   1428   EXPECT_EQ(0, cursor_view->GetEventCount(ui::ET_MOUSEWHEEL));
   1429 
   1430   widget->CloseNow();
   1431 }
   1432 
   1433 #endif  // defined(USE_AURA)
   1434 
   1435 // Tests that if a scroll-begin gesture is not handled, then subsequent scroll
   1436 // events are not dispatched to any view.
   1437 TEST_F(WidgetTest, GestureScrollEventDispatching) {
   1438   EventCountView* noscroll_view = new EventCountView;
   1439   EventCountView* scroll_view = new ScrollableEventCountView;
   1440 
   1441   noscroll_view->SetBounds(0, 0, 50, 40);
   1442   scroll_view->SetBounds(60, 0, 40, 40);
   1443 
   1444   Widget* widget = CreateTopLevelPlatformWidget();
   1445   widget->GetRootView()->AddChildView(noscroll_view);
   1446   widget->GetRootView()->AddChildView(scroll_view);
   1447 
   1448   {
   1449     ui::GestureEvent begin(ui::ET_GESTURE_SCROLL_BEGIN,
   1450         5, 5, 0, base::TimeDelta(),
   1451         ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 0),
   1452         1);
   1453     widget->OnGestureEvent(&begin);
   1454     ui::GestureEvent update(ui::ET_GESTURE_SCROLL_UPDATE,
   1455         25, 15, 0, base::TimeDelta(),
   1456         ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 20, 10),
   1457         1);
   1458     widget->OnGestureEvent(&update);
   1459     ui::GestureEvent end(ui::ET_GESTURE_SCROLL_END,
   1460         25, 15, 0, base::TimeDelta(),
   1461         ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END, 0, 0),
   1462         1);
   1463     widget->OnGestureEvent(&end);
   1464 
   1465     EXPECT_EQ(1, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
   1466     EXPECT_EQ(0, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
   1467     EXPECT_EQ(0, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_END));
   1468   }
   1469 
   1470   {
   1471     ui::GestureEvent begin(ui::ET_GESTURE_SCROLL_BEGIN,
   1472         65, 5, 0, base::TimeDelta(),
   1473         ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 0),
   1474         1);
   1475     widget->OnGestureEvent(&begin);
   1476     ui::GestureEvent update(ui::ET_GESTURE_SCROLL_UPDATE,
   1477         85, 15, 0, base::TimeDelta(),
   1478         ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 20, 10),
   1479         1);
   1480     widget->OnGestureEvent(&update);
   1481     ui::GestureEvent end(ui::ET_GESTURE_SCROLL_END,
   1482         85, 15, 0, base::TimeDelta(),
   1483         ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END, 0, 0),
   1484         1);
   1485     widget->OnGestureEvent(&end);
   1486 
   1487     EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
   1488     EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
   1489     EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_END));
   1490   }
   1491 
   1492   widget->CloseNow();
   1493 }
   1494 
   1495 // Tests that event-handlers installed on the RootView get triggered correctly.
   1496 TEST_F(WidgetTest, EventHandlersOnRootView) {
   1497   Widget* widget = CreateTopLevelNativeWidget();
   1498   View* root_view = widget->GetRootView();
   1499 
   1500   EventCountView* view = new EventCountView;
   1501   view->SetBounds(0, 0, 20, 20);
   1502   root_view->AddChildView(view);
   1503 
   1504   EventCountHandler h1;
   1505   root_view->AddPreTargetHandler(&h1);
   1506 
   1507   EventCountHandler h2;
   1508   root_view->AddPostTargetHandler(&h2);
   1509 
   1510   widget->SetBounds(gfx::Rect(0, 0, 100, 100));
   1511   widget->Show();
   1512 
   1513   ui::TouchEvent pressed(ui::ET_TOUCH_PRESSED,
   1514                          gfx::Point(10, 10),
   1515                          0, 0,
   1516                          ui::EventTimeForNow(),
   1517                          1.0, 0.0, 1.0, 0.0);
   1518   widget->OnTouchEvent(&pressed);
   1519   EXPECT_EQ(1, h1.GetEventCount(ui::ET_TOUCH_PRESSED));
   1520   EXPECT_EQ(1, view->GetEventCount(ui::ET_TOUCH_PRESSED));
   1521   EXPECT_EQ(1, h2.GetEventCount(ui::ET_TOUCH_PRESSED));
   1522 
   1523   ui::GestureEvent begin(ui::ET_GESTURE_BEGIN,
   1524       5, 5, 0, ui::EventTimeForNow(),
   1525       ui::GestureEventDetails(ui::ET_GESTURE_BEGIN, 0, 0), 1);
   1526   ui::GestureEvent end(ui::ET_GESTURE_END,
   1527       5, 5, 0, ui::EventTimeForNow(),
   1528       ui::GestureEventDetails(ui::ET_GESTURE_END, 0, 0), 1);
   1529   widget->OnGestureEvent(&begin);
   1530   EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_BEGIN));
   1531   EXPECT_EQ(1, view->GetEventCount(ui::ET_GESTURE_BEGIN));
   1532   EXPECT_EQ(1, h2.GetEventCount(ui::ET_GESTURE_BEGIN));
   1533 
   1534   ui::TouchEvent released(ui::ET_TOUCH_RELEASED,
   1535                           gfx::Point(10, 10),
   1536                           0, 0,
   1537                           ui::EventTimeForNow(),
   1538                           1.0, 0.0, 1.0, 0.0);
   1539   widget->OnTouchEvent(&released);
   1540   EXPECT_EQ(1, h1.GetEventCount(ui::ET_TOUCH_RELEASED));
   1541   EXPECT_EQ(1, view->GetEventCount(ui::ET_TOUCH_RELEASED));
   1542   EXPECT_EQ(1, h2.GetEventCount(ui::ET_TOUCH_RELEASED));
   1543 
   1544   widget->OnGestureEvent(&end);
   1545   EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_END));
   1546   EXPECT_EQ(1, view->GetEventCount(ui::ET_GESTURE_END));
   1547   EXPECT_EQ(1, h2.GetEventCount(ui::ET_GESTURE_END));
   1548 
   1549   ui::ScrollEvent scroll(ui::ET_SCROLL,
   1550                          gfx::Point(5, 5),
   1551                          ui::EventTimeForNow(),
   1552                          0,
   1553                          0, 20,
   1554                          0, 20,
   1555                          2);
   1556   widget->OnScrollEvent(&scroll);
   1557   EXPECT_EQ(1, h1.GetEventCount(ui::ET_SCROLL));
   1558   EXPECT_EQ(1, view->GetEventCount(ui::ET_SCROLL));
   1559   EXPECT_EQ(1, h2.GetEventCount(ui::ET_SCROLL));
   1560 
   1561   widget->CloseNow();
   1562 }
   1563 
   1564 TEST_F(WidgetTest, SynthesizeMouseMoveEvent) {
   1565   Widget* widget = CreateTopLevelNativeWidget();
   1566   View* root_view = widget->GetRootView();
   1567 
   1568   EventCountView* v1 = new EventCountView();
   1569   v1->SetBounds(0, 0, 10, 10);
   1570   root_view->AddChildView(v1);
   1571   EventCountView* v2 = new EventCountView();
   1572   v2->SetBounds(0, 10, 10, 10);
   1573   root_view->AddChildView(v2);
   1574 
   1575   gfx::Point cursor_location(5, 5);
   1576   ui::MouseEvent move(ui::ET_MOUSE_MOVED, cursor_location, cursor_location,
   1577                       ui::EF_NONE);
   1578   widget->OnMouseEvent(&move);
   1579 
   1580   EXPECT_EQ(1, v1->GetEventCount(ui::ET_MOUSE_ENTERED));
   1581   EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
   1582 
   1583   delete v1;
   1584   v2->SetBounds(0, 0, 10, 10);
   1585   EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
   1586 
   1587   widget->SynthesizeMouseMoveEvent();
   1588   EXPECT_EQ(1, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
   1589 }
   1590 
   1591 // Used by SingleWindowClosing to count number of times WindowClosing() has
   1592 // been invoked.
   1593 class ClosingDelegate : public WidgetDelegate {
   1594  public:
   1595   ClosingDelegate() : count_(0), widget_(NULL) {}
   1596 
   1597   int count() const { return count_; }
   1598 
   1599   void set_widget(views::Widget* widget) { widget_ = widget; }
   1600 
   1601   // WidgetDelegate overrides:
   1602   virtual Widget* GetWidget() OVERRIDE { return widget_; }
   1603   virtual const Widget* GetWidget() const OVERRIDE { return widget_; }
   1604   virtual void WindowClosing() OVERRIDE {
   1605     count_++;
   1606   }
   1607 
   1608  private:
   1609   int count_;
   1610   views::Widget* widget_;
   1611 
   1612   DISALLOW_COPY_AND_ASSIGN(ClosingDelegate);
   1613 };
   1614 
   1615 // Verifies WindowClosing() is invoked correctly on the delegate when a Widget
   1616 // is closed.
   1617 TEST_F(WidgetTest, SingleWindowClosing) {
   1618   scoped_ptr<ClosingDelegate> delegate(new ClosingDelegate());
   1619   Widget* widget = new Widget();  // Destroyed by CloseNow() below.
   1620   Widget::InitParams init_params =
   1621       CreateParams(Widget::InitParams::TYPE_WINDOW);
   1622   init_params.bounds = gfx::Rect(0, 0, 200, 200);
   1623   init_params.delegate = delegate.get();
   1624 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
   1625   init_params.native_widget = new DesktopNativeWidgetAura(widget);
   1626 #endif
   1627   widget->Init(init_params);
   1628   EXPECT_EQ(0, delegate->count());
   1629   widget->CloseNow();
   1630   EXPECT_EQ(1, delegate->count());
   1631 }
   1632 
   1633 class WidgetWindowTitleTest : public WidgetTest {
   1634  protected:
   1635   void RunTest(bool desktop_native_widget) {
   1636     Widget* widget = new Widget();  // Destroyed by CloseNow() below.
   1637     Widget::InitParams init_params =
   1638         CreateParams(Widget::InitParams::TYPE_WINDOW);
   1639     widget->Init(init_params);
   1640 
   1641 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
   1642     if (desktop_native_widget)
   1643       init_params.native_widget = new DesktopNativeWidgetAura(widget);
   1644 #else
   1645     DCHECK(!desktop_native_widget)
   1646         << "DesktopNativeWidget does not exist on non-Aura or on ChromeOS.";
   1647 #endif
   1648 
   1649     internal::NativeWidgetPrivate* native_widget =
   1650         widget->native_widget_private();
   1651 
   1652     string16 empty;
   1653     string16 s1(UTF8ToUTF16("Title1"));
   1654     string16 s2(UTF8ToUTF16("Title2"));
   1655     string16 s3(UTF8ToUTF16("TitleLong"));
   1656 
   1657     // The widget starts with no title, setting empty should not change
   1658     // anything.
   1659     EXPECT_FALSE(native_widget->SetWindowTitle(empty));
   1660     // Setting the title to something non-empty should cause a change.
   1661     EXPECT_TRUE(native_widget->SetWindowTitle(s1));
   1662     // Setting the title to something else with the same length should cause a
   1663     // change.
   1664     EXPECT_TRUE(native_widget->SetWindowTitle(s2));
   1665     // Setting the title to something else with a different length should cause
   1666     // a change.
   1667     EXPECT_TRUE(native_widget->SetWindowTitle(s3));
   1668     // Setting the title to the same thing twice should not cause a change.
   1669     EXPECT_FALSE(native_widget->SetWindowTitle(s3));
   1670 
   1671     widget->CloseNow();
   1672   }
   1673 };
   1674 
   1675 TEST_F(WidgetWindowTitleTest, SetWindowTitleChanged_NativeWidget) {
   1676   // Use the default NativeWidget.
   1677   bool desktop_native_widget = false;
   1678   RunTest(desktop_native_widget);
   1679 }
   1680 
   1681 // DesktopNativeWidget does not exist on non-Aura or on ChromeOS.
   1682 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
   1683 TEST_F(WidgetWindowTitleTest, SetWindowTitleChanged_DesktopNativeWidget) {
   1684   // Override to use a DesktopNativeWidget.
   1685   bool desktop_native_widget = true;
   1686   RunTest(desktop_native_widget);
   1687 }
   1688 #endif  // USE_AURA && !OS_CHROMEOS
   1689 
   1690 // Used by SetTopLevelCorrectly to track calls to OnBeforeWidgetInit().
   1691 class VerifyTopLevelDelegate : public TestViewsDelegate {
   1692  public:
   1693   VerifyTopLevelDelegate()
   1694       : on_before_init_called_(false),
   1695         is_top_level_(false) {
   1696   }
   1697 
   1698   bool on_before_init_called() const { return on_before_init_called_; }
   1699   bool is_top_level() const { return is_top_level_; }
   1700 
   1701   virtual void OnBeforeWidgetInit(
   1702       Widget::InitParams* params,
   1703       internal::NativeWidgetDelegate* delegate) OVERRIDE {
   1704     on_before_init_called_ = true;
   1705     is_top_level_ = params->top_level;
   1706   }
   1707 
   1708  private:
   1709   bool on_before_init_called_;
   1710   bool is_top_level_;
   1711 
   1712   DISALLOW_COPY_AND_ASSIGN(VerifyTopLevelDelegate);
   1713 };
   1714 
   1715 // Verifies |top_level| is correctly passed to
   1716 // ViewsDelegate::OnBeforeWidgetInit().
   1717 TEST_F(WidgetTest, SetTopLevelCorrectly) {
   1718   set_views_delegate(NULL);
   1719   VerifyTopLevelDelegate* delegate = new VerifyTopLevelDelegate;
   1720   set_views_delegate(delegate);  // ViewsTestBase takes ownership.
   1721   scoped_ptr<Widget> widget(new Widget);
   1722   Widget::InitParams params =
   1723       CreateParams(views::Widget::InitParams::TYPE_POPUP);
   1724   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1725   widget->Init(params);
   1726   EXPECT_TRUE(delegate->on_before_init_called());
   1727   EXPECT_TRUE(delegate->is_top_level());
   1728 }
   1729 
   1730 // A scumbag View that deletes its owning widget OnMousePressed.
   1731 class WidgetDeleterView : public View {
   1732  public:
   1733   WidgetDeleterView() : View() {}
   1734 
   1735   // Overridden from View.
   1736   virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
   1737     delete GetWidget();
   1738     return true;
   1739   }
   1740 
   1741  private:
   1742   DISALLOW_COPY_AND_ASSIGN(WidgetDeleterView);
   1743 };
   1744 
   1745 TEST_F(WidgetTest, TestWidgetDeletedInOnMousePressed) {
   1746   Widget* widget = new Widget;
   1747   Widget::InitParams params =
   1748       CreateParams(views::Widget::InitParams::TYPE_POPUP);
   1749   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1750   widget->Init(params);
   1751 
   1752   widget->SetContentsView(new WidgetDeleterView);
   1753 
   1754   widget->SetSize(gfx::Size(100, 100));
   1755   widget->Show();
   1756 
   1757   gfx::Point click_location(45, 15);
   1758   ui::MouseEvent press(ui::ET_MOUSE_PRESSED, click_location, click_location,
   1759       ui::EF_LEFT_MOUSE_BUTTON);
   1760   widget->OnMouseEvent(&press);
   1761 
   1762   // Yay we did not crash!
   1763 }
   1764 
   1765 // See description of RunGetNativeThemeFromDestructor() for details.
   1766 class GetNativeThemeFromDestructorView : public WidgetDelegateView {
   1767  public:
   1768   GetNativeThemeFromDestructorView() {}
   1769   virtual ~GetNativeThemeFromDestructorView() {
   1770     VerifyNativeTheme();
   1771   }
   1772 
   1773   virtual View* GetContentsView() OVERRIDE {
   1774     return this;
   1775   }
   1776 
   1777  private:
   1778   void VerifyNativeTheme() {
   1779     ASSERT_TRUE(GetNativeTheme() != NULL);
   1780   }
   1781 
   1782   DISALLOW_COPY_AND_ASSIGN(GetNativeThemeFromDestructorView);
   1783 };
   1784 
   1785 // Verifies GetNativeTheme() from the destructor of a WidgetDelegateView doesn't
   1786 // crash. |is_first_run| is true if this is the first call. A return value of
   1787 // true indicates this should be run again with a value of false.
   1788 // First run uses DesktopNativeWidgetAura (if possible). Second run doesn't.
   1789 bool RunGetNativeThemeFromDestructor(const Widget::InitParams& in_params,
   1790                                      bool is_first_run) {
   1791   bool needs_second_run = false;
   1792   // Destroyed by CloseNow() below.
   1793   Widget* widget = new Widget;
   1794   Widget::InitParams params(in_params);
   1795   // Deletes itself when the Widget is destroyed.
   1796   params.delegate = new GetNativeThemeFromDestructorView;
   1797 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
   1798   if (is_first_run) {
   1799     params.native_widget = new DesktopNativeWidgetAura(widget);
   1800     needs_second_run = true;
   1801   }
   1802 #endif
   1803   widget->Init(params);
   1804   widget->CloseNow();
   1805   return needs_second_run;
   1806 }
   1807 
   1808 // See description of RunGetNativeThemeFromDestructor() for details.
   1809 TEST_F(WidgetTest, GetNativeThemeFromDestructor) {
   1810   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   1811   if (RunGetNativeThemeFromDestructor(params, true))
   1812     RunGetNativeThemeFromDestructor(params, false);
   1813 }
   1814 
   1815 // Used by HideCloseDestroy. Allows setting a boolean when the widget is
   1816 // destroyed.
   1817 class CloseDestroysWidget : public Widget {
   1818  public:
   1819   explicit CloseDestroysWidget(bool* destroyed)
   1820       : destroyed_(destroyed) {
   1821   }
   1822 
   1823   virtual ~CloseDestroysWidget() {
   1824     if (destroyed_) {
   1825       *destroyed_ = true;
   1826       base::MessageLoop::current()->QuitNow();
   1827     }
   1828   }
   1829 
   1830   void Detach() { destroyed_ = NULL; }
   1831 
   1832  private:
   1833   // If non-null set to true from destructor.
   1834   bool* destroyed_;
   1835 
   1836   DISALLOW_COPY_AND_ASSIGN(CloseDestroysWidget);
   1837 };
   1838 
   1839 // Verifies Close() results in destroying.
   1840 TEST_F(WidgetTest, CloseDestroys) {
   1841   bool destroyed = false;
   1842   CloseDestroysWidget* widget = new CloseDestroysWidget(&destroyed);
   1843   Widget::InitParams params =
   1844       CreateParams(views::Widget::InitParams::TYPE_MENU);
   1845   params.opacity = Widget::InitParams::OPAQUE_WINDOW;
   1846 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
   1847   params.native_widget = new DesktopNativeWidgetAura(widget);
   1848 #endif
   1849   widget->Init(params);
   1850   widget->Show();
   1851   widget->Hide();
   1852   widget->Close();
   1853   // Run the message loop as Close() asynchronously deletes.
   1854   RunPendingMessages();
   1855   EXPECT_TRUE(destroyed);
   1856   // Close() should destroy the widget. If not we'll cleanup to avoid leaks.
   1857   if (!destroyed) {
   1858     widget->Detach();
   1859     widget->CloseNow();
   1860   }
   1861 }
   1862 
   1863 // A view that consumes mouse-pressed event and gesture-tap-down events.
   1864 class RootViewTestView : public View {
   1865  public:
   1866   RootViewTestView(): View() {}
   1867 
   1868  private:
   1869   virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
   1870     return true;
   1871   }
   1872 
   1873   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
   1874     if (event->type() == ui::ET_GESTURE_TAP_DOWN)
   1875       event->SetHandled();
   1876   }
   1877 };
   1878 
   1879 // Checks if RootView::*_handler_ fields are unset when widget is hidden.
   1880 // Fails on chromium.webkit Windows bot, see crbug.com/264872.
   1881 #if defined(OS_WIN)
   1882 #define MAYBE_DisableTestRootViewHandlersWhenHidden\
   1883     DISABLED_TestRootViewHandlersWhenHidden
   1884 #else
   1885 #define MAYBE_DisableTestRootViewHandlersWhenHidden\
   1886     TestRootViewHandlersWhenHidden
   1887 #endif
   1888 TEST_F(WidgetTest, MAYBE_DisableTestRootViewHandlersWhenHidden) {
   1889   Widget* widget = CreateTopLevelNativeWidget();
   1890   widget->SetBounds(gfx::Rect(0, 0, 300, 300));
   1891   View* view = new RootViewTestView();
   1892   view->SetBounds(0, 0, 300, 300);
   1893   internal::RootView* root_view =
   1894       static_cast<internal::RootView*>(widget->GetRootView());
   1895   root_view->AddChildView(view);
   1896 
   1897   // Check RootView::mouse_pressed_handler_.
   1898   widget->Show();
   1899   EXPECT_EQ(NULL, GetMousePressedHandler(root_view));
   1900   gfx::Point click_location(45, 15);
   1901   ui::MouseEvent press(ui::ET_MOUSE_PRESSED, click_location, click_location,
   1902       ui::EF_LEFT_MOUSE_BUTTON);
   1903   widget->OnMouseEvent(&press);
   1904   EXPECT_EQ(view, GetMousePressedHandler(root_view));
   1905   widget->Hide();
   1906   EXPECT_EQ(NULL, GetMousePressedHandler(root_view));
   1907 
   1908   // Check RootView::mouse_move_handler_.
   1909   widget->Show();
   1910   EXPECT_EQ(NULL, GetMouseMoveHandler(root_view));
   1911   gfx::Point move_location(45, 15);
   1912   ui::MouseEvent move(ui::ET_MOUSE_MOVED, move_location, move_location, 0);
   1913   widget->OnMouseEvent(&move);
   1914   EXPECT_EQ(view, GetMouseMoveHandler(root_view));
   1915   widget->Hide();
   1916   EXPECT_EQ(NULL, GetMouseMoveHandler(root_view));
   1917 
   1918   // Check RootView::gesture_handler_.
   1919   widget->Show();
   1920   EXPECT_EQ(NULL, GetGestureHandler(root_view));
   1921   ui::GestureEvent tap_down(
   1922       ui::ET_GESTURE_TAP_DOWN,
   1923       15,
   1924       15,
   1925       0,
   1926       base::TimeDelta(),
   1927       ui::GestureEventDetails(ui::ET_GESTURE_TAP_DOWN, 0, 0),
   1928       1);
   1929   widget->OnGestureEvent(&tap_down);
   1930   EXPECT_EQ(view, GetGestureHandler(root_view));
   1931   widget->Hide();
   1932   EXPECT_EQ(NULL, GetGestureHandler(root_view));
   1933 
   1934   widget->Close();
   1935 }
   1936 
   1937 // Test the result of Widget::GetAllChildWidgets().
   1938 TEST_F(WidgetTest, GetAllChildWidgets) {
   1939   // Create the following widget hierarchy:
   1940   //
   1941   // toplevel
   1942   // +-- w1
   1943   //     +-- w11
   1944   // +-- w2
   1945   //     +-- w21
   1946   //     +-- w22
   1947   Widget* toplevel = CreateTopLevelPlatformWidget();
   1948   Widget* w1 = CreateChildPlatformWidget(toplevel->GetNativeView());
   1949   Widget* w11 = CreateChildPlatformWidget(w1->GetNativeView());
   1950   Widget* w2 = CreateChildPlatformWidget(toplevel->GetNativeView());
   1951   Widget* w21 = CreateChildPlatformWidget(w2->GetNativeView());
   1952   Widget* w22 = CreateChildPlatformWidget(w2->GetNativeView());
   1953 
   1954   std::set<Widget*> expected;
   1955   expected.insert(toplevel);
   1956   expected.insert(w1);
   1957   expected.insert(w11);
   1958   expected.insert(w2);
   1959   expected.insert(w21);
   1960   expected.insert(w22);
   1961 
   1962   std::set<Widget*> widgets;
   1963   Widget::GetAllChildWidgets(toplevel->GetNativeView(), &widgets);
   1964 
   1965   EXPECT_EQ(expected.size(), widgets.size());
   1966   EXPECT_TRUE(std::equal(expected.begin(), expected.end(), widgets.begin()));
   1967 }
   1968 
   1969 // Used by DestroyChildWidgetsInOrder. On destruction adds the supplied name to
   1970 // a vector.
   1971 class DestroyedTrackingView : public View {
   1972  public:
   1973   DestroyedTrackingView(const std::string& name,
   1974                         std::vector<std::string>* add_to)
   1975       : name_(name),
   1976         add_to_(add_to) {
   1977   }
   1978 
   1979   virtual ~DestroyedTrackingView() {
   1980     add_to_->push_back(name_);
   1981   }
   1982 
   1983  private:
   1984   const std::string name_;
   1985   std::vector<std::string>* add_to_;
   1986 
   1987   DISALLOW_COPY_AND_ASSIGN(DestroyedTrackingView);
   1988 };
   1989 
   1990 class WidgetChildDestructionTest : public WidgetTest {
   1991  public:
   1992   WidgetChildDestructionTest() {}
   1993 
   1994   // Creates a top level and a child, destroys the child and verifies the views
   1995   // of the child are destroyed before the views of the parent.
   1996   void RunDestroyChildWidgetsTest(bool top_level_has_desktop_native_widget_aura,
   1997                                   bool child_has_desktop_native_widget_aura) {
   1998     // When a View is destroyed its name is added here.
   1999     std::vector<std::string> destroyed;
   2000 
   2001     Widget* top_level = new Widget;
   2002     Widget::InitParams params =
   2003         CreateParams(views::Widget::InitParams::TYPE_WINDOW);
   2004 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
   2005     if (top_level_has_desktop_native_widget_aura)
   2006       params.native_widget = new DesktopNativeWidgetAura(top_level);
   2007 #endif
   2008     top_level->Init(params);
   2009     top_level->GetRootView()->AddChildView(
   2010         new DestroyedTrackingView("parent", &destroyed));
   2011     top_level->Show();
   2012 
   2013     Widget* child = new Widget;
   2014     Widget::InitParams child_params =
   2015         CreateParams(views::Widget::InitParams::TYPE_POPUP);
   2016     child_params.parent = top_level->GetNativeView();
   2017 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
   2018     if (child_has_desktop_native_widget_aura)
   2019       child_params.native_widget = new DesktopNativeWidgetAura(child);
   2020 #endif
   2021     child->Init(child_params);
   2022     child->GetRootView()->AddChildView(
   2023         new DestroyedTrackingView("child", &destroyed));
   2024     child->Show();
   2025 
   2026     // Should trigger destruction of the child too.
   2027     top_level->native_widget_private()->CloseNow();
   2028 
   2029     // Child should be destroyed first.
   2030     ASSERT_EQ(2u, destroyed.size());
   2031     EXPECT_EQ("child", destroyed[0]);
   2032     EXPECT_EQ("parent", destroyed[1]);
   2033   }
   2034 
   2035  private:
   2036   DISALLOW_COPY_AND_ASSIGN(WidgetChildDestructionTest);
   2037 };
   2038 
   2039 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
   2040 // See description of RunDestroyChildWidgetsTest(). Parent uses
   2041 // DesktopNativeWidgetAura.
   2042 TEST_F(WidgetChildDestructionTest,
   2043        DestroyChildWidgetsInOrderWithDesktopNativeWidget) {
   2044   RunDestroyChildWidgetsTest(true, false);
   2045 }
   2046 
   2047 // See description of RunDestroyChildWidgetsTest(). Both parent and child use
   2048 // DesktopNativeWidgetAura.
   2049 TEST_F(WidgetChildDestructionTest,
   2050        DestroyChildWidgetsInOrderWithDesktopNativeWidgetForBoth) {
   2051   RunDestroyChildWidgetsTest(true, true);
   2052 }
   2053 #endif
   2054 
   2055 // See description of RunDestroyChildWidgetsTest().
   2056 TEST_F(WidgetChildDestructionTest, DestroyChildWidgetsInOrder) {
   2057   RunDestroyChildWidgetsTest(false, false);
   2058 }
   2059 
   2060 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
   2061 // Provides functionality to create a window modal dialog.
   2062 class ModalDialogDelegate : public DialogDelegateView {
   2063  public:
   2064   ModalDialogDelegate() {}
   2065   virtual ~ModalDialogDelegate() {}
   2066 
   2067   // WidgetDelegate overrides.
   2068   virtual ui::ModalType GetModalType() const OVERRIDE {
   2069     return ui::MODAL_TYPE_WINDOW;
   2070   }
   2071 
   2072  private:
   2073   DISALLOW_COPY_AND_ASSIGN(ModalDialogDelegate);
   2074 };
   2075 
   2076 // This test verifies that whether mouse events when a modal dialog is
   2077 // displayed are eaten or recieved by the dialog.
   2078 TEST_F(WidgetTest, WindowMouseModalityTest) {
   2079   // Create a top level widget.
   2080   Widget top_level_widget;
   2081   Widget::InitParams init_params =
   2082       CreateParams(Widget::InitParams::TYPE_WINDOW);
   2083   init_params.show_state = ui::SHOW_STATE_NORMAL;
   2084   gfx::Rect initial_bounds(0, 0, 500, 500);
   2085   init_params.bounds = initial_bounds;
   2086   init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   2087   init_params.native_widget = new DesktopNativeWidgetAura(&top_level_widget);
   2088   top_level_widget.Init(init_params);
   2089   top_level_widget.Show();
   2090   EXPECT_TRUE(top_level_widget.IsVisible());
   2091 
   2092   // Create a view and validate that a mouse moves makes it to the view.
   2093   EventCountView* widget_view = new EventCountView();
   2094   widget_view->SetBounds(0, 0, 10, 10);
   2095   top_level_widget.GetRootView()->AddChildView(widget_view);
   2096 
   2097   gfx::Point cursor_location_main(5, 5);
   2098   ui::MouseEvent move_main(ui::ET_MOUSE_MOVED,
   2099                            cursor_location_main,
   2100                            cursor_location_main,
   2101                            ui::EF_NONE);
   2102   top_level_widget.GetNativeView()->GetDispatcher()->
   2103       AsRootWindowHostDelegate()->OnHostMouseEvent(&move_main);
   2104 
   2105   EXPECT_EQ(1, widget_view->GetEventCount(ui::ET_MOUSE_ENTERED));
   2106   widget_view->ResetCounts();
   2107 
   2108   // Create a modal dialog and validate that a mouse down message makes it to
   2109   // the main view within the dialog.
   2110 
   2111   // This instance will be destroyed when the dialog is destroyed.
   2112   ModalDialogDelegate* dialog_delegate = new ModalDialogDelegate;
   2113 
   2114   Widget* modal_dialog_widget = views::DialogDelegate::CreateDialogWidget(
   2115       dialog_delegate, NULL, top_level_widget.GetNativeWindow());
   2116   modal_dialog_widget->SetBounds(gfx::Rect(100, 100, 200, 200));
   2117   EventCountView* dialog_widget_view = new EventCountView();
   2118   dialog_widget_view->SetBounds(0, 0, 50, 50);
   2119   modal_dialog_widget->GetRootView()->AddChildView(dialog_widget_view);
   2120   modal_dialog_widget->Show();
   2121   EXPECT_TRUE(modal_dialog_widget->IsVisible());
   2122 
   2123   gfx::Point cursor_location_dialog(100, 100);
   2124   ui::MouseEvent mouse_down_dialog(ui::ET_MOUSE_PRESSED,
   2125                                    cursor_location_dialog,
   2126                                    cursor_location_dialog,
   2127                                    ui::EF_NONE);
   2128   top_level_widget.GetNativeView()->GetDispatcher()->
   2129       AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse_down_dialog);
   2130   EXPECT_EQ(1, dialog_widget_view->GetEventCount(ui::ET_MOUSE_PRESSED));
   2131 
   2132   // Send a mouse move message to the main window. It should not be received by
   2133   // the main window as the modal dialog is still active.
   2134   gfx::Point cursor_location_main2(6, 6);
   2135   ui::MouseEvent mouse_down_main(ui::ET_MOUSE_MOVED,
   2136                                  cursor_location_main2,
   2137                                  cursor_location_main2,
   2138                                  ui::EF_NONE);
   2139   top_level_widget.GetNativeView()->GetDispatcher()->
   2140       AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse_down_main);
   2141   EXPECT_EQ(0, widget_view->GetEventCount(ui::ET_MOUSE_MOVED));
   2142 
   2143   modal_dialog_widget->CloseNow();
   2144   top_level_widget.CloseNow();
   2145 }
   2146 
   2147 #if defined(USE_AURA)
   2148 // Verifies nativeview visbility matches that of Widget visibility when
   2149 // SetFullscreen is invoked.
   2150 TEST_F(WidgetTest, FullscreenStatePropagated) {
   2151   Widget::InitParams init_params =
   2152       CreateParams(Widget::InitParams::TYPE_WINDOW);
   2153   init_params.show_state = ui::SHOW_STATE_NORMAL;
   2154   init_params.bounds = gfx::Rect(0, 0, 500, 500);
   2155   init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   2156 
   2157   {
   2158     Widget top_level_widget;
   2159     top_level_widget.Init(init_params);
   2160     top_level_widget.SetFullscreen(true);
   2161     EXPECT_EQ(top_level_widget.IsVisible(),
   2162               top_level_widget.GetNativeView()->IsVisible());
   2163     top_level_widget.CloseNow();
   2164   }
   2165 
   2166 #if !defined(OS_CHROMEOS)
   2167   {
   2168     Widget top_level_widget;
   2169     init_params.native_widget = new DesktopNativeWidgetAura(&top_level_widget);
   2170     top_level_widget.Init(init_params);
   2171     top_level_widget.SetFullscreen(true);
   2172     EXPECT_EQ(top_level_widget.IsVisible(),
   2173               top_level_widget.GetNativeView()->IsVisible());
   2174     top_level_widget.CloseNow();
   2175   }
   2176 #endif
   2177 }
   2178 #endif
   2179 
   2180 #if defined(OS_WIN)
   2181 
   2182 // Provides functionality to test widget activation via an activation flag
   2183 // which can be set by an accessor.
   2184 class ModalWindowTestWidgetDelegate : public WidgetDelegate {
   2185  public:
   2186   ModalWindowTestWidgetDelegate()
   2187       : widget_(NULL),
   2188         can_activate_(true) {}
   2189 
   2190   virtual ~ModalWindowTestWidgetDelegate() {}
   2191 
   2192   // Overridden from WidgetDelegate:
   2193   virtual void DeleteDelegate() OVERRIDE {
   2194     delete this;
   2195   }
   2196   virtual Widget* GetWidget() OVERRIDE {
   2197     return widget_;
   2198   }
   2199   virtual const Widget* GetWidget() const OVERRIDE {
   2200     return widget_;
   2201   }
   2202   virtual bool CanActivate() const OVERRIDE {
   2203     return can_activate_;
   2204   }
   2205   virtual bool ShouldAdvanceFocusToTopLevelWidget() const OVERRIDE {
   2206     return true;
   2207   }
   2208 
   2209   void set_can_activate(bool can_activate) {
   2210     can_activate_ = can_activate;
   2211   }
   2212 
   2213   void set_widget(Widget* widget) {
   2214     widget_ = widget;
   2215   }
   2216 
   2217  private:
   2218   Widget* widget_;
   2219   bool can_activate_;
   2220 
   2221   DISALLOW_COPY_AND_ASSIGN(ModalWindowTestWidgetDelegate);
   2222 };
   2223 
   2224 // Tests whether we can activate the top level widget when a modal dialog is
   2225 // active.
   2226 TEST_F(WidgetTest, WindowModalityActivationTest) {
   2227   // Destroyed when the top level widget created below is destroyed.
   2228   ModalWindowTestWidgetDelegate* widget_delegate =
   2229       new ModalWindowTestWidgetDelegate;
   2230   // Create a top level widget.
   2231   Widget top_level_widget;
   2232   Widget::InitParams init_params =
   2233       CreateParams(Widget::InitParams::TYPE_WINDOW);
   2234   init_params.show_state = ui::SHOW_STATE_NORMAL;
   2235   gfx::Rect initial_bounds(0, 0, 500, 500);
   2236   init_params.bounds = initial_bounds;
   2237   init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   2238   init_params.native_widget = new DesktopNativeWidgetAura(&top_level_widget);
   2239   init_params.delegate = widget_delegate;
   2240   top_level_widget.Init(init_params);
   2241   widget_delegate->set_widget(&top_level_widget);
   2242   top_level_widget.Show();
   2243   EXPECT_TRUE(top_level_widget.IsVisible());
   2244 
   2245   HWND win32_window = views::HWNDForWidget(&top_level_widget);
   2246   EXPECT_TRUE(::IsWindow(win32_window));
   2247 
   2248   // This instance will be destroyed when the dialog is destroyed.
   2249   ModalDialogDelegate* dialog_delegate = new ModalDialogDelegate;
   2250 
   2251   // We should be able to activate the window even if the WidgetDelegate
   2252   // says no, when a modal dialog is active.
   2253   widget_delegate->set_can_activate(false);
   2254 
   2255   Widget* modal_dialog_widget = views::DialogDelegate::CreateDialogWidget(
   2256       dialog_delegate, NULL, top_level_widget.GetNativeWindow());
   2257   modal_dialog_widget->SetBounds(gfx::Rect(100, 100, 200, 200));
   2258   modal_dialog_widget->Show();
   2259   EXPECT_TRUE(modal_dialog_widget->IsVisible());
   2260 
   2261   LRESULT activate_result = ::SendMessage(
   2262       win32_window,
   2263       WM_MOUSEACTIVATE,
   2264       reinterpret_cast<WPARAM>(win32_window),
   2265       MAKELPARAM(WM_LBUTTONDOWN, HTCLIENT));
   2266   EXPECT_EQ(activate_result, MA_ACTIVATE);
   2267 
   2268   modal_dialog_widget->CloseNow();
   2269   top_level_widget.CloseNow();
   2270 }
   2271 #endif
   2272 #endif
   2273 
   2274 namespace {
   2275 
   2276 class FullscreenAwareFrame : public views::NonClientFrameView {
   2277  public:
   2278   explicit FullscreenAwareFrame(views::Widget* widget)
   2279       : widget_(widget), fullscreen_layout_called_(false) {}
   2280   virtual ~FullscreenAwareFrame() {}
   2281 
   2282   // views::NonClientFrameView overrides:
   2283   virtual gfx::Rect GetBoundsForClientView() const OVERRIDE {
   2284     return gfx::Rect();
   2285   }
   2286   virtual gfx::Rect GetWindowBoundsForClientBounds(
   2287       const gfx::Rect& client_bounds) const OVERRIDE {
   2288     return gfx::Rect();
   2289   }
   2290   virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE {
   2291     return HTNOWHERE;
   2292   }
   2293   virtual void GetWindowMask(const gfx::Size& size,
   2294                              gfx::Path* window_mask) OVERRIDE {}
   2295   virtual void ResetWindowControls() OVERRIDE {}
   2296   virtual void UpdateWindowIcon() OVERRIDE {}
   2297   virtual void UpdateWindowTitle() OVERRIDE {}
   2298 
   2299   // views::View overrides:
   2300   virtual void Layout() OVERRIDE {
   2301     if (widget_->IsFullscreen())
   2302       fullscreen_layout_called_ = true;
   2303   }
   2304 
   2305   bool fullscreen_layout_called() const { return fullscreen_layout_called_; }
   2306 
   2307  private:
   2308   views::Widget* widget_;
   2309   bool fullscreen_layout_called_;
   2310 
   2311   DISALLOW_COPY_AND_ASSIGN(FullscreenAwareFrame);
   2312 };
   2313 
   2314 }  // namespace
   2315 
   2316 // Tests that frame Layout is called when a widget goes fullscreen without
   2317 // changing its size or title.
   2318 TEST_F(WidgetTest, FullscreenFrameLayout) {
   2319   Widget* widget = CreateTopLevelPlatformWidget();
   2320   FullscreenAwareFrame* frame = new FullscreenAwareFrame(widget);
   2321   widget->non_client_view()->SetFrameView(frame);  // Owns |frame|.
   2322 
   2323   widget->Maximize();
   2324   RunPendingMessages();
   2325 
   2326   EXPECT_FALSE(frame->fullscreen_layout_called());
   2327   widget->SetFullscreen(true);
   2328   widget->Show();
   2329   RunPendingMessages();
   2330   EXPECT_TRUE(frame->fullscreen_layout_called());
   2331 
   2332   widget->CloseNow();
   2333 }
   2334 
   2335 #if !defined(OS_CHROMEOS)
   2336 namespace {
   2337 
   2338 // Trivial WidgetObserverTest that invokes Widget::IsActive() from
   2339 // OnWindowDestroying.
   2340 class IsActiveFromDestroyObserver : public WidgetObserver {
   2341  public:
   2342   IsActiveFromDestroyObserver() {}
   2343   virtual ~IsActiveFromDestroyObserver() {}
   2344   virtual void OnWidgetDestroying(Widget* widget) OVERRIDE {
   2345     widget->IsActive();
   2346   }
   2347 
   2348  private:
   2349   DISALLOW_COPY_AND_ASSIGN(IsActiveFromDestroyObserver);
   2350 };
   2351 
   2352 }  // namespace
   2353 
   2354 // Verifies Widget::IsActive() invoked from
   2355 // WidgetObserver::OnWidgetDestroying() in a child widget doesn't crash.
   2356 TEST_F(WidgetTest, IsActiveFromDestroy) {
   2357   // Create two widgets, one a child of the other.
   2358   IsActiveFromDestroyObserver observer;
   2359   Widget parent_widget;
   2360   Widget::InitParams parent_params =
   2361       CreateParams(Widget::InitParams::TYPE_POPUP);
   2362   parent_params.native_widget = new DesktopNativeWidgetAura(&parent_widget);
   2363   parent_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   2364   parent_widget.Init(parent_params);
   2365   parent_widget.Show();
   2366 
   2367   Widget child_widget;
   2368   Widget::InitParams child_params =
   2369       CreateParams(Widget::InitParams::TYPE_POPUP);
   2370   child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   2371   child_params.context = parent_widget.GetNativeView();
   2372   child_widget.Init(child_params);
   2373   child_widget.AddObserver(&observer);
   2374   child_widget.Show();
   2375 
   2376   parent_widget.CloseNow();
   2377 }
   2378 #endif
   2379 
   2380 }  // namespace test
   2381 }  // namespace views
   2382