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