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