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