window_occlusion_change_builder_unittest.cc 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ui/aura/window_occlusion_change_builder.h"
  5. #include <memory>
  6. #include "base/memory/raw_ptr.h"
  7. #include "third_party/skia/include/core/SkRegion.h"
  8. #include "ui/aura/test/aura_test_base.h"
  9. #include "ui/aura/test/test_window_delegate.h"
  10. #include "ui/aura/test/test_windows.h"
  11. namespace aura {
  12. namespace {
  13. // A delegate that remembers the occlusion info of its window.
  14. class OcclusionTrackWindowDelegate : public test::TestWindowDelegate {
  15. public:
  16. OcclusionTrackWindowDelegate() = default;
  17. OcclusionTrackWindowDelegate(const OcclusionTrackWindowDelegate&) = delete;
  18. OcclusionTrackWindowDelegate& operator=(const OcclusionTrackWindowDelegate&) =
  19. delete;
  20. ~OcclusionTrackWindowDelegate() override = default;
  21. void set_window(Window* window) { window_ = window; }
  22. bool occlusion_change_count() const { return occlusion_change_count_; }
  23. Window::OcclusionState last_occlusion_state() const {
  24. return last_occlusion_state_;
  25. }
  26. const SkRegion& last_occluded_region() const { return last_occluded_region_; }
  27. private:
  28. // test::TestWindowDelegate:
  29. void OnWindowOcclusionChanged(
  30. Window::OcclusionState occlusion_state) override {
  31. ++occlusion_change_count_;
  32. last_occlusion_state_ = occlusion_state;
  33. last_occluded_region_ = window_->occluded_region_in_root();
  34. }
  35. raw_ptr<Window> window_ = nullptr;
  36. int occlusion_change_count_ = 0;
  37. Window::OcclusionState last_occlusion_state_ =
  38. Window::OcclusionState::UNKNOWN;
  39. SkRegion last_occluded_region_;
  40. };
  41. } // namespace
  42. class WindowOcclusionChangeBuilderTest : public test::AuraTestBase {
  43. public:
  44. WindowOcclusionChangeBuilderTest() = default;
  45. WindowOcclusionChangeBuilderTest(const WindowOcclusionChangeBuilderTest&) =
  46. delete;
  47. WindowOcclusionChangeBuilderTest& operator=(
  48. const WindowOcclusionChangeBuilderTest&) = delete;
  49. ~WindowOcclusionChangeBuilderTest() override = default;
  50. std::unique_ptr<Window> CreateTestWindow(
  51. OcclusionTrackWindowDelegate* delegate) {
  52. auto window = std::make_unique<Window>(delegate);
  53. delegate->set_window(window.get());
  54. window->set_owned_by_parent(false);
  55. window->SetType(client::WINDOW_TYPE_NORMAL);
  56. window->Init(ui::LAYER_TEXTURED);
  57. window->Show();
  58. root_window()->AddChild(window.get());
  59. return window;
  60. }
  61. };
  62. // Test that window occlusion info is updated after commit.
  63. TEST_F(WindowOcclusionChangeBuilderTest, SingleWindow) {
  64. SkRegion region;
  65. region.setRect({1, 2, 3, 4});
  66. for (const auto state :
  67. {Window::OcclusionState::VISIBLE, Window::OcclusionState::OCCLUDED,
  68. Window::OcclusionState::HIDDEN}) {
  69. OcclusionTrackWindowDelegate delegate;
  70. auto window = CreateTestWindow(&delegate);
  71. auto builder = WindowOcclusionChangeBuilder::Create();
  72. builder->Add(window.get(), state, region);
  73. // Change should not be applied before Commit call.
  74. EXPECT_EQ(0, delegate.occlusion_change_count());
  75. // All changes are committed when builder is released.
  76. builder.reset();
  77. EXPECT_EQ(1, delegate.occlusion_change_count());
  78. EXPECT_EQ(state, delegate.last_occlusion_state());
  79. EXPECT_EQ(region, delegate.last_occluded_region());
  80. }
  81. }
  82. // Test updating multiple windows.
  83. TEST_F(WindowOcclusionChangeBuilderTest, MultipleWindow) {
  84. auto builder = WindowOcclusionChangeBuilder::Create();
  85. OcclusionTrackWindowDelegate delegate1;
  86. auto window1 = CreateTestWindow(&delegate1);
  87. const Window::OcclusionState state1 = Window::OcclusionState::VISIBLE;
  88. SkRegion region1;
  89. region1.setRect({1, 2, 3, 4});
  90. builder->Add(window1.get(), state1, region1);
  91. OcclusionTrackWindowDelegate delegate2;
  92. auto window2 = CreateTestWindow(&delegate2);
  93. const Window::OcclusionState state2 = Window::OcclusionState::OCCLUDED;
  94. SkRegion region2;
  95. region2.setRect({5, 6, 7, 8});
  96. builder->Add(window2.get(), state2, region2);
  97. // Changes should not be applied before Commit call.
  98. EXPECT_EQ(0, delegate1.occlusion_change_count());
  99. EXPECT_EQ(0, delegate2.occlusion_change_count());
  100. // All changes are committed when builder is released.
  101. builder.reset();
  102. EXPECT_EQ(1, delegate1.occlusion_change_count());
  103. EXPECT_EQ(state1, delegate1.last_occlusion_state());
  104. EXPECT_EQ(region1, delegate1.last_occluded_region());
  105. EXPECT_EQ(1, delegate2.occlusion_change_count());
  106. EXPECT_EQ(state2, delegate2.last_occlusion_state());
  107. EXPECT_EQ(region2, delegate2.last_occluded_region());
  108. }
  109. // Tests that the last change wins when there are multiple changes on the same
  110. // window.
  111. TEST_F(WindowOcclusionChangeBuilderTest, MultipleChanges) {
  112. OcclusionTrackWindowDelegate delegate;
  113. auto window = CreateTestWindow(&delegate);
  114. auto builder = WindowOcclusionChangeBuilder::Create();
  115. builder->Add(window.get(), Window::OcclusionState::VISIBLE, SkRegion());
  116. builder->Add(window.get(), Window::OcclusionState::HIDDEN, SkRegion());
  117. SkRegion region;
  118. region.setRect({1, 2, 3, 4});
  119. builder->Add(window.get(), Window::OcclusionState::OCCLUDED, region);
  120. // All changes are committed when builder is released.
  121. builder.reset();
  122. EXPECT_EQ(1, delegate.occlusion_change_count());
  123. EXPECT_EQ(Window::OcclusionState::OCCLUDED, delegate.last_occlusion_state());
  124. EXPECT_EQ(region, delegate.last_occluded_region());
  125. }
  126. // Test that occlusion info is not updated if window is destroyed before commit.
  127. TEST_F(WindowOcclusionChangeBuilderTest, DestroyBeforeCommit) {
  128. OcclusionTrackWindowDelegate delegate;
  129. auto window = CreateTestWindow(&delegate);
  130. auto builder = WindowOcclusionChangeBuilder::Create();
  131. builder->Add(window.get(), Window::OcclusionState::VISIBLE, SkRegion());
  132. // Destroy window before applying the changes.
  133. window.reset();
  134. // All changes are committed when builder is released.
  135. builder.reset();
  136. // Occlusion info is not updated.
  137. EXPECT_EQ(0, delegate.occlusion_change_count());
  138. }
  139. } // namespace aura