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