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