123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- // Copyright 2018 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_change_builder.h"
- #include <memory>
- #include "base/memory/raw_ptr.h"
- #include "third_party/skia/include/core/SkRegion.h"
- #include "ui/aura/test/aura_test_base.h"
- #include "ui/aura/test/test_window_delegate.h"
- #include "ui/aura/test/test_windows.h"
- namespace aura {
- namespace {
- // A delegate that remembers the occlusion info of its window.
- class OcclusionTrackWindowDelegate : public test::TestWindowDelegate {
- public:
- OcclusionTrackWindowDelegate() = default;
- OcclusionTrackWindowDelegate(const OcclusionTrackWindowDelegate&) = delete;
- OcclusionTrackWindowDelegate& operator=(const OcclusionTrackWindowDelegate&) =
- delete;
- ~OcclusionTrackWindowDelegate() override = default;
- void set_window(Window* window) { window_ = window; }
- bool occlusion_change_count() const { return occlusion_change_count_; }
- Window::OcclusionState last_occlusion_state() const {
- return last_occlusion_state_;
- }
- const SkRegion& last_occluded_region() const { return last_occluded_region_; }
- private:
- // test::TestWindowDelegate:
- void OnWindowOcclusionChanged(
- Window::OcclusionState occlusion_state) override {
- ++occlusion_change_count_;
- last_occlusion_state_ = occlusion_state;
- last_occluded_region_ = window_->occluded_region_in_root();
- }
- raw_ptr<Window> window_ = nullptr;
- int occlusion_change_count_ = 0;
- Window::OcclusionState last_occlusion_state_ =
- Window::OcclusionState::UNKNOWN;
- SkRegion last_occluded_region_;
- };
- } // namespace
- class WindowOcclusionChangeBuilderTest : public test::AuraTestBase {
- public:
- WindowOcclusionChangeBuilderTest() = default;
- WindowOcclusionChangeBuilderTest(const WindowOcclusionChangeBuilderTest&) =
- delete;
- WindowOcclusionChangeBuilderTest& operator=(
- const WindowOcclusionChangeBuilderTest&) = delete;
- ~WindowOcclusionChangeBuilderTest() override = default;
- std::unique_ptr<Window> CreateTestWindow(
- OcclusionTrackWindowDelegate* delegate) {
- auto window = std::make_unique<Window>(delegate);
- delegate->set_window(window.get());
- window->set_owned_by_parent(false);
- window->SetType(client::WINDOW_TYPE_NORMAL);
- window->Init(ui::LAYER_TEXTURED);
- window->Show();
- root_window()->AddChild(window.get());
- return window;
- }
- };
- // Test that window occlusion info is updated after commit.
- TEST_F(WindowOcclusionChangeBuilderTest, SingleWindow) {
- SkRegion region;
- region.setRect({1, 2, 3, 4});
- for (const auto state :
- {Window::OcclusionState::VISIBLE, Window::OcclusionState::OCCLUDED,
- Window::OcclusionState::HIDDEN}) {
- OcclusionTrackWindowDelegate delegate;
- auto window = CreateTestWindow(&delegate);
- auto builder = WindowOcclusionChangeBuilder::Create();
- builder->Add(window.get(), state, region);
- // Change should not be applied before Commit call.
- EXPECT_EQ(0, delegate.occlusion_change_count());
- // All changes are committed when builder is released.
- builder.reset();
- EXPECT_EQ(1, delegate.occlusion_change_count());
- EXPECT_EQ(state, delegate.last_occlusion_state());
- EXPECT_EQ(region, delegate.last_occluded_region());
- }
- }
- // Test updating multiple windows.
- TEST_F(WindowOcclusionChangeBuilderTest, MultipleWindow) {
- auto builder = WindowOcclusionChangeBuilder::Create();
- OcclusionTrackWindowDelegate delegate1;
- auto window1 = CreateTestWindow(&delegate1);
- const Window::OcclusionState state1 = Window::OcclusionState::VISIBLE;
- SkRegion region1;
- region1.setRect({1, 2, 3, 4});
- builder->Add(window1.get(), state1, region1);
- OcclusionTrackWindowDelegate delegate2;
- auto window2 = CreateTestWindow(&delegate2);
- const Window::OcclusionState state2 = Window::OcclusionState::OCCLUDED;
- SkRegion region2;
- region2.setRect({5, 6, 7, 8});
- builder->Add(window2.get(), state2, region2);
- // Changes should not be applied before Commit call.
- EXPECT_EQ(0, delegate1.occlusion_change_count());
- EXPECT_EQ(0, delegate2.occlusion_change_count());
- // All changes are committed when builder is released.
- builder.reset();
- EXPECT_EQ(1, delegate1.occlusion_change_count());
- EXPECT_EQ(state1, delegate1.last_occlusion_state());
- EXPECT_EQ(region1, delegate1.last_occluded_region());
- EXPECT_EQ(1, delegate2.occlusion_change_count());
- EXPECT_EQ(state2, delegate2.last_occlusion_state());
- EXPECT_EQ(region2, delegate2.last_occluded_region());
- }
- // Tests that the last change wins when there are multiple changes on the same
- // window.
- TEST_F(WindowOcclusionChangeBuilderTest, MultipleChanges) {
- OcclusionTrackWindowDelegate delegate;
- auto window = CreateTestWindow(&delegate);
- auto builder = WindowOcclusionChangeBuilder::Create();
- builder->Add(window.get(), Window::OcclusionState::VISIBLE, SkRegion());
- builder->Add(window.get(), Window::OcclusionState::HIDDEN, SkRegion());
- SkRegion region;
- region.setRect({1, 2, 3, 4});
- builder->Add(window.get(), Window::OcclusionState::OCCLUDED, region);
- // All changes are committed when builder is released.
- builder.reset();
- EXPECT_EQ(1, delegate.occlusion_change_count());
- EXPECT_EQ(Window::OcclusionState::OCCLUDED, delegate.last_occlusion_state());
- EXPECT_EQ(region, delegate.last_occluded_region());
- }
- // Test that occlusion info is not updated if window is destroyed before commit.
- TEST_F(WindowOcclusionChangeBuilderTest, DestroyBeforeCommit) {
- OcclusionTrackWindowDelegate delegate;
- auto window = CreateTestWindow(&delegate);
- auto builder = WindowOcclusionChangeBuilder::Create();
- builder->Add(window.get(), Window::OcclusionState::VISIBLE, SkRegion());
- // Destroy window before applying the changes.
- window.reset();
- // All changes are committed when builder is released.
- builder.reset();
- // Occlusion info is not updated.
- EXPECT_EQ(0, delegate.occlusion_change_count());
- }
- } // namespace aura
|