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