#include "ui/aura/window_tree_host_platform.h"
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/window_tree_host_observer.h"
#include "ui/base/ui_base_features.h"
#include "ui/platform_window/stub/stub_window.h"
namespace aura {
namespace {
class WindowTreeHostPlatformTest : public test::AuraTestBase {
public:
WindowTreeHostPlatformTest() = default;
void SetUp() override {
test::AuraTestBase::SetUp();
#if BUILDFLAG(IS_WIN)
scoped_feature_list_.InitAndDisableFeature(
features::kApplyNativeOcclusionToCompositor);
#endif
}
private:
#if BUILDFLAG(IS_WIN)
base::test::ScopedFeatureList scoped_feature_list_;
#endif
};
class TestWindowTreeHost : public WindowTreeHostPlatform {
public:
TestWindowTreeHost() {
SetPlatformWindow(std::make_unique<ui::StubWindow>(this));
CreateCompositor();
}
TestWindowTreeHost(const TestWindowTreeHost&) = delete;
TestWindowTreeHost& operator=(const TestWindowTreeHost&) = delete;
ui::PlatformWindow* platform_window() {
return WindowTreeHostPlatform::platform_window();
}
};
class TestWindowTreeHostObserver : public WindowTreeHostObserver {
public:
TestWindowTreeHostObserver(WindowTreeHostPlatform* host,
ui::PlatformWindow* platform_window)
: host_(host), platform_window_(platform_window) {
host_->AddObserver(this);
}
TestWindowTreeHostObserver(const TestWindowTreeHostObserver&) = delete;
TestWindowTreeHostObserver& operator=(const TestWindowTreeHostObserver&) =
delete;
~TestWindowTreeHostObserver() override { host_->RemoveObserver(this); }
int on_host_did_process_bounds_change_count() const {
return on_host_did_process_bounds_change_count_;
}
int on_host_will_process_bounds_change_count() const {
return on_host_will_process_bounds_change_count_;
}
void OnHostResized(WindowTreeHost* host) override {
if (!should_change_bounds_in_on_resized_)
return;
should_change_bounds_in_on_resized_ = false;
gfx::Rect bounds = platform_window_->GetBoundsInPixels();
bounds.set_x(bounds.x() + 1);
host_->SetBoundsInPixels(bounds);
}
void OnHostWillProcessBoundsChange(WindowTreeHost* host) override {
++on_host_will_process_bounds_change_count_;
}
void OnHostDidProcessBoundsChange(WindowTreeHost* host) override {
++on_host_did_process_bounds_change_count_;
}
private:
raw_ptr<WindowTreeHostPlatform> host_;
raw_ptr<ui::PlatformWindow> platform_window_;
bool should_change_bounds_in_on_resized_ = true;
int on_host_will_process_bounds_change_count_ = 0;
int on_host_did_process_bounds_change_count_ = 0;
};
TEST_F(WindowTreeHostPlatformTest, HostWillProcessBoundsChangeRecursion) {
TestWindowTreeHost host;
TestWindowTreeHostObserver observer(&host, host.platform_window());
host.SetBoundsInPixels(gfx::Rect(1, 2, 3, 4));
EXPECT_EQ(1, observer.on_host_did_process_bounds_change_count());
EXPECT_EQ(1, observer.on_host_will_process_bounds_change_count());
}
class DeleteHostWindowTreeHostObserver : public WindowTreeHostObserver {
public:
explicit DeleteHostWindowTreeHostObserver(
std::unique_ptr<TestWindowTreeHost> host)
: host_(std::move(host)) {
host_->AddObserver(this);
}
DeleteHostWindowTreeHostObserver(const DeleteHostWindowTreeHostObserver&) =
delete;
DeleteHostWindowTreeHostObserver& operator=(
const DeleteHostWindowTreeHostObserver&) = delete;
~DeleteHostWindowTreeHostObserver() override = default;
TestWindowTreeHost* host() { return host_.get(); }
void OnHostMovedInPixels(WindowTreeHost* host) override {
host_->RemoveObserver(this);
host_.reset();
}
private:
std::unique_ptr<TestWindowTreeHost> host_;
};
TEST_F(WindowTreeHostPlatformTest, DeleteHostFromOnHostMovedInPixels) {
std::unique_ptr<TestWindowTreeHost> host =
std::make_unique<TestWindowTreeHost>();
DeleteHostWindowTreeHostObserver observer(std::move(host));
observer.host()->SetBoundsInPixels(gfx::Rect(1, 2, 3, 4));
EXPECT_EQ(nullptr, observer.host());
}
}
}