// Copyright 2017 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_occlusion_tracker.h"

#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/test/gtest_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/env.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/test/window_occlusion_tracker_test_api.h"
#include "ui/aura/window_observer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_animation_sequence.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/gfx/interpolated_transform.h"

namespace aura {

namespace {

constexpr base::TimeDelta kTransitionDuration = base::TimeDelta::FromSeconds(3);

class MockWindowDelegate : public test::ColorTestWindowDelegate {
 public:
  MockWindowDelegate() : test::ColorTestWindowDelegate(SK_ColorWHITE) {}
  ~MockWindowDelegate() override { EXPECT_FALSE(is_expecting_call()); }

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

  void SetName(const std::string& name) { window_->SetName(name); }

  void set_expectation(Window::OcclusionState occlusion_state,
                       const SkRegion& occluded_region) {
    expected_occlusion_state_ = occlusion_state;
    expected_occluded_region_ = occluded_region;
  }

  bool is_expecting_call() const {
    return expected_occlusion_state_ != Window::OcclusionState::UNKNOWN;
  }

  void OnWindowOcclusionChanged(Window::OcclusionState occlusion_state,
                                const SkRegion& occluded_region) override {
    SCOPED_TRACE(window_->GetName());
    ASSERT_TRUE(window_);
    EXPECT_NE(occlusion_state, Window::OcclusionState::UNKNOWN);
    EXPECT_EQ(occlusion_state, expected_occlusion_state_);
    EXPECT_EQ(occluded_region, expected_occluded_region_);
    expected_occlusion_state_ = Window::OcclusionState::UNKNOWN;
    expected_occluded_region_ = SkRegion();
  }

 private:
  Window::OcclusionState expected_occlusion_state_ =
      Window::OcclusionState::UNKNOWN;
  SkRegion expected_occluded_region_ = SkRegion();
  Window* window_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(MockWindowDelegate);
};

class WindowOcclusionTrackerTest : public test::AuraTestBase {
 public:
  WindowOcclusionTrackerTest() = default;

  Window* CreateTrackedWindow(MockWindowDelegate* delegate,
                              const gfx::Rect& bounds,
                              Window* parent = nullptr,
                              bool transparent = false) {
    Window* window = new Window(delegate);
    delegate->set_window(window);
    window->SetType(client::WINDOW_TYPE_NORMAL);
    window->Init(ui::LAYER_TEXTURED);
    window->SetTransparent(transparent);
    window->SetBounds(bounds);
    window->Show();
    parent = parent ? parent : root_window();
    parent->AddChild(window);
    window->TrackOcclusionState();
    return window;
  }

  Window* CreateUntrackedWindow(const gfx::Rect& bounds,
                                Window* parent = nullptr) {
    Window* window = test::CreateTestWindow(SK_ColorWHITE, 1, bounds,
                                            parent ? parent : root_window());
    return window;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(WindowOcclusionTrackerTest);
};

SkRegion SkRegionFromSkIRects(std::initializer_list<SkIRect> rects) {
  SkRegion r;
  r.setRects(rects.begin(), rects.size());
  return r;
}

}  // namespace

// Verify that non-overlapping windows have a VISIBLE occlusion state.
// _____  _____
// |    | |    |
// |____| |____|
TEST_F(WindowOcclusionTrackerTest, NonOverlappingWindows) {
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(15, 0, 10, 10)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_b, gfx::Rect(15, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
}

// Verify that partially overlapping windows have a VISIBLE occlusion state.
// ______
// |__|  |
// |_____|
TEST_F(WindowOcclusionTrackerTest, PartiallyOverlappingWindow) {
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeWH(5, 5)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
}

// Verify that a window whose bounds are covered by a hidden window is not
// occluded. Also, verify that calling Show() on the hidden window causes
// occlusion states to be recomputed.
//  __....     ... = hidden window
// |__|  .
// .......
TEST_F(WindowOcclusionTrackerTest, HiddenWindowCoversWindow) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b. Expect it to be non-occluded and expect window a to be
  // occluded.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 15, 15));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Hide window b. Expect window a to be non-occluded and window b to be
  // occluded.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::HIDDEN, SkRegion());
  window_b->Hide();
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Show window b. Expect window a to be occluded and window b to be non-
  // occluded.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  window_b->Show();
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
}

// Verify that a window whose bounds are covered by a semi-transparent window is
// not occluded. Also, verify that that when the opacity of a window changes,
// occlusion states are updated.
//  __....     ... = semi-transparent window
// |__|  .
// .......
TEST_F(WindowOcclusionTrackerTest, SemiTransparentWindowCoversWindow) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b. Expect it to be non-occluded and expect window a to be
  // occluded.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 15, 15));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Change the opacity of window b to 0.5f. Expect both windows to be non-
  // occluded.
  EXPECT_FALSE(delegate_a->is_expecting_call());
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  window_b->layer()->SetOpacity(0.5f);
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Change the opacity of window b back to 1.0f. Expect window a to be
  // occluded.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  window_b->layer()->SetOpacity(1.0f);
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Same as previous test, but the occlusion state of the semi-transparent is not
// tracked.
TEST_F(WindowOcclusionTrackerTest, SemiTransparentUntrackedWindowCoversWindow) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create untracked window b. Expect window a to be occluded.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  Window* window_b = CreateUntrackedWindow(gfx::Rect(0, 0, 15, 15));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Change the opacity of window b to 0.5f. Expect both windows to be non-
  // occluded.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  window_b->layer()->SetOpacity(0.5f);
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Change the opacity of window b back to 1.0f. Expect window a to be
  // occluded.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  window_b->layer()->SetOpacity(1.0f);
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Verify that one window whose bounds are covered by a set of two opaque
// windows is occluded.
//  ______
// |  |  |  <-- these two windows cover another window
// |__|__|
TEST_F(WindowOcclusionTrackerTest, TwoWindowsOccludeOneWindow) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b with bounds that partially cover window a. Expect both
  // windows to be non-occluded.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeWH(5, 10)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 5, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Create window c with bounds that cover the portion of window a that isn't
  // already covered by window b. Expect window a to be occluded and window a/b
  // to be non-occluded.
  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(5, 0, 5, 10)));
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_c, gfx::Rect(5, 0, 5, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());
}

// Verify that a window and its child that are covered by a sibling are
// occluded.
TEST_F(WindowOcclusionTrackerTest, SiblingOccludesWindowAndChild) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 20, 20));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b, with bounds that occlude half of its parent window a.
  // Expect it to be non-occluded.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 20), window_a);
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Create window c, with bounds that occlude window a and window b. Expect it
  // to be non-occluded, and window a and b to be occluded.
  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 20, 20));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());
}

// Verify that a window with one half covered by a child and the other half
// covered by a sibling is non-occluded.
TEST_F(WindowOcclusionTrackerTest, ChildAndSiblingOccludeOneWindow) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 20, 20));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b, with bounds that occlude half of its parent window a.
  // Expect it to be non-occluded.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 20), window_a);
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Create window c, with bounds that occlude the other half of window a.
  // Expect it to be non-occluded and expect window a to remain non-occluded.
  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(10, 0, 10, 20)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(10, 0, 10, 20)));
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_c, gfx::Rect(10, 0, 10, 20));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());
}

// Verify that a window covered by 2 non-occluded children is non-occluded.
TEST_F(WindowOcclusionTrackerTest, ChildrenOccludeOneWindow) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 20, 20));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b, with bounds that cover half of its parent window a. Expect
  // it to be non-occluded.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 20), window_a);
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window c, with bounds that cover the other half of its parent window
  // a. Expect it to be non-occluded. Expect window a to remain non-occluded.
  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(10, 0, 10, 20)));
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_c, gfx::Rect(10, 0, 10, 20), window_a);
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());
}

// Verify that when the bounds of a child window covers the bounds of a parent
// window but is itself visible, the parent window is visible.
TEST_F(WindowOcclusionTrackerTest, ChildDoesNotOccludeParent) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b with window a as parent. The bounds of window b fully cover
  // window a. Expect both windows to be non-occluded.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b =
      CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 10), window_a);
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Create window c whose bounds don't overlap existing windows.
  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(15, 0, 10, 10)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(15, 0, 10, 10)));
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_c = CreateTrackedWindow(delegate_c, gfx::Rect(15, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());

  // Change the parent of window b from window a to window c. Expect all windows
  // to remain non-occluded.
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  window_c->AddChild(window_b);
  EXPECT_FALSE(delegate_b->is_expecting_call());
}

// Verify that when the stacking order of windows change, occlusion states are
// updated.
TEST_F(WindowOcclusionTrackerTest, StackingChanged) {
  // Create three windows that have the same bounds. Expect window on top of the
  // stack to be non-occluded and other windows to be occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());

  // Move window a on top of the stack. Expect it to be non-occluded and expect
  // window c to be occluded.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  delegate_c->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  root_window()->StackChildAtTop(window_a);
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());
}

// Verify that when the stacking order of two transparent window changes, the
// occlusion states of their children is updated. The goal of this test is to
// ensure that the fact that the windows whose stacking order change are
// transparent doesn't prevent occlusion states from being recomputed.
TEST_F(WindowOcclusionTrackerTest, TransparentParentStackingChanged) {
  // Create window a which is transparent. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10),
                                         root_window(), true);
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b which has the same bounds as its parent window a. Expect it
  // to be non-occluded.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 10), window_a);
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Create window c which is transparent and has the same bounds as window a
  // and window b. Expect it to be non-occluded.
  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_c = CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 10, 10),
                                         root_window(), true);
  EXPECT_FALSE(delegate_c->is_expecting_call());

  // Create window d which has the same bounds as its parent window c. Expect
  // window d to be non-occluded and window a and b to be occluded.
  MockWindowDelegate* delegate_d = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_d->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_d, gfx::Rect(0, 0, 10, 10), window_c);
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_d->is_expecting_call());

  // Move window a on top of the stack. Expect window a and b to be non-occluded
  // and window c and d to be occluded.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  delegate_c->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_d->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  root_window()->StackChildAtTop(window_a);
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());
  EXPECT_FALSE(delegate_d->is_expecting_call());
}

// Verify that when StackChildAtTop() is called on a window whose occlusion
// state is not tracked, the occlusion state of tracked siblings is updated.
TEST_F(WindowOcclusionTrackerTest, UntrackedWindowStackingChanged) {
  Window* window_a = CreateUntrackedWindow(gfx::Rect(0, 0, 5, 5));

  // Create window b. Expect it to be non-occluded.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 5, 5));
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Stack window a on top of window b. Expect window b to be occluded.
  delegate_b->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  root_window()->StackChildAtTop(window_a);
  EXPECT_FALSE(delegate_b->is_expecting_call());
}

// Verify that occlusion states are updated when the bounds of a window change.
TEST_F(WindowOcclusionTrackerTest, BoundsChanged) {
  // Create two non-overlapping windows. Expect them to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 10, 10)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Move window b on top of window a. Expect window a to be occluded.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  window_b->SetBounds(window_a->bounds());
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Verify that when the bounds of a window are animated, occlusion states are
// updated at the beginning and at the end of the animation, but not during the
// animation. At the beginning of the animation, the window animated window
// should be considered non-occluded and should not occlude other windows. The
// animated window starts occluded.
TEST_F(WindowOcclusionTrackerTest, OccludedWindowBoundsAnimated) {
  ui::ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  ui::LayerAnimatorTestController test_controller(
      ui::LayerAnimator::CreateImplicitAnimator());
  ui::ScopedLayerAnimationSettings layer_animation_settings(
      test_controller.animator());
  layer_animation_settings.SetTransitionDuration(kTransitionDuration);

  // Create 3 windows. Window a is unoccluded. Window c occludes window b.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 10, 10)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
  window_b->layer()->SetAnimator(test_controller.animator());

  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_c, gfx::Rect(0, 10, 10, 10));
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());

  // Start animating the bounds of window b so that it moves on top of window a.
  // Window b should be non-occluded when the animation starts.
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  window_b->SetBounds(window_a->bounds());
  test_controller.Step(kTransitionDuration / 3);
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Window a should remain non-occluded during the animation.
  test_controller.Step(kTransitionDuration / 3);

  // Window b should occlude window a at the end of the animation.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  // Window b should have window c in its potential occlusion region.
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 10, 10)));
  test_controller.Step(kTransitionDuration / 3);
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  window_b->layer()->SetAnimator(nullptr);
}

// Same as the previous test, but the animated window starts non-occluded.
TEST_F(WindowOcclusionTrackerTest, NonOccludedWindowBoundsAnimated) {
  ui::ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  ui::LayerAnimatorTestController test_controller(
      ui::LayerAnimator::CreateImplicitAnimator());
  ui::ScopedLayerAnimationSettings layer_animation_settings(
      test_controller.animator());
  layer_animation_settings.SetTransitionDuration(kTransitionDuration);

  // Create 3 windows. Window a is unoccluded. Window c occludes window b.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 10, 10)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_c = CreateTrackedWindow(delegate_c, gfx::Rect(0, 10, 10, 10));
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());
  window_c->layer()->SetAnimator(test_controller.animator());

  // Start animating the bounds of window c so that it moves on top of window a.
  // Window b should be non-occluded when the animation starts.
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  window_c->SetBounds(window_a->bounds());
  test_controller.Step(kTransitionDuration / 3);
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Window a should remain non-occluded during the animation.
  test_controller.Step(kTransitionDuration / 3);

  // Window c should occlude window a at the end of the animation.
  // Window b should have a potentially occluded region including window c.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 0, 10, 10)));
  test_controller.Step(kTransitionDuration / 3);
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  window_c->layer()->SetAnimator(nullptr);
}

// Verify that occlusion states are updated when the bounds of a transparent
// window with opaque children change.
TEST_F(WindowOcclusionTrackerTest, TransparentParentBoundsChanged) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b which doesn't overlap window a and is transparent. Expect
  // it to be non-occluded.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 10, 10),
                                         root_window(), true);
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Create window c which has window b as parent and doesn't occlude any
  // window.
  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 5, 5)));
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 5, 5), window_b);
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());

  // Move window b so that window c occludes window a. Expect window a to be
  // occluded and other windows to be non-occluded.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  window_b->SetBounds(gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Verify that occlusion states are updated when the bounds of a window whose
// occlusion state is not tracked change.
TEST_F(WindowOcclusionTrackerTest, UntrackedWindowBoundsChanged) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b. It should not occlude window a.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 5, 5)));
  Window* window_b = CreateUntrackedWindow(gfx::Rect(0, 10, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Move window b on top of window a. Expect window a to be occluded.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  window_b->SetBounds(window_a->bounds());
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Verify that occlusion states are updated when the transform of a window
// changes.
TEST_F(WindowOcclusionTrackerTest, TransformChanged) {
  // Create two non-overlapping windows. Expect them to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 5, 5)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Scale and translate window b so that it covers window a. Expect window a to
  // be occluded.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  gfx::Transform transform;
  transform.Translate(0.0f, -10.0f);
  transform.Scale(2.0f, 2.0f);
  window_b->SetTransform(transform);
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Verify that when the transform of a window is animated, occlusion states are
// updated at the beginning and at the end of the animation, but not during the
// animation. At the beginning of the animation, the window animated window
// should be considered non-occluded and should not occlude other windows. The
// animated window starts occluded.
TEST_F(WindowOcclusionTrackerTest, OccludedWindowTransformAnimated) {
  ui::ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  ui::LayerAnimatorTestController test_controller(
      ui::LayerAnimator::CreateImplicitAnimator());
  ui::ScopedLayerAnimationSettings layer_animation_settings(
      test_controller.animator());
  layer_animation_settings.SetTransitionDuration(kTransitionDuration);

  // Create 3 windows. Window a is unoccluded. Window c occludes window b.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 5, 5)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
  window_b->layer()->SetAnimator(test_controller.animator());

  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_c, gfx::Rect(0, 10, 5, 5));
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());

  // Start animating the transform of window b so that it moves on top of window
  // a. Window b should be non-occluded when the animation starts.
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  auto transform = std::make_unique<ui::InterpolatedScale>(
      gfx::Point3F(1, 1, 1), gfx::Point3F(2.0f, 2.0f, 1));
  transform->SetChild(std::make_unique<ui::InterpolatedTranslation>(
      gfx::PointF(), gfx::PointF(-0.0f, -10.0f)));
  test_controller.animator()->StartAnimation(new ui::LayerAnimationSequence(
      ui::LayerAnimationElement::CreateInterpolatedTransformElement(
          std::move(transform), kTransitionDuration)));
  test_controller.Step(kTransitionDuration / 3);
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Window a should remain non-occluded during the animation.
  test_controller.Step(kTransitionDuration / 3);

  // Window b should occlude window a at the end of the animation.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  // Window b should see window c as part of the potential occlusion region.
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 5, 5)));
  test_controller.Step(kTransitionDuration / 3);
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  window_b->layer()->SetAnimator(nullptr);
}

// Same as the previous test, but the animated window starts non-occluded.
TEST_F(WindowOcclusionTrackerTest, NonOccludedWindowTransformAnimated) {
  ui::ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  ui::LayerAnimatorTestController test_controller(
      ui::LayerAnimator::CreateImplicitAnimator());
  ui::ScopedLayerAnimationSettings layer_animation_settings(
      test_controller.animator());
  layer_animation_settings.SetTransitionDuration(kTransitionDuration);

  // Create 3 windows. Window a is unoccluded. Window c occludes window b.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 20, 20));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 20, 10, 10)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_b, gfx::Rect(0, 20, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_c = CreateTrackedWindow(delegate_c, gfx::Rect(0, 20, 10, 10));
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());
  window_c->layer()->SetAnimator(test_controller.animator());

  // Start animating the bounds of window c so that it moves on top of window a.
  // Window b should be non-occluded when the animation starts.
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  auto transform = std::make_unique<ui::InterpolatedScale>(
      gfx::Point3F(1, 1, 1), gfx::Point3F(2.0f, 2.0f, 1));
  transform->SetChild(std::make_unique<ui::InterpolatedTranslation>(
      gfx::PointF(), gfx::PointF(-0.0f, -20.0f)));
  test_controller.animator()->StartAnimation(new ui::LayerAnimationSequence(
      ui::LayerAnimationElement::CreateInterpolatedTransformElement(
          std::move(transform), kTransitionDuration)));
  test_controller.Step(kTransitionDuration / 3);
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Window a should remain non-occluded during the animation.
  test_controller.Step(kTransitionDuration / 3);

  // Window c should occlude window a at the end of the animation.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  // Window b should now see window c in the potential occlusion region.
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeWH(20, 20)));
  test_controller.Step(kTransitionDuration / 3);
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  window_c->layer()->SetAnimator(nullptr);
}

// Verify that occlusion states are updated when the transform of a transparent
// window with opaque children change.
TEST_F(WindowOcclusionTrackerTest, TransparentParentTransformChanged) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b which doesn't overlap window a and is transparent. Expect
  // it to be non-occluded.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 10, 10),
                                         root_window(), true);
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Create window c which has window b as parent and doesn't occlude any
  // window.
  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 5, 5)));
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 5, 5), window_b);
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());

  // Scale and translate window b so that window c occludes window a. Expect
  // window a to be occluded and other windows to be non-occluded.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  gfx::Transform transform;
  transform.Translate(0.0f, -10.0f);
  transform.Scale(2.0f, 2.0f);
  window_b->SetTransform(transform);
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Verify that occlusion states are updated when the transform of a window whose
// occlusion state is not tracked changes.
TEST_F(WindowOcclusionTrackerTest, UntrackedWindowTransformChanged) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b. It should not occlude window a.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 5, 5)));
  Window* window_b = CreateUntrackedWindow(gfx::Rect(0, 10, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Scale and translate window b so that it occludes window a. Expect window a
  // to be occluded.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  gfx::Transform transform;
  transform.Translate(0.0f, -10.0f);
  transform.Scale(2.0f, 2.0f);
  window_b->SetTransform(transform);
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Verify that deleting an untracked window which covers a tracked window causes
// the tracked window to be non-occluded.
TEST_F(WindowOcclusionTrackerTest, DeleteUntrackedWindow) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b which occludes window a.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  Window* window_b = CreateUntrackedWindow(gfx::Rect(0, 0, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Delete window b. Expect a to be non-occluded.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  delete window_b;
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Verify that removing an untracked window which covers a tracked window causes
// the tracked window to be non-occluded.
TEST_F(WindowOcclusionTrackerTest, RemoveUntrackedWindow) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b which occludes window a.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  Window* window_b = CreateUntrackedWindow(gfx::Rect(0, 0, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Delete window b. Expect a to be non-occluded.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  root_window()->RemoveChild(window_b);
  EXPECT_FALSE(delegate_a->is_expecting_call());
  delete window_b;
}

// Verify that occlusion tracking with customized WindowHasContent callback.
TEST_F(WindowOcclusionTrackerTest, CustomizedWindowHasContent) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b with layer type LAYER_NOT_DRAWN. Occlusion state of a is
  // not changed.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  Window* window_b = new Window(delegate_b);
  delegate_b->set_window(window_b);
  window_b->Init(ui::LAYER_NOT_DRAWN);
  window_b->SetBounds(gfx::Rect(0, 0, 10, 10));
  root_window()->AddChild(window_b);
  delegate_b->set_expectation(Window::OcclusionState::HIDDEN, SkRegion());
  window_b->TrackOcclusionState();
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Use customized WindowHasContent callback to mark b as opaque.
  window_b->env()->GetWindowOcclusionTracker()->set_window_has_content_callback(
      base::BindLambdaForTesting([window_b](const Window* window) -> bool {
        return window == window_b;
      }));

  // Show window b to trigger a occlusion compute and window a is occluded.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  window_b->Show();
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  window_b->env()->GetWindowOcclusionTracker()->set_window_has_content_callback(
      base::NullCallback());
}

// Verify that when a tracked window is removed and re-added to a root,
// occlusion states are still tracked.
TEST_F(WindowOcclusionTrackerTest, RemoveAndAddTrackedToRoot) {
  Window* window_a = CreateUntrackedWindow(gfx::Rect(0, 0, 1, 1));
  CreateUntrackedWindow(gfx::Rect(0, 0, 10, 10), window_a);

  // Create window b. Expect it to be non-occluded.
  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_c = CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 5, 5));
  EXPECT_FALSE(delegate_c->is_expecting_call());

  // Remove window c from its root.
  root_window()->RemoveChild(window_c);

  // Add window c back under its root.
  root_window()->AddChild(window_c);

  // Create untracked window d which covers window a. Expect window a to be
  // occluded.
  delegate_c->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  Window* window_d = CreateUntrackedWindow(gfx::Rect(0, 0, 5, 5));
  EXPECT_FALSE(delegate_c->is_expecting_call());

  // Move window d so that it doesn't cover window c.
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 5, 5)));
  window_d->SetBounds(gfx::Rect(0, 10, 5, 5));
  EXPECT_FALSE(delegate_c->is_expecting_call());

  // Stack window a on top of window c. Expect window c to be non-occluded. This
  // won't work if WindowOcclusionTracked didn't register as an observer of
  // window a when window c was made a child of root_window().
  delegate_c->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  root_window()->StackChildAtTop(window_a);
  EXPECT_FALSE(delegate_c->is_expecting_call());
}

namespace {

class ResizeWindowObserver : public WindowObserver {
 public:
  ResizeWindowObserver(Window* window_to_resize)
      : window_to_resize_(window_to_resize) {}

  void OnWindowBoundsChanged(Window* window,
                             const gfx::Rect& old_bounds,
                             const gfx::Rect& new_bounds,
                             ui::PropertyChangeReason reason) override {
    window_to_resize_->SetBounds(old_bounds);
  }

 private:
  Window* const window_to_resize_;

  DISALLOW_COPY_AND_ASSIGN(ResizeWindowObserver);
};

}  // namespace

// Verify that when the bounds of a child window are updated in response to the
// bounds of a parent window being updated, occlusion states are updated once.
TEST_F(WindowOcclusionTrackerTest, ResizeChildFromObserver) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b. Expect it to be non-occluded and to occlude window a.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Create window c, which is a child of window b. Expect it to be non-
  // occluded.
  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_c =
      CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 5, 5), window_b);
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Create an observer that will resize window c when window b is resized.
  ResizeWindowObserver resize_window_observer(window_c);
  window_b->AddObserver(&resize_window_observer);

  // Resize window b. Expect window c to be resized so that window a stays
  // occluded. Window a should not temporarily be non-occluded.
  window_b->SetBounds(gfx::Rect(0, 0, 5, 5));

  window_b->RemoveObserver(&resize_window_observer);
}

// Verify that the bounds of windows are changed multiple times within the scope
// of a ScopedPause, occlusion states are updated once at the end of the scope.
TEST_F(WindowOcclusionTrackerTest, ScopedPause) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b which doesn't overlap window a. Expect it to be non
  // occluded.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 5, 5)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Change bounds multiple times. At the end of the scope, expect window a to
  // be occluded.
  {
    WindowOcclusionTracker::ScopedPause pause_occlusion_tracking(
        root_window()->env());
    window_b->SetBounds(window_a->bounds());
    window_a->SetBounds(gfx::Rect(0, 10, 5, 5));
    window_b->SetBounds(window_a->bounds());

    delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  }
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Same as the previous test, but with nested ScopedPause.
TEST_F(WindowOcclusionTrackerTest, NestedScopedPause) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  // Create window b which doesn't overlap window a. Expect it to be non-
  // occluded.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 5, 5)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Change bounds multiple times. At the end of the scope, expect window a to
  // be occluded.
  {
    WindowOcclusionTracker::ScopedPause pause_occlusion_tracking_a(
        root_window()->env());

    {
      WindowOcclusionTracker::ScopedPause pause_occlusion_tracking_b(
          root_window()->env());
      window_b->SetBounds(window_a->bounds());
    }
    {
      WindowOcclusionTracker::ScopedPause pause_occlusion_tracking_c(
          root_window()->env());
      window_a->SetBounds(gfx::Rect(0, 10, 5, 5));
    }
    {
      WindowOcclusionTracker::ScopedPause pause_occlusion_tracking_d(
          root_window()->env());
      window_b->SetBounds(window_a->bounds());
    }

    delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  }
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Verify that bounds are computed correctly when a hierarchy of windows have
// transforms.
TEST_F(WindowOcclusionTrackerTest, HierarchyOfTransforms) {
  gfx::Transform scale_2x_transform;
  scale_2x_transform.Scale(2.0f, 2.0f);

  // Effective bounds: x = 2, y = 2, height = 10, width = 10
  Window* window_a = CreateUntrackedWindow(gfx::Rect(2, 2, 5, 5));
  window_a->SetTransform(scale_2x_transform);

  // Effective bounds: x = 4, y = 4, height = 4, width = 4
  Window* window_b = CreateUntrackedWindow(gfx::Rect(1, 1, 2, 2), window_a);

  // Effective bounds: x = 34, y = 36, height = 8, width = 10
  CreateUntrackedWindow(gfx::Rect(15, 16, 4, 5), window_b);
  MockWindowDelegate* delegate_d = new MockWindowDelegate();
  delegate_d->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_d = CreateTrackedWindow(delegate_d, gfx::Rect(34, 36, 8, 10));
  EXPECT_FALSE(delegate_d->is_expecting_call());

  delegate_d->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  root_window()->StackChildAtBottom(window_d);
  EXPECT_FALSE(delegate_d->is_expecting_call());

  SkRegion occluded_area = SkRegionFromSkIRects(
      {SkIRect::MakeXYWH(2, 2, 10, 10), SkIRect::MakeXYWH(4, 4, 4, 4),
       SkIRect::MakeXYWH(34, 36, 8, 10)});
  delegate_d->set_expectation(Window::OcclusionState::VISIBLE, occluded_area);
  window_d->SetBounds(gfx::Rect(35, 36, 8, 10));
  EXPECT_FALSE(delegate_d->is_expecting_call());

  // |window_d| should remain non-occluded with the following bounds changes.
  window_d->SetBounds(gfx::Rect(33, 36, 8, 10));
  window_d->SetBounds(gfx::Rect(34, 37, 8, 10));
  window_d->SetBounds(gfx::Rect(34, 35, 8, 10));
}

// Verify that clipping is taken into account when computing occlusion.
TEST_F(WindowOcclusionTrackerTest, Clipping) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b. Expect it to be non-occluded.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeWH(5, 5)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
  window_b->layer()->SetMasksToBounds(true);
  // Create window c which has window b as parent. Don't expect it to occlude
  // window a since its bounds are clipped by window b.
  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 10, 10), window_b);
  EXPECT_FALSE(delegate_c->is_expecting_call());
}

// Verify that the DCHECK(!WindowIsAnimated(window)) in
// WindowOcclusionTracker::OnWindowDestroyed() doesn't fire if a window is
// destroyed with an incomplete animation (~Window should complete the animation
// and the window should be removed from |animated_windows_| before
// OnWindowDestroyed() is called).
TEST_F(WindowOcclusionTrackerTest, DestroyWindowWithPendingAnimation) {
  ui::ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  ui::LayerAnimatorTestController test_controller(
      ui::LayerAnimator::CreateImplicitAnimator());
  ui::ScopedLayerAnimationSettings layer_animation_settings(
      test_controller.animator());
  layer_animation_settings.SetTransitionDuration(kTransitionDuration);

  MockWindowDelegate* delegate = new MockWindowDelegate();
  delegate->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window = CreateTrackedWindow(delegate, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate->is_expecting_call());
  window->layer()->SetAnimator(test_controller.animator());

  // Start animating the bounds of window.
  window->SetBounds(gfx::Rect(10, 10, 5, 5));
  test_controller.Step(kTransitionDuration / 3);
  EXPECT_TRUE(test_controller.animator()->IsAnimatingProperty(
      ui::LayerAnimationElement::BOUNDS));

  // Destroy the window. Expect no DCHECK failure.
  delete window;
}

// Verify that an animated window stops being considered as animated when its
// layer is recreated.
TEST_F(WindowOcclusionTrackerTest, RecreateLayerOfAnimatedWindow) {
  ui::ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  ui::LayerAnimatorTestController test_controller(
      ui::LayerAnimator::CreateImplicitAnimator());
  ui::ScopedLayerAnimationSettings layer_animation_settings(
      test_controller.animator());
  layer_animation_settings.SetTransitionDuration(kTransitionDuration);

  // Create 2 windows. Window b occludes window a.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(2, 2, 1, 1));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  window_a->layer()->SetAnimator(test_controller.animator());

  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Start animating the bounds of window a. Window a should be non-occluded
  // when the animation starts.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  window_a->SetBounds(gfx::Rect(6, 6, 1, 1));
  test_controller.Step(kTransitionDuration / 2);
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Recreate the layer of window b. Expect this to behave the same as if the
  // animation was abandoned. Occlusion region should be half way between the
  // animation bounds.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  std::unique_ptr<ui::Layer> old_layer = window_a->RecreateLayer();
  EXPECT_FALSE(delegate_a->is_expecting_call());

  window_a->layer()->SetAnimator(nullptr);
}

namespace {

class ObserverChangingWindowBounds : public WindowObserver {
 public:
  ObserverChangingWindowBounds() = default;

  // WindowObserver:
  void OnWindowParentChanged(Window* window, Window* parent) override {
    window->SetBounds(gfx::Rect(1, 2, 3, 4));
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ObserverChangingWindowBounds);
};

}  // namespace

// Verify that no crash occurs if a tracked window is modified by an observer
// after it has been added to a new root but before WindowOcclusionTracker has
// been notified.
TEST_F(WindowOcclusionTrackerTest, ChangeTrackedWindowBeforeObserveAddToRoot) {
  // Create a window. Expect it to be non-occluded.
  MockWindowDelegate* delegate = new MockWindowDelegate();
  delegate->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window = CreateTrackedWindow(delegate, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate->is_expecting_call());

  // Remove the window from its root.
  root_window()->RemoveChild(window);

  // Add an observer that changes the bounds of |window| when it gets a new
  // parent.
  ObserverChangingWindowBounds observer;
  window->AddObserver(&observer);

  // Re-add the window to its root. Expect no crash when |observer| changes the
  // bounds.
  root_window()->AddChild(window);

  window->RemoveObserver(&observer);
}

namespace {

class ObserverDestroyingWindowOnAnimationEnded
    : public ui::LayerAnimationObserver {
 public:
  ObserverDestroyingWindowOnAnimationEnded(Window* window) : window_(window) {}

  ~ObserverDestroyingWindowOnAnimationEnded() override {
    EXPECT_FALSE(window_);
  }

  void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
    EXPECT_TRUE(window_);
    delete window_;
    window_ = nullptr;
  }

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

 private:
  Window* window_;

  DISALLOW_COPY_AND_ASSIGN(ObserverDestroyingWindowOnAnimationEnded);
};

}  // namespace

// Verify that no crash occurs if a LayerAnimationObserver destroys a tracked
// window before WindowOcclusionTracker is notified that the animation ended.
TEST_F(WindowOcclusionTrackerTest,
       DestroyTrackedWindowFromLayerAnimationObserver) {
  ui::ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  ui::LayerAnimatorTestController test_controller(
      ui::LayerAnimator::CreateImplicitAnimator());
  ui::ScopedLayerAnimationSettings layer_animation_settings(
      test_controller.animator());
  layer_animation_settings.SetTransitionDuration(kTransitionDuration);

  // Create a window. Expect it to be non-occluded.
  MockWindowDelegate* delegate = new MockWindowDelegate();
  delegate->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window = CreateTrackedWindow(delegate, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate->is_expecting_call());
  window->layer()->SetAnimator(test_controller.animator());

  // Add a LayerAnimationObserver that destroys the window when an animation
  // ends.
  ObserverDestroyingWindowOnAnimationEnded observer(window);
  window->layer()->GetAnimator()->AddObserver(&observer);

  // Start animating the opacity of the window.
  window->layer()->SetOpacity(0.5f);

  // Complete the animation. Expect no crash.
  window->layer()->GetAnimator()->StopAnimating();
}

// Verify that no crash occurs if an animation completes on a non-tracked
// window's layer after the window has been removed from a root with a tracked
// window and deleted.
TEST_F(WindowOcclusionTrackerTest,
       DeleteNonTrackedAnimatedWindowRemovedFromTrackedRoot) {
  ui::ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  ui::LayerAnimatorTestController test_controller(
      ui::LayerAnimator::CreateImplicitAnimator());
  ui::ScopedLayerAnimationSettings layer_animation_settings(
      test_controller.animator());
  layer_animation_settings.SetTransitionDuration(kTransitionDuration);

  // Create a tracked window. Expect it to be non-occluded.
  MockWindowDelegate* delegate = new MockWindowDelegate();
  delegate->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate->is_expecting_call());

  // Create a non-tracked window and add an observer that deletes it when its
  // stops being animated.
  delegate->set_expectation(Window::OcclusionState::VISIBLE,
                            SkRegion(SkIRect::MakeXYWH(10, 0, 10, 10)));
  Window* window = CreateUntrackedWindow(gfx::Rect(10, 0, 10, 10));
  EXPECT_FALSE(delegate->is_expecting_call());

  window->layer()->SetAnimator(test_controller.animator());
  ObserverDestroyingWindowOnAnimationEnded observer(window);
  window->layer()->GetAnimator()->AddObserver(&observer);

  // Animate the window. WindowOcclusionTracker should add itself as an observer
  // of its LayerAnimator (after |observer|). Upon beginning animation, the
  // window should no longer affect the occluded region.
  delegate->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  window->layer()->SetOpacity(0.5f);
  EXPECT_FALSE(delegate->is_expecting_call());

  // Remove the non-tracked window from its root. WindowOcclusionTracker should
  // remove the window from its list of animated windows and stop observing it
  // and its LayerAnimator.
  root_window()->RemoveChild(window);

  // Complete animations on the window. |observer| will delete the window when
  // it is notified that animations are complete. Expect that
  // WindowOcclusionTracker will not try to access |window| after that (if it
  // does, the test will crash).
  window->layer()->GetAnimator()->StopAnimating();
}

namespace {

class WindowDelegateHidingWindowIfOccluded : public MockWindowDelegate {
 public:
  WindowDelegateHidingWindowIfOccluded(Window* other_window)
      : other_window_(other_window) {}

  // MockWindowDelegate:
  void OnWindowOcclusionChanged(Window::OcclusionState occlusion_state,
                                const SkRegion& occluded_region) override {
    MockWindowDelegate::OnWindowOcclusionChanged(occlusion_state,
                                                 occluded_region);
    if (occlusion_state == Window::OcclusionState::HIDDEN) {
      other_window_->Hide();
    }
  }

 private:
  Window* other_window_;

  DISALLOW_COPY_AND_ASSIGN(WindowDelegateHidingWindowIfOccluded);
};

class WindowDelegateWithQueuedExpectation : public MockWindowDelegate {
 public:
  WindowDelegateWithQueuedExpectation() = default;

  void set_queued_expectation(Window::OcclusionState occlusion_state,
                              const SkRegion& occluded_region) {
    queued_expected_occlusion_state_ = occlusion_state;
    queued_expected_occluded_region_ = occluded_region;
  }

  // MockWindowDelegate:
  void OnWindowOcclusionChanged(Window::OcclusionState occlusion_state,
                                const SkRegion& occluded_region) override {
    MockWindowDelegate::OnWindowOcclusionChanged(occlusion_state,
                                                 occluded_region);
    if (queued_expected_occlusion_state_ != Window::OcclusionState::UNKNOWN) {
      set_expectation(queued_expected_occlusion_state_,
                      queued_expected_occluded_region_);
      queued_expected_occlusion_state_ = Window::OcclusionState::UNKNOWN;
      queued_expected_occluded_region_ = SkRegion();
    }
  }

 private:
  Window::OcclusionState queued_expected_occlusion_state_ =
      Window::OcclusionState::UNKNOWN;
  SkRegion queued_expected_occluded_region_ = SkRegion();

  DISALLOW_COPY_AND_ASSIGN(WindowDelegateWithQueuedExpectation);
};

}  // namespace

// Verify that a window delegate can change the visibility of another window
// when it is notified that its occlusion changed.
TEST_F(WindowOcclusionTrackerTest, HideFromOnWindowOcclusionChanged) {
  // Create a tracked window. Expect it to be visible.
  WindowDelegateWithQueuedExpectation* delegate_a =
      new WindowDelegateWithQueuedExpectation();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create a tracked window. Expect it to be visible.
  MockWindowDelegate* delegate_b =
      new WindowDelegateHidingWindowIfOccluded(window_a);
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(10, 0, 10, 10)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(10, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Hide the tracked window. It should be able to hide |window_a|. Before
  // |window_a| is hidden, it will notice that the occlusion region has changed
  // now that |window_b| is hidden. Then, it will be hidden by |window_b|.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  delegate_a->set_queued_expectation(Window::OcclusionState::HIDDEN,
                                     SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::HIDDEN, SkRegion());
  window_b->Hide();

  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(window_a->IsVisible());
  EXPECT_FALSE(window_b->IsVisible());
}

namespace {

class WindowDelegateDeletingWindow : public MockWindowDelegate {
 public:
  WindowDelegateDeletingWindow() = default;

  void set_other_window(Window* other_window) { other_window_ = other_window; }

  // MockWindowDelegate:
  void OnWindowOcclusionChanged(Window::OcclusionState occlusion_state,
                                const SkRegion& occluded_region) override {
    MockWindowDelegate::OnWindowOcclusionChanged(occlusion_state,
                                                 occluded_region);
    if (occlusion_state == Window::OcclusionState::OCCLUDED) {
      delete other_window_;
      other_window_ = nullptr;
    }
  }

 private:
  Window* other_window_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(WindowDelegateDeletingWindow);
};

}  // namespace

// Verify that a window can delete a window that is on top of it when it is
// notified that its occlusion changed (a crash would occur if
// WindowOcclusionTracker accessed that window after it was deleted).
TEST_F(WindowOcclusionTrackerTest, DeleteFromOnWindowOcclusionChanged) {
  // Create a tracked window. Expect it to be visible.
  WindowDelegateDeletingWindow* delegate_a = new WindowDelegateDeletingWindow();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create a tracked window. Expect it to be visible.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(10, 0, 10, 10)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(10, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Create a tracked window. Expect it to be visible.
  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_a->set_expectation(
      Window::OcclusionState::VISIBLE,
      SkRegionFromSkIRects({SkIRect::MakeXYWH(10, 0, 10, 10),
                            SkIRect::MakeXYWH(20, 0, 10, 10)}));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(20, 0, 10, 10)));
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_c = CreateTrackedWindow(delegate_c, gfx::Rect(20, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());

  // |window_c| will be deleted when |window_a| is occluded.
  delegate_a->set_other_window(window_c);

  // Move |window_b| on top of |window_a|.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  window_b->SetBounds(window_a->bounds());
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
}

namespace {

class WindowDelegateChangingWindowVisibility : public MockWindowDelegate {
 public:
  WindowDelegateChangingWindowVisibility() = default;

  void set_window_to_update(Window* window) { window_to_update_ = window; }

  // MockWindowDelegate:
  void OnWindowOcclusionChanged(Window::OcclusionState occlusion_state,
                                const SkRegion& occluded_region) override {
    MockWindowDelegate::OnWindowOcclusionChanged(occlusion_state,
                                                 occluded_region);
    if (!window_to_update_)
      return;

    ++num_occlusion_change_;

    if (window_to_update_->IsVisible()) {
      window_to_update_->Hide();
      if (num_occlusion_change_ <= 3)
        set_expectation(Window::OcclusionState::HIDDEN, SkRegion());
    } else {
      window_to_update_->Show();
      set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
    }
  }

 private:
  Window* window_to_update_ = nullptr;
  int num_occlusion_change_ = 0;

  DISALLOW_COPY_AND_ASSIGN(WindowDelegateChangingWindowVisibility);
};

}  // namespace

// Verify that if a window changes its visibility every time it is notified that
// its occlusion state changed, a DCHECK occurs.
TEST_F(WindowOcclusionTrackerTest, OcclusionStatesDontBecomeStable) {
  test::WindowOcclusionTrackerTestApi test_api(
      root_window()->env()->GetWindowOcclusionTracker());

  // Create 2 superposed tracked windows.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Create a hidden tracked window.
  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(10, 0, 10, 10)));
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_c = CreateTrackedWindow(delegate_c, gfx::Rect(10, 0, 10, 10));
  EXPECT_FALSE(delegate_c->is_expecting_call());
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  delegate_c->set_expectation(Window::OcclusionState::HIDDEN, SkRegion());
  window_c->Hide();
  EXPECT_FALSE(delegate_c->is_expecting_call());

  // Create a tracked window. Expect it to be non-occluded.
  auto* delegate_d = new WindowDelegateChangingWindowVisibility();
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(20, 0, 10, 10)));
  delegate_d->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_d = CreateTrackedWindow(delegate_d, gfx::Rect(20, 0, 10, 10));
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_d->is_expecting_call());

  // Store a pointer to |window_d| in |delegate_d|. This will cause a call to
  // Show()/Hide() every time |delegate_d| is notified of an occlusion change.
  delegate_d->set_window_to_update(window_d);

  // Hide |window_d|. This will cause occlusion to be recomputed multiple times.
  // Once the maximum number of times that occlusion can be recomputed is
  // reached, the occlusion state of all IsVisible() windows should be set to
  // VISIBLE.
  EXPECT_DCHECK_DEATH({
    delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                                SkRegion(SkIRect::MakeXYWH(20, 0, 10, 10)));
    delegate_d->set_expectation(Window::OcclusionState::HIDDEN, SkRegion());
    window_d->Hide();
  });
}

// Verify that the occlusion states are correctly updated when a branch of the
// tree is hidden.
TEST_F(WindowOcclusionTrackerTest, HideTreeBranch) {
  // Create a branch of 3 tracked windows. Expect them to be visible.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b =
      CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 10, 10), window_a);
  EXPECT_FALSE(delegate_b->is_expecting_call());

  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_c, gfx::Rect(0, 20, 10, 10), window_b);
  EXPECT_FALSE(delegate_c->is_expecting_call());

  // Hide |window_b| (and hence |window_c|). Expect |window_b| and |window_c| to
  // be hidden.
  delegate_b->set_expectation(Window::OcclusionState::HIDDEN, SkRegion());
  delegate_c->set_expectation(Window::OcclusionState::HIDDEN, SkRegion());
  window_b->Hide();
  EXPECT_FALSE(delegate_b->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());
}

// Verify that a window covered by a shaped window isn't considered occluded.
TEST_F(WindowOcclusionTrackerTest, WindowWithAlphaShape) {
  // Create 2 superposed tracked windows.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Set a shape for the top window. The window underneath should no longer be
  // occluded.
  auto shape = std::make_unique<ui::Layer::ShapeRects>();
  shape->emplace_back(0, 0, 5, 5);
  // Shaped windows are not considered opaque, so the occluded region is empty.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  window_b->layer()->SetAlphaShape(std::move(shape));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Clear the shape for the top window. The window underneath should be
  // occluded.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  window_b->layer()->SetAlphaShape(nullptr);
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Verify that a window covered by a window whose parent has an alpha shape
// isn't considered occluded.
TEST_F(WindowOcclusionTrackerTest, WindowWithParentAlphaShape) {
  // Create a child and parent that cover another window.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 20, 20));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeWH(10, 10)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  MockWindowDelegate* delegate_c = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  delegate_c->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 20, 20), window_b);
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_c->is_expecting_call());

  // Set a shape for |window_b|. |window_a| and |window_b| should no longer be
  // occluded.
  auto shape = std::make_unique<ui::Layer::ShapeRects>();
  shape->emplace_back(0, 0, 5, 5);
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  window_b->layer()->SetAlphaShape(std::move(shape));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Clear the shape for |window_b|. |window_a| and |window_b| should be
  // occluded.
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  window_b->layer()->SetAlphaShape(nullptr);
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

namespace {

class WindowDelegateHidingWindow : public MockWindowDelegate {
 public:
  WindowDelegateHidingWindow() = default;

  void set_window_to_update(Window* window) { window_to_update_ = window; }

  // MockWindowDelegate:
  void OnWindowOcclusionChanged(Window::OcclusionState occlusion_state,
                                const SkRegion& occluded_region) override {
    MockWindowDelegate::OnWindowOcclusionChanged(occlusion_state,
                                                 occluded_region);
    if (!window_to_update_)
      return;

    window_to_update_->Hide();
  }

 private:
  Window* window_to_update_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(WindowDelegateHidingWindow);
};

class WindowDelegateAddingAndHidingChild : public MockWindowDelegate {
 public:
  explicit WindowDelegateAddingAndHidingChild(WindowOcclusionTrackerTest* test)
      : test_(test) {}

  void set_queued_expectation(Window::OcclusionState occlusion_state,
                              const SkRegion& occluded_region) {
    queued_expected_occlusion_state_ = occlusion_state;
    queued_expected_occluded_region_ = occluded_region;
  }

  void set_window_to_update(Window* window) { window_to_update_ = window; }

  // MockWindowDelegate:
  void OnWindowOcclusionChanged(Window::OcclusionState occlusion_state,
                                const SkRegion& occluded_region) override {
    MockWindowDelegate::OnWindowOcclusionChanged(occlusion_state,
                                                 occluded_region);
    if (queued_expected_occlusion_state_ != Window::OcclusionState::UNKNOWN) {
      set_expectation(queued_expected_occlusion_state_,
                      queued_expected_occluded_region_);
      queued_expected_occlusion_state_ = Window::OcclusionState::UNKNOWN;
      queued_expected_occluded_region_ = SkRegion();
    }

    if (!window_to_update_)
      return;

    // Create a child window and hide it. Since this code runs when occlusion
    // has already been recomputed twice, if one of the operations below causes
    // occlusion to be recomputed, the test will fail with a DCHECK.
    Window* window =
        test_->CreateUntrackedWindow(gfx::Rect(0, 0, 5, 5), window_to_update_);
    window->Hide();
  }

 private:
  WindowOcclusionTrackerTest* test_;
  Window* window_to_update_ = nullptr;
  Window::OcclusionState queued_expected_occlusion_state_ =
      Window::OcclusionState::UNKNOWN;
  SkRegion queued_expected_occluded_region_ = SkRegion();

  DISALLOW_COPY_AND_ASSIGN(WindowDelegateAddingAndHidingChild);
};

}  // namespace

// Verify that hiding a window that has a hidden parent doesn't cause occlusion
// to be recomputed.
TEST_F(WindowOcclusionTrackerTest,
       HideWindowWithHiddenParentOnOcclusionChange) {
  test::WindowOcclusionTrackerTestApi test_api(
      root_window()->env()->GetWindowOcclusionTracker());

  auto* delegate_a = new WindowDelegateAddingAndHidingChild(this);
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  auto* delegate_b = new WindowDelegateHidingWindow();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(0, 10, 10, 10)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // When |window_b| is hidden, it will hide |window_a|. |window_a| will in turn
  // add a child to itself and hide it.
  delegate_a->set_window_to_update(window_a);
  delegate_b->set_window_to_update(window_a);
  // Initially A is marked as visible with no potential occlusion.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  delegate_a->set_queued_expectation(Window::OcclusionState::HIDDEN,
                                     SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::HIDDEN, SkRegion());
  // Hiding a child to |window_a| and hiding it shouldn't cause occlusion to be
  // recomputed too many times (i.e. the call below shouldn't DCHECK).
  window_b->Hide();
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
}

// Verify that hiding a window changes the occlusion region to show that the
// window is fully occluded.
TEST_F(WindowOcclusionTrackerTest,
       HideWindowChangesOcclusionRegionToBeFullyOccluded) {
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  delegate_a->set_expectation(Window::OcclusionState::HIDDEN, SkRegion());
  window_a->Hide();
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Test partial occlusion, test partial occlusion changing hidden, alpha shape
// occlusion from multiple windows

// Verify that a window can occlude another one partially.
TEST_F(WindowOcclusionTrackerTest, WindowOccludesWindowPartially) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 20, 20));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b, occluding window a partially.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(6, 7, 8, 9)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(6, 7, 8, 9));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Hiding window b should stop occluding window a partially.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  delegate_b->set_expectation(Window::OcclusionState::HIDDEN, SkRegion());
  window_b->Hide();
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());
}

// Verify that windows with alpha shape do not affect occlusion regions.
TEST_F(WindowOcclusionTrackerTest,
       WindowWithAlphaShapeDoesNotPartiallyOccludeOtherWindows) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 20, 20));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Create window b, occluding window a partially.
  MockWindowDelegate* delegate_b = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(6, 7, 8, 9)));
  delegate_b->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(6, 7, 8, 9));
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_b->is_expecting_call());

  // Set a shape for window b. The window underneath should no longer be
  // partially occluded.
  auto shape = std::make_unique<ui::Layer::ShapeRects>();
  shape->emplace_back(0, 0, 5, 5);
  // Shaped windows are not considered opaque, so the occluded region is empty.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  window_b->layer()->SetAlphaShape(std::move(shape));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  // Clear the shape for the top window. The window underneath should be
  // occluded.
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              SkRegion(SkIRect::MakeXYWH(6, 7, 8, 9)));
  window_b->layer()->SetAlphaShape(nullptr);
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Verify that a window can be occluded by multiple other windows.
TEST_F(WindowOcclusionTrackerTest, WindowCanBeOccludedByMultipleWindows) {
  // Create window a. Expect it to be non-occluded.
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  SkRegion window_a_occlusion = SkRegion(SkIRect::MakeXYWH(9, 9, 5, 5));
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              window_a_occlusion);
  CreateUntrackedWindow(gfx::Rect(9, 9, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  window_a_occlusion.op(SkIRect::MakeXYWH(-4, -4, 5, 5),
                        SkRegion::Op::kUnion_Op);
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              window_a_occlusion);
  CreateUntrackedWindow(gfx::Rect(-4, -4, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  window_a_occlusion.op(SkIRect::MakeXYWH(9, -4, 5, 5),
                        SkRegion::Op::kUnion_Op);
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              window_a_occlusion);
  CreateUntrackedWindow(gfx::Rect(9, -4, 5, 5));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  window_a_occlusion.op(SkIRect::MakeXYWH(5, 5, 2, 3), SkRegion::Op::kUnion_Op);
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                              window_a_occlusion);
  CreateUntrackedWindow(gfx::Rect(5, 5, 2, 3));
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Verify that the excluded window is indeed ignored by occlusion tracking.
TEST_F(WindowOcclusionTrackerTest, ExcludeWindow) {
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  delegate_a->SetName("WindowA");

  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  Window* window_b = CreateUntrackedWindow(gfx::Rect(0, 0, 100, 100), nullptr);
  EXPECT_FALSE(delegate_a->is_expecting_call());

  MockWindowDelegate* delegate_bb = new MockWindowDelegate();
  delegate_bb->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_bb, gfx::Rect(0, 0, 10, 10), window_b);
  EXPECT_FALSE(delegate_bb->is_expecting_call());

  delegate_bb->SetName("WindowBB");

  delegate_bb->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  Window* window_c = CreateUntrackedWindow(gfx::Rect(0, 0, 100, 100), nullptr);
  EXPECT_FALSE(delegate_bb->is_expecting_call());

  {
    // |window_b| is excluded, so its child's occlusion state becomes VISIBlE.
    delegate_bb->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
    EXPECT_TRUE(delegate_bb->is_expecting_call());
    WindowOcclusionTracker::ScopedExclude scoped(window_b);
    EXPECT_FALSE(delegate_bb->is_expecting_call());

    // Moving |window_c| out from |window_a| will make |window_a| visible
    // because |window_b| is ignored.
    SkRegion window_a_occlusion(SkIRect::MakeXYWH(100, 100, 100, 100));
    delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                                window_a_occlusion);
    SkRegion window_bb_occlusion;
    window_bb_occlusion.op(SkIRect::MakeXYWH(100, 100, 100, 100),
                           SkRegion::kUnion_Op);
    delegate_bb->set_expectation(Window::OcclusionState::VISIBLE,
                                 window_bb_occlusion);
    window_c->SetBounds(gfx::Rect(100, 100, 100, 100));

    // Un-excluding wil make |window_bb| OCCLUDED.
    delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
    delegate_bb->set_expectation(Window::OcclusionState::VISIBLE,
                                 window_bb_occlusion);
  }
  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_bb->is_expecting_call());

  {
    delegate_bb->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
    SkRegion window_a_occlusion(SkIRect::MakeXYWH(100, 100, 100, 100));
    delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                                window_a_occlusion);
    EXPECT_TRUE(delegate_bb->is_expecting_call());
    WindowOcclusionTracker::ScopedExclude scoped(window_b);
    EXPECT_FALSE(delegate_bb->is_expecting_call());
    EXPECT_FALSE(delegate_a->is_expecting_call());

    // Moving |window_b| will not affect the occlusion status.
    window_b->SetBounds(gfx::Rect(5, 5, 100, 100));

    // Un-excluding will update the occlustion status.
    // A's occlustion status includes all windows above a.
    window_a_occlusion.setEmpty();
    window_a_occlusion.op(SkIRect::MakeXYWH(5, 5, 100, 100),
                          SkRegion::kUnion_Op);
    window_a_occlusion.op(SkIRect::MakeXYWH(100, 100, 100, 100),
                          SkRegion::kUnion_Op);
    delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                                window_a_occlusion);

    SkRegion window_bb_occlusion(SkIRect::MakeXYWH(100, 100, 100, 100));
    delegate_bb->set_expectation(Window::OcclusionState::VISIBLE,
                                 window_bb_occlusion);
  }

  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_bb->is_expecting_call());

  {
    delegate_bb->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
    SkRegion window_a_occlusion(SkIRect::MakeXYWH(100, 100, 100, 100));
    delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                                window_a_occlusion);
    EXPECT_TRUE(delegate_bb->is_expecting_call());
    WindowOcclusionTracker::ScopedExclude scoped(window_b);
    EXPECT_FALSE(delegate_bb->is_expecting_call());
    EXPECT_FALSE(delegate_a->is_expecting_call());

    // Deleting the excluded window will un-exclude itself and recomputes the
    // occlustion state, but should not affect the state on existing windows
    // because it's already excluded.
    delete window_b;
    EXPECT_FALSE(scoped.window());
  }

  MockWindowDelegate* delegate_d = new MockWindowDelegate();
  delegate_d->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());

  auto* window_d = CreateTrackedWindow(delegate_d, gfx::Rect(0, 0, 10, 10));
  window_d->SetName("WindowD");

  EXPECT_FALSE(delegate_a->is_expecting_call());
  EXPECT_FALSE(delegate_d->is_expecting_call());

  {
    // Make sure excluding the tracked window also works.
    SkRegion window_a_occlusion(SkIRect::MakeXYWH(100, 100, 100, 100));
    delegate_a->set_expectation(Window::OcclusionState::VISIBLE,
                                window_a_occlusion);
    WindowOcclusionTracker::ScopedExclude scoped(window_d);
    EXPECT_FALSE(delegate_a->is_expecting_call());

    // Changing opacity/bounds shouldn't change the occlusion state.
    window_d->layer()->SetOpacity(0.5f);
    window_d->SetBounds(gfx::Rect(0, 0, 20, 20));

    // A is now visible even if |window_d| is un-excluded becaues
    // window_d is not fully opaque.
  }

  EXPECT_FALSE(delegate_a->is_expecting_call());
  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  window_d->layer()->SetOpacity(1.f);
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

// Test that calling OnOcclusionStateChanged on a root window causes children
// of the root window to have their delegate notified that it is occluded or
// visible, depending on whether the root window is occluded or not.
TEST_F(WindowOcclusionTrackerTest, NativeWindowOcclusion) {
  MockWindowDelegate* delegate_a = new MockWindowDelegate();
  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
  EXPECT_FALSE(delegate_a->is_expecting_call());

  delegate_a->set_expectation(Window::OcclusionState::OCCLUDED, SkRegion());
  // Make the host call OnOcclusionStateChanged on the root window.
  host()->SetNativeWindowOcclusionState(Window::OcclusionState::OCCLUDED);
  EXPECT_FALSE(delegate_a->is_expecting_call());

  delegate_a->set_expectation(Window::OcclusionState::VISIBLE, SkRegion());
  host()->SetNativeWindowOcclusionState(Window::OcclusionState::VISIBLE);
  EXPECT_FALSE(delegate_a->is_expecting_call());
}

}  // namespace aura
