Home | History | Annotate | Download | only in aura
      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 "ui/aura/window.h"
      6 
      7 #include <string>
      8 #include <utility>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/compiler_specific.h"
     13 #include "base/strings/string_number_conversions.h"
     14 #include "base/strings/string_util.h"
     15 #include "base/strings/stringprintf.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 #include "ui/aura/client/capture_client.h"
     18 #include "ui/aura/client/focus_change_observer.h"
     19 #include "ui/aura/client/visibility_client.h"
     20 #include "ui/aura/client/window_tree_client.h"
     21 #include "ui/aura/layout_manager.h"
     22 #include "ui/aura/root_window.h"
     23 #include "ui/aura/root_window_observer.h"
     24 #include "ui/aura/test/aura_test_base.h"
     25 #include "ui/aura/test/event_generator.h"
     26 #include "ui/aura/test/test_window_delegate.h"
     27 #include "ui/aura/test/test_windows.h"
     28 #include "ui/aura/test/window_test_api.h"
     29 #include "ui/aura/window_delegate.h"
     30 #include "ui/aura/window_observer.h"
     31 #include "ui/aura/window_property.h"
     32 #include "ui/aura/window_tree_host.h"
     33 #include "ui/base/hit_test.h"
     34 #include "ui/compositor/layer.h"
     35 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
     36 #include "ui/compositor/scoped_layer_animation_settings.h"
     37 #include "ui/compositor/test/test_layers.h"
     38 #include "ui/events/event.h"
     39 #include "ui/events/event_utils.h"
     40 #include "ui/events/gestures/gesture_configuration.h"
     41 #include "ui/events/keycodes/keyboard_codes.h"
     42 #include "ui/gfx/canvas.h"
     43 #include "ui/gfx/screen.h"
     44 #include "ui/gfx/skia_util.h"
     45 #include "ui/gfx/vector2d.h"
     46 
     47 DECLARE_WINDOW_PROPERTY_TYPE(const char*)
     48 DECLARE_WINDOW_PROPERTY_TYPE(int)
     49 
     50 namespace aura {
     51 namespace test {
     52 
     53 class WindowTest : public AuraTestBase {
     54  public:
     55   WindowTest() : max_separation_(0) {
     56   }
     57 
     58   virtual void SetUp() OVERRIDE {
     59     AuraTestBase::SetUp();
     60     // TODO: there needs to be an easier way to do this.
     61     max_separation_ = ui::GestureConfiguration::
     62         max_separation_for_gesture_touches_in_pixels();
     63     ui::GestureConfiguration::
     64         set_max_separation_for_gesture_touches_in_pixels(0);
     65   }
     66 
     67   virtual void TearDown() OVERRIDE {
     68     AuraTestBase::TearDown();
     69     ui::GestureConfiguration::
     70         set_max_separation_for_gesture_touches_in_pixels(max_separation_);
     71   }
     72 
     73  private:
     74   int max_separation_;
     75 
     76   DISALLOW_COPY_AND_ASSIGN(WindowTest);
     77 };
     78 
     79 namespace {
     80 
     81 // Used for verifying destruction methods are invoked.
     82 class DestroyTrackingDelegateImpl : public TestWindowDelegate {
     83  public:
     84   DestroyTrackingDelegateImpl()
     85       : destroying_count_(0),
     86         destroyed_count_(0),
     87         in_destroying_(false) {}
     88 
     89   void clear_destroying_count() { destroying_count_ = 0; }
     90   int destroying_count() const { return destroying_count_; }
     91 
     92   void clear_destroyed_count() { destroyed_count_ = 0; }
     93   int destroyed_count() const { return destroyed_count_; }
     94 
     95   bool in_destroying() const { return in_destroying_; }
     96 
     97   virtual void OnWindowDestroying() OVERRIDE {
     98     EXPECT_FALSE(in_destroying_);
     99     in_destroying_ = true;
    100     destroying_count_++;
    101   }
    102 
    103   virtual void OnWindowDestroyed() OVERRIDE {
    104     EXPECT_TRUE(in_destroying_);
    105     in_destroying_ = false;
    106     destroyed_count_++;
    107   }
    108 
    109  private:
    110   int destroying_count_;
    111   int destroyed_count_;
    112   bool in_destroying_;
    113 
    114   DISALLOW_COPY_AND_ASSIGN(DestroyTrackingDelegateImpl);
    115 };
    116 
    117 // Used to verify that when OnWindowDestroying is invoked the parent is also
    118 // is in the process of being destroyed.
    119 class ChildWindowDelegateImpl : public DestroyTrackingDelegateImpl {
    120  public:
    121   explicit ChildWindowDelegateImpl(
    122       DestroyTrackingDelegateImpl* parent_delegate)
    123       : parent_delegate_(parent_delegate) {
    124   }
    125 
    126   virtual void OnWindowDestroying() OVERRIDE {
    127     EXPECT_TRUE(parent_delegate_->in_destroying());
    128     DestroyTrackingDelegateImpl::OnWindowDestroying();
    129   }
    130 
    131  private:
    132   DestroyTrackingDelegateImpl* parent_delegate_;
    133 
    134   DISALLOW_COPY_AND_ASSIGN(ChildWindowDelegateImpl);
    135 };
    136 
    137 // Used to verify that a Window is removed from its parent when
    138 // OnWindowDestroyed is called.
    139 class DestroyOrphanDelegate : public TestWindowDelegate {
    140  public:
    141   DestroyOrphanDelegate() : window_(NULL) {
    142   }
    143 
    144   void set_window(Window* window) { window_ = window; }
    145 
    146   virtual void OnWindowDestroyed() OVERRIDE {
    147     EXPECT_FALSE(window_->parent());
    148   }
    149 
    150  private:
    151   Window* window_;
    152   DISALLOW_COPY_AND_ASSIGN(DestroyOrphanDelegate);
    153 };
    154 
    155 // Used in verifying mouse capture.
    156 class CaptureWindowDelegateImpl : public TestWindowDelegate {
    157  public:
    158   CaptureWindowDelegateImpl() {
    159     ResetCounts();
    160   }
    161 
    162   void ResetCounts() {
    163     capture_changed_event_count_ = 0;
    164     capture_lost_count_ = 0;
    165     mouse_event_count_ = 0;
    166     touch_event_count_ = 0;
    167     gesture_event_count_ = 0;
    168   }
    169 
    170   int capture_changed_event_count() const {
    171     return capture_changed_event_count_;
    172   }
    173   int capture_lost_count() const { return capture_lost_count_; }
    174   int mouse_event_count() const { return mouse_event_count_; }
    175   int touch_event_count() const { return touch_event_count_; }
    176   int gesture_event_count() const { return gesture_event_count_; }
    177 
    178   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
    179     if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED)
    180       capture_changed_event_count_++;
    181     mouse_event_count_++;
    182   }
    183   virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
    184     touch_event_count_++;
    185   }
    186   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
    187     gesture_event_count_++;
    188   }
    189   virtual void OnCaptureLost() OVERRIDE {
    190     capture_lost_count_++;
    191   }
    192 
    193  private:
    194   int capture_changed_event_count_;
    195   int capture_lost_count_;
    196   int mouse_event_count_;
    197   int touch_event_count_;
    198   int gesture_event_count_;
    199 
    200   DISALLOW_COPY_AND_ASSIGN(CaptureWindowDelegateImpl);
    201 };
    202 
    203 // Keeps track of the location of the gesture.
    204 class GestureTrackPositionDelegate : public TestWindowDelegate {
    205  public:
    206   GestureTrackPositionDelegate() {}
    207 
    208   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
    209     position_ = event->location();
    210     event->StopPropagation();
    211   }
    212 
    213   const gfx::Point& position() const { return position_; }
    214 
    215  private:
    216   gfx::Point position_;
    217 
    218   DISALLOW_COPY_AND_ASSIGN(GestureTrackPositionDelegate);
    219 };
    220 
    221 base::TimeDelta getTime() {
    222   return ui::EventTimeForNow();
    223 }
    224 
    225 class SelfEventHandlingWindowDelegate : public TestWindowDelegate {
    226  public:
    227   SelfEventHandlingWindowDelegate() {}
    228 
    229   virtual bool ShouldDescendIntoChildForEventHandling(
    230       Window* child,
    231       const gfx::Point& location) OVERRIDE {
    232     return false;
    233   }
    234 
    235  private:
    236   DISALLOW_COPY_AND_ASSIGN(SelfEventHandlingWindowDelegate);
    237 };
    238 
    239 // The delegate deletes itself when the window is being destroyed.
    240 class DestroyWindowDelegate : public TestWindowDelegate {
    241  public:
    242   DestroyWindowDelegate() {}
    243 
    244  private:
    245   virtual ~DestroyWindowDelegate() {}
    246 
    247   // Overridden from WindowDelegate.
    248   virtual void OnWindowDestroyed() OVERRIDE {
    249     delete this;
    250   }
    251 
    252   DISALLOW_COPY_AND_ASSIGN(DestroyWindowDelegate);
    253 };
    254 
    255 }  // namespace
    256 
    257 TEST_F(WindowTest, GetChildById) {
    258   scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
    259   scoped_ptr<Window> w11(CreateTestWindowWithId(11, w1.get()));
    260   scoped_ptr<Window> w111(CreateTestWindowWithId(111, w11.get()));
    261   scoped_ptr<Window> w12(CreateTestWindowWithId(12, w1.get()));
    262 
    263   EXPECT_EQ(NULL, w1->GetChildById(57));
    264   EXPECT_EQ(w12.get(), w1->GetChildById(12));
    265   EXPECT_EQ(w111.get(), w1->GetChildById(111));
    266 }
    267 
    268 // Make sure that Window::Contains correctly handles children, grandchildren,
    269 // and not containing NULL or parents.
    270 TEST_F(WindowTest, Contains) {
    271   Window parent(NULL);
    272   parent.Init(ui::LAYER_NOT_DRAWN);
    273   Window child1(NULL);
    274   child1.Init(ui::LAYER_NOT_DRAWN);
    275   Window child2(NULL);
    276   child2.Init(ui::LAYER_NOT_DRAWN);
    277 
    278   parent.AddChild(&child1);
    279   child1.AddChild(&child2);
    280 
    281   EXPECT_TRUE(parent.Contains(&parent));
    282   EXPECT_TRUE(parent.Contains(&child1));
    283   EXPECT_TRUE(parent.Contains(&child2));
    284 
    285   EXPECT_FALSE(parent.Contains(NULL));
    286   EXPECT_FALSE(child1.Contains(&parent));
    287   EXPECT_FALSE(child2.Contains(&child1));
    288 }
    289 
    290 TEST_F(WindowTest, ContainsPointInRoot) {
    291   scoped_ptr<Window> w(
    292       CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 5, 5),
    293                        root_window()));
    294   EXPECT_FALSE(w->ContainsPointInRoot(gfx::Point(9, 9)));
    295   EXPECT_TRUE(w->ContainsPointInRoot(gfx::Point(10, 10)));
    296   EXPECT_TRUE(w->ContainsPointInRoot(gfx::Point(14, 14)));
    297   EXPECT_FALSE(w->ContainsPointInRoot(gfx::Point(15, 15)));
    298   EXPECT_FALSE(w->ContainsPointInRoot(gfx::Point(20, 20)));
    299 }
    300 
    301 TEST_F(WindowTest, ContainsPoint) {
    302   scoped_ptr<Window> w(
    303       CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 5, 5),
    304                        root_window()));
    305   EXPECT_TRUE(w->ContainsPoint(gfx::Point(0, 0)));
    306   EXPECT_TRUE(w->ContainsPoint(gfx::Point(4, 4)));
    307   EXPECT_FALSE(w->ContainsPoint(gfx::Point(5, 5)));
    308   EXPECT_FALSE(w->ContainsPoint(gfx::Point(10, 10)));
    309 }
    310 
    311 TEST_F(WindowTest, ConvertPointToWindow) {
    312   // Window::ConvertPointToWindow is mostly identical to
    313   // Layer::ConvertPointToLayer, except NULL values for |source| are permitted,
    314   // in which case the function just returns.
    315   scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
    316   gfx::Point reference_point(100, 100);
    317   gfx::Point test_point = reference_point;
    318   Window::ConvertPointToTarget(NULL, w1.get(), &test_point);
    319   EXPECT_EQ(reference_point, test_point);
    320 }
    321 
    322 TEST_F(WindowTest, MoveCursorTo) {
    323   scoped_ptr<Window> w1(
    324       CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500),
    325                        root_window()));
    326   scoped_ptr<Window> w11(
    327       CreateTestWindow(SK_ColorGREEN, 11, gfx::Rect(5, 5, 100, 100), w1.get()));
    328   scoped_ptr<Window> w111(
    329       CreateTestWindow(SK_ColorCYAN, 111, gfx::Rect(5, 5, 75, 75), w11.get()));
    330   scoped_ptr<Window> w1111(
    331       CreateTestWindow(SK_ColorRED, 1111, gfx::Rect(5, 5, 50, 50), w111.get()));
    332 
    333   Window* root = root_window();
    334   root->MoveCursorTo(gfx::Point(10, 10));
    335   EXPECT_EQ("10,10",
    336       gfx::Screen::GetScreenFor(root)->GetCursorScreenPoint().ToString());
    337   w1->MoveCursorTo(gfx::Point(10, 10));
    338   EXPECT_EQ("20,20",
    339       gfx::Screen::GetScreenFor(root)->GetCursorScreenPoint().ToString());
    340   w11->MoveCursorTo(gfx::Point(10, 10));
    341   EXPECT_EQ("25,25",
    342       gfx::Screen::GetScreenFor(root)->GetCursorScreenPoint().ToString());
    343   w111->MoveCursorTo(gfx::Point(10, 10));
    344   EXPECT_EQ("30,30",
    345       gfx::Screen::GetScreenFor(root)->GetCursorScreenPoint().ToString());
    346   w1111->MoveCursorTo(gfx::Point(10, 10));
    347   EXPECT_EQ("35,35",
    348       gfx::Screen::GetScreenFor(root)->GetCursorScreenPoint().ToString());
    349 }
    350 
    351 TEST_F(WindowTest, ContainsMouse) {
    352   scoped_ptr<Window> w(
    353       CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500),
    354                        root_window()));
    355   w->Show();
    356   WindowTestApi w_test_api(w.get());
    357   Window* root = root_window();
    358   root->MoveCursorTo(gfx::Point(10, 10));
    359   EXPECT_TRUE(w_test_api.ContainsMouse());
    360   root->MoveCursorTo(gfx::Point(9, 10));
    361   EXPECT_FALSE(w_test_api.ContainsMouse());
    362 }
    363 
    364 // Test Window::ConvertPointToWindow() with transform to root_window.
    365 #if defined(USE_OZONE)
    366 // TODO(rjkroege): Add cursor support in ozone: http://crbug.com/252315.
    367 TEST_F(WindowTest, DISABLED_MoveCursorToWithTransformRootWindow) {
    368 #else
    369 TEST_F(WindowTest, MoveCursorToWithTransformRootWindow) {
    370 #endif
    371   gfx::Transform transform;
    372   transform.Translate(100.0, 100.0);
    373   transform.Rotate(90.0);
    374   transform.Scale(2.0, 5.0);
    375   dispatcher()->SetTransform(transform);
    376   dispatcher()->MoveCursorTo(gfx::Point(10, 10));
    377 #if !defined(OS_WIN)
    378   gfx::Point mouse_location;
    379   EXPECT_TRUE(dispatcher()->host()->QueryMouseLocation(&mouse_location));
    380   // TODO(yoshiki): fix this to build on Windows. See crbug.com/133413.OD
    381   EXPECT_EQ("50,120", mouse_location.ToString());
    382 #endif
    383   EXPECT_EQ("10,10", gfx::Screen::GetScreenFor(
    384       root_window())->GetCursorScreenPoint().ToString());
    385 }
    386 
    387 // Tests Window::ConvertPointToWindow() with transform to non-root windows.
    388 TEST_F(WindowTest, MoveCursorToWithTransformWindow) {
    389   scoped_ptr<Window> w1(
    390       CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500),
    391                        root_window()));
    392 
    393   gfx::Transform transform1;
    394   transform1.Scale(2, 2);
    395   w1->SetTransform(transform1);
    396   w1->MoveCursorTo(gfx::Point(10, 10));
    397   EXPECT_EQ("30,30",
    398       gfx::Screen::GetScreenFor(w1.get())->GetCursorScreenPoint().ToString());
    399 
    400   gfx::Transform transform2;
    401   transform2.Translate(-10, 20);
    402   w1->SetTransform(transform2);
    403   w1->MoveCursorTo(gfx::Point(10, 10));
    404   EXPECT_EQ("10,40",
    405       gfx::Screen::GetScreenFor(w1.get())->GetCursorScreenPoint().ToString());
    406 
    407   gfx::Transform transform3;
    408   transform3.Rotate(90.0);
    409   w1->SetTransform(transform3);
    410   w1->MoveCursorTo(gfx::Point(5, 5));
    411   EXPECT_EQ("5,15",
    412       gfx::Screen::GetScreenFor(w1.get())->GetCursorScreenPoint().ToString());
    413 
    414   gfx::Transform transform4;
    415   transform4.Translate(100.0, 100.0);
    416   transform4.Rotate(90.0);
    417   transform4.Scale(2.0, 5.0);
    418   w1->SetTransform(transform4);
    419   w1->MoveCursorTo(gfx::Point(10, 10));
    420   EXPECT_EQ("60,130",
    421       gfx::Screen::GetScreenFor(w1.get())->GetCursorScreenPoint().ToString());
    422 }
    423 
    424 // Test Window::ConvertPointToWindow() with complex transforms to both root and
    425 // non-root windows.
    426 // Test Window::ConvertPointToWindow() with transform to root_window.
    427 #if defined(USE_OZONE)
    428 // TODO(rjkroege): Add cursor support in ozone: http://crbug.com/252315.
    429 TEST_F(WindowTest, DISABLED_MoveCursorToWithComplexTransform) {
    430 #else
    431 TEST_F(WindowTest, MoveCursorToWithComplexTransform) {
    432 #endif
    433   scoped_ptr<Window> w1(
    434       CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500),
    435                        root_window()));
    436   scoped_ptr<Window> w11(
    437       CreateTestWindow(SK_ColorGREEN, 11, gfx::Rect(5, 5, 100, 100), w1.get()));
    438   scoped_ptr<Window> w111(
    439       CreateTestWindow(SK_ColorCYAN, 111, gfx::Rect(5, 5, 75, 75), w11.get()));
    440   scoped_ptr<Window> w1111(
    441       CreateTestWindow(SK_ColorRED, 1111, gfx::Rect(5, 5, 50, 50), w111.get()));
    442 
    443   Window* root = root_window();
    444 
    445   // The root window expects transforms that produce integer rects.
    446   gfx::Transform root_transform;
    447   root_transform.Translate(60.0, 70.0);
    448   root_transform.Rotate(-90.0);
    449   root_transform.Translate(-50.0, -50.0);
    450   root_transform.Scale(2.0, 3.0);
    451 
    452   gfx::Transform transform;
    453   transform.Translate(10.0, 20.0);
    454   transform.Rotate(10.0);
    455   transform.Scale(0.3f, 0.5f);
    456   dispatcher()->SetTransform(root_transform);
    457   w1->SetTransform(transform);
    458   w11->SetTransform(transform);
    459   w111->SetTransform(transform);
    460   w1111->SetTransform(transform);
    461 
    462   w1111->MoveCursorTo(gfx::Point(10, 10));
    463 
    464 #if !defined(OS_WIN)
    465   // TODO(yoshiki): fix this to build on Windows. See crbug.com/133413.
    466   gfx::Point mouse_location;
    467   EXPECT_TRUE(dispatcher()->host()->QueryMouseLocation(&mouse_location));
    468   EXPECT_EQ("169,80", mouse_location.ToString());
    469 #endif
    470   EXPECT_EQ("20,53",
    471       gfx::Screen::GetScreenFor(root)->GetCursorScreenPoint().ToString());
    472 }
    473 
    474 TEST_F(WindowTest, HitTest) {
    475   Window w1(new ColorTestWindowDelegate(SK_ColorWHITE));
    476   w1.set_id(1);
    477   w1.Init(ui::LAYER_TEXTURED);
    478   w1.SetBounds(gfx::Rect(10, 20, 50, 60));
    479   w1.Show();
    480   ParentWindow(&w1);
    481 
    482   // Points are in the Window's coordinates.
    483   EXPECT_TRUE(w1.HitTest(gfx::Point(1, 1)));
    484   EXPECT_FALSE(w1.HitTest(gfx::Point(-1, -1)));
    485 
    486   // We can expand the bounds slightly to track events outside our border.
    487   w1.SetHitTestBoundsOverrideOuter(gfx::Insets(-1, -1, -1, -1),
    488                                    gfx::Insets(-5, -5, -5, -5));
    489   EXPECT_TRUE(w1.HitTest(gfx::Point(-1, -1)));
    490   EXPECT_FALSE(w1.HitTest(gfx::Point(-2, -2)));
    491 
    492   ui::TouchEvent pressed(
    493       ui::ET_TOUCH_PRESSED, gfx::Point(50, 50), 0, getTime());
    494   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&pressed);
    495   EXPECT_TRUE(w1.HitTest(gfx::Point(-2, -2)));
    496   EXPECT_TRUE(w1.HitTest(gfx::Point(-5, -5)));
    497   EXPECT_FALSE(w1.HitTest(gfx::Point(-5, -6)));
    498   ui::TouchEvent released(
    499       ui::ET_TOUCH_RELEASED, gfx::Point(50, 50), 0, getTime());
    500   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&released);
    501   EXPECT_FALSE(w1.HitTest(gfx::Point(-2, -2)));
    502 
    503   // TODO(beng): clip Window to parent.
    504 }
    505 
    506 TEST_F(WindowTest, HitTestMask) {
    507   MaskedWindowDelegate d1(gfx::Rect(5, 6, 20, 30));
    508   Window w1(&d1);
    509   w1.Init(ui::LAYER_NOT_DRAWN);
    510   w1.SetBounds(gfx::Rect(10, 20, 50, 60));
    511   w1.Show();
    512   ParentWindow(&w1);
    513 
    514   // Points inside the mask.
    515   EXPECT_TRUE(w1.HitTest(gfx::Point(5, 6)));  // top-left
    516   EXPECT_TRUE(w1.HitTest(gfx::Point(15, 21)));  // center
    517   EXPECT_TRUE(w1.HitTest(gfx::Point(24, 35)));  // bottom-right
    518 
    519   // Points outside the mask.
    520   EXPECT_FALSE(w1.HitTest(gfx::Point(0, 0)));
    521   EXPECT_FALSE(w1.HitTest(gfx::Point(60, 80)));
    522   EXPECT_FALSE(w1.HitTest(gfx::Point(4, 6)));
    523   EXPECT_FALSE(w1.HitTest(gfx::Point(5, 5)));
    524   EXPECT_FALSE(w1.HitTest(gfx::Point(25, 36)));
    525 }
    526 
    527 TEST_F(WindowTest, GetEventHandlerForPoint) {
    528   scoped_ptr<Window> w1(
    529       CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500),
    530                        root_window()));
    531   scoped_ptr<Window> w11(
    532       CreateTestWindow(SK_ColorGREEN, 11, gfx::Rect(5, 5, 100, 100), w1.get()));
    533   scoped_ptr<Window> w111(
    534       CreateTestWindow(SK_ColorCYAN, 111, gfx::Rect(5, 5, 75, 75), w11.get()));
    535   scoped_ptr<Window> w1111(
    536       CreateTestWindow(SK_ColorRED, 1111, gfx::Rect(5, 5, 50, 50), w111.get()));
    537   scoped_ptr<Window> w12(
    538       CreateTestWindow(SK_ColorMAGENTA, 12, gfx::Rect(10, 420, 25, 25),
    539                        w1.get()));
    540   scoped_ptr<Window> w121(
    541       CreateTestWindow(SK_ColorYELLOW, 121, gfx::Rect(5, 5, 5, 5), w12.get()));
    542   scoped_ptr<Window> w13(
    543       CreateTestWindow(SK_ColorGRAY, 13, gfx::Rect(5, 470, 50, 50), w1.get()));
    544 
    545   Window* root = root_window();
    546   w1->parent()->SetBounds(gfx::Rect(500, 500));
    547   EXPECT_EQ(NULL, root->GetEventHandlerForPoint(gfx::Point(5, 5)));
    548   EXPECT_EQ(w1.get(), root->GetEventHandlerForPoint(gfx::Point(11, 11)));
    549   EXPECT_EQ(w11.get(), root->GetEventHandlerForPoint(gfx::Point(16, 16)));
    550   EXPECT_EQ(w111.get(), root->GetEventHandlerForPoint(gfx::Point(21, 21)));
    551   EXPECT_EQ(w1111.get(), root->GetEventHandlerForPoint(gfx::Point(26, 26)));
    552   EXPECT_EQ(w12.get(), root->GetEventHandlerForPoint(gfx::Point(21, 431)));
    553   EXPECT_EQ(w121.get(), root->GetEventHandlerForPoint(gfx::Point(26, 436)));
    554   EXPECT_EQ(w13.get(), root->GetEventHandlerForPoint(gfx::Point(26, 481)));
    555 }
    556 
    557 TEST_F(WindowTest, GetEventHandlerForPointWithOverride) {
    558   // If our child is flush to our top-left corner he gets events just inside the
    559   // window edges.
    560   scoped_ptr<Window> parent(
    561       CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 20, 400, 500),
    562                        root_window()));
    563   scoped_ptr<Window> child(
    564       CreateTestWindow(SK_ColorRED, 2, gfx::Rect(0, 0, 60, 70), parent.get()));
    565   EXPECT_EQ(child.get(), parent->GetEventHandlerForPoint(gfx::Point(0, 0)));
    566   EXPECT_EQ(child.get(), parent->GetEventHandlerForPoint(gfx::Point(1, 1)));
    567 
    568   // We can override the hit test bounds of the parent to make the parent grab
    569   // events along that edge.
    570   parent->set_hit_test_bounds_override_inner(gfx::Insets(1, 1, 1, 1));
    571   EXPECT_EQ(parent.get(), parent->GetEventHandlerForPoint(gfx::Point(0, 0)));
    572   EXPECT_EQ(child.get(),  parent->GetEventHandlerForPoint(gfx::Point(1, 1)));
    573 }
    574 
    575 TEST_F(WindowTest, GetEventHandlerForPointWithOverrideDescendingOrder) {
    576   scoped_ptr<SelfEventHandlingWindowDelegate> parent_delegate(
    577       new SelfEventHandlingWindowDelegate);
    578   scoped_ptr<Window> parent(CreateTestWindowWithDelegate(
    579       parent_delegate.get(), 1, gfx::Rect(10, 20, 400, 500), root_window()));
    580   scoped_ptr<Window> child(
    581       CreateTestWindow(SK_ColorRED, 2, gfx::Rect(0, 0, 390, 480),
    582                        parent.get()));
    583 
    584   // We can override ShouldDescendIntoChildForEventHandling to make the parent
    585   // grab all events.
    586   EXPECT_EQ(parent.get(), parent->GetEventHandlerForPoint(gfx::Point(0, 0)));
    587   EXPECT_EQ(parent.get(), parent->GetEventHandlerForPoint(gfx::Point(50, 50)));
    588 }
    589 
    590 TEST_F(WindowTest, GetTopWindowContainingPoint) {
    591   Window* root = root_window();
    592   root->SetBounds(gfx::Rect(0, 0, 300, 300));
    593 
    594   scoped_ptr<Window> w1(
    595       CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 100, 100),
    596                        root_window()));
    597   scoped_ptr<Window> w11(
    598       CreateTestWindow(SK_ColorGREEN, 11, gfx::Rect(0, 0, 120, 120), w1.get()));
    599 
    600   scoped_ptr<Window> w2(
    601       CreateTestWindow(SK_ColorRED, 2, gfx::Rect(5, 5, 55, 55),
    602                        root_window()));
    603 
    604   scoped_ptr<Window> w3(
    605       CreateTestWindowWithDelegate(
    606           NULL, 3, gfx::Rect(200, 200, 100, 100), root_window()));
    607   scoped_ptr<Window> w31(
    608       CreateTestWindow(SK_ColorCYAN, 31, gfx::Rect(0, 0, 50, 50), w3.get()));
    609   scoped_ptr<Window> w311(
    610       CreateTestWindow(SK_ColorBLUE, 311, gfx::Rect(0, 0, 10, 10), w31.get()));
    611 
    612   EXPECT_EQ(NULL, root->GetTopWindowContainingPoint(gfx::Point(0, 0)));
    613   EXPECT_EQ(w2.get(), root->GetTopWindowContainingPoint(gfx::Point(5, 5)));
    614   EXPECT_EQ(w2.get(), root->GetTopWindowContainingPoint(gfx::Point(10, 10)));
    615   EXPECT_EQ(w2.get(), root->GetTopWindowContainingPoint(gfx::Point(59, 59)));
    616   EXPECT_EQ(w1.get(), root->GetTopWindowContainingPoint(gfx::Point(60, 60)));
    617   EXPECT_EQ(w1.get(), root->GetTopWindowContainingPoint(gfx::Point(109, 109)));
    618   EXPECT_EQ(NULL, root->GetTopWindowContainingPoint(gfx::Point(110, 110)));
    619   EXPECT_EQ(w31.get(), root->GetTopWindowContainingPoint(gfx::Point(200, 200)));
    620   EXPECT_EQ(w31.get(), root->GetTopWindowContainingPoint(gfx::Point(220, 220)));
    621   EXPECT_EQ(NULL, root->GetTopWindowContainingPoint(gfx::Point(260, 260)));
    622 }
    623 
    624 TEST_F(WindowTest, GetToplevelWindow) {
    625   const gfx::Rect kBounds(0, 0, 10, 10);
    626   TestWindowDelegate delegate;
    627 
    628   scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
    629   scoped_ptr<Window> w11(
    630       CreateTestWindowWithDelegate(&delegate, 11, kBounds, w1.get()));
    631   scoped_ptr<Window> w111(CreateTestWindowWithId(111, w11.get()));
    632   scoped_ptr<Window> w1111(
    633       CreateTestWindowWithDelegate(&delegate, 1111, kBounds, w111.get()));
    634 
    635   EXPECT_TRUE(root_window()->GetToplevelWindow() == NULL);
    636   EXPECT_TRUE(w1->GetToplevelWindow() == NULL);
    637   EXPECT_EQ(w11.get(), w11->GetToplevelWindow());
    638   EXPECT_EQ(w11.get(), w111->GetToplevelWindow());
    639   EXPECT_EQ(w11.get(), w1111->GetToplevelWindow());
    640 }
    641 
    642 class AddedToRootWindowObserver : public WindowObserver {
    643  public:
    644   AddedToRootWindowObserver() : called_(false) {}
    645 
    646   virtual void OnWindowAddedToRootWindow(Window* window) OVERRIDE {
    647     called_ = true;
    648   }
    649 
    650   bool called() const { return called_; }
    651 
    652  private:
    653   bool called_;
    654 
    655   DISALLOW_COPY_AND_ASSIGN(AddedToRootWindowObserver);
    656 };
    657 
    658 TEST_F(WindowTest, WindowAddedToRootWindowShouldNotifyChildAndNotParent) {
    659   AddedToRootWindowObserver parent_observer;
    660   AddedToRootWindowObserver child_observer;
    661   scoped_ptr<Window> parent_window(CreateTestWindowWithId(1, root_window()));
    662   scoped_ptr<Window> child_window(new Window(NULL));
    663   child_window->Init(ui::LAYER_TEXTURED);
    664   child_window->Show();
    665 
    666   parent_window->AddObserver(&parent_observer);
    667   child_window->AddObserver(&child_observer);
    668 
    669   parent_window->AddChild(child_window.get());
    670 
    671   EXPECT_FALSE(parent_observer.called());
    672   EXPECT_TRUE(child_observer.called());
    673 
    674   parent_window->RemoveObserver(&parent_observer);
    675   child_window->RemoveObserver(&child_observer);
    676 }
    677 
    678 // Various destruction assertions.
    679 TEST_F(WindowTest, DestroyTest) {
    680   DestroyTrackingDelegateImpl parent_delegate;
    681   ChildWindowDelegateImpl child_delegate(&parent_delegate);
    682   {
    683     scoped_ptr<Window> parent(
    684         CreateTestWindowWithDelegate(&parent_delegate, 0, gfx::Rect(),
    685                                      root_window()));
    686     CreateTestWindowWithDelegate(&child_delegate, 0, gfx::Rect(), parent.get());
    687   }
    688   // Both the parent and child should have been destroyed.
    689   EXPECT_EQ(1, parent_delegate.destroying_count());
    690   EXPECT_EQ(1, parent_delegate.destroyed_count());
    691   EXPECT_EQ(1, child_delegate.destroying_count());
    692   EXPECT_EQ(1, child_delegate.destroyed_count());
    693 }
    694 
    695 // Tests that a window is orphaned before OnWindowDestroyed is called.
    696 TEST_F(WindowTest, OrphanedBeforeOnDestroyed) {
    697   TestWindowDelegate parent_delegate;
    698   DestroyOrphanDelegate child_delegate;
    699   {
    700     scoped_ptr<Window> parent(
    701         CreateTestWindowWithDelegate(&parent_delegate, 0, gfx::Rect(),
    702                                      root_window()));
    703     scoped_ptr<Window> child(CreateTestWindowWithDelegate(&child_delegate, 0,
    704           gfx::Rect(), parent.get()));
    705     child_delegate.set_window(child.get());
    706   }
    707 }
    708 
    709 // Make sure StackChildAtTop moves both the window and layer to the front.
    710 TEST_F(WindowTest, StackChildAtTop) {
    711   Window parent(NULL);
    712   parent.Init(ui::LAYER_NOT_DRAWN);
    713   Window child1(NULL);
    714   child1.Init(ui::LAYER_NOT_DRAWN);
    715   Window child2(NULL);
    716   child2.Init(ui::LAYER_NOT_DRAWN);
    717 
    718   parent.AddChild(&child1);
    719   parent.AddChild(&child2);
    720   ASSERT_EQ(2u, parent.children().size());
    721   EXPECT_EQ(&child1, parent.children()[0]);
    722   EXPECT_EQ(&child2, parent.children()[1]);
    723   ASSERT_EQ(2u, parent.layer()->children().size());
    724   EXPECT_EQ(child1.layer(), parent.layer()->children()[0]);
    725   EXPECT_EQ(child2.layer(), parent.layer()->children()[1]);
    726 
    727   parent.StackChildAtTop(&child1);
    728   ASSERT_EQ(2u, parent.children().size());
    729   EXPECT_EQ(&child1, parent.children()[1]);
    730   EXPECT_EQ(&child2, parent.children()[0]);
    731   ASSERT_EQ(2u, parent.layer()->children().size());
    732   EXPECT_EQ(child1.layer(), parent.layer()->children()[1]);
    733   EXPECT_EQ(child2.layer(), parent.layer()->children()[0]);
    734 }
    735 
    736 // Make sure StackChildBelow works.
    737 TEST_F(WindowTest, StackChildBelow) {
    738   Window parent(NULL);
    739   parent.Init(ui::LAYER_NOT_DRAWN);
    740   Window child1(NULL);
    741   child1.Init(ui::LAYER_NOT_DRAWN);
    742   child1.set_id(1);
    743   Window child2(NULL);
    744   child2.Init(ui::LAYER_NOT_DRAWN);
    745   child2.set_id(2);
    746   Window child3(NULL);
    747   child3.Init(ui::LAYER_NOT_DRAWN);
    748   child3.set_id(3);
    749 
    750   parent.AddChild(&child1);
    751   parent.AddChild(&child2);
    752   parent.AddChild(&child3);
    753   EXPECT_EQ("1 2 3", ChildWindowIDsAsString(&parent));
    754 
    755   parent.StackChildBelow(&child1, &child2);
    756   EXPECT_EQ("1 2 3", ChildWindowIDsAsString(&parent));
    757 
    758   parent.StackChildBelow(&child2, &child1);
    759   EXPECT_EQ("2 1 3", ChildWindowIDsAsString(&parent));
    760 
    761   parent.StackChildBelow(&child3, &child2);
    762   EXPECT_EQ("3 2 1", ChildWindowIDsAsString(&parent));
    763 
    764   parent.StackChildBelow(&child3, &child1);
    765   EXPECT_EQ("2 3 1", ChildWindowIDsAsString(&parent));
    766 }
    767 
    768 // Various assertions for StackChildAbove.
    769 TEST_F(WindowTest, StackChildAbove) {
    770   Window parent(NULL);
    771   parent.Init(ui::LAYER_NOT_DRAWN);
    772   Window child1(NULL);
    773   child1.Init(ui::LAYER_NOT_DRAWN);
    774   Window child2(NULL);
    775   child2.Init(ui::LAYER_NOT_DRAWN);
    776   Window child3(NULL);
    777   child3.Init(ui::LAYER_NOT_DRAWN);
    778 
    779   parent.AddChild(&child1);
    780   parent.AddChild(&child2);
    781 
    782   // Move 1 in front of 2.
    783   parent.StackChildAbove(&child1, &child2);
    784   ASSERT_EQ(2u, parent.children().size());
    785   EXPECT_EQ(&child2, parent.children()[0]);
    786   EXPECT_EQ(&child1, parent.children()[1]);
    787   ASSERT_EQ(2u, parent.layer()->children().size());
    788   EXPECT_EQ(child2.layer(), parent.layer()->children()[0]);
    789   EXPECT_EQ(child1.layer(), parent.layer()->children()[1]);
    790 
    791   // Add 3, resulting in order [2, 1, 3], then move 2 in front of 1, resulting
    792   // in [1, 2, 3].
    793   parent.AddChild(&child3);
    794   parent.StackChildAbove(&child2, &child1);
    795   ASSERT_EQ(3u, parent.children().size());
    796   EXPECT_EQ(&child1, parent.children()[0]);
    797   EXPECT_EQ(&child2, parent.children()[1]);
    798   EXPECT_EQ(&child3, parent.children()[2]);
    799   ASSERT_EQ(3u, parent.layer()->children().size());
    800   EXPECT_EQ(child1.layer(), parent.layer()->children()[0]);
    801   EXPECT_EQ(child2.layer(), parent.layer()->children()[1]);
    802   EXPECT_EQ(child3.layer(), parent.layer()->children()[2]);
    803 
    804   // Move 1 in front of 3, resulting in [2, 3, 1].
    805   parent.StackChildAbove(&child1, &child3);
    806   ASSERT_EQ(3u, parent.children().size());
    807   EXPECT_EQ(&child2, parent.children()[0]);
    808   EXPECT_EQ(&child3, parent.children()[1]);
    809   EXPECT_EQ(&child1, parent.children()[2]);
    810   ASSERT_EQ(3u, parent.layer()->children().size());
    811   EXPECT_EQ(child2.layer(), parent.layer()->children()[0]);
    812   EXPECT_EQ(child3.layer(), parent.layer()->children()[1]);
    813   EXPECT_EQ(child1.layer(), parent.layer()->children()[2]);
    814 
    815   // Moving 1 in front of 2 should lower it, resulting in [2, 1, 3].
    816   parent.StackChildAbove(&child1, &child2);
    817   ASSERT_EQ(3u, parent.children().size());
    818   EXPECT_EQ(&child2, parent.children()[0]);
    819   EXPECT_EQ(&child1, parent.children()[1]);
    820   EXPECT_EQ(&child3, parent.children()[2]);
    821   ASSERT_EQ(3u, parent.layer()->children().size());
    822   EXPECT_EQ(child2.layer(), parent.layer()->children()[0]);
    823   EXPECT_EQ(child1.layer(), parent.layer()->children()[1]);
    824   EXPECT_EQ(child3.layer(), parent.layer()->children()[2]);
    825 }
    826 
    827 // Various capture assertions.
    828 TEST_F(WindowTest, CaptureTests) {
    829   CaptureWindowDelegateImpl delegate;
    830   scoped_ptr<Window> window(CreateTestWindowWithDelegate(
    831       &delegate, 0, gfx::Rect(0, 0, 20, 20), root_window()));
    832   EXPECT_FALSE(window->HasCapture());
    833 
    834   delegate.ResetCounts();
    835 
    836   // Do a capture.
    837   window->SetCapture();
    838   EXPECT_TRUE(window->HasCapture());
    839   EXPECT_EQ(0, delegate.capture_lost_count());
    840   EXPECT_EQ(0, delegate.capture_changed_event_count());
    841   EventGenerator generator(root_window(), gfx::Point(50, 50));
    842   generator.PressLeftButton();
    843   EXPECT_EQ(1, delegate.mouse_event_count());
    844   generator.ReleaseLeftButton();
    845 
    846   EXPECT_EQ(2, delegate.mouse_event_count());
    847   delegate.ResetCounts();
    848 
    849   ui::TouchEvent touchev(
    850       ui::ET_TOUCH_PRESSED, gfx::Point(50, 50), 0, getTime());
    851   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&touchev);
    852   EXPECT_EQ(1, delegate.touch_event_count());
    853   delegate.ResetCounts();
    854 
    855   window->ReleaseCapture();
    856   EXPECT_FALSE(window->HasCapture());
    857   EXPECT_EQ(1, delegate.capture_lost_count());
    858   EXPECT_EQ(1, delegate.capture_changed_event_count());
    859   EXPECT_EQ(1, delegate.mouse_event_count());
    860   EXPECT_EQ(0, delegate.touch_event_count());
    861 
    862   generator.PressLeftButton();
    863   EXPECT_EQ(1, delegate.mouse_event_count());
    864 
    865   ui::TouchEvent touchev2(
    866       ui::ET_TOUCH_PRESSED, gfx::Point(250, 250), 1, getTime());
    867   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&touchev2);
    868   EXPECT_EQ(0, delegate.touch_event_count());
    869 
    870   // Removing the capture window from parent should reset the capture window
    871   // in the root window.
    872   window->SetCapture();
    873   EXPECT_EQ(window.get(), aura::client::GetCaptureWindow(root_window()));
    874   window->parent()->RemoveChild(window.get());
    875   EXPECT_FALSE(window->HasCapture());
    876   EXPECT_EQ(NULL, aura::client::GetCaptureWindow(root_window()));
    877 }
    878 
    879 TEST_F(WindowTest, TouchCaptureCancelsOtherTouches) {
    880   CaptureWindowDelegateImpl delegate1;
    881   scoped_ptr<Window> w1(CreateTestWindowWithDelegate(
    882       &delegate1, 0, gfx::Rect(0, 0, 50, 50), root_window()));
    883   CaptureWindowDelegateImpl delegate2;
    884   scoped_ptr<Window> w2(CreateTestWindowWithDelegate(
    885       &delegate2, 0, gfx::Rect(50, 50, 50, 50), root_window()));
    886 
    887   // Press on w1.
    888   ui::TouchEvent press(
    889       ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 0, getTime());
    890   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press);
    891   // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN.
    892   EXPECT_EQ(2, delegate1.gesture_event_count());
    893   delegate1.ResetCounts();
    894 
    895   // Capturing to w2 should cause the touch to be canceled.
    896   w2->SetCapture();
    897   EXPECT_EQ(1, delegate1.touch_event_count());
    898   EXPECT_EQ(0, delegate2.touch_event_count());
    899   delegate1.ResetCounts();
    900   delegate2.ResetCounts();
    901 
    902   // Events now go to w2.
    903   ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 0, getTime());
    904   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move);
    905   EXPECT_EQ(0, delegate1.gesture_event_count());
    906   EXPECT_EQ(0, delegate1.touch_event_count());
    907   EXPECT_EQ(0, delegate2.gesture_event_count());
    908   EXPECT_EQ(1, delegate2.touch_event_count());
    909 
    910   ui::TouchEvent release(
    911       ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 0, getTime());
    912   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release);
    913   EXPECT_EQ(0, delegate1.gesture_event_count());
    914   EXPECT_EQ(0, delegate2.gesture_event_count());
    915 
    916   // A new press is captured by w2.
    917   ui::TouchEvent press2(
    918       ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 0, getTime());
    919   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2);
    920   EXPECT_EQ(0, delegate1.gesture_event_count());
    921   // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN.
    922   EXPECT_EQ(2, delegate2.gesture_event_count());
    923   delegate1.ResetCounts();
    924   delegate2.ResetCounts();
    925 
    926   // And releasing capture changes nothing.
    927   w2->ReleaseCapture();
    928   EXPECT_EQ(0, delegate1.gesture_event_count());
    929   EXPECT_EQ(0, delegate1.touch_event_count());
    930   EXPECT_EQ(0, delegate2.gesture_event_count());
    931   EXPECT_EQ(0, delegate2.touch_event_count());
    932 }
    933 
    934 TEST_F(WindowTest, TouchCaptureDoesntCancelCapturedTouches) {
    935   CaptureWindowDelegateImpl delegate;
    936   scoped_ptr<Window> window(CreateTestWindowWithDelegate(
    937       &delegate, 0, gfx::Rect(0, 0, 50, 50), root_window()));
    938 
    939   ui::TouchEvent press(
    940       ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 0, getTime());
    941   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press);
    942 
    943   // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN.
    944   EXPECT_EQ(2, delegate.gesture_event_count());
    945   EXPECT_EQ(1, delegate.touch_event_count());
    946   delegate.ResetCounts();
    947 
    948   window->SetCapture();
    949   EXPECT_EQ(0, delegate.gesture_event_count());
    950   EXPECT_EQ(0, delegate.touch_event_count());
    951   delegate.ResetCounts();
    952 
    953   // On move We will get TOUCH_MOVED, GESTURE_TAP_CANCEL,
    954   // GESTURE_SCROLL_START and GESTURE_SCROLL_UPDATE.
    955   ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 0, getTime());
    956   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move);
    957   EXPECT_EQ(1, delegate.touch_event_count());
    958   EXPECT_EQ(3, delegate.gesture_event_count());
    959   delegate.ResetCounts();
    960 
    961   // Release capture shouldn't change anything.
    962   window->ReleaseCapture();
    963   EXPECT_EQ(0, delegate.touch_event_count());
    964   EXPECT_EQ(0, delegate.gesture_event_count());
    965   delegate.ResetCounts();
    966 
    967   // On move we still get TOUCH_MOVED and GESTURE_SCROLL_UPDATE.
    968   ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(10, 30), 0, getTime());
    969   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move2);
    970   EXPECT_EQ(1, delegate.touch_event_count());
    971   EXPECT_EQ(1, delegate.gesture_event_count());
    972   delegate.ResetCounts();
    973 
    974   // And on release we get TOUCH_RELEASED, GESTURE_SCROLL_END, GESTURE_END
    975   ui::TouchEvent release(
    976       ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 0, getTime());
    977   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release);
    978   EXPECT_EQ(1, delegate.touch_event_count());
    979   EXPECT_EQ(2, delegate.gesture_event_count());
    980 }
    981 
    982 
    983 // Assertions around SetCapture() and touch/gestures.
    984 TEST_F(WindowTest, TransferCaptureTouchEvents) {
    985   // Touch on |w1|.
    986   CaptureWindowDelegateImpl d1;
    987   scoped_ptr<Window> w1(CreateTestWindowWithDelegate(
    988       &d1, 0, gfx::Rect(0, 0, 20, 20), root_window()));
    989   ui::TouchEvent p1(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 0, getTime());
    990   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&p1);
    991   // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN.
    992   EXPECT_EQ(1, d1.touch_event_count());
    993   EXPECT_EQ(2, d1.gesture_event_count());
    994   d1.ResetCounts();
    995 
    996   // Touch on |w2| with a different id.
    997   CaptureWindowDelegateImpl d2;
    998   scoped_ptr<Window> w2(CreateTestWindowWithDelegate(
    999       &d2, 0, gfx::Rect(40, 0, 40, 20), root_window()));
   1000   ui::TouchEvent p2(ui::ET_TOUCH_PRESSED, gfx::Point(41, 10), 1, getTime());
   1001   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&p2);
   1002   EXPECT_EQ(0, d1.touch_event_count());
   1003   EXPECT_EQ(0, d1.gesture_event_count());
   1004   // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN for new target window.
   1005   EXPECT_EQ(1, d2.touch_event_count());
   1006   EXPECT_EQ(2, d2.gesture_event_count());
   1007   d1.ResetCounts();
   1008   d2.ResetCounts();
   1009 
   1010   // Set capture on |w2|, this should send a cancel (TAP_CANCEL, END) to |w1|
   1011   // but not |w2|.
   1012   w2->SetCapture();
   1013   EXPECT_EQ(1, d1.touch_event_count());
   1014   EXPECT_EQ(2, d1.gesture_event_count());
   1015   EXPECT_EQ(0, d2.touch_event_count());
   1016   EXPECT_EQ(0, d2.gesture_event_count());
   1017   d1.ResetCounts();
   1018   d2.ResetCounts();
   1019 
   1020   CaptureWindowDelegateImpl d3;
   1021   scoped_ptr<Window> w3(CreateTestWindowWithDelegate(
   1022       &d3, 0, gfx::Rect(0, 0, 100, 101), root_window()));
   1023   // Set capture on w3. No new events should be received.
   1024   // Note this difference in behavior between the first and second capture
   1025   // is confusing and error prone.  http://crbug.com/236930
   1026   w3->SetCapture();
   1027   EXPECT_EQ(0, d1.touch_event_count());
   1028   EXPECT_EQ(0, d1.gesture_event_count());
   1029   EXPECT_EQ(0, d2.touch_event_count());
   1030   EXPECT_EQ(0, d2.gesture_event_count());
   1031   EXPECT_EQ(0, d3.touch_event_count());
   1032   EXPECT_EQ(0, d3.gesture_event_count());
   1033 
   1034   // Move touch id originally associated with |w2|. Since capture was transfered
   1035   // from 2 to 3 only |w3| should get the event.
   1036   ui::TouchEvent m3(ui::ET_TOUCH_MOVED, gfx::Point(110, 105), 1, getTime());
   1037   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&m3);
   1038   EXPECT_EQ(0, d1.touch_event_count());
   1039   EXPECT_EQ(0, d1.gesture_event_count());
   1040   EXPECT_EQ(0, d2.touch_event_count());
   1041   EXPECT_EQ(0, d2.gesture_event_count());
   1042   // |w3| gets a TOUCH_MOVE, TAP_CANCEL and two scroll related events.
   1043   EXPECT_EQ(1, d3.touch_event_count());
   1044   EXPECT_EQ(3, d3.gesture_event_count());
   1045   d1.ResetCounts();
   1046   d2.ResetCounts();
   1047   d3.ResetCounts();
   1048 
   1049   // When we release capture, no touches are canceled.
   1050   w3->ReleaseCapture();
   1051   EXPECT_EQ(0, d1.touch_event_count());
   1052   EXPECT_EQ(0, d1.gesture_event_count());
   1053   EXPECT_EQ(0, d2.touch_event_count());
   1054   EXPECT_EQ(0, d2.gesture_event_count());
   1055   EXPECT_EQ(0, d3.touch_event_count());
   1056   EXPECT_EQ(0, d3.gesture_event_count());
   1057 
   1058   // And when we move the touch again, |w3| still gets the events.
   1059   ui::TouchEvent m4(ui::ET_TOUCH_MOVED, gfx::Point(120, 105), 1, getTime());
   1060   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&m4);
   1061   EXPECT_EQ(0, d1.touch_event_count());
   1062   EXPECT_EQ(0, d1.gesture_event_count());
   1063   EXPECT_EQ(0, d2.touch_event_count());
   1064   EXPECT_EQ(0, d2.gesture_event_count());
   1065   EXPECT_EQ(1, d3.touch_event_count());
   1066   EXPECT_EQ(1, d3.gesture_event_count());
   1067   d1.ResetCounts();
   1068   d2.ResetCounts();
   1069   d3.ResetCounts();
   1070 }
   1071 
   1072 // Changes capture while capture is already ongoing.
   1073 TEST_F(WindowTest, ChangeCaptureWhileMouseDown) {
   1074   CaptureWindowDelegateImpl delegate;
   1075   scoped_ptr<Window> window(CreateTestWindowWithDelegate(
   1076       &delegate, 0, gfx::Rect(0, 0, 20, 20), root_window()));
   1077   CaptureWindowDelegateImpl delegate2;
   1078   scoped_ptr<Window> w2(CreateTestWindowWithDelegate(
   1079       &delegate2, 0, gfx::Rect(20, 20, 20, 20), root_window()));
   1080 
   1081   // Execute the scheduled draws so that mouse events are not
   1082   // aggregated.
   1083   RunAllPendingInMessageLoop();
   1084 
   1085   EXPECT_FALSE(window->HasCapture());
   1086 
   1087   // Do a capture.
   1088   delegate.ResetCounts();
   1089   window->SetCapture();
   1090   EXPECT_TRUE(window->HasCapture());
   1091   EXPECT_EQ(0, delegate.capture_lost_count());
   1092   EXPECT_EQ(0, delegate.capture_changed_event_count());
   1093   EventGenerator generator(root_window(), gfx::Point(50, 50));
   1094   generator.PressLeftButton();
   1095   EXPECT_EQ(0, delegate.capture_lost_count());
   1096   EXPECT_EQ(0, delegate.capture_changed_event_count());
   1097   EXPECT_EQ(1, delegate.mouse_event_count());
   1098 
   1099   // Set capture to |w2|, should implicitly unset capture for |window|.
   1100   delegate.ResetCounts();
   1101   delegate2.ResetCounts();
   1102   w2->SetCapture();
   1103 
   1104   generator.MoveMouseTo(gfx::Point(40, 40), 2);
   1105   EXPECT_EQ(1, delegate.capture_lost_count());
   1106   EXPECT_EQ(1, delegate.capture_changed_event_count());
   1107   EXPECT_EQ(1, delegate.mouse_event_count());
   1108   EXPECT_EQ(2, delegate2.mouse_event_count());
   1109 }
   1110 
   1111 // Verifies capture is reset when a window is destroyed.
   1112 TEST_F(WindowTest, ReleaseCaptureOnDestroy) {
   1113   CaptureWindowDelegateImpl delegate;
   1114   scoped_ptr<Window> window(CreateTestWindowWithDelegate(
   1115       &delegate, 0, gfx::Rect(0, 0, 20, 20), root_window()));
   1116   EXPECT_FALSE(window->HasCapture());
   1117 
   1118   // Do a capture.
   1119   window->SetCapture();
   1120   EXPECT_TRUE(window->HasCapture());
   1121 
   1122   // Destroy the window.
   1123   window.reset();
   1124 
   1125   // Make sure the root window doesn't reference the window anymore.
   1126   EXPECT_EQ(NULL, dispatcher()->mouse_pressed_handler());
   1127   EXPECT_EQ(NULL, aura::client::GetCaptureWindow(root_window()));
   1128 }
   1129 
   1130 TEST_F(WindowTest, GetBoundsInRootWindow) {
   1131   scoped_ptr<Window> viewport(CreateTestWindowWithBounds(
   1132       gfx::Rect(0, 0, 300, 300), root_window()));
   1133   scoped_ptr<Window> child(CreateTestWindowWithBounds(
   1134       gfx::Rect(0, 0, 100, 100), viewport.get()));
   1135   // Sanity check.
   1136   EXPECT_EQ("0,0 100x100", child->GetBoundsInRootWindow().ToString());
   1137 
   1138   // The |child| window's screen bounds should move along with the |viewport|.
   1139   viewport->SetBounds(gfx::Rect(-100, -100, 300, 300));
   1140   EXPECT_EQ("-100,-100 100x100", child->GetBoundsInRootWindow().ToString());
   1141 
   1142   // The |child| window is moved to the 0,0 in screen coordinates.
   1143   // |GetBoundsInRootWindow()| should return 0,0.
   1144   child->SetBounds(gfx::Rect(100, 100, 100, 100));
   1145   EXPECT_EQ("0,0 100x100", child->GetBoundsInRootWindow().ToString());
   1146 }
   1147 
   1148 class MouseEnterExitWindowDelegate : public TestWindowDelegate {
   1149  public:
   1150   MouseEnterExitWindowDelegate() : entered_(false), exited_(false) {}
   1151 
   1152   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
   1153     switch (event->type()) {
   1154       case ui::ET_MOUSE_ENTERED:
   1155         EXPECT_TRUE(event->flags() & ui::EF_IS_SYNTHESIZED);
   1156         entered_ = true;
   1157         break;
   1158       case ui::ET_MOUSE_EXITED:
   1159         EXPECT_TRUE(event->flags() & ui::EF_IS_SYNTHESIZED);
   1160         exited_ = true;
   1161         break;
   1162       default:
   1163         break;
   1164     }
   1165   }
   1166 
   1167   bool entered() const { return entered_; }
   1168   bool exited() const { return exited_; }
   1169 
   1170   // Clear the entered / exited states.
   1171   void ResetExpectations() {
   1172     entered_ = false;
   1173     exited_ = false;
   1174   }
   1175 
   1176  private:
   1177   bool entered_;
   1178   bool exited_;
   1179 
   1180   DISALLOW_COPY_AND_ASSIGN(MouseEnterExitWindowDelegate);
   1181 };
   1182 
   1183 
   1184 // Verifies that the WindowDelegate receives MouseExit and MouseEnter events for
   1185 // mouse transitions from window to window.
   1186 TEST_F(WindowTest, MouseEnterExit) {
   1187   MouseEnterExitWindowDelegate d1;
   1188   scoped_ptr<Window> w1(
   1189       CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50),
   1190                                    root_window()));
   1191   MouseEnterExitWindowDelegate d2;
   1192   scoped_ptr<Window> w2(
   1193       CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(70, 70, 50, 50),
   1194                                    root_window()));
   1195 
   1196   test::EventGenerator generator(root_window());
   1197   generator.MoveMouseToCenterOf(w1.get());
   1198   EXPECT_TRUE(d1.entered());
   1199   EXPECT_FALSE(d1.exited());
   1200   EXPECT_FALSE(d2.entered());
   1201   EXPECT_FALSE(d2.exited());
   1202 
   1203   generator.MoveMouseToCenterOf(w2.get());
   1204   EXPECT_TRUE(d1.entered());
   1205   EXPECT_TRUE(d1.exited());
   1206   EXPECT_TRUE(d2.entered());
   1207   EXPECT_FALSE(d2.exited());
   1208 }
   1209 
   1210 // Verifies that the WindowDelegate receives MouseExit from ET_MOUSE_EXITED.
   1211 TEST_F(WindowTest, RootWindowHostExit) {
   1212   MouseEnterExitWindowDelegate d1;
   1213   scoped_ptr<Window> w1(
   1214       CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50),
   1215                                    root_window()));
   1216 
   1217   test::EventGenerator generator(root_window());
   1218   generator.MoveMouseToCenterOf(w1.get());
   1219   EXPECT_TRUE(d1.entered());
   1220   EXPECT_FALSE(d1.exited());
   1221   d1.ResetExpectations();
   1222 
   1223   ui::MouseEvent exit_event(
   1224       ui::ET_MOUSE_EXITED, gfx::Point(), gfx::Point(), 0);
   1225   dispatcher()->AsRootWindowHostDelegate()->OnHostMouseEvent(&exit_event);
   1226   EXPECT_FALSE(d1.entered());
   1227   EXPECT_TRUE(d1.exited());
   1228 }
   1229 
   1230 // Verifies that the WindowDelegate receives MouseExit and MouseEnter events for
   1231 // mouse transitions from window to window, even if the entered window sets
   1232 // and releases capture.
   1233 TEST_F(WindowTest, MouseEnterExitWithClick) {
   1234   MouseEnterExitWindowDelegate d1;
   1235   scoped_ptr<Window> w1(
   1236       CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50),
   1237                                    root_window()));
   1238   MouseEnterExitWindowDelegate d2;
   1239   scoped_ptr<Window> w2(
   1240       CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(70, 70, 50, 50),
   1241                                    root_window()));
   1242 
   1243   test::EventGenerator generator(root_window());
   1244   generator.MoveMouseToCenterOf(w1.get());
   1245   EXPECT_TRUE(d1.entered());
   1246   EXPECT_FALSE(d1.exited());
   1247   EXPECT_FALSE(d2.entered());
   1248   EXPECT_FALSE(d2.exited());
   1249 
   1250   // Emmulate what Views does on a click by grabbing and releasing capture.
   1251   generator.PressLeftButton();
   1252   w1->SetCapture();
   1253   w1->ReleaseCapture();
   1254   generator.ReleaseLeftButton();
   1255 
   1256   generator.MoveMouseToCenterOf(w2.get());
   1257   EXPECT_TRUE(d1.entered());
   1258   EXPECT_TRUE(d1.exited());
   1259   EXPECT_TRUE(d2.entered());
   1260   EXPECT_FALSE(d2.exited());
   1261 }
   1262 
   1263 TEST_F(WindowTest, MouseEnterExitWhenDeleteWithCapture) {
   1264   MouseEnterExitWindowDelegate delegate;
   1265   scoped_ptr<Window> window(
   1266       CreateTestWindowWithDelegate(&delegate, 1, gfx::Rect(10, 10, 50, 50),
   1267                                    root_window()));
   1268 
   1269   test::EventGenerator generator(root_window());
   1270   generator.MoveMouseToCenterOf(window.get());
   1271   EXPECT_TRUE(delegate.entered());
   1272   EXPECT_FALSE(delegate.exited());
   1273 
   1274   // Emmulate what Views does on a click by grabbing and releasing capture.
   1275   generator.PressLeftButton();
   1276   window->SetCapture();
   1277 
   1278   delegate.ResetExpectations();
   1279   generator.MoveMouseTo(0, 0);
   1280   EXPECT_FALSE(delegate.entered());
   1281   EXPECT_FALSE(delegate.exited());
   1282 
   1283   delegate.ResetExpectations();
   1284   window.reset();
   1285   EXPECT_FALSE(delegate.entered());
   1286   EXPECT_FALSE(delegate.exited());
   1287 }
   1288 
   1289 // Verifies that enter / exits are sent if windows appear and are deleted
   1290 // under the current mouse position..
   1291 TEST_F(WindowTest, MouseEnterExitWithDelete) {
   1292   MouseEnterExitWindowDelegate d1;
   1293   scoped_ptr<Window> w1(
   1294       CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50),
   1295                                    root_window()));
   1296 
   1297   test::EventGenerator generator(root_window());
   1298   generator.MoveMouseToCenterOf(w1.get());
   1299   EXPECT_TRUE(d1.entered());
   1300   EXPECT_FALSE(d1.exited());
   1301 
   1302   MouseEnterExitWindowDelegate d2;
   1303   {
   1304     scoped_ptr<Window> w2(
   1305         CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(10, 10, 50, 50),
   1306                                      root_window()));
   1307     // Enters / exits can be send asynchronously.
   1308     RunAllPendingInMessageLoop();
   1309     EXPECT_TRUE(d1.entered());
   1310     EXPECT_TRUE(d1.exited());
   1311     EXPECT_TRUE(d2.entered());
   1312     EXPECT_FALSE(d2.exited());
   1313     d1.ResetExpectations();
   1314   }
   1315   // Enters / exits can be send asynchronously.
   1316   RunAllPendingInMessageLoop();
   1317   EXPECT_TRUE(d2.exited());
   1318   EXPECT_TRUE(d1.entered());
   1319 }
   1320 
   1321 // Verifies that enter / exits are sent if windows appear and are hidden
   1322 // under the current mouse position..
   1323 TEST_F(WindowTest, MouseEnterExitWithHide) {
   1324   MouseEnterExitWindowDelegate d1;
   1325   scoped_ptr<Window> w1(
   1326       CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50),
   1327                                    root_window()));
   1328 
   1329   test::EventGenerator generator(root_window());
   1330   generator.MoveMouseToCenterOf(w1.get());
   1331   EXPECT_TRUE(d1.entered());
   1332   EXPECT_FALSE(d1.exited());
   1333 
   1334   MouseEnterExitWindowDelegate d2;
   1335   scoped_ptr<Window> w2(
   1336       CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(10, 10, 50, 50),
   1337                                    root_window()));
   1338   // Enters / exits can be send asynchronously.
   1339   RunAllPendingInMessageLoop();
   1340   EXPECT_TRUE(d1.entered());
   1341   EXPECT_TRUE(d1.exited());
   1342   EXPECT_TRUE(d2.entered());
   1343   EXPECT_FALSE(d2.exited());
   1344 
   1345   d1.ResetExpectations();
   1346   w2->Hide();
   1347   // Enters / exits can be send asynchronously.
   1348   RunAllPendingInMessageLoop();
   1349   EXPECT_TRUE(d2.exited());
   1350   EXPECT_TRUE(d1.entered());
   1351 }
   1352 
   1353 TEST_F(WindowTest, MouseEnterExitWithParentHide) {
   1354   MouseEnterExitWindowDelegate d1;
   1355   scoped_ptr<Window> w1(
   1356       CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50),
   1357                                    root_window()));
   1358   MouseEnterExitWindowDelegate d2;
   1359   Window* w2 = CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(10, 10, 50, 50),
   1360                                             w1.get());
   1361   test::EventGenerator generator(root_window());
   1362   generator.MoveMouseToCenterOf(w2);
   1363   // Enters / exits can be send asynchronously.
   1364   RunAllPendingInMessageLoop();
   1365   EXPECT_TRUE(d2.entered());
   1366   EXPECT_FALSE(d2.exited());
   1367 
   1368   d2.ResetExpectations();
   1369   w1->Hide();
   1370   RunAllPendingInMessageLoop();
   1371   EXPECT_FALSE(d2.entered());
   1372   EXPECT_TRUE(d2.exited());
   1373 
   1374   w1.reset();
   1375 }
   1376 
   1377 TEST_F(WindowTest, MouseEnterExitWithParentDelete) {
   1378   MouseEnterExitWindowDelegate d1;
   1379   scoped_ptr<Window> w1(
   1380       CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50),
   1381                                    root_window()));
   1382   MouseEnterExitWindowDelegate d2;
   1383   Window* w2 = CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(10, 10, 50, 50),
   1384                                             w1.get());
   1385   test::EventGenerator generator(root_window());
   1386   generator.MoveMouseToCenterOf(w2);
   1387 
   1388   // Enters / exits can be send asynchronously.
   1389   RunAllPendingInMessageLoop();
   1390   EXPECT_TRUE(d2.entered());
   1391   EXPECT_FALSE(d2.exited());
   1392 
   1393   d2.ResetExpectations();
   1394   w1.reset();
   1395   RunAllPendingInMessageLoop();
   1396   EXPECT_FALSE(d2.entered());
   1397   EXPECT_TRUE(d2.exited());
   1398 }
   1399 
   1400 // Creates a window with a delegate (w111) that can handle events at a lower
   1401 // z-index than a window without a delegate (w12). w12 is sized to fill the
   1402 // entire bounds of the container. This test verifies that
   1403 // GetEventHandlerForPoint() skips w12 even though its bounds contain the event,
   1404 // because it has no children that can handle the event and it has no delegate
   1405 // allowing it to handle the event itself.
   1406 TEST_F(WindowTest, GetEventHandlerForPoint_NoDelegate) {
   1407   TestWindowDelegate d111;
   1408   scoped_ptr<Window> w1(CreateTestWindowWithDelegate(NULL, 1,
   1409       gfx::Rect(0, 0, 500, 500), root_window()));
   1410   scoped_ptr<Window> w11(CreateTestWindowWithDelegate(NULL, 11,
   1411       gfx::Rect(0, 0, 500, 500), w1.get()));
   1412   scoped_ptr<Window> w111(CreateTestWindowWithDelegate(&d111, 111,
   1413       gfx::Rect(50, 50, 450, 450), w11.get()));
   1414   scoped_ptr<Window> w12(CreateTestWindowWithDelegate(NULL, 12,
   1415       gfx::Rect(0, 0, 500, 500), w1.get()));
   1416 
   1417   gfx::Point target_point = w111->bounds().CenterPoint();
   1418   EXPECT_EQ(w111.get(), w1->GetEventHandlerForPoint(target_point));
   1419 }
   1420 
   1421 class VisibilityWindowDelegate : public TestWindowDelegate {
   1422  public:
   1423   VisibilityWindowDelegate()
   1424       : shown_(0),
   1425         hidden_(0) {
   1426   }
   1427 
   1428   int shown() const { return shown_; }
   1429   int hidden() const { return hidden_; }
   1430   void Clear() {
   1431     shown_ = 0;
   1432     hidden_ = 0;
   1433   }
   1434 
   1435   virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {
   1436     if (visible)
   1437       shown_++;
   1438     else
   1439       hidden_++;
   1440   }
   1441 
   1442  private:
   1443   int shown_;
   1444   int hidden_;
   1445 
   1446   DISALLOW_COPY_AND_ASSIGN(VisibilityWindowDelegate);
   1447 };
   1448 
   1449 // Verifies show/hide propagate correctly to children and the layer.
   1450 TEST_F(WindowTest, Visibility) {
   1451   VisibilityWindowDelegate d;
   1452   VisibilityWindowDelegate d2;
   1453   scoped_ptr<Window> w1(CreateTestWindowWithDelegate(&d, 1, gfx::Rect(),
   1454                                                      root_window()));
   1455   scoped_ptr<Window> w2(
   1456       CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(),  w1.get()));
   1457   scoped_ptr<Window> w3(CreateTestWindowWithId(3, w2.get()));
   1458 
   1459   // Create shows all the windows.
   1460   EXPECT_TRUE(w1->IsVisible());
   1461   EXPECT_TRUE(w2->IsVisible());
   1462   EXPECT_TRUE(w3->IsVisible());
   1463   EXPECT_EQ(1, d.shown());
   1464 
   1465   d.Clear();
   1466   w1->Hide();
   1467   EXPECT_FALSE(w1->IsVisible());
   1468   EXPECT_FALSE(w2->IsVisible());
   1469   EXPECT_FALSE(w3->IsVisible());
   1470   EXPECT_EQ(1, d.hidden());
   1471   EXPECT_EQ(0, d.shown());
   1472 
   1473   w2->Show();
   1474   EXPECT_FALSE(w1->IsVisible());
   1475   EXPECT_FALSE(w2->IsVisible());
   1476   EXPECT_FALSE(w3->IsVisible());
   1477 
   1478   w3->Hide();
   1479   EXPECT_FALSE(w1->IsVisible());
   1480   EXPECT_FALSE(w2->IsVisible());
   1481   EXPECT_FALSE(w3->IsVisible());
   1482 
   1483   d.Clear();
   1484   w1->Show();
   1485   EXPECT_TRUE(w1->IsVisible());
   1486   EXPECT_TRUE(w2->IsVisible());
   1487   EXPECT_FALSE(w3->IsVisible());
   1488   EXPECT_EQ(0, d.hidden());
   1489   EXPECT_EQ(1, d.shown());
   1490 
   1491   w3->Show();
   1492   EXPECT_TRUE(w1->IsVisible());
   1493   EXPECT_TRUE(w2->IsVisible());
   1494   EXPECT_TRUE(w3->IsVisible());
   1495 
   1496   // Verify that if an ancestor isn't visible and we change the visibility of a
   1497   // child window that OnChildWindowVisibilityChanged() is still invoked.
   1498   w1->Hide();
   1499   d2.Clear();
   1500   w2->Hide();
   1501   EXPECT_EQ(1, d2.hidden());
   1502   EXPECT_EQ(0, d2.shown());
   1503   d2.Clear();
   1504   w2->Show();
   1505   EXPECT_EQ(0, d2.hidden());
   1506   EXPECT_EQ(1, d2.shown());
   1507 }
   1508 
   1509 TEST_F(WindowTest, IgnoreEventsTest) {
   1510   TestWindowDelegate d11;
   1511   TestWindowDelegate d12;
   1512   TestWindowDelegate d111;
   1513   TestWindowDelegate d121;
   1514   scoped_ptr<Window> w1(CreateTestWindowWithDelegate(NULL, 1,
   1515       gfx::Rect(0, 0, 500, 500), root_window()));
   1516   scoped_ptr<Window> w11(CreateTestWindowWithDelegate(&d11, 11,
   1517       gfx::Rect(0, 0, 500, 500), w1.get()));
   1518   scoped_ptr<Window> w111(CreateTestWindowWithDelegate(&d111, 111,
   1519       gfx::Rect(50, 50, 450, 450), w11.get()));
   1520   scoped_ptr<Window> w12(CreateTestWindowWithDelegate(&d12, 12,
   1521       gfx::Rect(0, 0, 500, 500), w1.get()));
   1522   scoped_ptr<Window> w121(CreateTestWindowWithDelegate(&d121, 121,
   1523       gfx::Rect(150, 150, 50, 50), w12.get()));
   1524 
   1525   EXPECT_EQ(w12.get(), w1->GetEventHandlerForPoint(gfx::Point(10, 10)));
   1526   w12->set_ignore_events(true);
   1527   EXPECT_EQ(w11.get(), w1->GetEventHandlerForPoint(gfx::Point(10, 10)));
   1528   w12->set_ignore_events(false);
   1529 
   1530   EXPECT_EQ(w121.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
   1531   w121->set_ignore_events(true);
   1532   EXPECT_EQ(w12.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
   1533   w12->set_ignore_events(true);
   1534   EXPECT_EQ(w111.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
   1535   w111->set_ignore_events(true);
   1536   EXPECT_EQ(w11.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
   1537 }
   1538 
   1539 // Tests transformation on the root window.
   1540 TEST_F(WindowTest, Transform) {
   1541   gfx::Size size = dispatcher()->host()->GetBounds().size();
   1542   EXPECT_EQ(gfx::Rect(size),
   1543             gfx::Screen::GetScreenFor(root_window())->GetDisplayNearestPoint(
   1544                 gfx::Point()).bounds());
   1545 
   1546   // Rotate it clock-wise 90 degrees.
   1547   gfx::Transform transform;
   1548   transform.Translate(size.height(), 0);
   1549   transform.Rotate(90.0);
   1550   dispatcher()->SetTransform(transform);
   1551 
   1552   // The size should be the transformed size.
   1553   gfx::Size transformed_size(size.height(), size.width());
   1554   EXPECT_EQ(transformed_size.ToString(),
   1555             root_window()->bounds().size().ToString());
   1556   EXPECT_EQ(
   1557       gfx::Rect(transformed_size).ToString(),
   1558       gfx::Screen::GetScreenFor(root_window())->GetDisplayNearestPoint(
   1559           gfx::Point()).bounds().ToString());
   1560 
   1561   // Host size shouldn't change.
   1562   EXPECT_EQ(size.ToString(),
   1563             dispatcher()->host()->GetBounds().size().ToString());
   1564 }
   1565 
   1566 TEST_F(WindowTest, TransformGesture) {
   1567   gfx::Size size = dispatcher()->host()->GetBounds().size();
   1568 
   1569   scoped_ptr<GestureTrackPositionDelegate> delegate(
   1570       new GestureTrackPositionDelegate);
   1571   scoped_ptr<Window> window(CreateTestWindowWithDelegate(delegate.get(), -1234,
   1572       gfx::Rect(0, 0, 20, 20), root_window()));
   1573 
   1574   // Rotate the root-window clock-wise 90 degrees.
   1575   gfx::Transform transform;
   1576   transform.Translate(size.height(), 0.0);
   1577   transform.Rotate(90.0);
   1578   dispatcher()->SetTransform(transform);
   1579 
   1580   ui::TouchEvent press(
   1581       ui::ET_TOUCH_PRESSED, gfx::Point(size.height() - 10, 10), 0, getTime());
   1582   dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press);
   1583   EXPECT_EQ(gfx::Point(10, 10).ToString(), delegate->position().ToString());
   1584 }
   1585 
   1586 // Various assertions for transient children.
   1587 TEST_F(WindowTest, TransientChildren) {
   1588   scoped_ptr<Window> parent(CreateTestWindowWithId(0, root_window()));
   1589   scoped_ptr<Window> w1(CreateTestWindowWithId(1, parent.get()));
   1590   scoped_ptr<Window> w3(CreateTestWindowWithId(3, parent.get()));
   1591   Window* w2 = CreateTestWindowWithId(2, parent.get());
   1592   w1->AddTransientChild(w2);  // w2 is now owned by w1.
   1593   // Stack w1 at the top (end), this should force w2 to be last (on top of w1).
   1594   parent->StackChildAtTop(w1.get());
   1595   ASSERT_EQ(3u, parent->children().size());
   1596   EXPECT_EQ(w2, parent->children().back());
   1597 
   1598   // Destroy w1, which should also destroy w3 (since it's a transient child).
   1599   w1.reset();
   1600   w2 = NULL;
   1601   ASSERT_EQ(1u, parent->children().size());
   1602   EXPECT_EQ(w3.get(), parent->children()[0]);
   1603 
   1604   w1.reset(CreateTestWindowWithId(4, parent.get()));
   1605   w2 = CreateTestWindowWithId(5, w3.get());
   1606   w1->AddTransientChild(w2);
   1607   parent->StackChildAtTop(w3.get());
   1608   // Stack w1 at the top (end), this shouldn't affect w2 since it has a
   1609   // different parent.
   1610   parent->StackChildAtTop(w1.get());
   1611   ASSERT_EQ(2u, parent->children().size());
   1612   EXPECT_EQ(w3.get(), parent->children()[0]);
   1613   EXPECT_EQ(w1.get(), parent->children()[1]);
   1614 
   1615   // Hiding parent should hide transient children.
   1616   EXPECT_TRUE(w2->IsVisible());
   1617   w1->Hide();
   1618   EXPECT_FALSE(w2->IsVisible());
   1619 }
   1620 
   1621 namespace {
   1622 DEFINE_WINDOW_PROPERTY_KEY(int, kIntKey, -2);
   1623 DEFINE_WINDOW_PROPERTY_KEY(const char*, kStringKey, "squeamish");
   1624 }
   1625 
   1626 TEST_F(WindowTest, Property) {
   1627   scoped_ptr<Window> w(CreateTestWindowWithId(0, root_window()));
   1628 
   1629   static const char native_prop_key[] = "fnord";
   1630 
   1631   // Non-existent properties should return the default values.
   1632   EXPECT_EQ(-2, w->GetProperty(kIntKey));
   1633   EXPECT_EQ(std::string("squeamish"), w->GetProperty(kStringKey));
   1634   EXPECT_EQ(NULL, w->GetNativeWindowProperty(native_prop_key));
   1635 
   1636   // A set property value should be returned again (even if it's the default
   1637   // value).
   1638   w->SetProperty(kIntKey, INT_MAX);
   1639   EXPECT_EQ(INT_MAX, w->GetProperty(kIntKey));
   1640   w->SetProperty(kIntKey, -2);
   1641   EXPECT_EQ(-2, w->GetProperty(kIntKey));
   1642   w->SetProperty(kIntKey, INT_MIN);
   1643   EXPECT_EQ(INT_MIN, w->GetProperty(kIntKey));
   1644 
   1645   w->SetProperty(kStringKey, static_cast<const char*>(NULL));
   1646   EXPECT_EQ(NULL, w->GetProperty(kStringKey));
   1647   w->SetProperty(kStringKey, "squeamish");
   1648   EXPECT_EQ(std::string("squeamish"), w->GetProperty(kStringKey));
   1649   w->SetProperty(kStringKey, "ossifrage");
   1650   EXPECT_EQ(std::string("ossifrage"), w->GetProperty(kStringKey));
   1651 
   1652   w->SetNativeWindowProperty(native_prop_key, &*w);
   1653   EXPECT_EQ(&*w, w->GetNativeWindowProperty(native_prop_key));
   1654   w->SetNativeWindowProperty(native_prop_key, NULL);
   1655   EXPECT_EQ(NULL, w->GetNativeWindowProperty(native_prop_key));
   1656 
   1657   // ClearProperty should restore the default value.
   1658   w->ClearProperty(kIntKey);
   1659   EXPECT_EQ(-2, w->GetProperty(kIntKey));
   1660   w->ClearProperty(kStringKey);
   1661   EXPECT_EQ(std::string("squeamish"), w->GetProperty(kStringKey));
   1662 }
   1663 
   1664 namespace {
   1665 
   1666 class TestProperty {
   1667  public:
   1668   TestProperty() {}
   1669   virtual ~TestProperty() {
   1670     last_deleted_ = this;
   1671   }
   1672   static TestProperty* last_deleted() { return last_deleted_; }
   1673 
   1674  private:
   1675   static TestProperty* last_deleted_;
   1676   DISALLOW_COPY_AND_ASSIGN(TestProperty);
   1677 };
   1678 
   1679 TestProperty* TestProperty::last_deleted_ = NULL;
   1680 
   1681 DEFINE_OWNED_WINDOW_PROPERTY_KEY(TestProperty, kOwnedKey, NULL);
   1682 
   1683 }  // namespace
   1684 
   1685 TEST_F(WindowTest, OwnedProperty) {
   1686   scoped_ptr<Window> w(CreateTestWindowWithId(0, root_window()));
   1687   EXPECT_EQ(NULL, w->GetProperty(kOwnedKey));
   1688   TestProperty* p1 = new TestProperty();
   1689   w->SetProperty(kOwnedKey, p1);
   1690   EXPECT_EQ(p1, w->GetProperty(kOwnedKey));
   1691   EXPECT_EQ(NULL, TestProperty::last_deleted());
   1692 
   1693   TestProperty* p2 = new TestProperty();
   1694   w->SetProperty(kOwnedKey, p2);
   1695   EXPECT_EQ(p2, w->GetProperty(kOwnedKey));
   1696   EXPECT_EQ(p1, TestProperty::last_deleted());
   1697 
   1698   w->ClearProperty(kOwnedKey);
   1699   EXPECT_EQ(NULL, w->GetProperty(kOwnedKey));
   1700   EXPECT_EQ(p2, TestProperty::last_deleted());
   1701 
   1702   TestProperty* p3 = new TestProperty();
   1703   w->SetProperty(kOwnedKey, p3);
   1704   EXPECT_EQ(p3, w->GetProperty(kOwnedKey));
   1705   EXPECT_EQ(p2, TestProperty::last_deleted());
   1706   w.reset();
   1707   EXPECT_EQ(p3, TestProperty::last_deleted());
   1708 }
   1709 
   1710 TEST_F(WindowTest, SetBoundsInternalShouldCheckTargetBounds) {
   1711   // We cannot short-circuit animations in this test.
   1712   ui::ScopedAnimationDurationScaleMode normal_duration_mode(
   1713       ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
   1714 
   1715   scoped_ptr<Window> w1(
   1716       CreateTestWindowWithBounds(gfx::Rect(0, 0, 100, 100), root_window()));
   1717 
   1718   EXPECT_FALSE(!w1->layer());
   1719   w1->layer()->GetAnimator()->set_disable_timer_for_test(true);
   1720   gfx::AnimationContainerElement* element = w1->layer()->GetAnimator();
   1721 
   1722   EXPECT_EQ("0,0 100x100", w1->bounds().ToString());
   1723   EXPECT_EQ("0,0 100x100", w1->layer()->GetTargetBounds().ToString());
   1724 
   1725   // Animate to a different position.
   1726   {
   1727     ui::ScopedLayerAnimationSettings settings(w1->layer()->GetAnimator());
   1728     w1->SetBounds(gfx::Rect(100, 100, 100, 100));
   1729   }
   1730 
   1731   EXPECT_EQ("0,0 100x100", w1->bounds().ToString());
   1732   EXPECT_EQ("100,100 100x100", w1->layer()->GetTargetBounds().ToString());
   1733 
   1734   // Animate back to the first position. The animation hasn't started yet, so
   1735   // the current bounds are still (0, 0, 100, 100), but the target bounds are
   1736   // (100, 100, 100, 100). If we step the animator ahead, we should find that
   1737   // we're at (0, 0, 100, 100). That is, the second animation should be applied.
   1738   {
   1739     ui::ScopedLayerAnimationSettings settings(w1->layer()->GetAnimator());
   1740     w1->SetBounds(gfx::Rect(0, 0, 100, 100));
   1741   }
   1742 
   1743   EXPECT_EQ("0,0 100x100", w1->bounds().ToString());
   1744   EXPECT_EQ("0,0 100x100", w1->layer()->GetTargetBounds().ToString());
   1745 
   1746   // Confirm that the target bounds are reached.
   1747   base::TimeTicks start_time =
   1748       w1->layer()->GetAnimator()->last_step_time();
   1749 
   1750   element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
   1751 
   1752   EXPECT_EQ("0,0 100x100", w1->bounds().ToString());
   1753 }
   1754 
   1755 
   1756 typedef std::pair<const void*, intptr_t> PropertyChangeInfo;
   1757 
   1758 class WindowObserverTest : public WindowTest,
   1759                            public WindowObserver {
   1760  public:
   1761   struct VisibilityInfo {
   1762     bool window_visible;
   1763     bool visible_param;
   1764   };
   1765 
   1766   WindowObserverTest()
   1767       : added_count_(0),
   1768         removed_count_(0),
   1769         destroyed_count_(0),
   1770         old_property_value_(-3) {
   1771   }
   1772 
   1773   virtual ~WindowObserverTest() {}
   1774 
   1775   const VisibilityInfo* GetVisibilityInfo() const {
   1776     return visibility_info_.get();
   1777   }
   1778 
   1779   void ResetVisibilityInfo() {
   1780     visibility_info_.reset();
   1781   }
   1782 
   1783   // Returns a description of the WindowObserver methods that have been invoked.
   1784   std::string WindowObserverCountStateAndClear() {
   1785     std::string result(
   1786         base::StringPrintf("added=%d removed=%d",
   1787         added_count_, removed_count_));
   1788     added_count_ = removed_count_ = 0;
   1789     return result;
   1790   }
   1791 
   1792   int DestroyedCountAndClear() {
   1793     int result = destroyed_count_;
   1794     destroyed_count_ = 0;
   1795     return result;
   1796   }
   1797 
   1798   // Return a tuple of the arguments passed in OnPropertyChanged callback.
   1799   PropertyChangeInfo PropertyChangeInfoAndClear() {
   1800     PropertyChangeInfo result(property_key_, old_property_value_);
   1801     property_key_ = NULL;
   1802     old_property_value_ = -3;
   1803     return result;
   1804   }
   1805 
   1806  private:
   1807   virtual void OnWindowAdded(Window* new_window) OVERRIDE {
   1808     added_count_++;
   1809   }
   1810 
   1811   virtual void OnWillRemoveWindow(Window* window) OVERRIDE {
   1812     removed_count_++;
   1813   }
   1814 
   1815   virtual void OnWindowVisibilityChanged(Window* window,
   1816                                          bool visible) OVERRIDE {
   1817     visibility_info_.reset(new VisibilityInfo);
   1818     visibility_info_->window_visible = window->IsVisible();
   1819     visibility_info_->visible_param = visible;
   1820   }
   1821 
   1822   virtual void OnWindowDestroyed(Window* window) OVERRIDE {
   1823     EXPECT_FALSE(window->parent());
   1824     destroyed_count_++;
   1825   }
   1826 
   1827   virtual void OnWindowPropertyChanged(Window* window,
   1828                                        const void* key,
   1829                                        intptr_t old) OVERRIDE {
   1830     property_key_ = key;
   1831     old_property_value_ = old;
   1832   }
   1833 
   1834   int added_count_;
   1835   int removed_count_;
   1836   int destroyed_count_;
   1837   scoped_ptr<VisibilityInfo> visibility_info_;
   1838   const void* property_key_;
   1839   intptr_t old_property_value_;
   1840 
   1841   DISALLOW_COPY_AND_ASSIGN(WindowObserverTest);
   1842 };
   1843 
   1844 // Various assertions for WindowObserver.
   1845 TEST_F(WindowObserverTest, WindowObserver) {
   1846   scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
   1847   w1->AddObserver(this);
   1848 
   1849   // Create a new window as a child of w1, our observer should be notified.
   1850   scoped_ptr<Window> w2(CreateTestWindowWithId(2, w1.get()));
   1851   EXPECT_EQ("added=1 removed=0", WindowObserverCountStateAndClear());
   1852 
   1853   // Delete w2, which should result in the remove notification.
   1854   w2.reset();
   1855   EXPECT_EQ("added=0 removed=1", WindowObserverCountStateAndClear());
   1856 
   1857   // Create a window that isn't parented to w1, we shouldn't get any
   1858   // notification.
   1859   scoped_ptr<Window> w3(CreateTestWindowWithId(3, root_window()));
   1860   EXPECT_EQ("added=0 removed=0", WindowObserverCountStateAndClear());
   1861 
   1862   // Similarly destroying w3 shouldn't notify us either.
   1863   w3.reset();
   1864   EXPECT_EQ("added=0 removed=0", WindowObserverCountStateAndClear());
   1865   w1->RemoveObserver(this);
   1866 }
   1867 
   1868 // Test if OnWindowVisibilityChagned is invoked with expected
   1869 // parameters.
   1870 TEST_F(WindowObserverTest, WindowVisibility) {
   1871   scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
   1872   scoped_ptr<Window> w2(CreateTestWindowWithId(1, w1.get()));
   1873   w2->AddObserver(this);
   1874 
   1875   // Hide should make the window invisible and the passed visible
   1876   // parameter is false.
   1877   w2->Hide();
   1878   EXPECT_FALSE(!GetVisibilityInfo());
   1879   EXPECT_FALSE(!GetVisibilityInfo());
   1880   if (!GetVisibilityInfo())
   1881     return;
   1882   EXPECT_FALSE(GetVisibilityInfo()->window_visible);
   1883   EXPECT_FALSE(GetVisibilityInfo()->visible_param);
   1884 
   1885   // If parent isn't visible, showing window won't make the window visible, but
   1886   // passed visible value must be true.
   1887   w1->Hide();
   1888   ResetVisibilityInfo();
   1889   EXPECT_TRUE(!GetVisibilityInfo());
   1890   w2->Show();
   1891   EXPECT_FALSE(!GetVisibilityInfo());
   1892   if (!GetVisibilityInfo())
   1893     return;
   1894   EXPECT_FALSE(GetVisibilityInfo()->window_visible);
   1895   EXPECT_TRUE(GetVisibilityInfo()->visible_param);
   1896 
   1897   // If parent is visible, showing window will make the window
   1898   // visible and the passed visible value is true.
   1899   w1->Show();
   1900   w2->Hide();
   1901   ResetVisibilityInfo();
   1902   w2->Show();
   1903   EXPECT_FALSE(!GetVisibilityInfo());
   1904   if (!GetVisibilityInfo())
   1905     return;
   1906   EXPECT_TRUE(GetVisibilityInfo()->window_visible);
   1907   EXPECT_TRUE(GetVisibilityInfo()->visible_param);
   1908 }
   1909 
   1910 // Test if OnWindowDestroyed is invoked as expected.
   1911 TEST_F(WindowObserverTest, WindowDestroyed) {
   1912   // Delete a window should fire a destroyed notification.
   1913   scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
   1914   w1->AddObserver(this);
   1915   w1.reset();
   1916   EXPECT_EQ(1, DestroyedCountAndClear());
   1917 
   1918   // Observe on child and delete parent window should fire a notification.
   1919   scoped_ptr<Window> parent(CreateTestWindowWithId(1, root_window()));
   1920   Window* child = CreateTestWindowWithId(1, parent.get());  // owned by parent
   1921   child->AddObserver(this);
   1922   parent.reset();
   1923   EXPECT_EQ(1, DestroyedCountAndClear());
   1924 }
   1925 
   1926 TEST_F(WindowObserverTest, PropertyChanged) {
   1927   // Setting property should fire a property change notification.
   1928   scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
   1929   w1->AddObserver(this);
   1930 
   1931   static const WindowProperty<int> prop = {-2};
   1932   static const char native_prop_key[] = "fnord";
   1933 
   1934   w1->SetProperty(&prop, 1);
   1935   EXPECT_EQ(PropertyChangeInfo(&prop, -2), PropertyChangeInfoAndClear());
   1936   w1->SetProperty(&prop, -2);
   1937   EXPECT_EQ(PropertyChangeInfo(&prop, 1), PropertyChangeInfoAndClear());
   1938   w1->SetProperty(&prop, 3);
   1939   EXPECT_EQ(PropertyChangeInfo(&prop, -2), PropertyChangeInfoAndClear());
   1940   w1->ClearProperty(&prop);
   1941   EXPECT_EQ(PropertyChangeInfo(&prop, 3), PropertyChangeInfoAndClear());
   1942 
   1943   w1->SetNativeWindowProperty(native_prop_key, &*w1);
   1944   EXPECT_EQ(PropertyChangeInfo(native_prop_key, 0),
   1945             PropertyChangeInfoAndClear());
   1946   w1->SetNativeWindowProperty(native_prop_key, NULL);
   1947   EXPECT_EQ(PropertyChangeInfo(native_prop_key,
   1948                                reinterpret_cast<intptr_t>(&*w1)),
   1949             PropertyChangeInfoAndClear());
   1950 
   1951   // Sanity check to see if |PropertyChangeInfoAndClear| really clears.
   1952   EXPECT_EQ(PropertyChangeInfo(
   1953       reinterpret_cast<const void*>(NULL), -3), PropertyChangeInfoAndClear());
   1954 }
   1955 
   1956 TEST_F(WindowTest, AcquireLayer) {
   1957   scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
   1958   scoped_ptr<Window> window2(CreateTestWindowWithId(2, root_window()));
   1959   ui::Layer* parent = window1->parent()->layer();
   1960   EXPECT_EQ(2U, parent->children().size());
   1961 
   1962   WindowTestApi window1_test_api(window1.get());
   1963   WindowTestApi window2_test_api(window2.get());
   1964 
   1965   EXPECT_TRUE(window1_test_api.OwnsLayer());
   1966   EXPECT_TRUE(window2_test_api.OwnsLayer());
   1967 
   1968   // After acquisition, window1 should not own its layer, but it should still
   1969   // be available to the window.
   1970   scoped_ptr<ui::Layer> window1_layer(window1->AcquireLayer());
   1971   EXPECT_FALSE(window1_test_api.OwnsLayer());
   1972   EXPECT_TRUE(window1_layer.get() == window1->layer());
   1973 
   1974   // Upon destruction, window1's layer should still be valid, and in the layer
   1975   // hierarchy, but window2's should be gone, and no longer in the hierarchy.
   1976   window1.reset();
   1977   window2.reset();
   1978 
   1979   // This should be set by the window's destructor.
   1980   EXPECT_TRUE(window1_layer->delegate() == NULL);
   1981   EXPECT_EQ(1U, parent->children().size());
   1982 }
   1983 
   1984 // Make sure that properties which should persist from the old layer to the new
   1985 // layer actually do.
   1986 TEST_F(WindowTest, RecreateLayer) {
   1987   // Set properties to non default values.
   1988   Window w(new ColorTestWindowDelegate(SK_ColorWHITE));
   1989   w.set_id(1);
   1990   w.Init(ui::LAYER_SOLID_COLOR);
   1991   w.SetBounds(gfx::Rect(0, 0, 100, 100));
   1992 
   1993   ui::Layer* layer = w.layer();
   1994   layer->set_scale_content(false);
   1995   layer->SetVisible(false);
   1996   layer->SetMasksToBounds(true);
   1997 
   1998   ui::Layer child_layer;
   1999   layer->Add(&child_layer);
   2000 
   2001   scoped_ptr<ui::Layer> old_layer(w.RecreateLayer());
   2002   layer = w.layer();
   2003   EXPECT_EQ(ui::LAYER_SOLID_COLOR, layer->type());
   2004   EXPECT_FALSE(layer->scale_content());
   2005   EXPECT_FALSE(layer->visible());
   2006   EXPECT_EQ(1u, layer->children().size());
   2007   EXPECT_TRUE(layer->GetMasksToBounds());
   2008 }
   2009 
   2010 // Verify that RecreateLayer() stacks the old layer above the newly creatd
   2011 // layer.
   2012 TEST_F(WindowTest, RecreateLayerZOrder) {
   2013   scoped_ptr<Window> w(
   2014       CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(0, 0, 100, 100),
   2015                        root_window()));
   2016   scoped_ptr<ui::Layer> old_layer(w->RecreateLayer());
   2017 
   2018   const std::vector<ui::Layer*>& child_layers =
   2019       root_window()->layer()->children();
   2020   ASSERT_EQ(2u, child_layers.size());
   2021   EXPECT_EQ(w->layer(), child_layers[0]);
   2022   EXPECT_EQ(old_layer.get(), child_layers[1]);
   2023 }
   2024 
   2025 // Ensure that acquiring a layer then recreating a layer does not crash
   2026 // and that RecreateLayer returns null.
   2027 TEST_F(WindowTest, AcquireThenRecreateLayer) {
   2028   scoped_ptr<Window> w(
   2029       CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(0, 0, 100, 100),
   2030                        root_window()));
   2031   scoped_ptr<ui::Layer>acquired_layer(w->AcquireLayer());
   2032   scoped_ptr<ui::Layer>doubly_acquired_layer(w->RecreateLayer());
   2033   EXPECT_EQ(NULL, doubly_acquired_layer.get());
   2034 
   2035   // Destroy window before layer gets destroyed.
   2036   w.reset();
   2037 }
   2038 
   2039 TEST_F(WindowTest, StackWindowAtBottomBelowWindowWhoseLayerHasNoDelegate) {
   2040   scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
   2041   window1->layer()->set_name("1");
   2042   scoped_ptr<Window> window2(CreateTestWindowWithId(2, root_window()));
   2043   window2->layer()->set_name("2");
   2044   scoped_ptr<Window> window3(CreateTestWindowWithId(3, root_window()));
   2045   window3->layer()->set_name("3");
   2046 
   2047   EXPECT_EQ("1 2 3", ChildWindowIDsAsString(root_window()));
   2048   EXPECT_EQ("1 2 3",
   2049             ui::test::ChildLayerNamesAsString(*root_window()->layer()));
   2050   window1->layer()->set_delegate(NULL);
   2051   root_window()->StackChildAtBottom(window3.get());
   2052 
   2053   // Window 3 should have moved to the bottom.
   2054   EXPECT_EQ("3 1 2", ChildWindowIDsAsString(root_window()));
   2055   EXPECT_EQ("3 1 2",
   2056             ui::test::ChildLayerNamesAsString(*root_window()->layer()));
   2057 }
   2058 
   2059 TEST_F(WindowTest, StackWindowsWhoseLayersHaveNoDelegate) {
   2060   scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
   2061   window1->layer()->set_name("1");
   2062   scoped_ptr<Window> window2(CreateTestWindowWithId(2, root_window()));
   2063   window2->layer()->set_name("2");
   2064   scoped_ptr<Window> window3(CreateTestWindowWithId(3, root_window()));
   2065   window3->layer()->set_name("3");
   2066 
   2067   // This brings |window1| (and its layer) to the front.
   2068   root_window()->StackChildAbove(window1.get(), window3.get());
   2069   EXPECT_EQ("2 3 1", ChildWindowIDsAsString(root_window()));
   2070   EXPECT_EQ("2 3 1",
   2071             ui::test::ChildLayerNamesAsString(*root_window()->layer()));
   2072 
   2073   // Since |window1| does not have a delegate, |window2| should not move in
   2074   // front of it, nor should its layer.
   2075   window1->layer()->set_delegate(NULL);
   2076   root_window()->StackChildAbove(window2.get(), window1.get());
   2077   EXPECT_EQ("3 2 1", ChildWindowIDsAsString(root_window()));
   2078   EXPECT_EQ("3 2 1",
   2079             ui::test::ChildLayerNamesAsString(*root_window()->layer()));
   2080 
   2081   // It should still be possible to stack |window3| immediately below |window1|.
   2082   root_window()->StackChildBelow(window3.get(), window1.get());
   2083   EXPECT_EQ("2 3 1", ChildWindowIDsAsString(root_window()));
   2084   EXPECT_EQ("2 3 1",
   2085             ui::test::ChildLayerNamesAsString(*root_window()->layer()));
   2086 
   2087   // Since neither |window3| nor |window1| have a delegate, |window2| should
   2088   // not move in front of either.
   2089   window3->layer()->set_delegate(NULL);
   2090   root_window()->StackChildBelow(window2.get(), window1.get());
   2091   EXPECT_EQ("2 3 1", ChildWindowIDsAsString(root_window()));
   2092   EXPECT_EQ("2 3 1",
   2093             ui::test::ChildLayerNamesAsString(*root_window()->layer()));
   2094 }
   2095 
   2096 TEST_F(WindowTest, StackTransientsWhoseLayersHaveNoDelegate) {
   2097   // Create a window with several transients, then a couple windows on top.
   2098   scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
   2099   scoped_ptr<Window> window11(CreateTransientChild(11, window1.get()));
   2100   scoped_ptr<Window> window12(CreateTransientChild(12, window1.get()));
   2101   scoped_ptr<Window> window13(CreateTransientChild(13, window1.get()));
   2102   scoped_ptr<Window> window2(CreateTestWindowWithId(2, root_window()));
   2103   scoped_ptr<Window> window3(CreateTestWindowWithId(3, root_window()));
   2104 
   2105   EXPECT_EQ("1 11 12 13 2 3", ChildWindowIDsAsString(root_window()));
   2106 
   2107   // Remove the delegates of a couple of transients, as if they are closing
   2108   // and animating out.
   2109   window11->layer()->set_delegate(NULL);
   2110   window13->layer()->set_delegate(NULL);
   2111 
   2112   // Move window1 to the front.  All transients should move with it, and their
   2113   // order should be preserved.
   2114   root_window()->StackChildAtTop(window1.get());
   2115 
   2116   EXPECT_EQ("2 3 1 11 12 13", ChildWindowIDsAsString(root_window()));
   2117 }
   2118 
   2119 class TestVisibilityClient : public client::VisibilityClient {
   2120  public:
   2121   explicit TestVisibilityClient(Window* root_window)
   2122       : ignore_visibility_changes_(false) {
   2123     client::SetVisibilityClient(root_window, this);
   2124   }
   2125   virtual ~TestVisibilityClient() {
   2126   }
   2127 
   2128   void set_ignore_visibility_changes(bool ignore_visibility_changes) {
   2129     ignore_visibility_changes_ = ignore_visibility_changes;
   2130   }
   2131 
   2132   // Overridden from client::VisibilityClient:
   2133   virtual void UpdateLayerVisibility(aura::Window* window,
   2134                                      bool visible) OVERRIDE {
   2135     if (!ignore_visibility_changes_)
   2136       window->layer()->SetVisible(visible);
   2137   }
   2138 
   2139  private:
   2140   bool ignore_visibility_changes_;
   2141   DISALLOW_COPY_AND_ASSIGN(TestVisibilityClient);
   2142 };
   2143 
   2144 TEST_F(WindowTest, VisibilityClientIsVisible) {
   2145   TestVisibilityClient client(root_window());
   2146 
   2147   scoped_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
   2148   EXPECT_TRUE(window->IsVisible());
   2149   EXPECT_TRUE(window->layer()->visible());
   2150 
   2151   window->Hide();
   2152   EXPECT_FALSE(window->IsVisible());
   2153   EXPECT_FALSE(window->layer()->visible());
   2154   window->Show();
   2155 
   2156   client.set_ignore_visibility_changes(true);
   2157   window->Hide();
   2158   EXPECT_FALSE(window->IsVisible());
   2159   EXPECT_TRUE(window->layer()->visible());
   2160 }
   2161 
   2162 // Tests mouse events on window change.
   2163 TEST_F(WindowTest, MouseEventsOnWindowChange) {
   2164   gfx::Size size = dispatcher()->host()->GetBounds().size();
   2165 
   2166   EventGenerator generator(root_window());
   2167   generator.MoveMouseTo(50, 50);
   2168 
   2169   EventCountDelegate d1;
   2170   scoped_ptr<Window> w1(CreateTestWindowWithDelegate(&d1, 1,
   2171       gfx::Rect(0, 0, 100, 100), root_window()));
   2172   RunAllPendingInMessageLoop();
   2173   // The format of result is "Enter/Mouse/Leave".
   2174   EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
   2175 
   2176   // Adding new window.
   2177   EventCountDelegate d11;
   2178   scoped_ptr<Window> w11(CreateTestWindowWithDelegate(
   2179       &d11, 1, gfx::Rect(0, 0, 100, 100), w1.get()));
   2180   RunAllPendingInMessageLoop();
   2181   EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
   2182   EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());
   2183 
   2184   // Move bounds.
   2185   w11->SetBounds(gfx::Rect(0, 0, 10, 10));
   2186   RunAllPendingInMessageLoop();
   2187   EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
   2188   EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset());
   2189 
   2190   w11->SetBounds(gfx::Rect(0, 0, 60, 60));
   2191   RunAllPendingInMessageLoop();
   2192   EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
   2193   EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());
   2194 
   2195   // Detach, then re-attach.
   2196   w1->RemoveChild(w11.get());
   2197   RunAllPendingInMessageLoop();
   2198   EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
   2199   // Window is detached, so no event is set.
   2200   EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset());
   2201 
   2202   w1->AddChild(w11.get());
   2203   RunAllPendingInMessageLoop();
   2204   EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
   2205   // Window is detached, so no event is set.
   2206   EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());
   2207 
   2208   // Visibility Change
   2209   w11->Hide();
   2210   RunAllPendingInMessageLoop();
   2211   EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
   2212   EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset());
   2213 
   2214   w11->Show();
   2215   RunAllPendingInMessageLoop();
   2216   EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
   2217   EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());
   2218 
   2219   // Transform: move d11 by 100 100.
   2220   gfx::Transform transform;
   2221   transform.Translate(100, 100);
   2222   w11->SetTransform(transform);
   2223   RunAllPendingInMessageLoop();
   2224   EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
   2225   EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset());
   2226 
   2227   w11->SetTransform(gfx::Transform());
   2228   RunAllPendingInMessageLoop();
   2229   EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
   2230   EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());
   2231 
   2232   // Closing a window.
   2233   w11.reset();
   2234   RunAllPendingInMessageLoop();
   2235   EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
   2236 
   2237   // Make sure we don't synthesize events if the mouse
   2238   // is outside of the root window.
   2239   generator.MoveMouseTo(-10, -10);
   2240   EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
   2241 
   2242   // Adding new windows.
   2243   w11.reset(CreateTestWindowWithDelegate(
   2244       &d11, 1, gfx::Rect(0, 0, 100, 100), w1.get()));
   2245   RunAllPendingInMessageLoop();
   2246   EXPECT_EQ("0 0 0", d1.GetMouseMotionCountsAndReset());
   2247   EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset());
   2248 
   2249   // Closing windows
   2250   w11.reset();
   2251   RunAllPendingInMessageLoop();
   2252   EXPECT_EQ("0 0 0", d1.GetMouseMotionCountsAndReset());
   2253   EXPECT_EQ("0 0 0", d11.GetMouseMotionCountsAndReset());
   2254 }
   2255 
   2256 class StackingMadrigalLayoutManager : public LayoutManager {
   2257  public:
   2258   explicit StackingMadrigalLayoutManager(Window* root_window)
   2259       : root_window_(root_window) {
   2260     root_window_->SetLayoutManager(this);
   2261   }
   2262   virtual ~StackingMadrigalLayoutManager() {
   2263   }
   2264 
   2265  private:
   2266   // Overridden from LayoutManager:
   2267   virtual void OnWindowResized() OVERRIDE {}
   2268   virtual void OnWindowAddedToLayout(Window* child) OVERRIDE {}
   2269   virtual void OnWillRemoveWindowFromLayout(Window* child) OVERRIDE {}
   2270   virtual void OnWindowRemovedFromLayout(Window* child) OVERRIDE {}
   2271   virtual void OnChildWindowVisibilityChanged(Window* child,
   2272                                               bool visible) OVERRIDE {
   2273     Window::Windows::const_iterator it = root_window_->children().begin();
   2274     Window* last_window = NULL;
   2275     for (; it != root_window_->children().end(); ++it) {
   2276       if (*it == child && last_window) {
   2277         if (!visible)
   2278           root_window_->StackChildAbove(last_window, *it);
   2279         else
   2280           root_window_->StackChildAbove(*it, last_window);
   2281         break;
   2282       }
   2283       last_window = *it;
   2284     }
   2285   }
   2286   virtual void SetChildBounds(Window* child,
   2287                               const gfx::Rect& requested_bounds) OVERRIDE {
   2288     SetChildBoundsDirect(child, requested_bounds);
   2289   }
   2290 
   2291   Window* root_window_;
   2292 
   2293   DISALLOW_COPY_AND_ASSIGN(StackingMadrigalLayoutManager);
   2294 };
   2295 
   2296 class StackingMadrigalVisibilityClient : public client::VisibilityClient {
   2297  public:
   2298   explicit StackingMadrigalVisibilityClient(Window* root_window)
   2299       : ignored_window_(NULL) {
   2300     client::SetVisibilityClient(root_window, this);
   2301   }
   2302   virtual ~StackingMadrigalVisibilityClient() {
   2303   }
   2304 
   2305   void set_ignored_window(Window* ignored_window) {
   2306     ignored_window_ = ignored_window;
   2307   }
   2308 
   2309  private:
   2310   // Overridden from client::VisibilityClient:
   2311   virtual void UpdateLayerVisibility(Window* window, bool visible) OVERRIDE {
   2312     if (!visible) {
   2313       if (window == ignored_window_)
   2314         window->layer()->set_delegate(NULL);
   2315       else
   2316         window->layer()->SetVisible(visible);
   2317     } else {
   2318       window->layer()->SetVisible(visible);
   2319     }
   2320   }
   2321 
   2322   Window* ignored_window_;
   2323 
   2324   DISALLOW_COPY_AND_ASSIGN(StackingMadrigalVisibilityClient);
   2325 };
   2326 
   2327 // This test attempts to reconstruct a circumstance that can happen when the
   2328 // aura client attempts to manipulate the visibility and delegate of a layer
   2329 // independent of window visibility.
   2330 // A use case is where the client attempts to keep a window visible onscreen
   2331 // even after code has called Hide() on the window. The use case for this would
   2332 // be that window hides are animated (e.g. the window fades out). To prevent
   2333 // spurious updating the client code may also clear window's layer's delegate,
   2334 // so that the window cannot attempt to paint or update it further. The window
   2335 // uses the presence of a NULL layer delegate as a signal in stacking to note
   2336 // that the window is being manipulated by such a use case and its stacking
   2337 // should not be adjusted.
   2338 // One issue that can arise when a window opens two transient children, and the
   2339 // first is hidden. Subsequent attempts to activate the transient parent can
   2340 // result in the transient parent being stacked above the second transient
   2341 // child. A fix is made to Window::StackAbove to prevent this, and this test
   2342 // verifies this fix.
   2343 TEST_F(WindowTest, StackingMadrigal) {
   2344   new StackingMadrigalLayoutManager(root_window());
   2345   StackingMadrigalVisibilityClient visibility_client(root_window());
   2346 
   2347   scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
   2348   scoped_ptr<Window> window11(CreateTransientChild(11, window1.get()));
   2349 
   2350   visibility_client.set_ignored_window(window11.get());
   2351 
   2352   window11->Show();
   2353   window11->Hide();
   2354 
   2355   // As a transient, window11 should still be stacked above window1, even when
   2356   // hidden.
   2357   EXPECT_TRUE(WindowIsAbove(window11.get(), window1.get()));
   2358   EXPECT_TRUE(LayerIsAbove(window11.get(), window1.get()));
   2359 
   2360   // A new transient should still be above window1.  It will appear behind
   2361   // window11 because we don't stack windows on top of targets with NULL
   2362   // delegates.
   2363   scoped_ptr<Window> window12(CreateTransientChild(12, window1.get()));
   2364   window12->Show();
   2365 
   2366   EXPECT_TRUE(WindowIsAbove(window12.get(), window1.get()));
   2367   EXPECT_TRUE(LayerIsAbove(window12.get(), window1.get()));
   2368 
   2369   // In earlier versions of the StackChildAbove() method, attempting to stack
   2370   // window1 above window12 at this point would actually restack the layers
   2371   // resulting in window12's layer being below window1's layer (though the
   2372   // windows themselves would still be correctly stacked, so events would pass
   2373   // through.)
   2374   root_window()->StackChildAbove(window1.get(), window12.get());
   2375 
   2376   // Both window12 and its layer should be stacked above window1.
   2377   EXPECT_TRUE(WindowIsAbove(window12.get(), window1.get()));
   2378   EXPECT_TRUE(LayerIsAbove(window12.get(), window1.get()));
   2379 }
   2380 
   2381 // Test for an issue where attempting to stack a primary window on top of a
   2382 // transient with a NULL layer delegate causes that primary window to be moved,
   2383 // but the layer order not changed to match.  http://crbug.com/112562
   2384 TEST_F(WindowTest, StackOverClosingTransient) {
   2385   scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
   2386   scoped_ptr<Window> transient1(CreateTransientChild(11, window1.get()));
   2387   scoped_ptr<Window> window2(CreateTestWindowWithId(2, root_window()));
   2388   scoped_ptr<Window> transient2(CreateTransientChild(21, window2.get()));
   2389 
   2390   // Both windows and layers are stacked in creation order.
   2391   Window* root = root_window();
   2392   ASSERT_EQ(4u, root->children().size());
   2393   EXPECT_EQ(root->children()[0], window1.get());
   2394   EXPECT_EQ(root->children()[1], transient1.get());
   2395   EXPECT_EQ(root->children()[2], window2.get());
   2396   EXPECT_EQ(root->children()[3], transient2.get());
   2397   ASSERT_EQ(4u, root->layer()->children().size());
   2398   EXPECT_EQ(root->layer()->children()[0], window1->layer());
   2399   EXPECT_EQ(root->layer()->children()[1], transient1->layer());
   2400   EXPECT_EQ(root->layer()->children()[2], window2->layer());
   2401   EXPECT_EQ(root->layer()->children()[3], transient2->layer());
   2402   EXPECT_EQ("1 11 2 21", ChildWindowIDsAsString(root_window()));
   2403 
   2404   // This brings window1 and its transient to the front.
   2405   root->StackChildAtTop(window1.get());
   2406   EXPECT_EQ("2 21 1 11", ChildWindowIDsAsString(root_window()));
   2407 
   2408   EXPECT_EQ(root->children()[0], window2.get());
   2409   EXPECT_EQ(root->children()[1], transient2.get());
   2410   EXPECT_EQ(root->children()[2], window1.get());
   2411   EXPECT_EQ(root->children()[3], transient1.get());
   2412   EXPECT_EQ(root->layer()->children()[0], window2->layer());
   2413   EXPECT_EQ(root->layer()->children()[1], transient2->layer());
   2414   EXPECT_EQ(root->layer()->children()[2], window1->layer());
   2415   EXPECT_EQ(root->layer()->children()[3], transient1->layer());
   2416 
   2417   // Pretend we're closing the top-most transient, then bring window2 to the
   2418   // front.  This mimics activating a browser window while the status bubble
   2419   // is fading out.  The transient should stay topmost.
   2420   transient1->layer()->set_delegate(NULL);
   2421   root->StackChildAtTop(window2.get());
   2422 
   2423   EXPECT_EQ(root->children()[0], window1.get());
   2424   EXPECT_EQ(root->children()[1], window2.get());
   2425   EXPECT_EQ(root->children()[2], transient2.get());
   2426   EXPECT_EQ(root->children()[3], transient1.get());
   2427   EXPECT_EQ(root->layer()->children()[0], window1->layer());
   2428   EXPECT_EQ(root->layer()->children()[1], window2->layer());
   2429   EXPECT_EQ(root->layer()->children()[2], transient2->layer());
   2430   EXPECT_EQ(root->layer()->children()[3], transient1->layer());
   2431 
   2432   // Close the transient.  Remaining windows are stable.
   2433   transient1.reset();
   2434 
   2435   ASSERT_EQ(3u, root->children().size());
   2436   EXPECT_EQ(root->children()[0], window1.get());
   2437   EXPECT_EQ(root->children()[1], window2.get());
   2438   EXPECT_EQ(root->children()[2], transient2.get());
   2439   ASSERT_EQ(3u, root->layer()->children().size());
   2440   EXPECT_EQ(root->layer()->children()[0], window1->layer());
   2441   EXPECT_EQ(root->layer()->children()[1], window2->layer());
   2442   EXPECT_EQ(root->layer()->children()[2], transient2->layer());
   2443 
   2444   // Open another window on top.
   2445   scoped_ptr<Window> window3(CreateTestWindowWithId(3, root_window()));
   2446 
   2447   ASSERT_EQ(4u, root->children().size());
   2448   EXPECT_EQ(root->children()[0], window1.get());
   2449   EXPECT_EQ(root->children()[1], window2.get());
   2450   EXPECT_EQ(root->children()[2], transient2.get());
   2451   EXPECT_EQ(root->children()[3], window3.get());
   2452   ASSERT_EQ(4u, root->layer()->children().size());
   2453   EXPECT_EQ(root->layer()->children()[0], window1->layer());
   2454   EXPECT_EQ(root->layer()->children()[1], window2->layer());
   2455   EXPECT_EQ(root->layer()->children()[2], transient2->layer());
   2456   EXPECT_EQ(root->layer()->children()[3], window3->layer());
   2457 
   2458   // Pretend we're closing the topmost non-transient window, then bring
   2459   // window2 to the top.  It should not move.
   2460   window3->layer()->set_delegate(NULL);
   2461   root->StackChildAtTop(window2.get());
   2462 
   2463   ASSERT_EQ(4u, root->children().size());
   2464   EXPECT_EQ(root->children()[0], window1.get());
   2465   EXPECT_EQ(root->children()[1], window2.get());
   2466   EXPECT_EQ(root->children()[2], transient2.get());
   2467   EXPECT_EQ(root->children()[3], window3.get());
   2468   ASSERT_EQ(4u, root->layer()->children().size());
   2469   EXPECT_EQ(root->layer()->children()[0], window1->layer());
   2470   EXPECT_EQ(root->layer()->children()[1], window2->layer());
   2471   EXPECT_EQ(root->layer()->children()[2], transient2->layer());
   2472   EXPECT_EQ(root->layer()->children()[3], window3->layer());
   2473 
   2474   // Bring window1 to the top.  It should move ahead of window2, but not
   2475   // ahead of window3 (with NULL delegate).
   2476   root->StackChildAtTop(window1.get());
   2477 
   2478   ASSERT_EQ(4u, root->children().size());
   2479   EXPECT_EQ(root->children()[0], window2.get());
   2480   EXPECT_EQ(root->children()[1], transient2.get());
   2481   EXPECT_EQ(root->children()[2], window1.get());
   2482   EXPECT_EQ(root->children()[3], window3.get());
   2483   ASSERT_EQ(4u, root->layer()->children().size());
   2484   EXPECT_EQ(root->layer()->children()[0], window2->layer());
   2485   EXPECT_EQ(root->layer()->children()[1], transient2->layer());
   2486   EXPECT_EQ(root->layer()->children()[2], window1->layer());
   2487   EXPECT_EQ(root->layer()->children()[3], window3->layer());
   2488 }
   2489 
   2490 class RootWindowAttachmentObserver : public WindowObserver {
   2491  public:
   2492   RootWindowAttachmentObserver() : added_count_(0), removed_count_(0) {}
   2493   virtual ~RootWindowAttachmentObserver() {}
   2494 
   2495   int added_count() const { return added_count_; }
   2496   int removed_count() const { return removed_count_; }
   2497 
   2498   void Clear() {
   2499     added_count_ = 0;
   2500     removed_count_ = 0;
   2501   }
   2502 
   2503   // Overridden from WindowObserver:
   2504   virtual void OnWindowAddedToRootWindow(Window* window) OVERRIDE {
   2505     ++added_count_;
   2506   }
   2507   virtual void OnWindowRemovingFromRootWindow(Window* window) OVERRIDE {
   2508     ++removed_count_;
   2509   }
   2510 
   2511  private:
   2512   int added_count_;
   2513   int removed_count_;
   2514 
   2515   DISALLOW_COPY_AND_ASSIGN(RootWindowAttachmentObserver);
   2516 };
   2517 
   2518 TEST_F(WindowTest, RootWindowAttachment) {
   2519   RootWindowAttachmentObserver observer;
   2520 
   2521   // Test a direct add/remove from the RootWindow.
   2522   scoped_ptr<Window> w1(new Window(NULL));
   2523   w1->Init(ui::LAYER_NOT_DRAWN);
   2524   w1->AddObserver(&observer);
   2525 
   2526   ParentWindow(w1.get());
   2527   EXPECT_EQ(1, observer.added_count());
   2528   EXPECT_EQ(0, observer.removed_count());
   2529 
   2530   w1.reset();
   2531   EXPECT_EQ(1, observer.added_count());
   2532   EXPECT_EQ(1, observer.removed_count());
   2533 
   2534   observer.Clear();
   2535 
   2536   // Test an indirect add/remove from the RootWindow.
   2537   w1.reset(new Window(NULL));
   2538   w1->Init(ui::LAYER_NOT_DRAWN);
   2539   Window* w11 = new Window(NULL);
   2540   w11->Init(ui::LAYER_NOT_DRAWN);
   2541   w11->AddObserver(&observer);
   2542   w1->AddChild(w11);
   2543   EXPECT_EQ(0, observer.added_count());
   2544   EXPECT_EQ(0, observer.removed_count());
   2545 
   2546   ParentWindow(w1.get());
   2547   EXPECT_EQ(1, observer.added_count());
   2548   EXPECT_EQ(0, observer.removed_count());
   2549 
   2550   w1.reset();  // Deletes w11.
   2551   w11 = NULL;
   2552   EXPECT_EQ(1, observer.added_count());
   2553   EXPECT_EQ(1, observer.removed_count());
   2554 
   2555   observer.Clear();
   2556 
   2557   // Test an indirect add/remove with nested observers.
   2558   w1.reset(new Window(NULL));
   2559   w1->Init(ui::LAYER_NOT_DRAWN);
   2560   w11 = new Window(NULL);
   2561   w11->Init(ui::LAYER_NOT_DRAWN);
   2562   w11->AddObserver(&observer);
   2563   w1->AddChild(w11);
   2564   Window* w111 = new Window(NULL);
   2565   w111->Init(ui::LAYER_NOT_DRAWN);
   2566   w111->AddObserver(&observer);
   2567   w11->AddChild(w111);
   2568 
   2569   EXPECT_EQ(0, observer.added_count());
   2570   EXPECT_EQ(0, observer.removed_count());
   2571 
   2572   ParentWindow(w1.get());
   2573   EXPECT_EQ(2, observer.added_count());
   2574   EXPECT_EQ(0, observer.removed_count());
   2575 
   2576   w1.reset();  // Deletes w11 and w111.
   2577   w11 = NULL;
   2578   w111 = NULL;
   2579   EXPECT_EQ(2, observer.added_count());
   2580   EXPECT_EQ(2, observer.removed_count());
   2581 }
   2582 
   2583 TEST_F(WindowTest, OwnedByParentFalse) {
   2584   // By default, a window is owned by its parent. If this is set to false, the
   2585   // window will not be destroyed when its parent is.
   2586 
   2587   scoped_ptr<Window> w1(new Window(NULL));
   2588   w1->Init(ui::LAYER_NOT_DRAWN);
   2589   scoped_ptr<Window> w2(new Window(NULL));
   2590   w2->set_owned_by_parent(false);
   2591   w2->Init(ui::LAYER_NOT_DRAWN);
   2592   w1->AddChild(w2.get());
   2593 
   2594   w1.reset();
   2595 
   2596   // We should be able to deref w2 still, but its parent should now be NULL.
   2597   EXPECT_EQ(NULL, w2->parent());
   2598 }
   2599 
   2600 namespace {
   2601 
   2602 // Used By DeleteWindowFromOnWindowDestroyed. Destroys a Window from
   2603 // OnWindowDestroyed().
   2604 class OwningWindowDelegate : public TestWindowDelegate {
   2605  public:
   2606   OwningWindowDelegate() {}
   2607 
   2608   void SetOwnedWindow(Window* window) {
   2609     owned_window_.reset(window);
   2610   }
   2611 
   2612   virtual void OnWindowDestroyed() OVERRIDE {
   2613     owned_window_.reset(NULL);
   2614   }
   2615 
   2616  private:
   2617   scoped_ptr<Window> owned_window_;
   2618 
   2619   DISALLOW_COPY_AND_ASSIGN(OwningWindowDelegate);
   2620 };
   2621 
   2622 }  // namespace
   2623 
   2624 // Creates a window with two child windows. When the first child window is
   2625 // destroyed (WindowDelegate::OnWindowDestroyed) it deletes the second child.
   2626 // This synthesizes BrowserView and the status bubble. Both are children of the
   2627 // same parent and destroying BrowserView triggers it destroying the status
   2628 // bubble.
   2629 TEST_F(WindowTest, DeleteWindowFromOnWindowDestroyed) {
   2630   scoped_ptr<Window> parent(new Window(NULL));
   2631   parent->Init(ui::LAYER_NOT_DRAWN);
   2632   OwningWindowDelegate delegate;
   2633   Window* c1 = new Window(&delegate);
   2634   c1->Init(ui::LAYER_NOT_DRAWN);
   2635   parent->AddChild(c1);
   2636   Window* c2 = new Window(NULL);
   2637   c2->Init(ui::LAYER_NOT_DRAWN);
   2638   parent->AddChild(c2);
   2639   delegate.SetOwnedWindow(c2);
   2640   parent.reset();
   2641 }
   2642 
   2643 namespace {
   2644 
   2645 // Used by DelegateNotifiedAsBoundsChange to verify OnBoundsChanged() is
   2646 // invoked.
   2647 class BoundsChangeDelegate : public TestWindowDelegate {
   2648  public:
   2649   BoundsChangeDelegate() : bounds_changed_(false) {}
   2650 
   2651   void clear_bounds_changed() { bounds_changed_ = false; }
   2652   bool bounds_changed() const {
   2653     return bounds_changed_;
   2654   }
   2655 
   2656   // Window
   2657   virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
   2658                                const gfx::Rect& new_bounds) OVERRIDE {
   2659     bounds_changed_ = true;
   2660   }
   2661 
   2662  private:
   2663   // Was OnBoundsChanged() invoked?
   2664   bool bounds_changed_;
   2665 
   2666   DISALLOW_COPY_AND_ASSIGN(BoundsChangeDelegate);
   2667 };
   2668 
   2669 }  // namespace
   2670 
   2671 // Verifies the delegate is notified when the actual bounds of the layer
   2672 // change.
   2673 TEST_F(WindowTest, DelegateNotifiedAsBoundsChange) {
   2674   BoundsChangeDelegate delegate;
   2675 
   2676   // We cannot short-circuit animations in this test.
   2677   ui::ScopedAnimationDurationScaleMode normal_duration_mode(
   2678       ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
   2679 
   2680   scoped_ptr<Window> window(
   2681       CreateTestWindowWithDelegate(&delegate, 1,
   2682                                    gfx::Rect(0, 0, 100, 100), root_window()));
   2683   window->layer()->GetAnimator()->set_disable_timer_for_test(true);
   2684 
   2685   delegate.clear_bounds_changed();
   2686 
   2687   // Animate to a different position.
   2688   {
   2689     ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
   2690     window->SetBounds(gfx::Rect(100, 100, 100, 100));
   2691   }
   2692 
   2693   // Bounds shouldn't immediately have changed.
   2694   EXPECT_EQ("0,0 100x100", window->bounds().ToString());
   2695   EXPECT_FALSE(delegate.bounds_changed());
   2696 
   2697   // Animate to the end, which should notify of the change.
   2698   base::TimeTicks start_time =
   2699       window->layer()->GetAnimator()->last_step_time();
   2700   gfx::AnimationContainerElement* element = window->layer()->GetAnimator();
   2701   element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
   2702   EXPECT_TRUE(delegate.bounds_changed());
   2703   EXPECT_NE("0,0 100x100", window->bounds().ToString());
   2704 }
   2705 
   2706 // Verifies the delegate is notified when the actual bounds of the layer
   2707 // change even when the window is not the layer's delegate
   2708 TEST_F(WindowTest, DelegateNotifiedAsBoundsChangeInHiddenLayer) {
   2709   BoundsChangeDelegate delegate;
   2710 
   2711   // We cannot short-circuit animations in this test.
   2712   ui::ScopedAnimationDurationScaleMode normal_duration_mode(
   2713       ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
   2714 
   2715   scoped_ptr<Window> window(
   2716       CreateTestWindowWithDelegate(&delegate, 1,
   2717                                    gfx::Rect(0, 0, 100, 100), root_window()));
   2718   window->layer()->GetAnimator()->set_disable_timer_for_test(true);
   2719 
   2720   delegate.clear_bounds_changed();
   2721 
   2722   // Suppress paint on the window since it is hidden (should reset the layer's
   2723   // delegate to NULL)
   2724   window->SuppressPaint();
   2725   EXPECT_EQ(NULL, window->layer()->delegate());
   2726 
   2727   // Animate to a different position.
   2728   {
   2729     ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
   2730     window->SetBounds(gfx::Rect(100, 100, 110, 100));
   2731   }
   2732 
   2733   // Layer delegate is NULL but we should still get bounds changed notification.
   2734   EXPECT_EQ("100,100 110x100", window->GetTargetBounds().ToString());
   2735   EXPECT_TRUE(delegate.bounds_changed());
   2736 
   2737   delegate.clear_bounds_changed();
   2738 
   2739   // Animate to the end: will *not* notify of the change since we are hidden.
   2740   base::TimeTicks start_time =
   2741       window->layer()->GetAnimator()->last_step_time();
   2742   gfx::AnimationContainerElement* element = window->layer()->GetAnimator();
   2743   element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
   2744 
   2745   // No bounds changed notification at the end of animation since layer
   2746   // delegate is NULL.
   2747   EXPECT_FALSE(delegate.bounds_changed());
   2748   EXPECT_NE("0,0 100x100", window->layer()->bounds().ToString());
   2749 }
   2750 
   2751 namespace {
   2752 
   2753 // Used by AddChildNotifications to track notification counts.
   2754 class AddChildNotificationsObserver : public WindowObserver {
   2755  public:
   2756   AddChildNotificationsObserver() : added_count_(0), removed_count_(0) {}
   2757 
   2758   std::string CountStringAndReset() {
   2759     std::string result = base::IntToString(added_count_) + " " +
   2760         base::IntToString(removed_count_);
   2761     added_count_ = removed_count_ = 0;
   2762     return result;
   2763   }
   2764 
   2765   // WindowObserver overrides:
   2766   virtual void OnWindowAddedToRootWindow(Window* window) OVERRIDE {
   2767     added_count_++;
   2768   }
   2769   virtual void OnWindowRemovingFromRootWindow(Window* window) OVERRIDE {
   2770     removed_count_++;
   2771   }
   2772 
   2773  private:
   2774   int added_count_;
   2775   int removed_count_;
   2776 
   2777   DISALLOW_COPY_AND_ASSIGN(AddChildNotificationsObserver);
   2778 };
   2779 
   2780 }  // namespace
   2781 
   2782 // Assertions around when root window notifications are sent.
   2783 TEST_F(WindowTest, AddChildNotifications) {
   2784   AddChildNotificationsObserver observer;
   2785   scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
   2786   scoped_ptr<Window> w2(CreateTestWindowWithId(1, root_window()));
   2787   w2->AddObserver(&observer);
   2788   w2->Focus();
   2789   EXPECT_TRUE(w2->HasFocus());
   2790 
   2791   // Move |w2| to be a child of |w1|.
   2792   w1->AddChild(w2.get());
   2793   // Sine we moved in the same root, observer shouldn't be notified.
   2794   EXPECT_EQ("0 0", observer.CountStringAndReset());
   2795   // |w2| should still have focus after moving.
   2796   EXPECT_TRUE(w2->HasFocus());
   2797 }
   2798 
   2799 // Tests that a delegate that destroys itself when the window is destroyed does
   2800 // not break.
   2801 TEST_F(WindowTest, DelegateDestroysSelfOnWindowDestroy) {
   2802   scoped_ptr<Window> w1(CreateTestWindowWithDelegate(
   2803       new DestroyWindowDelegate(),
   2804       0,
   2805       gfx::Rect(10, 20, 30, 40),
   2806       root_window()));
   2807 }
   2808 
   2809 class HierarchyObserver : public WindowObserver {
   2810  public:
   2811   HierarchyObserver(Window* target) : target_(target) {
   2812     target_->AddObserver(this);
   2813   }
   2814   virtual ~HierarchyObserver() {
   2815     target_->RemoveObserver(this);
   2816   }
   2817 
   2818   void ValidateState(
   2819       int index,
   2820       const WindowObserver::HierarchyChangeParams& params) const {
   2821     ParamsMatch(params_[index], params);
   2822   }
   2823 
   2824   void Reset() {
   2825     params_.clear();
   2826   }
   2827 
   2828  private:
   2829   // Overridden from WindowObserver:
   2830   virtual void OnWindowHierarchyChanging(
   2831       const HierarchyChangeParams& params) OVERRIDE {
   2832     params_.push_back(params);
   2833   }
   2834   virtual void OnWindowHierarchyChanged(
   2835       const HierarchyChangeParams& params) OVERRIDE {
   2836     params_.push_back(params);
   2837   }
   2838 
   2839   void ParamsMatch(const WindowObserver::HierarchyChangeParams& p1,
   2840                    const WindowObserver::HierarchyChangeParams& p2) const {
   2841     EXPECT_EQ(p1.phase, p2.phase);
   2842     EXPECT_EQ(p1.target, p2.target);
   2843     EXPECT_EQ(p1.new_parent, p2.new_parent);
   2844     EXPECT_EQ(p1.old_parent, p2.old_parent);
   2845     EXPECT_EQ(p1.receiver, p2.receiver);
   2846   }
   2847 
   2848   Window* target_;
   2849   std::vector<WindowObserver::HierarchyChangeParams> params_;
   2850 
   2851   DISALLOW_COPY_AND_ASSIGN(HierarchyObserver);
   2852 };
   2853 
   2854 // Tests hierarchy change notifications.
   2855 TEST_F(WindowTest, OnWindowHierarchyChange) {
   2856   {
   2857     // Simple add & remove.
   2858     HierarchyObserver oroot(root_window());
   2859 
   2860     scoped_ptr<Window> w1(CreateTestWindowWithId(1, NULL));
   2861     HierarchyObserver o1(w1.get());
   2862 
   2863     // Add.
   2864     root_window()->AddChild(w1.get());
   2865 
   2866     WindowObserver::HierarchyChangeParams params;
   2867     params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
   2868     params.target = w1.get();
   2869     params.old_parent = NULL;
   2870     params.new_parent = root_window();
   2871     params.receiver = w1.get();
   2872     o1.ValidateState(0, params);
   2873 
   2874     params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
   2875     params.receiver = w1.get();
   2876     o1.ValidateState(1, params);
   2877 
   2878     params.receiver = root_window();
   2879     oroot.ValidateState(0, params);
   2880 
   2881     // Remove.
   2882     o1.Reset();
   2883     oroot.Reset();
   2884 
   2885     root_window()->RemoveChild(w1.get());
   2886 
   2887     params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
   2888     params.old_parent = root_window();
   2889     params.new_parent = NULL;
   2890     params.receiver = w1.get();
   2891 
   2892     o1.ValidateState(0, params);
   2893 
   2894     params.receiver = root_window();
   2895     oroot.ValidateState(0, params);
   2896 
   2897     params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
   2898     params.receiver = w1.get();
   2899     o1.ValidateState(1, params);
   2900   }
   2901 
   2902   {
   2903     // Add & remove of hierarchy. Tests notification order per documentation in
   2904     // WindowObserver.
   2905     HierarchyObserver o(root_window());
   2906     scoped_ptr<Window> w1(CreateTestWindowWithId(1, NULL));
   2907     Window* w11 = CreateTestWindowWithId(11, w1.get());
   2908     w1->AddObserver(&o);
   2909     w11->AddObserver(&o);
   2910 
   2911     // Add.
   2912     root_window()->AddChild(w1.get());
   2913 
   2914     // Dispatched to target first.
   2915     int index = 0;
   2916     WindowObserver::HierarchyChangeParams params;
   2917     params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
   2918     params.target = w1.get();
   2919     params.old_parent = NULL;
   2920     params.new_parent = root_window();
   2921     params.receiver = w1.get();
   2922     o.ValidateState(index++, params);
   2923 
   2924     // Dispatched to target's children.
   2925     params.receiver = w11;
   2926     o.ValidateState(index++, params);
   2927 
   2928     params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
   2929 
   2930     // Now process the "changed" phase.
   2931     params.receiver = w1.get();
   2932     o.ValidateState(index++, params);
   2933     params.receiver = w11;
   2934     o.ValidateState(index++, params);
   2935     params.receiver = root_window();
   2936     o.ValidateState(index++, params);
   2937 
   2938     // Remove.
   2939     root_window()->RemoveChild(w1.get());
   2940     params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
   2941     params.old_parent = root_window();
   2942     params.new_parent = NULL;
   2943     params.receiver = w1.get();
   2944     o.ValidateState(index++, params);
   2945     params.receiver = w11;
   2946     o.ValidateState(index++, params);
   2947     params.receiver = root_window();
   2948     o.ValidateState(index++, params);
   2949     params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
   2950     params.receiver = w1.get();
   2951     o.ValidateState(index++, params);
   2952     params.receiver = w11;
   2953     o.ValidateState(index++, params);
   2954 
   2955     w1.reset();
   2956   }
   2957 
   2958   {
   2959     // Reparent. Tests notification order per documentation in WindowObserver.
   2960     scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
   2961     Window* w11 = CreateTestWindowWithId(11, w1.get());
   2962     Window* w111 = CreateTestWindowWithId(111, w11);
   2963     scoped_ptr<Window> w2(CreateTestWindowWithId(2, root_window()));
   2964 
   2965     HierarchyObserver o(root_window());
   2966     w1->AddObserver(&o);
   2967     w11->AddObserver(&o);
   2968     w111->AddObserver(&o);
   2969     w2->AddObserver(&o);
   2970 
   2971     w2->AddChild(w11);
   2972 
   2973     // Dispatched to target first.
   2974     int index = 0;
   2975     WindowObserver::HierarchyChangeParams params;
   2976     params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
   2977     params.target = w11;
   2978     params.old_parent = w1.get();
   2979     params.new_parent = w2.get();
   2980     params.receiver = w11;
   2981     o.ValidateState(index++, params);
   2982 
   2983     // Then to target's children.
   2984     params.receiver = w111;
   2985     o.ValidateState(index++, params);
   2986 
   2987     // Then to target's old parent chain.
   2988     params.receiver = w1.get();
   2989     o.ValidateState(index++, params);
   2990     params.receiver = root_window();
   2991     o.ValidateState(index++, params);
   2992 
   2993     // "Changed" phase.
   2994     params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
   2995     params.receiver = w11;
   2996     o.ValidateState(index++, params);
   2997     params.receiver = w111;
   2998     o.ValidateState(index++, params);
   2999     params.receiver = w2.get();
   3000     o.ValidateState(index++, params);
   3001     params.receiver = root_window();
   3002     o.ValidateState(index++, params);
   3003 
   3004     w1.reset();
   3005     w2.reset();
   3006   }
   3007 
   3008 }
   3009 
   3010 namespace {
   3011 
   3012 // Used by NotifyDelegateAfterDeletingTransients. Adds a string to a vector when
   3013 // OnWindowDestroyed() is invoked so that destruction order can be verified.
   3014 class DestroyedTrackingDelegate : public TestWindowDelegate {
   3015  public:
   3016   explicit DestroyedTrackingDelegate(const std::string& name,
   3017                                      std::vector<std::string>* results)
   3018       : name_(name),
   3019         results_(results) {}
   3020 
   3021   virtual void OnWindowDestroyed() OVERRIDE {
   3022     results_->push_back(name_);
   3023   }
   3024 
   3025  private:
   3026   const std::string name_;
   3027   std::vector<std::string>* results_;
   3028 
   3029   DISALLOW_COPY_AND_ASSIGN(DestroyedTrackingDelegate);
   3030 };
   3031 
   3032 }  // namespace
   3033 
   3034 // Verifies the delegate is notified of destruction after transients are
   3035 // destroyed.
   3036 TEST_F(WindowTest, NotifyDelegateAfterDeletingTransients) {
   3037   std::vector<std::string> destruction_order;
   3038 
   3039   DestroyedTrackingDelegate parent_delegate("parent", &destruction_order);
   3040   scoped_ptr<Window> parent(new Window(&parent_delegate));
   3041   parent->Init(ui::LAYER_NOT_DRAWN);
   3042 
   3043   DestroyedTrackingDelegate transient_delegate("transient", &destruction_order);
   3044   Window* transient = new Window(&transient_delegate);  // Owned by |parent|.
   3045   transient->Init(ui::LAYER_NOT_DRAWN);
   3046   parent->AddTransientChild(transient);
   3047   parent.reset();
   3048 
   3049   ASSERT_EQ(2u, destruction_order.size());
   3050   EXPECT_EQ("transient", destruction_order[0]);
   3051   EXPECT_EQ("parent", destruction_order[1]);
   3052 }
   3053 
   3054 // Verifies SchedulePaint() on a layerless window results in damaging the right
   3055 // thing.
   3056 TEST_F(WindowTest, LayerlessWindowSchedulePaint) {
   3057   Window root(NULL);
   3058   root.Init(ui::LAYER_NOT_DRAWN);
   3059   root.SetBounds(gfx::Rect(0, 0, 100, 100));
   3060 
   3061   Window* layerless_window = new Window(NULL);  // Owned by |root|.
   3062   layerless_window->InitWithWindowLayerType(WINDOW_LAYER_NONE);
   3063   layerless_window->SetBounds(gfx::Rect(10, 11, 12, 13));
   3064   root.AddChild(layerless_window);
   3065 
   3066   root.layer()->SendDamagedRects();
   3067   layerless_window->SchedulePaintInRect(gfx::Rect(1, 2, 100, 4));
   3068   // Note the the region is clipped by the parent hence 100 going to 11.
   3069   EXPECT_EQ("11,13 11x4",
   3070             gfx::SkIRectToRect(root.layer()->damaged_region().getBounds()).
   3071             ToString());
   3072 
   3073   Window* layerless_window2 = new Window(NULL);  // Owned by |layerless_window|.
   3074   layerless_window2->InitWithWindowLayerType(WINDOW_LAYER_NONE);
   3075   layerless_window2->SetBounds(gfx::Rect(1, 2, 3, 4));
   3076   layerless_window->AddChild(layerless_window2);
   3077 
   3078   root.layer()->SendDamagedRects();
   3079   layerless_window2->SchedulePaintInRect(gfx::Rect(1, 2, 100, 4));
   3080   // Note the the region is clipped by the |layerless_window| hence 100 going to
   3081   // 2.
   3082   EXPECT_EQ("12,15 2x2",
   3083             gfx::SkIRectToRect(root.layer()->damaged_region().getBounds()).
   3084             ToString());
   3085 }
   3086 
   3087 // Verifies bounds of layerless windows are correctly updated when adding
   3088 // removing.
   3089 TEST_F(WindowTest, NestedLayerlessWindowsBoundsOnAddRemove) {
   3090   // Creates the following structure (all children owned by root):
   3091   // root
   3092   //   w1ll      1,2
   3093   //     w11ll   3,4
   3094   //       w111  5,6
   3095   //     w12     7,8
   3096   //       w121  9,10
   3097   //
   3098   // ll: layer less, eg no layer
   3099   Window root(NULL);
   3100   root.InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3101   root.SetBounds(gfx::Rect(0, 0, 100, 100));
   3102 
   3103   Window* w1ll = new Window(NULL);
   3104   w1ll->InitWithWindowLayerType(WINDOW_LAYER_NONE);
   3105   w1ll->SetBounds(gfx::Rect(1, 2, 100, 100));
   3106 
   3107   Window* w11ll = new Window(NULL);
   3108   w11ll->InitWithWindowLayerType(WINDOW_LAYER_NONE);
   3109   w11ll->SetBounds(gfx::Rect(3, 4, 100, 100));
   3110   w1ll->AddChild(w11ll);
   3111 
   3112   Window* w111 = new Window(NULL);
   3113   w111->InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3114   w111->SetBounds(gfx::Rect(5, 6, 100, 100));
   3115   w11ll->AddChild(w111);
   3116 
   3117   Window* w12 = new Window(NULL);
   3118   w12->InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3119   w12->SetBounds(gfx::Rect(7, 8, 100, 100));
   3120   w1ll->AddChild(w12);
   3121 
   3122   Window* w121 = new Window(NULL);
   3123   w121->InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3124   w121->SetBounds(gfx::Rect(9, 10, 100, 100));
   3125   w12->AddChild(w121);
   3126 
   3127   root.AddChild(w1ll);
   3128 
   3129   // All layers should be parented to the root.
   3130   EXPECT_EQ(root.layer(), w111->layer()->parent());
   3131   EXPECT_EQ(root.layer(), w12->layer()->parent());
   3132   EXPECT_EQ(w12->layer(), w121->layer()->parent());
   3133 
   3134   // Ensure bounds are what we expect.
   3135   EXPECT_EQ("1,2 100x100", w1ll->bounds().ToString());
   3136   EXPECT_EQ("3,4 100x100", w11ll->bounds().ToString());
   3137   EXPECT_EQ("5,6 100x100", w111->bounds().ToString());
   3138   EXPECT_EQ("7,8 100x100", w12->bounds().ToString());
   3139   EXPECT_EQ("9,10 100x100", w121->bounds().ToString());
   3140 
   3141   // Bounds of layers are relative to the nearest ancestor with a layer.
   3142   EXPECT_EQ("8,10 100x100", w12->layer()->bounds().ToString());
   3143   EXPECT_EQ("9,12 100x100", w111->layer()->bounds().ToString());
   3144   EXPECT_EQ("9,10 100x100", w121->layer()->bounds().ToString());
   3145 
   3146   // Remove and repeat.
   3147   root.RemoveChild(w1ll);
   3148 
   3149   EXPECT_TRUE(w111->layer()->parent() == NULL);
   3150   EXPECT_TRUE(w12->layer()->parent() == NULL);
   3151 
   3152   // Verify bounds haven't changed again.
   3153   EXPECT_EQ("1,2 100x100", w1ll->bounds().ToString());
   3154   EXPECT_EQ("3,4 100x100", w11ll->bounds().ToString());
   3155   EXPECT_EQ("5,6 100x100", w111->bounds().ToString());
   3156   EXPECT_EQ("7,8 100x100", w12->bounds().ToString());
   3157   EXPECT_EQ("9,10 100x100", w121->bounds().ToString());
   3158 
   3159   // Bounds of layers should now match that of windows.
   3160   EXPECT_EQ("7,8 100x100", w12->layer()->bounds().ToString());
   3161   EXPECT_EQ("5,6 100x100", w111->layer()->bounds().ToString());
   3162   EXPECT_EQ("9,10 100x100", w121->layer()->bounds().ToString());
   3163 
   3164   delete w1ll;
   3165 }
   3166 
   3167 // Verifies bounds of layerless windows are correctly updated when bounds
   3168 // of ancestor changes.
   3169 TEST_F(WindowTest, NestedLayerlessWindowsBoundsOnSetBounds) {
   3170   // Creates the following structure (all children owned by root):
   3171   // root
   3172   //   w1ll      1,2
   3173   //     w11ll   3,4
   3174   //       w111  5,6
   3175   //     w12     7,8
   3176   //       w121  9,10
   3177   //
   3178   // ll: layer less, eg no layer
   3179   Window root(NULL);
   3180   root.InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3181   root.SetBounds(gfx::Rect(0, 0, 100, 100));
   3182 
   3183   Window* w1ll = new Window(NULL);
   3184   w1ll->InitWithWindowLayerType(WINDOW_LAYER_NONE);
   3185   w1ll->SetBounds(gfx::Rect(1, 2, 100, 100));
   3186 
   3187   Window* w11ll = new Window(NULL);
   3188   w11ll->InitWithWindowLayerType(WINDOW_LAYER_NONE);
   3189   w11ll->SetBounds(gfx::Rect(3, 4, 100, 100));
   3190   w1ll->AddChild(w11ll);
   3191 
   3192   Window* w111 = new Window(NULL);
   3193   w111->InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3194   w111->SetBounds(gfx::Rect(5, 6, 100, 100));
   3195   w11ll->AddChild(w111);
   3196 
   3197   Window* w12 = new Window(NULL);
   3198   w12->InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3199   w12->SetBounds(gfx::Rect(7, 8, 100, 100));
   3200   w1ll->AddChild(w12);
   3201 
   3202   Window* w121 = new Window(NULL);
   3203   w121->InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3204   w121->SetBounds(gfx::Rect(9, 10, 100, 100));
   3205   w12->AddChild(w121);
   3206 
   3207   root.AddChild(w1ll);
   3208 
   3209   w111->SetBounds(gfx::Rect(7, 8, 11, 12));
   3210   EXPECT_EQ("7,8 11x12", w111->bounds().ToString());
   3211   EXPECT_EQ("7,8 11x12", w111->GetTargetBounds().ToString());
   3212   EXPECT_EQ("11,14 11x12", w111->layer()->bounds().ToString());
   3213 
   3214   // Set back.
   3215   w111->SetBounds(gfx::Rect(5, 6, 100, 100));
   3216   EXPECT_EQ("5,6 100x100", w111->bounds().ToString());
   3217   EXPECT_EQ("5,6 100x100", w111->GetTargetBounds().ToString());
   3218   EXPECT_EQ("9,12 100x100", w111->layer()->bounds().ToString());
   3219 
   3220   // Setting the bounds of a layerless window needs to adjust the bounds of
   3221   // layered children.
   3222   w11ll->SetBounds(gfx::Rect(5, 6, 100, 100));
   3223   EXPECT_EQ("5,6 100x100", w11ll->bounds().ToString());
   3224   EXPECT_EQ("5,6 100x100", w11ll->GetTargetBounds().ToString());
   3225   EXPECT_EQ("5,6 100x100", w111->bounds().ToString());
   3226   EXPECT_EQ("5,6 100x100", w111->GetTargetBounds().ToString());
   3227   EXPECT_EQ("11,14 100x100", w111->layer()->bounds().ToString());
   3228 
   3229   root.RemoveChild(w1ll);
   3230 
   3231   w111->SetBounds(gfx::Rect(7, 8, 11, 12));
   3232   EXPECT_EQ("7,8 11x12", w111->bounds().ToString());
   3233   EXPECT_EQ("7,8 11x12", w111->GetTargetBounds().ToString());
   3234   EXPECT_EQ("7,8 11x12", w111->layer()->bounds().ToString());
   3235 
   3236   delete w1ll;
   3237 }
   3238 
   3239 namespace {
   3240 
   3241 // Tracks the number of times paint is invoked along with what the clip and
   3242 // translate was.
   3243 class PaintWindowDelegate : public TestWindowDelegate {
   3244  public:
   3245   PaintWindowDelegate() : paint_count_(0) {}
   3246   virtual ~PaintWindowDelegate() {}
   3247 
   3248   const gfx::Rect& most_recent_paint_clip_bounds() const {
   3249     return most_recent_paint_clip_bounds_;
   3250   }
   3251 
   3252   const gfx::Vector2d& most_recent_paint_matrix_offset() const {
   3253     return most_recent_paint_matrix_offset_;
   3254   }
   3255 
   3256   void clear_paint_count() { paint_count_ = 0; }
   3257   int paint_count() const { return paint_count_; }
   3258 
   3259   // TestWindowDelegate::
   3260   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
   3261     paint_count_++;
   3262     canvas->GetClipBounds(&most_recent_paint_clip_bounds_);
   3263     const SkMatrix& matrix = canvas->sk_canvas()->getTotalMatrix();
   3264     most_recent_paint_matrix_offset_ = gfx::Vector2d(
   3265         SkScalarFloorToInt(matrix.getTranslateX()),
   3266         SkScalarFloorToInt(matrix.getTranslateY()));
   3267   }
   3268 
   3269  private:
   3270   int paint_count_;
   3271   gfx::Rect most_recent_paint_clip_bounds_;
   3272   gfx::Vector2d most_recent_paint_matrix_offset_;
   3273 
   3274   DISALLOW_COPY_AND_ASSIGN(PaintWindowDelegate);
   3275 };
   3276 
   3277 }  // namespace
   3278 
   3279 // Assertions around layerless children being painted when non-layerless window
   3280 // is painted.
   3281 TEST_F(WindowTest, PaintLayerless) {
   3282   // Creates the following structure (all children owned by root):
   3283   // root
   3284   //   w1ll      1,2 40x50
   3285   //     w11ll   3,4 11x12
   3286   //       w111  5,6
   3287   //
   3288   // ll: layer less, eg no layer
   3289   PaintWindowDelegate w1ll_delegate;
   3290   PaintWindowDelegate w11ll_delegate;
   3291   PaintWindowDelegate w111_delegate;
   3292 
   3293   Window root(NULL);
   3294   root.InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3295   root.SetBounds(gfx::Rect(0, 0, 100, 100));
   3296 
   3297   Window* w1ll = new Window(&w1ll_delegate);
   3298   w1ll->InitWithWindowLayerType(WINDOW_LAYER_NONE);
   3299   w1ll->SetBounds(gfx::Rect(1, 2, 40, 50));
   3300   w1ll->Show();
   3301   root.AddChild(w1ll);
   3302 
   3303   Window* w11ll = new Window(&w11ll_delegate);
   3304   w11ll->InitWithWindowLayerType(WINDOW_LAYER_NONE);
   3305   w11ll->SetBounds(gfx::Rect(3, 4, 11, 12));
   3306   w11ll->Show();
   3307   w1ll->AddChild(w11ll);
   3308 
   3309   Window* w111 = new Window(&w111_delegate);
   3310   w111->InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3311   w111->SetBounds(gfx::Rect(5, 6, 100, 100));
   3312   w111->Show();
   3313   w11ll->AddChild(w111);
   3314 
   3315   EXPECT_EQ(0, w1ll_delegate.paint_count());
   3316   EXPECT_EQ(0, w11ll_delegate.paint_count());
   3317   EXPECT_EQ(0, w111_delegate.paint_count());
   3318 
   3319   // Paint the root, this should trigger painting of the two layerless
   3320   // descendants but not the layered descendant.
   3321   gfx::Canvas canvas(gfx::Size(200, 200), 1.0f, true);
   3322   static_cast<ui::LayerDelegate&>(root).OnPaintLayer(&canvas);
   3323 
   3324   // NOTE: SkCanvas::getClipBounds() extends the clip 1 pixel to the left and up
   3325   // and 2 pixels down and to the right.
   3326   EXPECT_EQ(1, w1ll_delegate.paint_count());
   3327   EXPECT_EQ("-1,-1 42x52",
   3328             w1ll_delegate.most_recent_paint_clip_bounds().ToString());
   3329   EXPECT_EQ("[1 2]",
   3330             w1ll_delegate.most_recent_paint_matrix_offset().ToString());
   3331   EXPECT_EQ(1, w11ll_delegate.paint_count());
   3332   EXPECT_EQ("-1,-1 13x14",
   3333             w11ll_delegate.most_recent_paint_clip_bounds().ToString());
   3334   EXPECT_EQ("[4 6]",
   3335             w11ll_delegate.most_recent_paint_matrix_offset().ToString());
   3336   EXPECT_EQ(0, w111_delegate.paint_count());
   3337 }
   3338 
   3339 namespace {
   3340 
   3341 std::string ConvertPointToTargetString(const Window* source,
   3342                                        const Window* target) {
   3343   gfx::Point location;
   3344   Window::ConvertPointToTarget(source, target, &location);
   3345   return location.ToString();
   3346 }
   3347 
   3348 }  // namespace
   3349 
   3350 // Assertions around Window::ConvertPointToTarget() with layerless windows.
   3351 TEST_F(WindowTest, ConvertPointToTargetLayerless) {
   3352   // Creates the following structure (all children owned by root):
   3353   // root
   3354   //   w1ll      1,2
   3355   //     w11ll   3,4
   3356   //       w111  5,6
   3357   //     w12     7,8
   3358   //       w121  9,10
   3359   //
   3360   // ll: layer less, eg no layer
   3361   Window root(NULL);
   3362   root.InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3363   root.SetBounds(gfx::Rect(0, 0, 100, 100));
   3364 
   3365   Window* w1ll = new Window(NULL);
   3366   w1ll->InitWithWindowLayerType(WINDOW_LAYER_NONE);
   3367   w1ll->SetBounds(gfx::Rect(1, 2, 100, 100));
   3368 
   3369   Window* w11ll = new Window(NULL);
   3370   w11ll->InitWithWindowLayerType(WINDOW_LAYER_NONE);
   3371   w11ll->SetBounds(gfx::Rect(3, 4, 100, 100));
   3372   w1ll->AddChild(w11ll);
   3373 
   3374   Window* w111 = new Window(NULL);
   3375   w111->InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3376   w111->SetBounds(gfx::Rect(5, 6, 100, 100));
   3377   w11ll->AddChild(w111);
   3378 
   3379   Window* w12 = new Window(NULL);
   3380   w12->InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3381   w12->SetBounds(gfx::Rect(7, 8, 100, 100));
   3382   w1ll->AddChild(w12);
   3383 
   3384   Window* w121 = new Window(NULL);
   3385   w121->InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3386   w121->SetBounds(gfx::Rect(9, 10, 100, 100));
   3387   w12->AddChild(w121);
   3388 
   3389   root.AddChild(w1ll);
   3390 
   3391   // w111->w11ll
   3392   EXPECT_EQ("5,6", ConvertPointToTargetString(w111, w11ll));
   3393 
   3394   // w111->w1ll
   3395   EXPECT_EQ("8,10", ConvertPointToTargetString(w111, w1ll));
   3396 
   3397   // w111->root
   3398   EXPECT_EQ("9,12", ConvertPointToTargetString(w111, &root));
   3399 
   3400   // w111->w12
   3401   EXPECT_EQ("1,2", ConvertPointToTargetString(w111, w12));
   3402 
   3403   // w111->w121
   3404   EXPECT_EQ("-8,-8", ConvertPointToTargetString(w111, w121));
   3405 
   3406   // w11ll->w111
   3407   EXPECT_EQ("-5,-6", ConvertPointToTargetString(w11ll, w111));
   3408 
   3409   // w11ll->w11ll
   3410   EXPECT_EQ("3,4", ConvertPointToTargetString(w11ll, w1ll));
   3411 
   3412   // w11ll->root
   3413   EXPECT_EQ("4,6", ConvertPointToTargetString(w11ll, &root));
   3414 
   3415   // w11ll->w12
   3416   EXPECT_EQ("-4,-4", ConvertPointToTargetString(w11ll, w12));
   3417 }
   3418 
   3419 #if !defined(NDEBUG)
   3420 // Verifies PrintWindowHierarchy() doesn't crash with a layerless window.
   3421 TEST_F(WindowTest, PrintWindowHierarchyNotCrashLayerless) {
   3422   Window root(NULL);
   3423   root.InitWithWindowLayerType(WINDOW_LAYER_NONE);
   3424   root.SetBounds(gfx::Rect(0, 0, 100, 100));
   3425   root.PrintWindowHierarchy(0);
   3426 }
   3427 #endif
   3428 
   3429 namespace {
   3430 
   3431 // See AddWindowsFromString() for details.
   3432 aura::Window* CreateWindowFromDescription(const std::string& description,
   3433                                           WindowDelegate* delegate) {
   3434   WindowLayerType window_type = WINDOW_LAYER_NOT_DRAWN;
   3435   std::vector<std::string> tokens;
   3436   Tokenize(description, ":", &tokens);
   3437   DCHECK(!tokens.empty());
   3438   std::string name(tokens[0]);
   3439   tokens.erase(tokens.begin());
   3440   if (!tokens.empty()) {
   3441     if (tokens[0] == "ll") {
   3442       window_type = WINDOW_LAYER_NONE;
   3443       tokens.erase(tokens.begin());
   3444     }
   3445     DCHECK(tokens.empty()) << "unknown tokens for creating window "
   3446                            << description;
   3447   }
   3448   Window* window = new Window(delegate);
   3449   window->InitWithWindowLayerType(window_type);
   3450   window->SetName(name);
   3451   // Window name is only propagated to layer in debug builds.
   3452   if (window->layer())
   3453     window->layer()->set_name(name);
   3454   return window;
   3455 }
   3456 
   3457 // Creates and adds a tree of windows to |parent|. |description| consists
   3458 // of the following pieces:
   3459 //   X: Identifies a new window. Consists of a name and optionally ":ll" to
   3460 //      specify  WINDOW_LAYER_NONE, eg "w1:ll".
   3461 //   []: optionally used to specify the children of the window. Contains any
   3462 //       number of window identifiers and their corresponding children.
   3463 // For example: "[ a [ a1 a2:ll ] b c [ c1 ] ]" creates the tree:
   3464 //   a
   3465 //     a1
   3466 //     a2 -> WINDOW_LAYER_NONE.
   3467 //   b
   3468 //   c
   3469 //     c1
   3470 // NOTE: you must have a space after every token.
   3471 std::string::size_type AddWindowsFromString(aura::Window* parent,
   3472                                             const std::string& description,
   3473                                             std::string::size_type start_pos,
   3474                                             WindowDelegate* delegate) {
   3475   DCHECK(parent);
   3476   std::string::size_type end_pos = description.find(' ', start_pos);
   3477   while (end_pos != std::string::npos) {
   3478     const std::string::size_type part_length = end_pos - start_pos;
   3479     const std::string window_description =
   3480         description.substr(start_pos, part_length);
   3481     if (window_description == "[") {
   3482       start_pos = AddWindowsFromString(parent->children().back(),
   3483                                        description,
   3484                                        end_pos + 1,
   3485                                        delegate);
   3486       end_pos = description.find(' ', start_pos);
   3487       if (end_pos == std::string::npos && start_pos != end_pos)
   3488         end_pos = description.length();
   3489     } else if (window_description == "]") {
   3490       ++end_pos;
   3491       break;
   3492     } else {
   3493       Window* window =
   3494           CreateWindowFromDescription(window_description, delegate);
   3495       parent->AddChild(window);
   3496       start_pos = ++end_pos;
   3497       end_pos = description.find(' ', start_pos);
   3498     }
   3499   }
   3500   return end_pos;
   3501 }
   3502 
   3503 // Used by BuildRootWindowTreeDescription().
   3504 std::string BuildWindowTreeDescription(const aura::Window& window) {
   3505   std::string result;
   3506   result += window.name();
   3507   if (window.children().empty())
   3508     return result;
   3509 
   3510   result += " [ ";
   3511   for (size_t i = 0; i < window.children().size(); ++i) {
   3512     if (i != 0)
   3513       result += " ";
   3514     result += BuildWindowTreeDescription(*(window.children()[i]));
   3515   }
   3516   result += " ]";
   3517   return result;
   3518 }
   3519 
   3520 // Creates a string from |window|. See AddWindowsFromString() for details of the
   3521 // returned string. This does *not* include the layer type in the description,
   3522 // on the name.
   3523 std::string BuildRootWindowTreeDescription(const aura::Window& window) {
   3524   std::string result;
   3525   for (size_t i = 0; i < window.children().size(); ++i) {
   3526     if (i != 0)
   3527       result += " ";
   3528     result += BuildWindowTreeDescription(*(window.children()[i]));
   3529   }
   3530   return result;
   3531 }
   3532 
   3533 // Used by BuildRootWindowTreeDescription().
   3534 std::string BuildLayerTreeDescription(const ui::Layer& layer) {
   3535   std::string result;
   3536   result += layer.name();
   3537   if (layer.children().empty())
   3538     return result;
   3539 
   3540   result += " [ ";
   3541   for (size_t i = 0; i < layer.children().size(); ++i) {
   3542     if (i != 0)
   3543       result += " ";
   3544     result += BuildLayerTreeDescription(*(layer.children()[i]));
   3545   }
   3546   result += " ]";
   3547   return result;
   3548 }
   3549 
   3550 // Builds a string for all the children of |layer|. The returned string is in
   3551 // the same format as AddWindowsFromString() but only includes the name of the
   3552 // layers.
   3553 std::string BuildRootLayerTreeDescription(const ui::Layer& layer) {
   3554   std::string result;
   3555   for (size_t i = 0; i < layer.children().size(); ++i) {
   3556     if (i != 0)
   3557       result += " ";
   3558     result += BuildLayerTreeDescription(*(layer.children()[i]));
   3559   }
   3560   return result;
   3561 }
   3562 
   3563 // Returns the first window whose name matches |name| in |parent|.
   3564 aura::Window* FindWindowByName(aura::Window* parent,
   3565                                const std::string& name) {
   3566   if (parent->name() == name)
   3567     return parent;
   3568   for (size_t i = 0; i < parent->children().size(); ++i) {
   3569     aura::Window* child = FindWindowByName(parent->children()[i], name);
   3570     if (child)
   3571       return child;
   3572   }
   3573   return NULL;
   3574 }
   3575 
   3576 }  // namespace
   3577 
   3578 // Direction to stack.
   3579 enum StackType {
   3580   STACK_ABOVE,
   3581   STACK_BELOW,
   3582   STACK_AT_BOTTOM,
   3583   STACK_AT_TOP,
   3584 };
   3585 
   3586 // Permutations of StackChildAt with various data.
   3587 TEST_F(WindowTest, StackChildAtLayerless) {
   3588   struct TestData {
   3589     // Describes the window tree to create. See AddWindowsFromString() for
   3590     // details.
   3591     const std::string initial_description;
   3592 
   3593     // Identifies the window to move.
   3594     const std::string source_window;
   3595 
   3596     // Window to move |source_window| relative to. Not used for STACK_AT_BOTTOM
   3597     // or STACK_AT_TOP.
   3598     const std::string target_window;
   3599 
   3600     StackType stack_type;
   3601 
   3602     // Expected window and layer results.
   3603     const std::string expected_description;
   3604     const std::string expected_layer_description;
   3605   } data[] = {
   3606     // 1 at top.
   3607     {
   3608       "1:ll [ 11 12 ] 2:ll [ 21 ]",
   3609       "1",
   3610       "",
   3611       STACK_AT_TOP,
   3612       "2 [ 21 ] 1 [ 11 12 ]",
   3613       "21 11 12",
   3614     },
   3615 
   3616     // 1 at bottom.
   3617     {
   3618       "1:ll [ 11 12 ] 2:ll [ 21 ]",
   3619       "1",
   3620       "",
   3621       STACK_AT_BOTTOM,
   3622       "1 [ 11 12 ] 2 [ 21 ]",
   3623       "11 12 21",
   3624     },
   3625 
   3626     // 2 at bottom.
   3627     {
   3628       "1:ll [ 11 12 ] 2:ll [ 21 ]",
   3629       "2",
   3630       "",
   3631       STACK_AT_BOTTOM,
   3632       "2 [ 21 ] 1 [ 11 12 ]",
   3633       "21 11 12",
   3634     },
   3635 
   3636     // 3 below 2.
   3637     {
   3638       "1:ll [ 11 12 ] 2:ll [ 21 ] 3:ll",
   3639       "3",
   3640       "2",
   3641       STACK_BELOW,
   3642       "1 [ 11 12 ] 3 2 [ 21 ]",
   3643       "11 12 21",
   3644     },
   3645 
   3646     // 2 below 1.
   3647     {
   3648       "1:ll [ 11 12 ] 2:ll [ 21 ]",
   3649       "2",
   3650       "1",
   3651       STACK_BELOW,
   3652       "2 [ 21 ] 1 [ 11 12 ]",
   3653       "21 11 12",
   3654     },
   3655 
   3656     // 1 above 3.
   3657     {
   3658       "1:ll [ 11 12 ] 2:ll [ 21 ] 3:ll",
   3659       "1",
   3660       "3",
   3661       STACK_ABOVE,
   3662       "2 [ 21 ] 3 1 [ 11 12 ]",
   3663       "21 11 12",
   3664     },
   3665 
   3666     // 1 above 2.
   3667     {
   3668       "1:ll [ 11 12 ] 2:ll [ 21 ]",
   3669       "1",
   3670       "2",
   3671       STACK_ABOVE,
   3672       "2 [ 21 ] 1 [ 11 12 ]",
   3673       "21 11 12",
   3674     },
   3675   };
   3676   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
   3677     test::TestWindowDelegate delegate;
   3678     Window root(NULL);
   3679     root.InitWithWindowLayerType(WINDOW_LAYER_NOT_DRAWN);
   3680     root.SetBounds(gfx::Rect(0, 0, 100, 100));
   3681     AddWindowsFromString(
   3682         &root,
   3683         data[i].initial_description,
   3684         static_cast<std::string::size_type>(0), &delegate);
   3685     aura::Window* source = FindWindowByName(&root, data[i].source_window);
   3686     ASSERT_TRUE(source != NULL) << "unable to find source window "
   3687                                 << data[i].source_window << " at " << i;
   3688     aura::Window* target = FindWindowByName(&root, data[i].target_window);
   3689     switch (data[i].stack_type) {
   3690       case STACK_ABOVE:
   3691         ASSERT_TRUE(target != NULL) << "unable to find target window "
   3692                                     << data[i].target_window << " at " << i;
   3693         source->parent()->StackChildAbove(source, target);
   3694         break;
   3695       case STACK_BELOW:
   3696         ASSERT_TRUE(target != NULL) << "unable to find target window "
   3697                                     << data[i].target_window << " at " << i;
   3698         source->parent()->StackChildBelow(source, target);
   3699         break;
   3700       case STACK_AT_BOTTOM:
   3701         source->parent()->StackChildAtBottom(source);
   3702         break;
   3703       case STACK_AT_TOP:
   3704         source->parent()->StackChildAtTop(source);
   3705         break;
   3706     }
   3707     EXPECT_EQ(data[i].expected_layer_description,
   3708               BuildRootLayerTreeDescription(*root.layer()))
   3709         << "layer tree doesn't match at " << i;
   3710     EXPECT_EQ(data[i].expected_description,
   3711               BuildRootWindowTreeDescription(root))
   3712         << "window tree doesn't match at " << i;
   3713   }
   3714 }
   3715 
   3716 }  // namespace test
   3717 }  // namespace aura
   3718