// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/aura/window.h"

#include <limits.h>

#include <string>
#include <utility>
#include <vector>

#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind_test_util.h"
#include "build/build_config.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/capture_client.h"
#include "ui/aura/client/focus_change_observer.h"
#include "ui/aura/client/visibility_client.h"
#include "ui/aura/client/window_parenting_client.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/aura_test_utils.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/test/window_test_api.h"
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_observer.h"
#include "ui/aura/window_tracker.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/class_property.h"
#include "ui/base/hit_test.h"
#include "ui/base/ui_base_switches_util.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_animator.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/compositor/test/layer_animator_test_controller.h"
#include "ui/compositor/test/test_layers.h"
#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/events/gesture_detection/gesture_configuration.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/skia_util.h"

DEFINE_UI_CLASS_PROPERTY_TYPE(const char*)

namespace {

enum class DeletionOrder {
  LAYOUT_MANAGER_FIRST,
  PROPERTY_FIRST,
  UNKNOWN,
};

class DeletionTracker {
 public:
  DeletionTracker() {}
  ~DeletionTracker() {}

  DeletionOrder order() const { return order_; }
  bool property_deleted() const { return property_deleted_; }
  bool layout_manager_deleted() const { return layout_manager_deleted_; }

  void PropertyDeleted() {
    property_deleted_ = true;
    if (order_ == DeletionOrder::UNKNOWN)
      order_ = DeletionOrder::PROPERTY_FIRST;
  }

  void LayoutManagerDeleted() {
    layout_manager_deleted_ = true;
    if (order_ == DeletionOrder::UNKNOWN)
      order_ = DeletionOrder::LAYOUT_MANAGER_FIRST;
  }

 private:
  bool property_deleted_ = false;
  bool layout_manager_deleted_ = false;
  DeletionOrder order_ = DeletionOrder::UNKNOWN;

  DISALLOW_COPY_AND_ASSIGN(DeletionTracker);
};

class DeletionTestProperty {
 public:
  explicit DeletionTestProperty(DeletionTracker* tracker) : tracker_(tracker) {}
  ~DeletionTestProperty() { tracker_->PropertyDeleted(); }

 private:
  DeletionTracker* tracker_;

  DISALLOW_COPY_AND_ASSIGN(DeletionTestProperty);
};

DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(DeletionTestProperty,
                                   kDeletionTestPropertyKey,
                                   nullptr)

}  // namespace

DEFINE_UI_CLASS_PROPERTY_TYPE(DeletionTestProperty*)

namespace aura {
namespace test {
namespace {

class WindowTest : public AuraTestBase {
 public:
  WindowTest() : max_separation_(0) {
  }

  void SetUp() override {
    AuraTestBase::SetUp();
    // TODO: there needs to be an easier way to do this.
    max_separation_ = ui::GestureConfiguration::GetInstance()
                          ->max_separation_for_gesture_touches_in_pixels();
    ui::GestureConfiguration::GetInstance()
        ->set_max_separation_for_gesture_touches_in_pixels(0);
  }

  void TearDown() override {
    AuraTestBase::TearDown();
    ui::GestureConfiguration::GetInstance()
        ->set_max_separation_for_gesture_touches_in_pixels(max_separation_);
  }

 private:
  float max_separation_;

  DISALLOW_COPY_AND_ASSIGN(WindowTest);
};

// Used for verifying destruction methods are invoked.
class DestroyTrackingDelegateImpl : public TestWindowDelegate {
 public:
  DestroyTrackingDelegateImpl()
      : destroying_count_(0),
        destroyed_count_(0),
        in_destroying_(false) {}

  void clear_destroying_count() { destroying_count_ = 0; }
  int destroying_count() const { return destroying_count_; }

  void clear_destroyed_count() { destroyed_count_ = 0; }
  int destroyed_count() const { return destroyed_count_; }

  bool in_destroying() const { return in_destroying_; }

  void OnWindowDestroying(Window* window) override {
    EXPECT_FALSE(in_destroying_);
    in_destroying_ = true;
    destroying_count_++;
  }

  void OnWindowDestroyed(Window* window) override {
    EXPECT_TRUE(in_destroying_);
    in_destroying_ = false;
    destroyed_count_++;
  }

 private:
  int destroying_count_;
  int destroyed_count_;
  bool in_destroying_;

  DISALLOW_COPY_AND_ASSIGN(DestroyTrackingDelegateImpl);
};

// Used to verify that when OnWindowDestroying is invoked the parent is also
// is in the process of being destroyed.
class ChildWindowDelegateImpl : public DestroyTrackingDelegateImpl {
 public:
  explicit ChildWindowDelegateImpl(
      DestroyTrackingDelegateImpl* parent_delegate)
      : parent_delegate_(parent_delegate) {
  }

  void OnWindowDestroying(Window* window) override {
    EXPECT_TRUE(parent_delegate_->in_destroying());
    DestroyTrackingDelegateImpl::OnWindowDestroying(window);
  }

 private:
  DestroyTrackingDelegateImpl* parent_delegate_;

  DISALLOW_COPY_AND_ASSIGN(ChildWindowDelegateImpl);
};

// Used to verify that a Window is removed from its parent when
// OnWindowDestroyed is called.
class DestroyOrphanDelegate : public TestWindowDelegate {
 public:
  DestroyOrphanDelegate() : window_(NULL) {
  }

  void set_window(Window* window) { window_ = window; }

  void OnWindowDestroyed(Window* window) override {
    EXPECT_FALSE(window_->parent());
  }

 private:
  Window* window_;
  DISALLOW_COPY_AND_ASSIGN(DestroyOrphanDelegate);
};

// Used in verifying mouse capture.
class CaptureWindowDelegateImpl : public TestWindowDelegate {
 public:
  CaptureWindowDelegateImpl() {
    ResetCounts();
  }

  void ResetCounts() {
    capture_changed_event_count_ = 0;
    capture_lost_count_ = 0;
    mouse_event_count_ = 0;
    touch_event_count_ = 0;
    gesture_event_count_ = 0;
  }

  int capture_changed_event_count() const {
    return capture_changed_event_count_;
  }
  int capture_lost_count() const { return capture_lost_count_; }
  int mouse_event_count() const { return mouse_event_count_; }
  int touch_event_count() const { return touch_event_count_; }
  int gesture_event_count() const { return gesture_event_count_; }

  void OnMouseEvent(ui::MouseEvent* event) override {
    if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED)
      capture_changed_event_count_++;
    mouse_event_count_++;
  }
  void OnTouchEvent(ui::TouchEvent* event) override { touch_event_count_++; }
  void OnGestureEvent(ui::GestureEvent* event) override {
    gesture_event_count_++;
  }
  void OnCaptureLost() override { capture_lost_count_++; }

 private:
  int capture_changed_event_count_;
  int capture_lost_count_;
  int mouse_event_count_;
  int touch_event_count_;
  int gesture_event_count_;

  DISALLOW_COPY_AND_ASSIGN(CaptureWindowDelegateImpl);
};

// Keeps track of the location of the gesture.
class GestureTrackPositionDelegate : public TestWindowDelegate {
 public:
  GestureTrackPositionDelegate() {}

  void OnGestureEvent(ui::GestureEvent* event) override {
    position_ = event->location();
    event->StopPropagation();
  }

  const gfx::Point& position() const { return position_; }

 private:
  gfx::Point position_;

  DISALLOW_COPY_AND_ASSIGN(GestureTrackPositionDelegate);
};

base::TimeTicks getTime() {
  return ui::EventTimeForNow();
}

class SelfEventHandlingWindowDelegate : public TestWindowDelegate {
 public:
  SelfEventHandlingWindowDelegate() {}

  bool ShouldDescendIntoChildForEventHandling(
      Window* child,
      const gfx::Point& location) override {
    return false;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(SelfEventHandlingWindowDelegate);
};

// The delegate deletes itself when the window is being destroyed.
class DestroyWindowDelegate : public TestWindowDelegate {
 public:
  DestroyWindowDelegate() {}

 private:
  ~DestroyWindowDelegate() override {}

  // Overridden from WindowDelegate.
  void OnWindowDestroyed(Window* window) override { delete this; }

  DISALLOW_COPY_AND_ASSIGN(DestroyWindowDelegate);
};

void OffsetBounds(Window* window, int horizontal, int vertical) {
  gfx::Rect bounds = window->bounds();
  bounds.Offset(horizontal, vertical);
  window->SetBounds(bounds);
}

TEST_F(WindowTest, GetChildById) {
  std::unique_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
  std::unique_ptr<Window> w11(CreateTestWindowWithId(11, w1.get()));
  std::unique_ptr<Window> w111(CreateTestWindowWithId(111, w11.get()));
  std::unique_ptr<Window> w12(CreateTestWindowWithId(12, w1.get()));

  EXPECT_EQ(NULL, w1->GetChildById(57));
  EXPECT_EQ(w12.get(), w1->GetChildById(12));
  EXPECT_EQ(w111.get(), w1->GetChildById(111));
}

// Make sure that Window::Contains correctly handles children, grandchildren,
// and not containing NULL or parents.
TEST_F(WindowTest, Contains) {
  Window parent(NULL);
  parent.Init(ui::LAYER_NOT_DRAWN);
  Window child1(NULL);
  child1.Init(ui::LAYER_NOT_DRAWN);
  Window child2(NULL);
  child2.Init(ui::LAYER_NOT_DRAWN);

  parent.AddChild(&child1);
  child1.AddChild(&child2);

  EXPECT_TRUE(parent.Contains(&parent));
  EXPECT_TRUE(parent.Contains(&child1));
  EXPECT_TRUE(parent.Contains(&child2));

  EXPECT_FALSE(parent.Contains(NULL));
  EXPECT_FALSE(child1.Contains(&parent));
  EXPECT_FALSE(child2.Contains(&child1));
}

TEST_F(WindowTest, ContainsPointInRoot) {
  std::unique_ptr<Window> w(CreateTestWindow(
      SK_ColorWHITE, 1, gfx::Rect(10, 10, 5, 5), root_window()));
  EXPECT_FALSE(w->ContainsPointInRoot(gfx::Point(9, 9)));
  EXPECT_TRUE(w->ContainsPointInRoot(gfx::Point(10, 10)));
  EXPECT_TRUE(w->ContainsPointInRoot(gfx::Point(14, 14)));
  EXPECT_FALSE(w->ContainsPointInRoot(gfx::Point(15, 15)));
  EXPECT_FALSE(w->ContainsPointInRoot(gfx::Point(20, 20)));
}

TEST_F(WindowTest, ContainsPoint) {
  std::unique_ptr<Window> w(CreateTestWindow(
      SK_ColorWHITE, 1, gfx::Rect(10, 10, 5, 5), root_window()));
  EXPECT_TRUE(w->ContainsPoint(gfx::Point(0, 0)));
  EXPECT_TRUE(w->ContainsPoint(gfx::Point(4, 4)));
  EXPECT_FALSE(w->ContainsPoint(gfx::Point(5, 5)));
  EXPECT_FALSE(w->ContainsPoint(gfx::Point(10, 10)));
}

TEST_F(WindowTest, ConvertPointToWindow) {
  // Window::ConvertPointToWindow is mostly identical to
  // Layer::ConvertPointToLayer, except NULL values for |source| are permitted,
  // in which case the function just returns.
  std::unique_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
  gfx::Point reference_point(100, 100);
  gfx::Point test_point = reference_point;
  Window::ConvertPointToTarget(NULL, w1.get(), &test_point);
  EXPECT_EQ(reference_point, test_point);
}

TEST_F(WindowTest, MoveCursorTo) {
  std::unique_ptr<Window> w1(CreateTestWindow(
      SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500), root_window()));
  std::unique_ptr<Window> w11(
      CreateTestWindow(SK_ColorGREEN, 11, gfx::Rect(5, 5, 100, 100), w1.get()));
  std::unique_ptr<Window> w111(
      CreateTestWindow(SK_ColorCYAN, 111, gfx::Rect(5, 5, 75, 75), w11.get()));
  std::unique_ptr<Window> w1111(
      CreateTestWindow(SK_ColorRED, 1111, gfx::Rect(5, 5, 50, 50), w111.get()));

  Window* root = root_window();
  root->MoveCursorTo(gfx::Point(10, 10));
  EXPECT_EQ("10,10",
            display::Screen::GetScreen()->GetCursorScreenPoint().ToString());
  w1->MoveCursorTo(gfx::Point(10, 10));
  EXPECT_EQ("20,20",
            display::Screen::GetScreen()->GetCursorScreenPoint().ToString());
  w11->MoveCursorTo(gfx::Point(10, 10));
  EXPECT_EQ("25,25",
            display::Screen::GetScreen()->GetCursorScreenPoint().ToString());
  w111->MoveCursorTo(gfx::Point(10, 10));
  EXPECT_EQ("30,30",
            display::Screen::GetScreen()->GetCursorScreenPoint().ToString());
  w1111->MoveCursorTo(gfx::Point(10, 10));
  EXPECT_EQ("35,35",
            display::Screen::GetScreen()->GetCursorScreenPoint().ToString());
}

TEST_F(WindowTest, ContainsMouse) {
  std::unique_ptr<Window> w(CreateTestWindow(
      SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500), root_window()));
  w->Show();
  WindowTestApi w_test_api(w.get());
  Window* root = root_window();
  root->MoveCursorTo(gfx::Point(10, 10));
  EXPECT_TRUE(w_test_api.ContainsMouse());
  root->MoveCursorTo(gfx::Point(9, 10));
  EXPECT_FALSE(w_test_api.ContainsMouse());
}

// Tests that the root window gets a valid LocalSurfaceId.
TEST_F(WindowTest, RootWindowHasValidLocalSurfaceId) {
  EXPECT_TRUE(root_window()
                  ->GetLocalSurfaceIdAllocation()
                  .local_surface_id()
                  .is_valid());
}

TEST_F(WindowTest, WindowEmbeddingClientHasValidLocalSurfaceId) {
  std::unique_ptr<Window> window(CreateTestWindow(
      SK_ColorWHITE, 1, gfx::Rect(10, 10, 300, 200), root_window()));
  test::WindowTestApi(window.get()).DisableFrameSinkRegistration();
  window->SetEmbedFrameSinkId(viz::FrameSinkId(0, 1));
  EXPECT_TRUE(
      window->GetLocalSurfaceIdAllocation().local_surface_id().is_valid());
}

// Test Window::ConvertPointToWindow() with transform to root_window.
TEST_F(WindowTest, MoveCursorToWithTransformRootWindow) {
  gfx::Transform transform;
  transform.Translate(100.0, 100.0);
  transform.Rotate(90.0);
  transform.Scale(2.0, 5.0);
  host()->SetRootTransform(transform);
  host()->MoveCursorToLocationInDIP(gfx::Point(10, 10));
#if !defined(OS_WIN)
  // TODO(yoshiki): fix this to build on Windows. See crbug.com/133413.OD
  EXPECT_EQ("50,120", QueryLatestMousePositionRequestInHost(host()).ToString());
#endif
  EXPECT_EQ("10,10",
            display::Screen::GetScreen()->GetCursorScreenPoint().ToString());
}

// Tests Window::ConvertPointToWindow() with transform to non-root windows.
TEST_F(WindowTest, MoveCursorToWithTransformWindow) {
  std::unique_ptr<Window> w1(CreateTestWindow(
      SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500), root_window()));

  gfx::Transform transform1;
  transform1.Scale(2, 2);
  w1->SetTransform(transform1);
  w1->MoveCursorTo(gfx::Point(10, 10));
  EXPECT_EQ("30,30",
            display::Screen::GetScreen()->GetCursorScreenPoint().ToString());

  gfx::Transform transform2;
  transform2.Translate(-10, 20);
  w1->SetTransform(transform2);
  w1->MoveCursorTo(gfx::Point(10, 10));
  EXPECT_EQ("10,40",
            display::Screen::GetScreen()->GetCursorScreenPoint().ToString());

  gfx::Transform transform3;
  transform3.Rotate(90.0);
  w1->SetTransform(transform3);
  w1->MoveCursorTo(gfx::Point(5, 5));
  EXPECT_EQ("5,15",
            display::Screen::GetScreen()->GetCursorScreenPoint().ToString());

  gfx::Transform transform4;
  transform4.Translate(100.0, 100.0);
  transform4.Rotate(90.0);
  transform4.Scale(2.0, 5.0);
  w1->SetTransform(transform4);
  w1->MoveCursorTo(gfx::Point(10, 10));
  EXPECT_EQ("60,130",
            display::Screen::GetScreen()->GetCursorScreenPoint().ToString());
}

// Test Window::ConvertPointToWindow() with complex transforms to both root and
// non-root windows.
// Test Window::ConvertPointToWindow() with transform to root_window.
TEST_F(WindowTest, MoveCursorToWithComplexTransform) {
  std::unique_ptr<Window> w1(CreateTestWindow(
      SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500), root_window()));
  std::unique_ptr<Window> w11(
      CreateTestWindow(SK_ColorGREEN, 11, gfx::Rect(5, 5, 100, 100), w1.get()));
  std::unique_ptr<Window> w111(
      CreateTestWindow(SK_ColorCYAN, 111, gfx::Rect(5, 5, 75, 75), w11.get()));
  std::unique_ptr<Window> w1111(
      CreateTestWindow(SK_ColorRED, 1111, gfx::Rect(5, 5, 50, 50), w111.get()));

  // The root window expects transforms that produce integer rects.
  gfx::Transform root_transform;
  root_transform.Translate(60.0, 70.0);
  root_transform.Rotate(-90.0);
  root_transform.Translate(-50.0, -50.0);
  root_transform.Scale(2.0, 3.0);

  gfx::Transform transform;
  transform.Translate(10.0, 20.0);
  transform.Rotate(10.0);
  transform.Scale(0.3f, 0.5f);
  host()->SetRootTransform(root_transform);
  w1->SetTransform(transform);
  w11->SetTransform(transform);
  w111->SetTransform(transform);
  w1111->SetTransform(transform);

  w1111->MoveCursorTo(gfx::Point(10, 10));

#if !defined(OS_WIN)
  // TODO(yoshiki): fix this to build on Windows. See crbug.com/133413.
  EXPECT_EQ("169,80", QueryLatestMousePositionRequestInHost(host()).ToString());
#endif
  EXPECT_EQ("20,53",
            display::Screen::GetScreen()->GetCursorScreenPoint().ToString());
}

// Tests that we do not crash when a Window is destroyed by going out of
// scope (as opposed to being explicitly deleted by its WindowDelegate).
TEST_F(WindowTest, NoCrashOnWindowDelete) {
  CaptureWindowDelegateImpl delegate;
  std::unique_ptr<Window> window(CreateTestWindowWithDelegate(
      &delegate, 0, gfx::Rect(0, 0, 20, 20), root_window()));
}

TEST_F(WindowTest, GetEventHandlerForPoint) {
  std::unique_ptr<Window> w1(CreateTestWindow(
      SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500), root_window()));
  std::unique_ptr<Window> w11(
      CreateTestWindow(SK_ColorGREEN, 11, gfx::Rect(5, 5, 100, 100), w1.get()));
  std::unique_ptr<Window> w111(
      CreateTestWindow(SK_ColorCYAN, 111, gfx::Rect(5, 5, 75, 75), w11.get()));
  std::unique_ptr<Window> w1111(
      CreateTestWindow(SK_ColorRED, 1111, gfx::Rect(5, 5, 50, 50), w111.get()));
  std::unique_ptr<Window> w12(CreateTestWindow(
      SK_ColorMAGENTA, 12, gfx::Rect(10, 420, 25, 25), w1.get()));
  std::unique_ptr<Window> w121(
      CreateTestWindow(SK_ColorYELLOW, 121, gfx::Rect(5, 5, 5, 5), w12.get()));
  std::unique_ptr<Window> w13(
      CreateTestWindow(SK_ColorGRAY, 13, gfx::Rect(5, 470, 50, 50), w1.get()));

  Window* root = root_window();
  w1->parent()->SetBounds(gfx::Rect(500, 500));
  EXPECT_EQ(NULL, root->GetEventHandlerForPoint(gfx::Point(5, 5)));
  EXPECT_EQ(w1.get(), root->GetEventHandlerForPoint(gfx::Point(11, 11)));
  EXPECT_EQ(w11.get(), root->GetEventHandlerForPoint(gfx::Point(16, 16)));
  EXPECT_EQ(w111.get(), root->GetEventHandlerForPoint(gfx::Point(21, 21)));
  EXPECT_EQ(w1111.get(), root->GetEventHandlerForPoint(gfx::Point(26, 26)));
  EXPECT_EQ(w12.get(), root->GetEventHandlerForPoint(gfx::Point(21, 431)));
  EXPECT_EQ(w121.get(), root->GetEventHandlerForPoint(gfx::Point(26, 436)));
  EXPECT_EQ(w13.get(), root->GetEventHandlerForPoint(gfx::Point(26, 481)));
}

TEST_F(WindowTest, GetEventHandlerForPointInCornerOfChildBounds) {
  // If our child is flush to our top-left corner it gets events just inside the
  // window edges.
  std::unique_ptr<Window> parent(CreateTestWindow(
      SK_ColorWHITE, 1, gfx::Rect(10, 20, 400, 500), root_window()));
  std::unique_ptr<Window> child(
      CreateTestWindow(SK_ColorRED, 2, gfx::Rect(0, 0, 60, 70), parent.get()));
  EXPECT_EQ(child.get(), parent->GetEventHandlerForPoint(gfx::Point(0, 0)));
  EXPECT_EQ(child.get(), parent->GetEventHandlerForPoint(gfx::Point(1, 1)));
}

TEST_F(WindowTest, GetEventHandlerForPointWithOverrideDescendingOrder) {
  std::unique_ptr<SelfEventHandlingWindowDelegate> parent_delegate(
      new SelfEventHandlingWindowDelegate);
  std::unique_ptr<Window> parent(CreateTestWindowWithDelegate(
      parent_delegate.get(), 1, gfx::Rect(10, 20, 400, 500), root_window()));
  std::unique_ptr<Window> child(CreateTestWindow(
      SK_ColorRED, 2, gfx::Rect(0, 0, 390, 480), parent.get()));

  // We can override ShouldDescendIntoChildForEventHandling to make the parent
  // grab all events.
  EXPECT_EQ(parent.get(), parent->GetEventHandlerForPoint(gfx::Point(0, 0)));
  EXPECT_EQ(parent.get(), parent->GetEventHandlerForPoint(gfx::Point(50, 50)));
}

TEST_F(WindowTest, GetToplevelWindow) {
  const gfx::Rect kBounds(0, 0, 10, 10);
  TestWindowDelegate delegate;

  std::unique_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
  std::unique_ptr<Window> w11(
      CreateTestWindowWithDelegate(&delegate, 11, kBounds, w1.get()));
  std::unique_ptr<Window> w111(CreateTestWindowWithId(111, w11.get()));
  std::unique_ptr<Window> w1111(
      CreateTestWindowWithDelegate(&delegate, 1111, kBounds, w111.get()));

  EXPECT_TRUE(root_window()->GetToplevelWindow() == NULL);
  EXPECT_TRUE(w1->GetToplevelWindow() == NULL);
  EXPECT_EQ(w11.get(), w11->GetToplevelWindow());
  EXPECT_EQ(w11.get(), w111->GetToplevelWindow());
  EXPECT_EQ(w11.get(), w1111->GetToplevelWindow());
}

class AddedToRootWindowObserver : public WindowObserver {
 public:
  AddedToRootWindowObserver() : called_(false) {}

  void OnWindowAddedToRootWindow(Window* window) override { called_ = true; }

  bool called() const { return called_; }

 private:
  bool called_;

  DISALLOW_COPY_AND_ASSIGN(AddedToRootWindowObserver);
};

TEST_F(WindowTest, WindowAddedToRootWindowShouldNotifyChildAndNotParent) {
  AddedToRootWindowObserver parent_observer;
  AddedToRootWindowObserver child_observer;
  std::unique_ptr<Window> parent_window(
      CreateTestWindowWithId(1, root_window()));
  std::unique_ptr<Window> child_window(new Window(NULL));
  child_window->Init(ui::LAYER_TEXTURED);
  child_window->Show();

  parent_window->AddObserver(&parent_observer);
  child_window->AddObserver(&child_observer);

  parent_window->AddChild(child_window.get());

  EXPECT_FALSE(parent_observer.called());
  EXPECT_TRUE(child_observer.called());

  parent_window->RemoveObserver(&parent_observer);
  child_window->RemoveObserver(&child_observer);
}

// Various destruction assertions.
TEST_F(WindowTest, DestroyTest) {
  DestroyTrackingDelegateImpl parent_delegate;
  ChildWindowDelegateImpl child_delegate(&parent_delegate);
  {
    std::unique_ptr<Window> parent(CreateTestWindowWithDelegate(
        &parent_delegate, 0, gfx::Rect(), root_window()));
    CreateTestWindowWithDelegate(&child_delegate, 0, gfx::Rect(), parent.get());
  }
  // Both the parent and child should have been destroyed.
  EXPECT_EQ(1, parent_delegate.destroying_count());
  EXPECT_EQ(1, parent_delegate.destroyed_count());
  EXPECT_EQ(1, child_delegate.destroying_count());
  EXPECT_EQ(1, child_delegate.destroyed_count());
}

// Tests that a window is orphaned before OnWindowDestroyed is called.
TEST_F(WindowTest, OrphanedBeforeOnDestroyed) {
  TestWindowDelegate parent_delegate;
  DestroyOrphanDelegate child_delegate;
  {
    std::unique_ptr<Window> parent(CreateTestWindowWithDelegate(
        &parent_delegate, 0, gfx::Rect(), root_window()));
    std::unique_ptr<Window> child(CreateTestWindowWithDelegate(
        &child_delegate, 0, gfx::Rect(), parent.get()));
    child_delegate.set_window(child.get());
  }
}

// Make sure StackChildAtTop moves both the window and layer to the front.
TEST_F(WindowTest, StackChildAtTop) {
  Window parent(NULL);
  parent.Init(ui::LAYER_NOT_DRAWN);
  Window child1(NULL);
  child1.Init(ui::LAYER_NOT_DRAWN);
  Window child2(NULL);
  child2.Init(ui::LAYER_NOT_DRAWN);

  parent.AddChild(&child1);
  parent.AddChild(&child2);
  ASSERT_EQ(2u, parent.children().size());
  EXPECT_EQ(&child1, parent.children()[0]);
  EXPECT_EQ(&child2, parent.children()[1]);
  ASSERT_EQ(2u, parent.layer()->children().size());
  EXPECT_EQ(child1.layer(), parent.layer()->children()[0]);
  EXPECT_EQ(child2.layer(), parent.layer()->children()[1]);

  parent.StackChildAtTop(&child1);
  ASSERT_EQ(2u, parent.children().size());
  EXPECT_EQ(&child1, parent.children()[1]);
  EXPECT_EQ(&child2, parent.children()[0]);
  ASSERT_EQ(2u, parent.layer()->children().size());
  EXPECT_EQ(child1.layer(), parent.layer()->children()[1]);
  EXPECT_EQ(child2.layer(), parent.layer()->children()[0]);
}

// Make sure StackChildBelow works.
TEST_F(WindowTest, StackChildBelow) {
  Window parent(NULL);
  parent.Init(ui::LAYER_NOT_DRAWN);
  Window child1(NULL);
  child1.Init(ui::LAYER_NOT_DRAWN);
  child1.set_id(1);
  Window child2(NULL);
  child2.Init(ui::LAYER_NOT_DRAWN);
  child2.set_id(2);
  Window child3(NULL);
  child3.Init(ui::LAYER_NOT_DRAWN);
  child3.set_id(3);

  parent.AddChild(&child1);
  parent.AddChild(&child2);
  parent.AddChild(&child3);
  EXPECT_EQ("1 2 3", ChildWindowIDsAsString(&parent));

  parent.StackChildBelow(&child1, &child2);
  EXPECT_EQ("1 2 3", ChildWindowIDsAsString(&parent));

  parent.StackChildBelow(&child2, &child1);
  EXPECT_EQ("2 1 3", ChildWindowIDsAsString(&parent));

  parent.StackChildBelow(&child3, &child2);
  EXPECT_EQ("3 2 1", ChildWindowIDsAsString(&parent));

  parent.StackChildBelow(&child3, &child1);
  EXPECT_EQ("2 3 1", ChildWindowIDsAsString(&parent));
}

// Various assertions for StackChildAbove.
TEST_F(WindowTest, StackChildAbove) {
  Window parent(NULL);
  parent.Init(ui::LAYER_NOT_DRAWN);
  Window child1(NULL);
  child1.Init(ui::LAYER_NOT_DRAWN);
  Window child2(NULL);
  child2.Init(ui::LAYER_NOT_DRAWN);
  Window child3(NULL);
  child3.Init(ui::LAYER_NOT_DRAWN);

  parent.AddChild(&child1);
  parent.AddChild(&child2);

  // Move 1 in front of 2.
  parent.StackChildAbove(&child1, &child2);
  ASSERT_EQ(2u, parent.children().size());
  EXPECT_EQ(&child2, parent.children()[0]);
  EXPECT_EQ(&child1, parent.children()[1]);
  ASSERT_EQ(2u, parent.layer()->children().size());
  EXPECT_EQ(child2.layer(), parent.layer()->children()[0]);
  EXPECT_EQ(child1.layer(), parent.layer()->children()[1]);

  // Add 3, resulting in order [2, 1, 3], then move 2 in front of 1, resulting
  // in [1, 2, 3].
  parent.AddChild(&child3);
  parent.StackChildAbove(&child2, &child1);
  ASSERT_EQ(3u, parent.children().size());
  EXPECT_EQ(&child1, parent.children()[0]);
  EXPECT_EQ(&child2, parent.children()[1]);
  EXPECT_EQ(&child3, parent.children()[2]);
  ASSERT_EQ(3u, parent.layer()->children().size());
  EXPECT_EQ(child1.layer(), parent.layer()->children()[0]);
  EXPECT_EQ(child2.layer(), parent.layer()->children()[1]);
  EXPECT_EQ(child3.layer(), parent.layer()->children()[2]);

  // Move 1 in front of 3, resulting in [2, 3, 1].
  parent.StackChildAbove(&child1, &child3);
  ASSERT_EQ(3u, parent.children().size());
  EXPECT_EQ(&child2, parent.children()[0]);
  EXPECT_EQ(&child3, parent.children()[1]);
  EXPECT_EQ(&child1, parent.children()[2]);
  ASSERT_EQ(3u, parent.layer()->children().size());
  EXPECT_EQ(child2.layer(), parent.layer()->children()[0]);
  EXPECT_EQ(child3.layer(), parent.layer()->children()[1]);
  EXPECT_EQ(child1.layer(), parent.layer()->children()[2]);

  // Moving 1 in front of 2 should lower it, resulting in [2, 1, 3].
  parent.StackChildAbove(&child1, &child2);
  ASSERT_EQ(3u, parent.children().size());
  EXPECT_EQ(&child2, parent.children()[0]);
  EXPECT_EQ(&child1, parent.children()[1]);
  EXPECT_EQ(&child3, parent.children()[2]);
  ASSERT_EQ(3u, parent.layer()->children().size());
  EXPECT_EQ(child2.layer(), parent.layer()->children()[0]);
  EXPECT_EQ(child1.layer(), parent.layer()->children()[1]);
  EXPECT_EQ(child3.layer(), parent.layer()->children()[2]);
}

// Various capture assertions.
TEST_F(WindowTest, CaptureTests) {
  CaptureWindowDelegateImpl delegate;
  std::unique_ptr<Window> window(CreateTestWindowWithDelegate(
      &delegate, 0, gfx::Rect(0, 0, 20, 20), root_window()));
  EXPECT_FALSE(window->HasCapture());

  delegate.ResetCounts();

  // Do a capture.
  window->SetCapture();
  EXPECT_TRUE(window->HasCapture());
  EXPECT_EQ(0, delegate.capture_lost_count());
  EXPECT_EQ(0, delegate.capture_changed_event_count());
  ui::test::EventGenerator generator(root_window(), gfx::Point(50, 50));
  generator.PressLeftButton();
  EXPECT_EQ(1, delegate.mouse_event_count());
  generator.ReleaseLeftButton();

  EXPECT_EQ(2, delegate.mouse_event_count());
  delegate.ResetCounts();

  ui::TouchEvent touchev(
      ui::ET_TOUCH_PRESSED, gfx::Point(50, 50), getTime(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  DispatchEventUsingWindowDispatcher(&touchev);
  EXPECT_EQ(1, delegate.touch_event_count());
  delegate.ResetCounts();

  window->ReleaseCapture();
  EXPECT_FALSE(window->HasCapture());
  EXPECT_EQ(1, delegate.capture_lost_count());
  EXPECT_EQ(1, delegate.capture_changed_event_count());
  EXPECT_EQ(1, delegate.mouse_event_count());
  EXPECT_EQ(0, delegate.touch_event_count());

  generator.PressLeftButton();
  EXPECT_EQ(1, delegate.mouse_event_count());

  ui::TouchEvent touchev2(
      ui::ET_TOUCH_PRESSED, gfx::Point(250, 250), getTime(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1));
  DispatchEventUsingWindowDispatcher(&touchev2);
  EXPECT_EQ(0, delegate.touch_event_count());

  // Removing the capture window from parent should reset the capture window
  // in the root window.
  window->SetCapture();
  EXPECT_EQ(window.get(), aura::client::GetCaptureWindow(root_window()));
  window->parent()->RemoveChild(window.get());
  EXPECT_FALSE(window->HasCapture());
  EXPECT_EQ(NULL, aura::client::GetCaptureWindow(root_window()));
}

TEST_F(WindowTest, TouchCaptureCancelsOtherTouches) {
  CaptureWindowDelegateImpl delegate1;
  std::unique_ptr<Window> w1(CreateTestWindowWithDelegate(
      &delegate1, 0, gfx::Rect(0, 0, 50, 50), root_window()));
  CaptureWindowDelegateImpl delegate2;
  std::unique_ptr<Window> w2(CreateTestWindowWithDelegate(
      &delegate2, 0, gfx::Rect(50, 50, 50, 50), root_window()));

  // Press on w1.
  ui::TouchEvent press1(
      ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), getTime(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  DispatchEventUsingWindowDispatcher(&press1);
  // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN.
  EXPECT_EQ(2, delegate1.gesture_event_count());
  delegate1.ResetCounts();

  // Capturing to w2 should cause the touch to be canceled.
  w2->SetCapture();
  EXPECT_EQ(1, delegate1.touch_event_count());
  EXPECT_EQ(0, delegate2.touch_event_count());
  delegate1.ResetCounts();
  delegate2.ResetCounts();

  // Events are now untargetted.
  ui::TouchEvent move(
      ui::ET_TOUCH_MOVED, gfx::Point(10, 20), getTime(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  DispatchEventUsingWindowDispatcher(&move);
  EXPECT_EQ(0, delegate1.gesture_event_count());
  EXPECT_EQ(0, delegate1.touch_event_count());
  EXPECT_EQ(0, delegate2.gesture_event_count());
  EXPECT_EQ(0, delegate2.touch_event_count());

  ui::TouchEvent release(
      ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), getTime(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  DispatchEventUsingWindowDispatcher(&release);
  EXPECT_EQ(0, delegate1.gesture_event_count());
  EXPECT_EQ(0, delegate2.gesture_event_count());

  // A new press is captured by w2.
  ui::TouchEvent press2(
      ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), getTime(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  DispatchEventUsingWindowDispatcher(&press2);
  EXPECT_EQ(0, delegate1.gesture_event_count());
  // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN.
  EXPECT_EQ(2, delegate2.gesture_event_count());
  delegate1.ResetCounts();
  delegate2.ResetCounts();

  // And releasing capture changes nothing.
  w2->ReleaseCapture();
  EXPECT_EQ(0, delegate1.gesture_event_count());
  EXPECT_EQ(0, delegate1.touch_event_count());
  EXPECT_EQ(0, delegate2.gesture_event_count());
  EXPECT_EQ(0, delegate2.touch_event_count());
}

TEST_F(WindowTest, TouchCaptureDoesntCancelCapturedTouches) {
  CaptureWindowDelegateImpl delegate;
  std::unique_ptr<Window> window(CreateTestWindowWithDelegate(
      &delegate, 0, gfx::Rect(0, 0, 50, 50), root_window()));
  base::TimeTicks time = getTime();
  const int kTimeDelta = 100;

  ui::TouchEvent press(
      ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), time,
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  DispatchEventUsingWindowDispatcher(&press);

  // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN.
  EXPECT_EQ(2, delegate.gesture_event_count());
  EXPECT_EQ(1, delegate.touch_event_count());
  delegate.ResetCounts();

  window->SetCapture();
  EXPECT_EQ(0, delegate.gesture_event_count());
  EXPECT_EQ(0, delegate.touch_event_count());
  delegate.ResetCounts();

  // On move We will get TOUCH_MOVED, GESTURE_TAP_CANCEL,
  // GESTURE_SCROLL_START and GESTURE_SCROLL_UPDATE.
  time += base::TimeDelta::FromMilliseconds(kTimeDelta);
  ui::TouchEvent move(
      ui::ET_TOUCH_MOVED, gfx::Point(10, 20), time,
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  DispatchEventUsingWindowDispatcher(&move);
  EXPECT_EQ(1, delegate.touch_event_count());
  EXPECT_EQ(3, delegate.gesture_event_count());
  delegate.ResetCounts();

  // Release capture shouldn't change anything.
  window->ReleaseCapture();
  EXPECT_EQ(0, delegate.touch_event_count());
  EXPECT_EQ(0, delegate.gesture_event_count());
  delegate.ResetCounts();

  // On move we still get TOUCH_MOVED and GESTURE_SCROLL_UPDATE.
  time += base::TimeDelta::FromMilliseconds(kTimeDelta);
  ui::TouchEvent move2(
      ui::ET_TOUCH_MOVED, gfx::Point(10, 30), time,
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  DispatchEventUsingWindowDispatcher(&move2);
  EXPECT_EQ(1, delegate.touch_event_count());
  EXPECT_EQ(1, delegate.gesture_event_count());
  delegate.ResetCounts();

  // And on release we get TOUCH_RELEASED, GESTURE_SCROLL_END, GESTURE_END
  time += base::TimeDelta::FromMilliseconds(kTimeDelta);
  ui::TouchEvent release(
      ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), time,
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  DispatchEventUsingWindowDispatcher(&release);
  EXPECT_EQ(1, delegate.touch_event_count());
  EXPECT_EQ(2, delegate.gesture_event_count());
}

// Assertions around SetCapture() and touch/gestures.
TEST_F(WindowTest, TransferCaptureTouchEvents) {
  // Touch on |w1|.
  CaptureWindowDelegateImpl d1;
  std::unique_ptr<Window> w1(CreateTestWindowWithDelegate(
      &d1, 0, gfx::Rect(0, 0, 20, 20), root_window()));
  ui::TouchEvent p1(
      ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), getTime(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  DispatchEventUsingWindowDispatcher(&p1);
  // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN.
  EXPECT_EQ(1, d1.touch_event_count());
  EXPECT_EQ(2, d1.gesture_event_count());
  d1.ResetCounts();

  // Touch on |w2| with a different id.
  CaptureWindowDelegateImpl d2;
  std::unique_ptr<Window> w2(CreateTestWindowWithDelegate(
      &d2, 0, gfx::Rect(40, 0, 40, 20), root_window()));
  ui::TouchEvent p2(
      ui::ET_TOUCH_PRESSED, gfx::Point(41, 10), getTime(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1));
  DispatchEventUsingWindowDispatcher(&p2);
  EXPECT_EQ(0, d1.touch_event_count());
  EXPECT_EQ(0, d1.gesture_event_count());
  // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN for new target window.
  EXPECT_EQ(1, d2.touch_event_count());
  EXPECT_EQ(2, d2.gesture_event_count());
  d1.ResetCounts();
  d2.ResetCounts();

  // Set capture on |w2|, this should send a cancel (TAP_CANCEL, END) to |w1|
  // but not |w2|.
  w2->SetCapture();
  EXPECT_EQ(1, d1.touch_event_count());
  EXPECT_EQ(2, d1.gesture_event_count());
  EXPECT_EQ(0, d2.touch_event_count());
  EXPECT_EQ(0, d2.gesture_event_count());
  d1.ResetCounts();
  d2.ResetCounts();

  CaptureWindowDelegateImpl d3;
  std::unique_ptr<Window> w3(CreateTestWindowWithDelegate(
      &d3, 0, gfx::Rect(0, 0, 100, 101), root_window()));
  // Set capture on |w3|. All touches have already been cancelled.
  w3->SetCapture();
  EXPECT_EQ(0, d1.touch_event_count());
  EXPECT_EQ(0, d1.gesture_event_count());
  EXPECT_EQ(1, d2.touch_event_count());
  EXPECT_EQ(2, d2.gesture_event_count());
  EXPECT_EQ(0, d3.touch_event_count());
  EXPECT_EQ(0, d3.gesture_event_count());
  d2.ResetCounts();

  // Move touch id originally associated with |w2|. The touch has been
  // cancelled, so no events should be dispatched.
  ui::TouchEvent m3(
      ui::ET_TOUCH_MOVED, gfx::Point(110, 105), getTime(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1));
  DispatchEventUsingWindowDispatcher(&m3);
  EXPECT_EQ(0, d1.touch_event_count());
  EXPECT_EQ(0, d1.gesture_event_count());
  EXPECT_EQ(0, d2.touch_event_count());
  EXPECT_EQ(0, d2.gesture_event_count());
  EXPECT_EQ(0, d3.touch_event_count());
  EXPECT_EQ(0, d3.gesture_event_count());

  // When we release capture, no touches are canceled.
  w3->ReleaseCapture();
  EXPECT_EQ(0, d1.touch_event_count());
  EXPECT_EQ(0, d1.gesture_event_count());
  EXPECT_EQ(0, d2.touch_event_count());
  EXPECT_EQ(0, d2.gesture_event_count());
  EXPECT_EQ(0, d3.touch_event_count());
  EXPECT_EQ(0, d3.gesture_event_count());

  // The touch has been cancelled, so no events are dispatched.
  ui::TouchEvent m4(
      ui::ET_TOUCH_MOVED, gfx::Point(120, 105), getTime(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1));
  DispatchEventUsingWindowDispatcher(&m4);
  EXPECT_EQ(0, d1.touch_event_count());
  EXPECT_EQ(0, d1.gesture_event_count());
  EXPECT_EQ(0, d2.touch_event_count());
  EXPECT_EQ(0, d2.gesture_event_count());
  EXPECT_EQ(0, d3.touch_event_count());
  EXPECT_EQ(0, d3.gesture_event_count());
}

// Changes capture while capture is already ongoing.
TEST_F(WindowTest, ChangeCaptureWhileMouseDown) {
  CaptureWindowDelegateImpl delegate;
  std::unique_ptr<Window> window(CreateTestWindowWithDelegate(
      &delegate, 0, gfx::Rect(0, 0, 20, 20), root_window()));
  CaptureWindowDelegateImpl delegate2;
  std::unique_ptr<Window> w2(CreateTestWindowWithDelegate(
      &delegate2, 0, gfx::Rect(20, 20, 20, 20), root_window()));

  // Execute the scheduled draws so that mouse events are not
  // aggregated.
  RunAllPendingInMessageLoop();

  EXPECT_FALSE(window->HasCapture());

  // Do a capture.
  delegate.ResetCounts();
  window->SetCapture();
  EXPECT_TRUE(window->HasCapture());
  EXPECT_EQ(0, delegate.capture_lost_count());
  EXPECT_EQ(0, delegate.capture_changed_event_count());
  ui::test::EventGenerator generator(root_window(), gfx::Point(50, 50));
  generator.PressLeftButton();
  EXPECT_EQ(0, delegate.capture_lost_count());
  EXPECT_EQ(0, delegate.capture_changed_event_count());
  EXPECT_EQ(1, delegate.mouse_event_count());

  // Set capture to |w2|, should implicitly unset capture for |window|.
  delegate.ResetCounts();
  delegate2.ResetCounts();
  w2->SetCapture();

  generator.MoveMouseTo(gfx::Point(40, 40), 2);
  EXPECT_EQ(1, delegate.capture_lost_count());
  EXPECT_EQ(1, delegate.capture_changed_event_count());
  EXPECT_EQ(1, delegate.mouse_event_count());
  EXPECT_EQ(2, delegate2.mouse_event_count());
}

// Verifies capture is reset when a window is destroyed.
TEST_F(WindowTest, ReleaseCaptureOnDestroy) {
  CaptureWindowDelegateImpl delegate;
  std::unique_ptr<Window> window(CreateTestWindowWithDelegate(
      &delegate, 0, gfx::Rect(0, 0, 20, 20), root_window()));
  EXPECT_FALSE(window->HasCapture());

  // Do a capture.
  window->SetCapture();
  EXPECT_TRUE(window->HasCapture());

  // Destroy the window.
  window.reset();

  // Make sure the root window doesn't reference the window anymore.
  EXPECT_EQ(NULL, host()->dispatcher()->mouse_pressed_handler());
  EXPECT_EQ(NULL, aura::client::GetCaptureWindow(root_window()));
}

TEST_F(WindowTest, GetBoundsInRootWindow) {
  std::unique_ptr<Window> viewport(
      CreateTestWindowWithBounds(gfx::Rect(0, 0, 300, 300), root_window()));
  std::unique_ptr<Window> child(
      CreateTestWindowWithBounds(gfx::Rect(0, 0, 100, 100), viewport.get()));
  // Sanity check.
  EXPECT_EQ("0,0 100x100", child->GetBoundsInRootWindow().ToString());

  // The |child| window's screen bounds should move along with the |viewport|.
  viewport->SetBounds(gfx::Rect(-100, -100, 300, 300));
  EXPECT_EQ("-100,-100 100x100", child->GetBoundsInRootWindow().ToString());

  // The |child| window is moved to the 0,0 in screen coordinates.
  // |GetBoundsInRootWindow()| should return 0,0.
  child->SetBounds(gfx::Rect(100, 100, 100, 100));
  EXPECT_EQ("0,0 100x100", child->GetBoundsInRootWindow().ToString());
}

TEST_F(WindowTest, GetBoundsInRootWindowWithLayers) {
  std::unique_ptr<Window> viewport(
      CreateTestWindowWithBounds(gfx::Rect(0, 0, 300, 300), root_window()));

  std::unique_ptr<Window> widget(
      CreateTestWindowWithBounds(gfx::Rect(0, 0, 200, 200), viewport.get()));

  std::unique_ptr<Window> child(
      CreateTestWindowWithBounds(gfx::Rect(0, 0, 100, 100), widget.get()));

  // Sanity check.
  EXPECT_EQ("0,0 100x100", child->GetBoundsInRootWindow().ToString());

  // The |child| window's screen bounds should move along with the |viewport|.
  OffsetBounds(viewport.get(), -100, -100);
  EXPECT_EQ("-100,-100 100x100", child->GetBoundsInRootWindow().ToString());

  OffsetBounds(widget.get(), 50, 50);
  EXPECT_EQ("-50,-50 100x100", child->GetBoundsInRootWindow().ToString());

  // The |child| window is moved to the 0,0 in screen coordinates.
  // |GetBoundsInRootWindow()| should return 0,0.
  OffsetBounds(child.get(), 50, 50);
  EXPECT_EQ("0,0 100x100", child->GetBoundsInRootWindow().ToString());
}

TEST_F(WindowTest, GetBoundsInRootWindowWithLayersAndTranslations) {
  std::unique_ptr<Window> viewport(
      CreateTestWindowWithBounds(gfx::Rect(0, 0, 300, 300), root_window()));

  std::unique_ptr<Window> widget(
      CreateTestWindowWithBounds(gfx::Rect(0, 0, 200, 200), viewport.get()));

  std::unique_ptr<Window> child(
      CreateTestWindowWithBounds(gfx::Rect(0, 0, 100, 100), widget.get()));

  // Sanity check.
  EXPECT_EQ("0,0 100x100", child->GetBoundsInRootWindow().ToString());

  // The |child| window's screen bounds should move along with the |viewport|.
  viewport->SetBounds(gfx::Rect(-100, -100, 300, 300));
  EXPECT_EQ("-100,-100 100x100", child->GetBoundsInRootWindow().ToString());

  widget->SetBounds(gfx::Rect(50, 50, 200, 200));
  EXPECT_EQ("-50,-50 100x100", child->GetBoundsInRootWindow().ToString());

  // The |child| window is moved to the 0,0 in screen coordinates.
  // |GetBoundsInRootWindow()| should return 0,0.
  child->SetBounds(gfx::Rect(50, 50, 100, 100));
  EXPECT_EQ("0,0 100x100", child->GetBoundsInRootWindow().ToString());

  gfx::Transform transform1;
  transform1.Translate(-10, 20);
  viewport->SetTransform(transform1);
  EXPECT_EQ("-10,20 100x100", child->GetBoundsInRootWindow().ToString());

  gfx::Transform transform2;
  transform2.Translate(40, 100);
  widget->SetTransform(transform2);
  EXPECT_EQ("30,120 100x100", child->GetBoundsInRootWindow().ToString());

  // Testing potentially buggy place
  gfx::Transform transform3;
  transform3.Translate(-30, -120);
  child->SetTransform(transform3);
  EXPECT_EQ("0,0 100x100", child->GetBoundsInRootWindow().ToString());
}

// TODO(tdanderson): Remove this class and use
//                   test::EventCountDelegate in its place.
class MouseEnterExitWindowDelegate : public TestWindowDelegate {
 public:
  MouseEnterExitWindowDelegate() : entered_(false), exited_(false) {}

  void OnMouseEvent(ui::MouseEvent* event) override {
    switch (event->type()) {
      case ui::ET_MOUSE_ENTERED:
        EXPECT_TRUE(event->flags() & ui::EF_IS_SYNTHESIZED);
        entered_ = true;
        break;
      case ui::ET_MOUSE_EXITED:
        EXPECT_TRUE(event->flags() & ui::EF_IS_SYNTHESIZED);
        exited_ = true;
        break;
      default:
        break;
    }
  }

  bool entered() const { return entered_; }
  bool exited() const { return exited_; }

  // Clear the entered / exited states.
  void ResetExpectations() {
    entered_ = false;
    exited_ = false;
  }

 private:
  bool entered_;
  bool exited_;

  DISALLOW_COPY_AND_ASSIGN(MouseEnterExitWindowDelegate);
};

// Verifies that the WindowDelegate receives MouseExit and MouseEnter events for
// mouse transitions from window to window.
TEST_F(WindowTest, MouseEnterExit) {
  MouseEnterExitWindowDelegate d1;
  std::unique_ptr<Window> w1(CreateTestWindowWithDelegate(
      &d1, 1, gfx::Rect(10, 10, 50, 50), root_window()));
  MouseEnterExitWindowDelegate d2;
  std::unique_ptr<Window> w2(CreateTestWindowWithDelegate(
      &d2, 2, gfx::Rect(70, 70, 50, 50), root_window()));

  ui::test::EventGenerator generator(root_window());
  generator.MoveMouseToCenterOf(w1.get());
  EXPECT_TRUE(d1.entered());
  EXPECT_FALSE(d1.exited());
  EXPECT_FALSE(d2.entered());
  EXPECT_FALSE(d2.exited());

  generator.MoveMouseToCenterOf(w2.get());
  EXPECT_TRUE(d1.entered());
  EXPECT_TRUE(d1.exited());
  EXPECT_TRUE(d2.entered());
  EXPECT_FALSE(d2.exited());
}

// Verifies that the WindowDelegate receives MouseExit from ET_MOUSE_EXITED.
TEST_F(WindowTest, WindowTreeHostExit) {
  MouseEnterExitWindowDelegate d1;
  std::unique_ptr<Window> w1(CreateTestWindowWithDelegate(
      &d1, 1, gfx::Rect(10, 10, 50, 50), root_window()));

  ui::test::EventGenerator generator(root_window());
  generator.MoveMouseToCenterOf(w1.get());
  EXPECT_TRUE(d1.entered());
  EXPECT_FALSE(d1.exited());
  d1.ResetExpectations();

  ui::MouseEvent exit_event(ui::ET_MOUSE_EXITED, gfx::Point(), gfx::Point(),
                            ui::EventTimeForNow(), 0, 0);
  DispatchEventUsingWindowDispatcher(&exit_event);
  EXPECT_FALSE(d1.entered());
  EXPECT_TRUE(d1.exited());
}

// Verifies that the WindowDelegate receives MouseExit and MouseEnter events for
// mouse transitions from window to window, even if the entered window sets
// and releases capture.
TEST_F(WindowTest, MouseEnterExitWithClick) {
  MouseEnterExitWindowDelegate d1;
  std::unique_ptr<Window> w1(CreateTestWindowWithDelegate(
      &d1, 1, gfx::Rect(10, 10, 50, 50), root_window()));
  MouseEnterExitWindowDelegate d2;
  std::unique_ptr<Window> w2(CreateTestWindowWithDelegate(
      &d2, 2, gfx::Rect(70, 70, 50, 50), root_window()));

  ui::test::EventGenerator generator(root_window());
  generator.MoveMouseToCenterOf(w1.get());
  EXPECT_TRUE(d1.entered());
  EXPECT_FALSE(d1.exited());
  EXPECT_FALSE(d2.entered());
  EXPECT_FALSE(d2.exited());

  // Emmulate what Views does on a click by grabbing and releasing capture.
  generator.PressLeftButton();
  w1->SetCapture();
  w1->ReleaseCapture();
  generator.ReleaseLeftButton();

  generator.MoveMouseToCenterOf(w2.get());
  EXPECT_TRUE(d1.entered());
  EXPECT_TRUE(d1.exited());
  EXPECT_TRUE(d2.entered());
  EXPECT_FALSE(d2.exited());
}

TEST_F(WindowTest, MouseEnterExitWhenDeleteWithCapture) {
  MouseEnterExitWindowDelegate delegate;
  std::unique_ptr<Window> window(CreateTestWindowWithDelegate(
      &delegate, 1, gfx::Rect(10, 10, 50, 50), root_window()));

  ui::test::EventGenerator generator(root_window());
  generator.MoveMouseToCenterOf(window.get());
  EXPECT_TRUE(delegate.entered());
  EXPECT_FALSE(delegate.exited());

  // Emmulate what Views does on a click by grabbing and releasing capture.
  generator.PressLeftButton();
  window->SetCapture();

  delegate.ResetExpectations();
  generator.MoveMouseTo(0, 0);
  EXPECT_FALSE(delegate.entered());
  EXPECT_FALSE(delegate.exited());

  delegate.ResetExpectations();
  window.reset();
  EXPECT_FALSE(delegate.entered());
  EXPECT_FALSE(delegate.exited());
}

// Verifies that the correct enter / exits are sent if windows appear and are
// deleted under the current mouse position.
TEST_F(WindowTest, MouseEnterExitWithWindowAppearAndDelete) {
  MouseEnterExitWindowDelegate d1;
  std::unique_ptr<Window> w1(CreateTestWindowWithDelegate(
      &d1, 1, gfx::Rect(10, 10, 50, 50), root_window()));

  // The cursor is moved into the bounds of |w1|. We expect the delegate
  // of |w1| to see an ET_MOUSE_ENTERED event.
  ui::test::EventGenerator generator(root_window());
  generator.MoveMouseToCenterOf(w1.get());
  EXPECT_TRUE(d1.entered());
  EXPECT_FALSE(d1.exited());
  d1.ResetExpectations();

  MouseEnterExitWindowDelegate d2;
  {
    std::unique_ptr<Window> w2(CreateTestWindowWithDelegate(
        &d2, 2, gfx::Rect(10, 10, 50, 50), root_window()));
    // Enters / exits can be sent asynchronously.
    RunAllPendingInMessageLoop();

    // |w2| appears over top of |w1|. We expect the delegate of |w1| to see
    // an ET_MOUSE_EXITED and the delegate of |w2| to see an ET_MOUSE_ENTERED.
    EXPECT_FALSE(d1.entered());
    EXPECT_TRUE(d1.exited());
    EXPECT_TRUE(d2.entered());
    EXPECT_FALSE(d2.exited());
    d1.ResetExpectations();
    d2.ResetExpectations();
  }

  // Enters / exits can be sent asynchronously.
  RunAllPendingInMessageLoop();

  // |w2| has been destroyed, so its delegate should see no further events.
  // The delegate of |w1| should see an ET_MOUSE_ENTERED event.
  EXPECT_TRUE(d1.entered());
  EXPECT_FALSE(d1.exited());
  EXPECT_FALSE(d2.entered());
  EXPECT_FALSE(d2.exited());
}

// Verifies that enter / exits are sent if windows appear and are hidden
// under the current mouse position..
TEST_F(WindowTest, MouseEnterExitWithHide) {
  MouseEnterExitWindowDelegate d1;
  std::unique_ptr<Window> w1(CreateTestWindowWithDelegate(
      &d1, 1, gfx::Rect(10, 10, 50, 50), root_window()));

  ui::test::EventGenerator generator(root_window());
  generator.MoveMouseToCenterOf(w1.get());
  EXPECT_TRUE(d1.entered());
  EXPECT_FALSE(d1.exited());

  MouseEnterExitWindowDelegate d2;
  std::unique_ptr<Window> w2(CreateTestWindowWithDelegate(
      &d2, 2, gfx::Rect(10, 10, 50, 50), root_window()));
  // Enters / exits can be send asynchronously.
  RunAllPendingInMessageLoop();
  EXPECT_TRUE(d1.entered());
  EXPECT_TRUE(d1.exited());
  EXPECT_TRUE(d2.entered());
  EXPECT_FALSE(d2.exited());

  d1.ResetExpectations();
  w2->Hide();
  // Enters / exits can be send asynchronously.
  RunAllPendingInMessageLoop();
  EXPECT_TRUE(d2.exited());
  EXPECT_TRUE(d1.entered());
}

TEST_F(WindowTest, MouseEnterExitWithParentHide) {
  MouseEnterExitWindowDelegate d1;
  std::unique_ptr<Window> w1(CreateTestWindowWithDelegate(
      &d1, 1, gfx::Rect(10, 10, 50, 50), root_window()));
  MouseEnterExitWindowDelegate d2;
  Window* w2 = CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(10, 10, 50, 50),
                                            w1.get());
  ui::test::EventGenerator generator(root_window());
  generator.MoveMouseToCenterOf(w2);
  // Enters / exits can be send asynchronously.
  RunAllPendingInMessageLoop();
  EXPECT_TRUE(d2.entered());
  EXPECT_FALSE(d2.exited());

  d2.ResetExpectations();
  w1->Hide();
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(d2.entered());
  EXPECT_TRUE(d2.exited());

  w1.reset();
}

TEST_F(WindowTest, MouseEnterExitWithParentDelete) {
  MouseEnterExitWindowDelegate d1;
  std::unique_ptr<Window> w1(CreateTestWindowWithDelegate(
      &d1, 1, gfx::Rect(10, 10, 50, 50), root_window()));
  MouseEnterExitWindowDelegate d2;
  Window* w2 = CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(10, 10, 50, 50),
                                            w1.get());
  ui::test::EventGenerator generator(root_window());
  generator.MoveMouseToCenterOf(w2);

  // Enters / exits can be send asynchronously.
  RunAllPendingInMessageLoop();
  EXPECT_TRUE(d2.entered());
  EXPECT_FALSE(d2.exited());

  d2.ResetExpectations();
  w1.reset();
  RunAllPendingInMessageLoop();

  // Both windows are in the process of destroying, so their delegates should
  // not see any mouse events.
  EXPECT_FALSE(d1.entered());
  EXPECT_FALSE(d1.exited());
  EXPECT_FALSE(d2.entered());
  EXPECT_FALSE(d2.exited());
}

// Creates a window with a delegate (w111) that can handle events at a lower
// z-index than a window without a delegate (w12). w12 is sized to fill the
// entire bounds of the container. This test verifies that
// GetEventHandlerForPoint() skips w12 even though its bounds contain the event,
// because it has no children that can handle the event and it has no delegate
// allowing it to handle the event itself.
TEST_F(WindowTest, GetEventHandlerForPoint_NoDelegate) {
  TestWindowDelegate d111;
  std::unique_ptr<Window> w1(CreateTestWindowWithDelegate(
      NULL, 1, gfx::Rect(0, 0, 500, 500), root_window()));
  std::unique_ptr<Window> w11(CreateTestWindowWithDelegate(
      NULL, 11, gfx::Rect(0, 0, 500, 500), w1.get()));
  std::unique_ptr<Window> w111(CreateTestWindowWithDelegate(
      &d111, 111, gfx::Rect(50, 50, 450, 450), w11.get()));
  std::unique_ptr<Window> w12(CreateTestWindowWithDelegate(
      NULL, 12, gfx::Rect(0, 0, 500, 500), w1.get()));

  gfx::Point target_point = w111->bounds().CenterPoint();
  EXPECT_EQ(w111.get(), w1->GetEventHandlerForPoint(target_point));
}

class VisibilityWindowDelegate : public TestWindowDelegate {
 public:
  VisibilityWindowDelegate()
      : shown_(0),
        hidden_(0) {
  }

  int shown() const { return shown_; }
  int hidden() const { return hidden_; }
  void Clear() {
    shown_ = 0;
    hidden_ = 0;
  }

  void OnWindowTargetVisibilityChanged(bool visible) override {
    if (visible)
      shown_++;
    else
      hidden_++;
  }

 private:
  int shown_;
  int hidden_;

  DISALLOW_COPY_AND_ASSIGN(VisibilityWindowDelegate);
};

// Verifies show/hide propagate correctly to children and the layer.
TEST_F(WindowTest, Visibility) {
  VisibilityWindowDelegate d;
  VisibilityWindowDelegate d2;
  std::unique_ptr<Window> w1(
      CreateTestWindowWithDelegate(&d, 1, gfx::Rect(), root_window()));
  std::unique_ptr<Window> w2(
      CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(), w1.get()));
  std::unique_ptr<Window> w3(CreateTestWindowWithId(3, w2.get()));

  // Create shows all the windows.
  EXPECT_TRUE(w1->IsVisible());
  EXPECT_TRUE(w2->IsVisible());
  EXPECT_TRUE(w3->IsVisible());
  EXPECT_EQ(1, d.shown());

  d.Clear();
  w1->Hide();
  EXPECT_FALSE(w1->IsVisible());
  EXPECT_FALSE(w2->IsVisible());
  EXPECT_FALSE(w3->IsVisible());
  EXPECT_EQ(1, d.hidden());
  EXPECT_EQ(0, d.shown());

  w2->Show();
  EXPECT_FALSE(w1->IsVisible());
  EXPECT_FALSE(w2->IsVisible());
  EXPECT_FALSE(w3->IsVisible());

  w3->Hide();
  EXPECT_FALSE(w1->IsVisible());
  EXPECT_FALSE(w2->IsVisible());
  EXPECT_FALSE(w3->IsVisible());

  d.Clear();
  w1->Show();
  EXPECT_TRUE(w1->IsVisible());
  EXPECT_TRUE(w2->IsVisible());
  EXPECT_FALSE(w3->IsVisible());
  EXPECT_EQ(0, d.hidden());
  EXPECT_EQ(1, d.shown());

  w3->Show();
  EXPECT_TRUE(w1->IsVisible());
  EXPECT_TRUE(w2->IsVisible());
  EXPECT_TRUE(w3->IsVisible());

  // Verify that if an ancestor isn't visible and we change the visibility of a
  // child window that OnChildWindowVisibilityChanged() is still invoked.
  w1->Hide();
  d2.Clear();
  w2->Hide();
  EXPECT_EQ(1, d2.hidden());
  EXPECT_EQ(0, d2.shown());
  d2.Clear();
  w2->Show();
  EXPECT_EQ(0, d2.hidden());
  EXPECT_EQ(1, d2.shown());
}

TEST_F(WindowTest, EventTargetingPolicy) {
  TestWindowDelegate d11;
  TestWindowDelegate d12;
  TestWindowDelegate d111;
  TestWindowDelegate d121;
  std::unique_ptr<Window> w1(CreateTestWindowWithDelegate(
      NULL, 1, gfx::Rect(0, 0, 500, 500), root_window()));
  std::unique_ptr<Window> w11(CreateTestWindowWithDelegate(
      &d11, 11, gfx::Rect(0, 0, 500, 500), w1.get()));
  std::unique_ptr<Window> w111(CreateTestWindowWithDelegate(
      &d111, 111, gfx::Rect(50, 50, 450, 450), w11.get()));
  std::unique_ptr<Window> w12(CreateTestWindowWithDelegate(
      &d12, 12, gfx::Rect(0, 0, 500, 500), w1.get()));
  std::unique_ptr<Window> w121(CreateTestWindowWithDelegate(
      &d121, 121, gfx::Rect(150, 150, 50, 50), w12.get()));

  EXPECT_EQ(w121.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
  w12->SetEventTargetingPolicy(EventTargetingPolicy::kTargetOnly);
  EXPECT_EQ(w12.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
  EXPECT_TRUE(w12.get()->layer()->accept_events());
  w12->SetEventTargetingPolicy(EventTargetingPolicy::kTargetAndDescendants);
  EXPECT_EQ(w12.get(), w1->GetEventHandlerForPoint(gfx::Point(10, 10)));
  EXPECT_TRUE(w12.get()->layer()->accept_events());
  w12->SetEventTargetingPolicy(EventTargetingPolicy::kNone);
  EXPECT_EQ(w11.get(), w1->GetEventHandlerForPoint(gfx::Point(10, 10)));
  EXPECT_FALSE(w12.get()->layer()->accept_events());

  w12->SetEventTargetingPolicy(EventTargetingPolicy::kTargetAndDescendants);

  EXPECT_EQ(w121.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
  w121->SetEventTargetingPolicy(EventTargetingPolicy::kNone);
  EXPECT_EQ(w12.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
  EXPECT_FALSE(w121.get()->layer()->accept_events());
  w12->SetEventTargetingPolicy(EventTargetingPolicy::kNone);
  EXPECT_EQ(w111.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
  EXPECT_FALSE(w12.get()->layer()->accept_events());
  w111->SetEventTargetingPolicy(EventTargetingPolicy::kNone);
  EXPECT_EQ(w11.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
  EXPECT_FALSE(w111.get()->layer()->accept_events());

  w11->SetEventTargetingPolicy(EventTargetingPolicy::kDescendantsOnly);
  EXPECT_EQ(nullptr, w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
  EXPECT_TRUE(w11.get()->layer()->accept_events());

  w111->SetEventTargetingPolicy(EventTargetingPolicy::kTargetAndDescendants);
  EXPECT_EQ(w111.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
  EXPECT_TRUE(w111.get()->layer()->accept_events());
}

// Tests transformation on the root window.
TEST_F(WindowTest, Transform) {
  gfx::Size size = host()->GetBoundsInPixels().size();
  EXPECT_EQ(gfx::Rect(size), display::Screen::GetScreen()
                                 ->GetDisplayNearestPoint(gfx::Point())
                                 .bounds());

  // Rotate it clock-wise 90 degrees.
  gfx::Transform transform;
  transform.Translate(size.height(), 0);
  transform.Rotate(90.0);
  host()->SetRootTransform(transform);

  // The size should be the transformed size.
  gfx::Size transformed_size(size.height(), size.width());
  EXPECT_EQ(transformed_size.ToString(),
            root_window()->bounds().size().ToString());
  EXPECT_EQ(gfx::Rect(transformed_size).ToString(),
            display::Screen::GetScreen()
                ->GetDisplayNearestPoint(gfx::Point())
                .bounds()
                .ToString());

  // Host size shouldn't change.
  EXPECT_EQ(size.ToString(), host()->GetBoundsInPixels().size().ToString());
}

TEST_F(WindowTest, TransformGesture) {
  gfx::Size size = host()->GetBoundsInPixels().size();

  std::unique_ptr<GestureTrackPositionDelegate> delegate(
      new GestureTrackPositionDelegate);
  std::unique_ptr<Window> window(CreateTestWindowWithDelegate(
      delegate.get(), -1234, gfx::Rect(0, 0, 20, 20), root_window()));

  // Rotate the root-window clock-wise 90 degrees.
  gfx::Transform transform;
  transform.Translate(size.height(), 0.0);
  transform.Rotate(90.0);
  host()->SetRootTransform(transform);

  ui::TouchEvent press(
      ui::ET_TOUCH_PRESSED, gfx::Point(size.height() - 10, 10), getTime(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  DispatchEventUsingWindowDispatcher(&press);
  EXPECT_EQ(gfx::Point(10, 10).ToString(), delegate->position().ToString());
}

TEST_F(WindowTest, Property) {
  std::unique_ptr<Window> w(CreateTestWindowWithId(0, root_window()));

  static const char native_prop_key[] = "fnord";

  // Non-existent properties should return the default values.
  EXPECT_EQ(nullptr, w->GetNativeWindowProperty(native_prop_key));

  w->SetNativeWindowProperty(native_prop_key, &*w);
  EXPECT_EQ(&*w, w->GetNativeWindowProperty(native_prop_key));
  w->SetNativeWindowProperty(native_prop_key, nullptr);
  EXPECT_EQ(nullptr, w->GetNativeWindowProperty(native_prop_key));
}

class DeletionTestLayoutManager : public LayoutManager {
 public:
  explicit DeletionTestLayoutManager(DeletionTracker* tracker)
      : tracker_(tracker) {}
  ~DeletionTestLayoutManager() override { tracker_->LayoutManagerDeleted(); }

 private:
  // LayoutManager:
  void OnWindowResized() override {}
  void OnWindowAddedToLayout(Window* child) override {}
  void OnWillRemoveWindowFromLayout(Window* child) override {}
  void OnWindowRemovedFromLayout(Window* child) override {}
  void OnChildWindowVisibilityChanged(Window* child, bool visible) override {}
  void SetChildBounds(Window* child,
                      const gfx::Rect& requested_bounds) override {}

  DeletionTracker* tracker_;

  DISALLOW_COPY_AND_ASSIGN(DeletionTestLayoutManager);
};

TEST_F(WindowTest, DeleteLayoutManagerBeforeOwnedProps) {
  DeletionTracker tracker;
  {
    Window w(nullptr);
    w.Init(ui::LAYER_NOT_DRAWN);
    w.SetLayoutManager(new DeletionTestLayoutManager(&tracker));
    w.SetProperty(kDeletionTestPropertyKey, new DeletionTestProperty(&tracker));
  }
  EXPECT_TRUE(tracker.property_deleted());
  EXPECT_TRUE(tracker.layout_manager_deleted());
  EXPECT_EQ(DeletionOrder::LAYOUT_MANAGER_FIRST, tracker.order());
}

TEST_F(WindowTest, SetBoundsInternalShouldCheckTargetBounds) {
  // We cannot short-circuit animations in this test.
  ui::ScopedAnimationDurationScaleMode test_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  std::unique_ptr<Window> w1(
      CreateTestWindowWithBounds(gfx::Rect(0, 0, 100, 100), root_window()));

  EXPECT_TRUE(w1->layer());
  w1->layer()->GetAnimator()->set_disable_timer_for_test(true);
  ui::LayerAnimator* animator = w1->layer()->GetAnimator();

  EXPECT_EQ("0,0 100x100", w1->bounds().ToString());
  EXPECT_EQ("0,0 100x100", w1->layer()->GetTargetBounds().ToString());

  // Animate to a different position.
  {
    ui::ScopedLayerAnimationSettings settings(w1->layer()->GetAnimator());
    w1->SetBounds(gfx::Rect(100, 100, 100, 100));
  }

  EXPECT_EQ("0,0 100x100", w1->bounds().ToString());
  EXPECT_EQ("100,100 100x100", w1->layer()->GetTargetBounds().ToString());

  // Animate back to the first position. The animation hasn't started yet, so
  // the current bounds are still (0, 0, 100, 100), but the target bounds are
  // (100, 100, 100, 100). If we step the animator ahead, we should find that
  // we're at (0, 0, 100, 100). That is, the second animation should be applied.
  {
    ui::ScopedLayerAnimationSettings settings(w1->layer()->GetAnimator());
    w1->SetBounds(gfx::Rect(0, 0, 100, 100));
  }

  EXPECT_EQ("0,0 100x100", w1->bounds().ToString());
  EXPECT_EQ("0,0 100x100", w1->layer()->GetTargetBounds().ToString());

  // Confirm that the target bounds are reached.
  base::TimeTicks start_time =
      w1->layer()->GetAnimator()->last_step_time();

  animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000));

  EXPECT_EQ("0,0 100x100", w1->bounds().ToString());
}

typedef std::pair<const void*, intptr_t> PropertyChangeInfo;

class WindowObserverTest : public WindowTest,
                           public WindowObserver {
 public:
  struct VisibilityInfo {
    bool window_visible;
    bool visible_param;
    int changed_count;
  };

  struct WindowBoundsInfo {
    int changed_count = 0;
    Window* window = nullptr;
    gfx::Rect old_bounds;
    gfx::Rect new_bounds;
    ui::PropertyChangeReason reason =
        ui::PropertyChangeReason::NOT_FROM_ANIMATION;
  };

  struct WindowOpacityInfo {
    int changed_count = 0;
    Window* window = nullptr;
    ui::PropertyChangeReason reason =
        ui::PropertyChangeReason::NOT_FROM_ANIMATION;
  };

  struct WindowTargetTransformChangingInfo {
    int changed_count = 0;
    Window* window = nullptr;
    gfx::Transform new_transform;
  };

  struct WindowTransformedInfo {
    int changed_count = 0;
    Window* window = nullptr;
    ui::PropertyChangeReason reason =
        ui::PropertyChangeReason::NOT_FROM_ANIMATION;
  };

  struct CountAndWindow {
    int count = 0;
    Window* window = nullptr;
  };

  WindowObserverTest() = default;
  ~WindowObserverTest() override = default;

  const VisibilityInfo* GetVisibilityInfo() const {
    return visibility_info_.get();
  }

  const WindowBoundsInfo& window_bounds_info() const {
    return window_bounds_info_;
  }

  const WindowOpacityInfo& window_opacity_info() const {
    return window_opacity_info_;
  }

  const CountAndWindow& alpha_shape_info() const { return alpha_shape_info_; }

  const WindowTargetTransformChangingInfo&
  window_target_transform_changing_info() const {
    return window_target_transform_changing_info_;
  }

  const WindowTransformedInfo& window_transformed_info() const {
    return window_transformed_info_;
  }

  const CountAndWindow& layer_recreated_info() const {
    return layer_recreated_info_;
  }

  void ResetVisibilityInfo() {
    visibility_info_.reset();
  }

  // Returns a description of the WindowObserver methods that have been invoked.
  std::string WindowObserverCountStateAndClear() {
    std::string result(
        base::StringPrintf("added=%d removed=%d",
        added_count_, removed_count_));
    added_count_ = removed_count_ = 0;
    return result;
  }

  int DestroyedCountAndClear() {
    int result = destroyed_count_;
    destroyed_count_ = 0;
    return result;
  }

  // Return a tuple of the arguments passed in OnPropertyChanged callback.
  PropertyChangeInfo PropertyChangeInfoAndClear() {
    PropertyChangeInfo result(property_key_, old_property_value_);
    property_key_ = NULL;
    old_property_value_ = -3;
    return result;
  }

 private:
  void OnWindowAdded(Window* new_window) override { added_count_++; }

  void OnWillRemoveWindow(Window* window) override { removed_count_++; }

  void OnWindowVisibilityChanged(Window* window, bool visible) override {
    if (!visibility_info_) {
      visibility_info_.reset(new VisibilityInfo);
      visibility_info_->changed_count = 0;
    }
    visibility_info_->window_visible = window->IsVisible();
    visibility_info_->visible_param = visible;
    visibility_info_->changed_count++;
  }

  void OnWindowDestroyed(Window* window) override {
    EXPECT_FALSE(window->parent());
    destroyed_count_++;
  }

  void OnWindowPropertyChanged(Window* window,
                               const void* key,
                               intptr_t old) override {
    property_key_ = key;
    old_property_value_ = old;
  }

  void OnWindowBoundsChanged(Window* window,
                             const gfx::Rect& old_bounds,
                             const gfx::Rect& new_bounds,
                             ui::PropertyChangeReason reason) override {
    ++window_bounds_info_.changed_count;
    window_bounds_info_.window = window;
    window_bounds_info_.old_bounds = old_bounds;
    window_bounds_info_.new_bounds = new_bounds;
    window_bounds_info_.reason = reason;
  }

  void OnWindowOpacitySet(Window* window,
                          ui::PropertyChangeReason reason) override {
    ++window_opacity_info_.changed_count;
    window_opacity_info_.window = window;
    window_opacity_info_.reason = reason;
  }

  void OnWindowAlphaShapeSet(Window* window) override {
    ++alpha_shape_info_.count;
    alpha_shape_info_.window = window;
  }

  void OnWindowTargetTransformChanging(
      Window* window,
      const gfx::Transform& new_transform) override {
    ++window_target_transform_changing_info_.changed_count;
    window_target_transform_changing_info_.window = window;
    window_target_transform_changing_info_.new_transform = new_transform;
  }

  void OnWindowTransformed(Window* window,
                           ui::PropertyChangeReason reason) override {
    ++window_transformed_info_.changed_count;
    window_transformed_info_.window = window;
    window_transformed_info_.reason = reason;
  }

  void OnWindowLayerRecreated(Window* window) override {
    ++layer_recreated_info_.count;
    layer_recreated_info_.window = window;
  }

  int added_count_ = 0;
  int removed_count_ = 0;
  int destroyed_count_ = 0;
  std::unique_ptr<VisibilityInfo> visibility_info_;
  const void* property_key_ = nullptr;
  intptr_t old_property_value_ = -3;
  std::vector<std::pair<int, int> > transform_notifications_;
  WindowBoundsInfo window_bounds_info_;
  WindowOpacityInfo window_opacity_info_;
  WindowTargetTransformChangingInfo window_target_transform_changing_info_;
  WindowTransformedInfo window_transformed_info_;
  CountAndWindow alpha_shape_info_;
  CountAndWindow layer_recreated_info_;

  DISALLOW_COPY_AND_ASSIGN(WindowObserverTest);
};

// Various assertions for WindowObserver.
TEST_F(WindowObserverTest, WindowObserver) {
  std::unique_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
  w1->AddObserver(this);

  // Create a new window as a child of w1, our observer should be notified.
  std::unique_ptr<Window> w2(CreateTestWindowWithId(2, w1.get()));
  EXPECT_EQ("added=1 removed=0", WindowObserverCountStateAndClear());

  // Delete w2, which should result in the remove notification.
  w2.reset();
  EXPECT_EQ("added=0 removed=1", WindowObserverCountStateAndClear());

  // Create a window that isn't parented to w1, we shouldn't get any
  // notification.
  std::unique_ptr<Window> w3(CreateTestWindowWithId(3, root_window()));
  EXPECT_EQ("added=0 removed=0", WindowObserverCountStateAndClear());

  // Similarly destroying w3 shouldn't notify us either.
  w3.reset();
  EXPECT_EQ("added=0 removed=0", WindowObserverCountStateAndClear());
  w1->RemoveObserver(this);
}

// Test if OnWindowVisibilityChanged is invoked with expected
// parameters.
TEST_F(WindowObserverTest, WindowVisibility) {
  std::unique_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
  std::unique_ptr<Window> w2(CreateTestWindowWithId(1, w1.get()));
  w2->AddObserver(this);

  // Hide should make the window invisible and the passed visible
  // parameter is false.
  w2->Hide();
  EXPECT_TRUE(GetVisibilityInfo());
  EXPECT_TRUE(GetVisibilityInfo());
  if (!GetVisibilityInfo())
    return;
  EXPECT_FALSE(GetVisibilityInfo()->window_visible);
  EXPECT_FALSE(GetVisibilityInfo()->visible_param);
  EXPECT_EQ(1, GetVisibilityInfo()->changed_count);

  // If parent isn't visible, showing window won't make the window visible, but
  // passed visible value must be true.
  w1->Hide();
  ResetVisibilityInfo();
  EXPECT_TRUE(!GetVisibilityInfo());
  w2->Show();
  EXPECT_TRUE(GetVisibilityInfo());
  if (!GetVisibilityInfo())
    return;
  EXPECT_FALSE(GetVisibilityInfo()->window_visible);
  EXPECT_TRUE(GetVisibilityInfo()->visible_param);
  EXPECT_EQ(1, GetVisibilityInfo()->changed_count);

  // If parent is visible, showing window will make the window
  // visible and the passed visible value is true.
  w1->Show();
  w2->Hide();
  ResetVisibilityInfo();
  w2->Show();
  EXPECT_TRUE(GetVisibilityInfo());
  if (!GetVisibilityInfo())
    return;
  EXPECT_TRUE(GetVisibilityInfo()->window_visible);
  EXPECT_TRUE(GetVisibilityInfo()->visible_param);
  EXPECT_EQ(1, GetVisibilityInfo()->changed_count);

  // Verify that the OnWindowVisibilityChanged only once
  // per visibility change.
  w2->Hide();
  EXPECT_EQ(2, GetVisibilityInfo()->changed_count);

  w2->Hide();
  EXPECT_EQ(2, GetVisibilityInfo()->changed_count);
}

// Test if OnWindowDestroyed is invoked as expected.
TEST_F(WindowObserverTest, WindowDestroyed) {
  // Delete a window should fire a destroyed notification.
  std::unique_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
  w1->AddObserver(this);
  w1.reset();
  EXPECT_EQ(1, DestroyedCountAndClear());

  // Observe on child and delete parent window should fire a notification.
  std::unique_ptr<Window> parent(CreateTestWindowWithId(1, root_window()));
  Window* child = CreateTestWindowWithId(1, parent.get());  // owned by parent
  child->AddObserver(this);
  parent.reset();
  EXPECT_EQ(1, DestroyedCountAndClear());
}

TEST_F(WindowObserverTest, PropertyChanged) {
  // Setting property should fire a property change notification.
  std::unique_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
  w1->AddObserver(this);

  static const WindowProperty<int> prop = {-2};
  static const char native_prop_key[] = "fnord";

  w1->SetProperty(&prop, 1);
  EXPECT_EQ(PropertyChangeInfo(&prop, -2), PropertyChangeInfoAndClear());
  w1->SetProperty(&prop, -2);
  EXPECT_EQ(PropertyChangeInfo(&prop, 1), PropertyChangeInfoAndClear());
  w1->SetProperty(&prop, 3);
  EXPECT_EQ(PropertyChangeInfo(&prop, -2), PropertyChangeInfoAndClear());
  w1->ClearProperty(&prop);
  EXPECT_EQ(PropertyChangeInfo(&prop, 3), PropertyChangeInfoAndClear());

  w1->SetNativeWindowProperty(native_prop_key, &*w1);
  EXPECT_EQ(PropertyChangeInfo(native_prop_key, 0),
            PropertyChangeInfoAndClear());
  w1->SetNativeWindowProperty(native_prop_key, NULL);
  EXPECT_EQ(PropertyChangeInfo(native_prop_key,
                               reinterpret_cast<intptr_t>(&*w1)),
            PropertyChangeInfoAndClear());

  // Sanity check to see if |PropertyChangeInfoAndClear| really clears.
  EXPECT_EQ(PropertyChangeInfo(
      reinterpret_cast<const void*>(NULL), -3), PropertyChangeInfoAndClear());
}

// Verify that WindowObserver::OnWindowBoundsChanged() is notified when the
// bounds of a Window's Layer change without an animation.
TEST_F(WindowObserverTest, WindowBoundsChanged) {
  std::unique_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
  window->AddObserver(this);
  const gfx::Rect initial_bounds = window->bounds();
  constexpr gfx::Rect kTargetBounds(10, 20, 30, 40);
  window->layer()->SetBounds(kTargetBounds);
  ASSERT_EQ(1, window_bounds_info().changed_count);
  EXPECT_EQ(window.get(), window_bounds_info().window);
  EXPECT_EQ(initial_bounds, window_bounds_info().old_bounds);
  EXPECT_EQ(kTargetBounds, window_bounds_info().new_bounds);
  EXPECT_EQ(ui::PropertyChangeReason::NOT_FROM_ANIMATION,
            window_bounds_info().reason);
}

// Verify that WindowObserver::OnWindowBoundsChanged() is notified at every step
// of a bounds animation.
TEST_F(WindowObserverTest, WindowBoundsChangedAnimation) {
  std::unique_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
  window->AddObserver(this);
  const gfx::Rect initial_bounds = window->bounds();
  constexpr gfx::Rect kTargetBounds(10, 20, 30, 40);
  const gfx::Rect step_bounds =
      gfx::Tween::RectValueBetween(0.5, initial_bounds, kTargetBounds);

  ui::ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
  window->layer()->SetBounds(kTargetBounds);
  ASSERT_EQ(0, window_opacity_info().changed_count);

  window->layer()->GetAnimator()->Step(
      window->layer()->GetAnimator()->last_step_time() +
      settings.GetTransitionDuration() / 2);
  ASSERT_EQ(1, window_bounds_info().changed_count);
  EXPECT_EQ(window.get(), window_bounds_info().window);
  EXPECT_EQ(initial_bounds, window_bounds_info().old_bounds);
  EXPECT_EQ(step_bounds, window_bounds_info().new_bounds);
  EXPECT_EQ(ui::PropertyChangeReason::FROM_ANIMATION,
            window_bounds_info().reason);

  window->layer()->GetAnimator()->StopAnimatingProperty(
      ui::LayerAnimationElement::BOUNDS);
  ASSERT_EQ(2, window_bounds_info().changed_count);
  EXPECT_EQ(window.get(), window_bounds_info().window);
  EXPECT_EQ(step_bounds, window_bounds_info().old_bounds);
  EXPECT_EQ(kTargetBounds, window_bounds_info().new_bounds);
  EXPECT_EQ(ui::PropertyChangeReason::FROM_ANIMATION,
            window_bounds_info().reason);
}

// Verify that WindowObserver::OnWindowOpacitySet() is notified when the
// opacity of a Window's Layer changes without an animation.
TEST_F(WindowObserverTest, WindowOpacityChanged) {
  std::unique_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
  window->AddObserver(this);
  window->layer()->SetOpacity(0.5f);
  ASSERT_EQ(1, window_opacity_info().changed_count);
  EXPECT_EQ(window.get(), window_opacity_info().window);
  EXPECT_EQ(ui::PropertyChangeReason::NOT_FROM_ANIMATION,
            window_opacity_info().reason);
}

// Verify that WindowObserver::OnWindowOpacitySet() is notified at the
// beginning and at the end of a threaded opacity animation.
TEST_F(WindowObserverTest, WindowOpacityChangedAnimation) {
  std::unique_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
  window->AddObserver(this);

  ui::ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
  window->layer()->SetOpacity(0.5f);
  ASSERT_EQ(1, window_opacity_info().changed_count);
  EXPECT_EQ(window.get(), window_opacity_info().window);
  EXPECT_EQ(ui::PropertyChangeReason::FROM_ANIMATION,
            window_opacity_info().reason);

  window->layer()->GetAnimator()->StopAnimatingProperty(
      ui::LayerAnimationElement::OPACITY);
  ASSERT_EQ(2, window_opacity_info().changed_count);
  EXPECT_EQ(window.get(), window_opacity_info().window);
  EXPECT_EQ(ui::PropertyChangeReason::FROM_ANIMATION,
            window_opacity_info().reason);
}

// Verify that WindowObserver::OnWindowAlphaShapeSet() is notified when an alpha
// shape is set for a window.
TEST_F(WindowObserverTest, WindowAlphaShapeChanged) {
  std::unique_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
  window->AddObserver(this);

  auto shape = std::make_unique<ui::Layer::ShapeRects>();
  shape->emplace_back(0, 0, 10, 20);

  EXPECT_EQ(0, alpha_shape_info().count);
  EXPECT_EQ(nullptr, alpha_shape_info().window);
  window->layer()->SetAlphaShape(std::move(shape));
  EXPECT_EQ(1, alpha_shape_info().count);
  EXPECT_EQ(window.get(), alpha_shape_info().window);
}

// Verify that WindowObserver::OnWindow(TargetTransformChanging|Transformed)()
// are notified when SetTransform() is called and there is no animation.
TEST_F(WindowObserverTest, SetTransform) {
  std::unique_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
  window->AddObserver(this);
  gfx::Transform target_transform;
  target_transform.Skew(10.0, 5.0);
  window->SetTransform(target_transform);

  ASSERT_EQ(1, window_target_transform_changing_info().changed_count);
  EXPECT_EQ(window.get(), window_target_transform_changing_info().window);
  EXPECT_EQ(target_transform,
            window_target_transform_changing_info().new_transform);

  ASSERT_EQ(1, window_transformed_info().changed_count);
  EXPECT_EQ(window.get(), window_transformed_info().window);
  EXPECT_EQ(ui::PropertyChangeReason::NOT_FROM_ANIMATION,
            window_transformed_info().reason);
}

// Verify that WindowObserver::OnWindowTransformed)() is notified at the
// beginning and at the end of a threaded transform animation. Verify that
// WindowObserver::OnWindowTargetTransformChanging() is notified when the
// threaded animation is started by SetTransform().
TEST_F(WindowObserverTest, SetTransformAnimation) {
  std::unique_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
  window->AddObserver(this);

  ui::ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
  gfx::Transform target_transform;
  target_transform.Skew(10.0, 5.0);
  window->SetTransform(target_transform);

  ASSERT_EQ(1, window_target_transform_changing_info().changed_count);
  EXPECT_EQ(window.get(), window_target_transform_changing_info().window);
  EXPECT_EQ(target_transform,
            window_target_transform_changing_info().new_transform);

  ASSERT_EQ(1, window_transformed_info().changed_count);
  EXPECT_EQ(window.get(), window_transformed_info().window);
  EXPECT_EQ(ui::PropertyChangeReason::FROM_ANIMATION,
            window_transformed_info().reason);

  window->layer()->GetAnimator()->StopAnimatingProperty(
      ui::LayerAnimationElement::TRANSFORM);

  EXPECT_EQ(1, window_target_transform_changing_info().changed_count);

  ASSERT_EQ(2, window_transformed_info().changed_count);
  EXPECT_EQ(window.get(), window_transformed_info().window);
  EXPECT_EQ(ui::PropertyChangeReason::FROM_ANIMATION,
            window_transformed_info().reason);
}

TEST_F(WindowObserverTest, OnWindowLayerRecreated) {
  std::unique_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
  window->AddObserver(this);

  EXPECT_EQ(0, layer_recreated_info().count);
  std::unique_ptr<ui::Layer> old_layer = window->RecreateLayer();
  EXPECT_EQ(1, layer_recreated_info().count);
  EXPECT_EQ(window.get(), layer_recreated_info().window);
}

TEST_F(WindowObserverTest, OnWindowLayerRecreatedWithOpacityAnimation) {
  std::unique_ptr<Window> window(CreateTestWindowWithId(1, root_window()));

  ui::ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
  window->layer()->SetOpacity(0.5);
  EXPECT_TRUE(window->layer()->GetAnimator()->IsAnimatingProperty(
      ui::LayerAnimationElement::OPACITY));

  window->AddObserver(this);

  EXPECT_EQ(0, layer_recreated_info().count);
  EXPECT_EQ(0, window_opacity_info().changed_count);
  std::unique_ptr<ui::Layer> old_layer = window->RecreateLayer();
  EXPECT_EQ(1, layer_recreated_info().count);
  EXPECT_EQ(window.get(), layer_recreated_info().window);
  EXPECT_EQ(1, window_opacity_info().changed_count);
  EXPECT_EQ(window.get(), window_opacity_info().window);
  EXPECT_EQ(ui::PropertyChangeReason::FROM_ANIMATION,
            window_opacity_info().reason);
}

TEST_F(WindowObserverTest, OnWindowLayerRecreatedWithTransformAnimation) {
  std::unique_ptr<Window> window(CreateTestWindowWithId(1, root_window()));

  ui::ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
  gfx::Transform target_transform;
  target_transform.Skew(10.0, 5.0);
  window->SetTransform(target_transform);
  EXPECT_TRUE(window->layer()->GetAnimator()->IsAnimatingProperty(
      ui::LayerAnimationElement::TRANSFORM));

  window->AddObserver(this);

  EXPECT_EQ(0, layer_recreated_info().count);
  EXPECT_EQ(0, window_transformed_info().changed_count);
  std::unique_ptr<ui::Layer> old_layer = window->RecreateLayer();
  EXPECT_EQ(1, layer_recreated_info().count);
  EXPECT_EQ(window.get(), layer_recreated_info().window);
  EXPECT_EQ(1, window_transformed_info().changed_count);
  EXPECT_EQ(window.get(), window_transformed_info().window);
  EXPECT_EQ(ui::PropertyChangeReason::FROM_ANIMATION,
            window_transformed_info().reason);
}

TEST_F(WindowTest, AcquireLayer) {
  std::unique_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
  std::unique_ptr<Window> window2(CreateTestWindowWithId(2, root_window()));
  ui::Layer* parent = window1->parent()->layer();
  EXPECT_EQ(2U, parent->children().size());

  WindowTestApi window1_test_api(window1.get());
  WindowTestApi window2_test_api(window2.get());

  EXPECT_TRUE(window1_test_api.OwnsLayer());
  EXPECT_TRUE(window2_test_api.OwnsLayer());

  // After acquisition, window1 should not own its layer, but it should still
  // be available to the window.
  std::unique_ptr<ui::Layer> window1_layer(window1->AcquireLayer());
  EXPECT_FALSE(window1_test_api.OwnsLayer());
  EXPECT_TRUE(window1_layer.get() == window1->layer());

  // The acquired layer's owner should be set NULL and re-acquring
  // should return NULL.
  EXPECT_FALSE(window1_layer->owner());
  std::unique_ptr<ui::Layer> window1_layer_reacquired(window1->AcquireLayer());
  EXPECT_FALSE(window1_layer_reacquired.get());

  // Upon destruction, window1's layer should still be valid, and in the layer
  // hierarchy, but window2's should be gone, and no longer in the hierarchy.
  window1.reset();
  window2.reset();

  // This should be set by the window's destructor.
  EXPECT_TRUE(window1_layer->delegate() == NULL);
  EXPECT_EQ(1U, parent->children().size());
}

// Make sure that properties which should persist from the old layer to the new
// layer actually do.
TEST_F(WindowTest, RecreateLayer) {
  // Set properties to non default values.
  gfx::Rect window_bounds(100, 100);
  Window w(new ColorTestWindowDelegate(SK_ColorWHITE));
  w.set_id(1);
  w.Init(ui::LAYER_SOLID_COLOR);
  w.SetBounds(window_bounds);

  ui::Layer* layer = w.layer();
  layer->SetVisible(false);
  layer->SetMasksToBounds(true);

  ui::Layer child_layer;
  layer->Add(&child_layer);

  std::unique_ptr<ui::Layer> old_layer(w.RecreateLayer());
  layer = w.layer();
  EXPECT_EQ(ui::LAYER_SOLID_COLOR, layer->type());
  EXPECT_FALSE(layer->visible());
  EXPECT_EQ(1u, layer->children().size());
  EXPECT_TRUE(layer->GetMasksToBounds());
  EXPECT_EQ("0,0 100x100", w.bounds().ToString());
  EXPECT_EQ("0,0 100x100", layer->bounds().ToString());
}

// Verify that RecreateLayer() stacks the old layer above the newly creatd
// layer.
TEST_F(WindowTest, RecreateLayerZOrder) {
  std::unique_ptr<Window> w(CreateTestWindow(
      SK_ColorWHITE, 1, gfx::Rect(0, 0, 100, 100), root_window()));
  std::unique_ptr<ui::Layer> old_layer(w->RecreateLayer());

  const std::vector<ui::Layer*>& child_layers =
      root_window()->layer()->children();
  ASSERT_EQ(2u, child_layers.size());
  EXPECT_EQ(w->layer(), child_layers[0]);
  EXPECT_EQ(old_layer.get(), child_layers[1]);
}

// Ensure that acquiring a layer then recreating a layer does not crash
// and that RecreateLayer returns null.
TEST_F(WindowTest, AcquireThenRecreateLayer) {
  std::unique_ptr<Window> w(CreateTestWindow(
      SK_ColorWHITE, 1, gfx::Rect(0, 0, 100, 100), root_window()));
  std::unique_ptr<ui::Layer> acquired_layer(w->AcquireLayer());
  std::unique_ptr<ui::Layer> doubly_acquired_layer(w->RecreateLayer());
  EXPECT_EQ(NULL, doubly_acquired_layer.get());

  // Destroy window before layer gets destroyed.
  w.reset();
}

class TestVisibilityClient : public client::VisibilityClient {
 public:
  explicit TestVisibilityClient(Window* root_window)
      : ignore_visibility_changes_(false) {
    client::SetVisibilityClient(root_window, this);
  }
  ~TestVisibilityClient() override {}

  void set_ignore_visibility_changes(bool ignore_visibility_changes) {
    ignore_visibility_changes_ = ignore_visibility_changes;
  }

  // Overridden from client::VisibilityClient:
  void UpdateLayerVisibility(aura::Window* window, bool visible) override {
    if (!ignore_visibility_changes_)
      window->layer()->SetVisible(visible);
  }

 private:
  bool ignore_visibility_changes_;
  DISALLOW_COPY_AND_ASSIGN(TestVisibilityClient);
};

TEST_F(WindowTest, VisibilityClientIsVisible) {
  TestVisibilityClient client(root_window());

  std::unique_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
  EXPECT_TRUE(window->IsVisible());
  EXPECT_TRUE(window->layer()->visible());

  window->Hide();
  EXPECT_FALSE(window->IsVisible());
  EXPECT_FALSE(window->layer()->visible());
  window->Show();

  client.set_ignore_visibility_changes(true);
  window->Hide();
  EXPECT_FALSE(window->IsVisible());
  EXPECT_TRUE(window->layer()->visible());
}

// Tests the mouse events seen by WindowDelegates in a Window hierarchy when
// changing the properties of a leaf Window.
TEST_F(WindowTest, MouseEventsOnLeafWindowChange) {
  ui::test::EventGenerator generator(root_window());
  generator.MoveMouseTo(50, 50);

  EventCountDelegate d1;
  std::unique_ptr<Window> w1(CreateTestWindowWithDelegate(
      &d1, 1, gfx::Rect(0, 0, 100, 100), root_window()));
  RunAllPendingInMessageLoop();
  // The format of result is "Enter/Move/Leave".
  EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());

  // Add new window |w11| on top of |w1| which contains the cursor.
  EventCountDelegate d11;
  std::unique_ptr<Window> w11(CreateTestWindowWithDelegate(
      &d11, 1, gfx::Rect(0, 0, 100, 100), w1.get()));
  RunAllPendingInMessageLoop();
  EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());

  // Resize |w11| so that it does not contain the cursor.
  w11->SetBounds(gfx::Rect(0, 0, 10, 10));
  RunAllPendingInMessageLoop();
  EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset());

  // Resize |w11| so that it does contain the cursor.
  w11->SetBounds(gfx::Rect(0, 0, 60, 60));
  RunAllPendingInMessageLoop();
  EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());

  // Detach |w11| from |w1|.
  w1->RemoveChild(w11.get());
  RunAllPendingInMessageLoop();
  EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset());

  // Re-attach |w11| to |w1|.
  w1->AddChild(w11.get());
  RunAllPendingInMessageLoop();
  EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());

  // Hide |w11|.
  w11->Hide();
  RunAllPendingInMessageLoop();
  EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset());

  // Show |w11|.
  w11->Show();
  RunAllPendingInMessageLoop();
  EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());

  // Translate |w11| so that it does not contain the mouse cursor.
  gfx::Transform transform;
  transform.Translate(100, 100);
  w11->SetTransform(transform);
  RunAllPendingInMessageLoop();
  EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset());

  // Clear the transform on |w11| so that it does contain the cursor.
  w11->SetTransform(gfx::Transform());
  RunAllPendingInMessageLoop();
  EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());

  // Close |w11|. Note that since |w11| is being destroyed, its delegate should
  // not see any further events.
  w11.reset();
  RunAllPendingInMessageLoop();
  EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("0 0 0", d11.GetMouseMotionCountsAndReset());

  // Move the mouse outside the bounds of the root window. Since the mouse
  // cursor is no longer within their bounds, the delegates of the child
  // windows should not see any mouse events.
  generator.MoveMouseTo(-10, -10);
  EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("0 0 0", d11.GetMouseMotionCountsAndReset());

  // Add |w11|.
  w11.reset(CreateTestWindowWithDelegate(
      &d11, 1, gfx::Rect(0, 0, 100, 100), w1.get()));
  RunAllPendingInMessageLoop();
  EXPECT_EQ("0 0 0", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("0 0 0", d11.GetMouseMotionCountsAndReset());

  // Close |w11|.
  w11.reset();
  RunAllPendingInMessageLoop();
  EXPECT_EQ("0 0 0", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("0 0 0", d11.GetMouseMotionCountsAndReset());
}

// Tests the mouse events seen by WindowDelegates in a Window hierarchy when
// deleting a non-leaf Window.
TEST_F(WindowTest, MouseEventsOnNonLeafWindowDelete) {
  ui::test::EventGenerator generator(root_window());
  generator.MoveMouseTo(50, 50);

  EventCountDelegate d1;
  std::unique_ptr<Window> w1(CreateTestWindowWithDelegate(
      &d1, 1, gfx::Rect(0, 0, 100, 100), root_window()));
  RunAllPendingInMessageLoop();
  // The format of result is "Enter/Move/Leave".
  EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());

  // Add new window |w2| on top of |w1| which contains the cursor.
  EventCountDelegate d2;
  std::unique_ptr<Window> w2(CreateTestWindowWithDelegate(
      &d2, 1, gfx::Rect(0, 0, 100, 100), w1.get()));
  RunAllPendingInMessageLoop();
  EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("1 1 0", d2.GetMouseMotionCountsAndReset());

  // Add new window on top of |w2| which contains the cursor.
  EventCountDelegate d3;
  CreateTestWindowWithDelegate(
      &d3, 1, gfx::Rect(0, 0, 100, 100), w2.get());
  RunAllPendingInMessageLoop();
  EXPECT_EQ("0 0 0", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("0 0 1", d2.GetMouseMotionCountsAndReset());
  EXPECT_EQ("1 1 0", d3.GetMouseMotionCountsAndReset());

  // Delete |w2|, which will also delete its owned child window. Since |w2| and
  // its child are in the process of being destroyed, their delegates should
  // not see any further events.
  w2.reset();
  RunAllPendingInMessageLoop();
  EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
  EXPECT_EQ("0 0 0", d2.GetMouseMotionCountsAndReset());
  EXPECT_EQ("0 0 0", d3.GetMouseMotionCountsAndReset());
}

class RootWindowAttachmentObserver : public WindowObserver {
 public:
  RootWindowAttachmentObserver() : added_count_(0), removed_count_(0) {}
  ~RootWindowAttachmentObserver() override {}

  int added_count() const { return added_count_; }
  int removed_count() const { return removed_count_; }

  void Clear() {
    added_count_ = 0;
    removed_count_ = 0;
  }

  // Overridden from WindowObserver:
  void OnWindowAddedToRootWindow(Window* window) override { ++added_count_; }
  void OnWindowRemovingFromRootWindow(Window* window,
                                      Window* new_root) override {
    ++removed_count_;
  }

 private:
  int added_count_;
  int removed_count_;

  DISALLOW_COPY_AND_ASSIGN(RootWindowAttachmentObserver);
};

TEST_F(WindowTest, RootWindowAttachment) {
  RootWindowAttachmentObserver observer;

  // Test a direct add/remove from the RootWindow.
  std::unique_ptr<Window> w1(new Window(NULL));
  w1->Init(ui::LAYER_NOT_DRAWN);
  w1->AddObserver(&observer);

  ParentWindow(w1.get());
  EXPECT_EQ(1, observer.added_count());
  EXPECT_EQ(0, observer.removed_count());

  w1.reset();
  EXPECT_EQ(1, observer.added_count());
  EXPECT_EQ(1, observer.removed_count());

  observer.Clear();

  // Test an indirect add/remove from the RootWindow.
  w1.reset(new Window(NULL));
  w1->Init(ui::LAYER_NOT_DRAWN);
  Window* w11 = new Window(NULL);
  w11->Init(ui::LAYER_NOT_DRAWN);
  w11->AddObserver(&observer);
  w1->AddChild(w11);
  EXPECT_EQ(0, observer.added_count());
  EXPECT_EQ(0, observer.removed_count());

  ParentWindow(w1.get());
  EXPECT_EQ(1, observer.added_count());
  EXPECT_EQ(0, observer.removed_count());

  w1.reset();  // Deletes w11.
  w11 = NULL;
  EXPECT_EQ(1, observer.added_count());
  EXPECT_EQ(1, observer.removed_count());

  observer.Clear();

  // Test an indirect add/remove with nested observers.
  w1.reset(new Window(NULL));
  w1->Init(ui::LAYER_NOT_DRAWN);
  w11 = new Window(NULL);
  w11->Init(ui::LAYER_NOT_DRAWN);
  w11->AddObserver(&observer);
  w1->AddChild(w11);
  Window* w111 = new Window(NULL);
  w111->Init(ui::LAYER_NOT_DRAWN);
  w111->AddObserver(&observer);
  w11->AddChild(w111);

  EXPECT_EQ(0, observer.added_count());
  EXPECT_EQ(0, observer.removed_count());

  ParentWindow(w1.get());
  EXPECT_EQ(2, observer.added_count());
  EXPECT_EQ(0, observer.removed_count());

  w1.reset();  // Deletes w11 and w111.
  w11 = NULL;
  w111 = NULL;
  EXPECT_EQ(2, observer.added_count());
  EXPECT_EQ(2, observer.removed_count());
}

class BoundsChangedWindowObserver : public WindowObserver {
 public:
  BoundsChangedWindowObserver() : root_set_(false) {}

  void OnWindowBoundsChanged(Window* window,
                             const gfx::Rect& old_bounds,
                             const gfx::Rect& new_bounds,
                             ui::PropertyChangeReason reason) override {
    root_set_ = window->GetRootWindow() != NULL;
  }

  bool root_set() const { return root_set_; }

 private:
  bool root_set_;

  DISALLOW_COPY_AND_ASSIGN(BoundsChangedWindowObserver);
};

TEST_F(WindowTest, RootWindowSetWhenReparenting) {
  Window parent1(NULL);
  parent1.Init(ui::LAYER_NOT_DRAWN);
  Window parent2(NULL);
  parent2.Init(ui::LAYER_NOT_DRAWN);
  ParentWindow(&parent1);
  ParentWindow(&parent2);
  parent1.SetBounds(gfx::Rect(10, 10, 300, 300));
  parent2.SetBounds(gfx::Rect(20, 20, 300, 300));

  BoundsChangedWindowObserver observer;
  Window child(NULL);
  child.Init(ui::LAYER_NOT_DRAWN);
  child.SetBounds(gfx::Rect(5, 5, 100, 100));
  parent1.AddChild(&child);

  // We need animations to start in order to observe the bounds changes.
  ui::ScopedAnimationDurationScaleMode test_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  ui::ScopedLayerAnimationSettings settings1(child.layer()->GetAnimator());
  settings1.SetTransitionDuration(base::TimeDelta::FromMilliseconds(100));
  gfx::Rect new_bounds(gfx::Rect(35, 35, 50, 50));
  child.SetBounds(new_bounds);

  child.AddObserver(&observer);

  // Reparenting the |child| will cause it to get moved. During this move
  // the window should still have root window set.
  parent2.AddChild(&child);
  EXPECT_TRUE(observer.root_set());

  // Animations should stop and the bounds should be as set before the |child|
  // got reparented.
  EXPECT_EQ(new_bounds.ToString(), child.GetTargetBounds().ToString());
  EXPECT_EQ(new_bounds.ToString(), child.bounds().ToString());
  EXPECT_EQ("55,55 50x50", child.GetBoundsInRootWindow().ToString());
}

TEST_F(WindowTest, OwnedByParentFalse) {
  // By default, a window is owned by its parent. If this is set to false, the
  // window will not be destroyed when its parent is.

  std::unique_ptr<Window> w1(new Window(NULL));
  w1->Init(ui::LAYER_NOT_DRAWN);
  std::unique_ptr<Window> w2(new Window(NULL));
  w2->set_owned_by_parent(false);
  w2->Init(ui::LAYER_NOT_DRAWN);
  w1->AddChild(w2.get());

  w1.reset();

  // We should be able to deref w2 still, but its parent should now be NULL.
  EXPECT_EQ(NULL, w2->parent());
}

// Used By DeleteWindowFromOnWindowDestroyed. Destroys a Window from
// OnWindowDestroyed().
class OwningWindowDelegate : public TestWindowDelegate {
 public:
  OwningWindowDelegate() {}

  void SetOwnedWindow(Window* window) {
    owned_window_.reset(window);
  }

  void OnWindowDestroyed(Window* window) override { owned_window_.reset(NULL); }

 private:
  std::unique_ptr<Window> owned_window_;

  DISALLOW_COPY_AND_ASSIGN(OwningWindowDelegate);
};

// Creates a window with two child windows. When the first child window is
// destroyed (WindowDelegate::OnWindowDestroyed) it deletes the second child.
// This synthesizes BrowserView and the status bubble. Both are children of the
// same parent and destroying BrowserView triggers it destroying the status
// bubble.
TEST_F(WindowTest, DeleteWindowFromOnWindowDestroyed) {
  std::unique_ptr<Window> parent(new Window(NULL));
  parent->Init(ui::LAYER_NOT_DRAWN);
  OwningWindowDelegate delegate;
  Window* c1 = new Window(&delegate);
  c1->Init(ui::LAYER_NOT_DRAWN);
  parent->AddChild(c1);
  Window* c2 = new Window(NULL);
  c2->Init(ui::LAYER_NOT_DRAWN);
  parent->AddChild(c2);
  delegate.SetOwnedWindow(c2);
  parent.reset();
}

// WindowObserver implementation that deletes a window in
// OnWindowVisibilityChanged().
class DeleteOnVisibilityChangedObserver : public WindowObserver {
 public:
  // |to_observe| is the Window this is added as an observer to. When
  // OnWindowVisibilityChanged() is called |to_delete| is deleted.
  explicit DeleteOnVisibilityChangedObserver(Window* to_observe,
                                             Window* to_delete)
      : to_observe_(to_observe), to_delete_(to_delete) {
    to_observe_->AddObserver(this);
  }
  ~DeleteOnVisibilityChangedObserver() override {
    // OnWindowVisibilityChanged() should have been called.
    DCHECK(!to_delete_);
  }

  // WindowObserver:
  void OnWindowVisibilityChanged(Window* window, bool visible) override {
    to_observe_->RemoveObserver(this);
    delete to_delete_;
    to_delete_ = nullptr;
  }

 private:
  Window* to_observe_;
  Window* to_delete_;

  DISALLOW_COPY_AND_ASSIGN(DeleteOnVisibilityChangedObserver);
};

TEST_F(WindowTest, DeleteParentWindowFromOnWindowVisibiltyChanged) {
  WindowTracker tracker;
  Window* root = CreateTestWindowWithId(0, nullptr);
  tracker.Add(root);
  Window* child1 = CreateTestWindowWithId(0, root);
  tracker.Add(child1);
  tracker.Add(CreateTestWindowWithId(0, root));

  // This deletes |root| (the parent) when OnWindowVisibilityChanged() is
  // received by |child1|.
  DeleteOnVisibilityChangedObserver deletion_observer(child1, root);
  // The Hide() calls trigger deleting |root|, which should delete the whole
  // tree.
  root->Hide();
  EXPECT_TRUE(tracker.windows().empty());
}

// Used by DelegateNotifiedAsBoundsChange to verify OnBoundsChanged() is
// invoked.
class BoundsChangeDelegate : public TestWindowDelegate {
 public:
  BoundsChangeDelegate() : bounds_changed_(false) {}

  void clear_bounds_changed() { bounds_changed_ = false; }
  bool bounds_changed() const {
    return bounds_changed_;
  }

  // Window
  void OnBoundsChanged(const gfx::Rect& old_bounds,
                       const gfx::Rect& new_bounds) override {
    bounds_changed_ = true;
  }

 private:
  // Was OnBoundsChanged() invoked?
  bool bounds_changed_;

  DISALLOW_COPY_AND_ASSIGN(BoundsChangeDelegate);
};

// Verifies the delegate is notified when the actual bounds of the layer
// change.
TEST_F(WindowTest, DelegateNotifiedAsBoundsChange) {
  BoundsChangeDelegate delegate;

  // We cannot short-circuit animations in this test.
  ui::ScopedAnimationDurationScaleMode test_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  std::unique_ptr<Window> window(CreateTestWindowWithDelegate(
      &delegate, 1, gfx::Rect(0, 0, 100, 100), root_window()));
  window->layer()->GetAnimator()->set_disable_timer_for_test(true);

  delegate.clear_bounds_changed();

  // Animate to a different position.
  {
    ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
    window->SetBounds(gfx::Rect(100, 100, 100, 100));
  }

  // Bounds shouldn't immediately have changed.
  EXPECT_EQ("0,0 100x100", window->bounds().ToString());
  EXPECT_FALSE(delegate.bounds_changed());

  // Animate to the end, which should notify of the change.
  base::TimeTicks start_time =
      window->layer()->GetAnimator()->last_step_time();
  ui::LayerAnimator* animator = window->layer()->GetAnimator();
  animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
  EXPECT_TRUE(delegate.bounds_changed());
  EXPECT_NE("0,0 100x100", window->bounds().ToString());
}

// Verifies the delegate is notified when the actual bounds of the layer
// change even when the window is not the layer's delegate
TEST_F(WindowTest, DelegateNotifiedAsBoundsChangeInHiddenLayer) {
  BoundsChangeDelegate delegate;

  // We cannot short-circuit animations in this test.
  ui::ScopedAnimationDurationScaleMode test_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  std::unique_ptr<Window> window(CreateTestWindowWithDelegate(
      &delegate, 1, gfx::Rect(0, 0, 100, 100), root_window()));
  window->layer()->GetAnimator()->set_disable_timer_for_test(true);

  delegate.clear_bounds_changed();

  // Suppress paint on the window since it is hidden (should reset the layer's
  // delegate to NULL)
  window->SuppressPaint();
  EXPECT_EQ(NULL, window->layer()->delegate());

  // Animate to a different position.
  {
    ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
    window->SetBounds(gfx::Rect(100, 100, 110, 100));
  }

  // Layer delegate is NULL but we should still get bounds changed notification.
  EXPECT_EQ("100,100 110x100", window->GetTargetBounds().ToString());
  EXPECT_TRUE(delegate.bounds_changed());

  delegate.clear_bounds_changed();

  // Animate to the end: will *not* notify of the change since we are hidden.
  base::TimeTicks start_time =
      window->layer()->GetAnimator()->last_step_time();
  ui::LayerAnimator* animator = window->layer()->GetAnimator();
  animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000));

  // No bounds changed notification at the end of animation since layer
  // delegate is NULL.
  EXPECT_FALSE(delegate.bounds_changed());
  EXPECT_NE("0,0 100x100", window->layer()->bounds().ToString());
}

// Used by AddChildNotifications to track notification counts.
class AddChildNotificationsObserver : public WindowObserver {
 public:
  AddChildNotificationsObserver() : added_count_(0), removed_count_(0) {}

  std::string CountStringAndReset() {
    std::string result = base::NumberToString(added_count_) + " " +
                         base::NumberToString(removed_count_);
    added_count_ = removed_count_ = 0;
    return result;
  }

  // WindowObserver overrides:
  void OnWindowAddedToRootWindow(Window* window) override { added_count_++; }
  void OnWindowRemovingFromRootWindow(Window* window,
                                      Window* new_root) override {
    removed_count_++;
  }

 private:
  int added_count_;
  int removed_count_;

  DISALLOW_COPY_AND_ASSIGN(AddChildNotificationsObserver);
};

// Assertions around when root window notifications are sent.
TEST_F(WindowTest, AddChildNotifications) {
  AddChildNotificationsObserver observer;
  std::unique_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
  std::unique_ptr<Window> w2(CreateTestWindowWithId(1, root_window()));
  w2->AddObserver(&observer);
  w2->Focus();
  EXPECT_TRUE(w2->HasFocus());

  // Move |w2| to be a child of |w1|.
  w1->AddChild(w2.get());
  // Sine we moved in the same root, observer shouldn't be notified.
  EXPECT_EQ("0 0", observer.CountStringAndReset());
  // |w2| should still have focus after moving.
  EXPECT_TRUE(w2->HasFocus());
}

// Tests that a delegate that destroys itself when the window is destroyed does
// not break.
TEST_F(WindowTest, DelegateDestroysSelfOnWindowDestroy) {
  std::unique_ptr<Window> w1(
      CreateTestWindowWithDelegate(new DestroyWindowDelegate(), 0,
                                   gfx::Rect(10, 20, 30, 40), root_window()));
}

class HierarchyObserver : public WindowObserver {
 public:
  explicit HierarchyObserver(Window* target) : target_(target) {
    target_->AddObserver(this);
  }
  ~HierarchyObserver() override { target_->RemoveObserver(this); }

  void ValidateState(
      int index,
      const WindowObserver::HierarchyChangeParams& params) const {
    ParamsMatch(params_[index], params);
  }

  void Reset() {
    params_.clear();
  }

 private:
  // Overridden from WindowObserver:
  void OnWindowHierarchyChanging(const HierarchyChangeParams& params) override {
    params_.push_back(params);
  }
  void OnWindowHierarchyChanged(const HierarchyChangeParams& params) override {
    params_.push_back(params);
  }

  void ParamsMatch(const WindowObserver::HierarchyChangeParams& p1,
                   const WindowObserver::HierarchyChangeParams& p2) const {
    EXPECT_EQ(p1.phase, p2.phase);
    EXPECT_EQ(p1.target, p2.target);
    EXPECT_EQ(p1.new_parent, p2.new_parent);
    EXPECT_EQ(p1.old_parent, p2.old_parent);
    EXPECT_EQ(p1.receiver, p2.receiver);
  }

  Window* target_;
  std::vector<WindowObserver::HierarchyChangeParams> params_;

  DISALLOW_COPY_AND_ASSIGN(HierarchyObserver);
};

// Tests hierarchy change notifications.
TEST_F(WindowTest, OnWindowHierarchyChange) {
  {
    // Simple add & remove.
    HierarchyObserver oroot(root_window());

    std::unique_ptr<Window> w1(CreateTestWindowWithId(1, NULL));
    HierarchyObserver o1(w1.get());

    // Add.
    root_window()->AddChild(w1.get());

    WindowObserver::HierarchyChangeParams params;
    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
    params.target = w1.get();
    params.old_parent = NULL;
    params.new_parent = root_window();
    params.receiver = w1.get();
    o1.ValidateState(0, params);

    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
    params.receiver = w1.get();
    o1.ValidateState(1, params);

    params.receiver = root_window();
    oroot.ValidateState(0, params);

    // Remove.
    o1.Reset();
    oroot.Reset();

    root_window()->RemoveChild(w1.get());

    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
    params.old_parent = root_window();
    params.new_parent = NULL;
    params.receiver = w1.get();

    o1.ValidateState(0, params);

    params.receiver = root_window();
    oroot.ValidateState(0, params);

    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
    params.receiver = w1.get();
    o1.ValidateState(1, params);
  }

  {
    // Add & remove of hierarchy. Tests notification order per documentation in
    // WindowObserver.
    HierarchyObserver o(root_window());
    std::unique_ptr<Window> w1(CreateTestWindowWithId(1, NULL));
    Window* w11 = CreateTestWindowWithId(11, w1.get());
    w1->AddObserver(&o);
    w11->AddObserver(&o);

    // Add.
    root_window()->AddChild(w1.get());

    // Dispatched to target first.
    int index = 0;
    WindowObserver::HierarchyChangeParams params;
    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
    params.target = w1.get();
    params.old_parent = NULL;
    params.new_parent = root_window();
    params.receiver = w1.get();
    o.ValidateState(index++, params);

    // Dispatched to target's children.
    params.receiver = w11;
    o.ValidateState(index++, params);

    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;

    // Now process the "changed" phase.
    params.receiver = w1.get();
    o.ValidateState(index++, params);
    params.receiver = w11;
    o.ValidateState(index++, params);
    params.receiver = root_window();
    o.ValidateState(index++, params);

    // Remove.
    root_window()->RemoveChild(w1.get());
    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
    params.old_parent = root_window();
    params.new_parent = NULL;
    params.receiver = w1.get();
    o.ValidateState(index++, params);
    params.receiver = w11;
    o.ValidateState(index++, params);
    params.receiver = root_window();
    o.ValidateState(index++, params);
    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
    params.receiver = w1.get();
    o.ValidateState(index++, params);
    params.receiver = w11;
    o.ValidateState(index++, params);

    w1.reset();
  }

  {
    // Reparent. Tests notification order per documentation in WindowObserver.
    std::unique_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
    Window* w11 = CreateTestWindowWithId(11, w1.get());
    Window* w111 = CreateTestWindowWithId(111, w11);
    std::unique_ptr<Window> w2(CreateTestWindowWithId(2, root_window()));

    HierarchyObserver o(root_window());
    w1->AddObserver(&o);
    w11->AddObserver(&o);
    w111->AddObserver(&o);
    w2->AddObserver(&o);

    w2->AddChild(w11);

    // Dispatched to target first.
    int index = 0;
    WindowObserver::HierarchyChangeParams params;
    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
    params.target = w11;
    params.old_parent = w1.get();
    params.new_parent = w2.get();
    params.receiver = w11;
    o.ValidateState(index++, params);

    // Then to target's children.
    params.receiver = w111;
    o.ValidateState(index++, params);

    // Then to target's old parent chain.
    params.receiver = w1.get();
    o.ValidateState(index++, params);
    params.receiver = root_window();
    o.ValidateState(index++, params);

    // "Changed" phase.
    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
    params.receiver = w11;
    o.ValidateState(index++, params);
    params.receiver = w111;
    o.ValidateState(index++, params);
    params.receiver = w2.get();
    o.ValidateState(index++, params);
    params.receiver = root_window();
    o.ValidateState(index++, params);

    w1.reset();
    w2.reset();
  }
}

class TestLayerAnimationObserver : public ui::LayerAnimationObserver {
 public:
  TestLayerAnimationObserver()
      : animation_completed_(false),
        animation_aborted_(false) {}
  ~TestLayerAnimationObserver() override {}

  bool animation_completed() const { return animation_completed_; }
  bool animation_aborted() const { return animation_aborted_; }

  void Reset() {
    animation_completed_ = false;
    animation_aborted_ = false;
  }

 private:
  // ui::LayerAnimationObserver:
  void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
    animation_completed_ = true;
  }

  void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {
    animation_aborted_ = true;
  }

  void OnLayerAnimationScheduled(
      ui::LayerAnimationSequence* sequence) override {}

  bool animation_completed_;
  bool animation_aborted_;

  DISALLOW_COPY_AND_ASSIGN(TestLayerAnimationObserver);
};

TEST_F(WindowTest, WindowDestroyCompletesAnimations) {
  ui::ScopedAnimationDurationScaleMode test_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  scoped_refptr<ui::LayerAnimator> animator =
      ui::LayerAnimator::CreateImplicitAnimator();
  TestLayerAnimationObserver observer;
  animator->AddObserver(&observer);
  // Make sure destroying a Window completes the animation.
  {
    std::unique_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
    window->layer()->SetAnimator(animator.get());

    gfx::Transform transform;
    transform.Scale(0.5f, 0.5f);
    window->SetTransform(transform);

    EXPECT_TRUE(animator->is_animating());
    EXPECT_FALSE(observer.animation_completed());
  }
  EXPECT_TRUE(animator.get());
  EXPECT_FALSE(animator->is_animating());
  EXPECT_TRUE(observer.animation_completed());
  EXPECT_FALSE(observer.animation_aborted());
  animator->RemoveObserver(&observer);
  observer.Reset();

  animator = ui::LayerAnimator::CreateImplicitAnimator();
  animator->AddObserver(&observer);
  ui::Layer layer;
  layer.SetAnimator(animator.get());
  {
    std::unique_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
    window->layer()->Add(&layer);

    gfx::Transform transform;
    transform.Scale(0.5f, 0.5f);
    layer.SetTransform(transform);

    EXPECT_TRUE(animator->is_animating());
    EXPECT_FALSE(observer.animation_completed());
  }

  EXPECT_TRUE(animator.get());
  EXPECT_FALSE(animator->is_animating());
  EXPECT_TRUE(observer.animation_completed());
  EXPECT_FALSE(observer.animation_aborted());
  animator->RemoveObserver(&observer);
}

TEST_F(WindowTest, RootWindowUsesCompositorFrameSinkId) {
  EXPECT_EQ(host()->compositor()->frame_sink_id(),
            root_window()->GetFrameSinkId());
  EXPECT_TRUE(root_window()->GetFrameSinkId().is_valid());
}

TEST_F(WindowTest, LocalSurfaceIdChanges) {
  Window window(nullptr);
  window.Init(ui::LAYER_NOT_DRAWN);
  window.SetBounds(gfx::Rect(300, 300));

  root_window()->AddChild(&window);

  std::unique_ptr<cc::LayerTreeFrameSink> frame_sink(
      window.CreateLayerTreeFrameSink());
  viz::LocalSurfaceId local_surface_id1 =
      window.GetLocalSurfaceIdAllocation().local_surface_id();
  EXPECT_NE(nullptr, frame_sink.get());
  EXPECT_TRUE(local_surface_id1.is_valid());

  // Resize to 0x0 to make sure the correct window size is stored before
  // creating the frame sink.
  window.SetBounds(gfx::Rect(0, 0));
  viz::LocalSurfaceId local_surface_id2 =
      window.GetLocalSurfaceIdAllocation().local_surface_id();
  EXPECT_TRUE(local_surface_id2.is_valid());
  EXPECT_NE(local_surface_id1, local_surface_id2);

  window.SetBounds(gfx::Rect(300, 300));
  viz::LocalSurfaceId local_surface_id3 =
      window.GetLocalSurfaceIdAllocation().local_surface_id();
  EXPECT_TRUE(local_surface_id3.is_valid());
  EXPECT_NE(local_surface_id1, local_surface_id3);
  EXPECT_NE(local_surface_id2, local_surface_id3);

  window.OnDeviceScaleFactorChanged(1.0f, 3.0f);
  viz::LocalSurfaceId local_surface_id4 =
      window.GetLocalSurfaceIdAllocation().local_surface_id();
  EXPECT_TRUE(local_surface_id4.is_valid());
  EXPECT_NE(local_surface_id1, local_surface_id4);
  EXPECT_NE(local_surface_id2, local_surface_id4);
  EXPECT_NE(local_surface_id3, local_surface_id4);

  window.RecreateLayer();
  viz::LocalSurfaceId local_surface_id5 =
      window.GetLocalSurfaceIdAllocation().local_surface_id();
  EXPECT_TRUE(local_surface_id5.is_valid());
  EXPECT_NE(local_surface_id1, local_surface_id5);
  EXPECT_NE(local_surface_id2, local_surface_id5);
  EXPECT_NE(local_surface_id3, local_surface_id5);
  EXPECT_NE(local_surface_id4, local_surface_id5);

  window.AllocateLocalSurfaceId();
  viz::LocalSurfaceId local_surface_id6 =
      window.GetLocalSurfaceIdAllocation().local_surface_id();
  EXPECT_TRUE(local_surface_id6.is_valid());
  EXPECT_NE(local_surface_id1, local_surface_id6);
  EXPECT_NE(local_surface_id2, local_surface_id6);
  EXPECT_NE(local_surface_id3, local_surface_id6);
  EXPECT_NE(local_surface_id4, local_surface_id6);
  EXPECT_NE(local_surface_id5, local_surface_id6);
}

// This delegate moves its parent window to the specified one when the gesture
// ends.
class HandleGestureEndDelegate : public TestWindowDelegate {
 public:
  explicit HandleGestureEndDelegate(
      base::OnceCallback<void(Window*)> on_gesture_end)
      : on_gesture_end_(std::move(on_gesture_end)) {}
  ~HandleGestureEndDelegate() override = default;

 private:
  // WindowDelegate:
  void OnGestureEvent(ui::GestureEvent* event) override {
    switch (event->type()) {
      case ui::ET_GESTURE_SCROLL_END:
      case ui::ET_GESTURE_END:
      case ui::ET_GESTURE_PINCH_END: {
        if (on_gesture_end_)
          std::move(on_gesture_end_).Run(static_cast<Window*>(event->target()));
        break;
      }
      default:
        break;
    }
  }

  base::OnceCallback<void(Window*)> on_gesture_end_;
  DISALLOW_COPY_AND_ASSIGN(HandleGestureEndDelegate);
};

TEST_F(WindowTest, CleanupGestureStateChangesWindowHierarchy) {
  Window window(nullptr);
  window.Init(ui::LAYER_NOT_DRAWN);
  root_window()->AddChild(&window);
  window.SetBounds(gfx::Rect(0, 0, 100, 100));
  window.Show();
  Window window2(nullptr);
  window2.Init(ui::LAYER_NOT_DRAWN);
  root_window()->AddChild(&window2);
  root_window()->StackChildAtBottom(&window2);
  window2.Show();
  HandleGestureEndDelegate delegate(base::BindLambdaForTesting(
      [&](Window* target_window) { window2.AddChild(target_window); }));
  std::unique_ptr<Window> child = std::make_unique<Window>(&delegate);
  child->Init(ui::LAYER_NOT_DRAWN);
  window.AddChild(child.get());
  child->SetBounds(gfx::Rect(0, 0, 100, 100));
  child->Show();
  EXPECT_EQ(1u, window.children().size());
  EXPECT_EQ(0u, window2.children().size());

  ui::test::EventGenerator event_generator(root_window(), child.get());
  event_generator.PressTouch();
  window.CleanupGestureState();
  EXPECT_EQ(0u, window.children().size());
  EXPECT_EQ(1u, window2.children().size());
  child.reset();
}

TEST_F(WindowTest, CleanupGestureStateDeleteOtherWindows) {
  Window window(nullptr);
  window.Init(ui::LAYER_NOT_DRAWN);
  root_window()->AddChild(&window);
  window.SetBounds(gfx::Rect(0, 0, 200, 200));
  window.Show();
  std::unique_ptr<Window> child1 = std::make_unique<Window>(nullptr);
  child1->Init(ui::LAYER_NOT_DRAWN);
  child1->SetBounds(gfx::Rect(100, 100, 100, 100));
  window.AddChild(child1.get());
  child1->Show();
  HandleGestureEndDelegate delegate(base::BindLambdaForTesting(
      [&](Window* target_window) { child1.reset(); }));
  std::unique_ptr<Window> child2 = std::make_unique<Window>(&delegate);
  child2->Init(ui::LAYER_NOT_DRAWN);
  window.AddChild(child2.get());
  child2->SetBounds(gfx::Rect(0, 0, 100, 100));
  child2->Show();
  window.StackChildAtBottom(child2.get());
  EXPECT_EQ(2u, window.children().size());
  EXPECT_EQ(child2.get(), window.children().front());

  ui::test::EventGenerator event_generator(root_window(), child2.get());
  event_generator.PressTouch();
  window.CleanupGestureState();
  EXPECT_EQ(1u, window.children().size());
  EXPECT_FALSE(child1);
  child2.reset();
}

}  // namespace
}  // namespace test
}  // namespace aura
