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