Commit 348ecf7e authored by Scott Violet's avatar Scott Violet Committed by Commit Bot

ui-service: updates AuraTest* to more correctly do the right thing

Prior to this patch AuraTestHelper configured TestScreen in such a way
that it would create a WindowTreeHost to represent a screen. The
WindowTreeHost was created was not a WindowTreeHostMus, rather a
WindowTreeHostPlatform. This doesn't make sense for mus.

As part of this I'm also moving how ash configures Env to
AuraTestBase. This way other code using AuraTestBase can work better
with mus.

Lastly I needed to make sure sure AuraTestHelper resets some state
that was persisting between runs. This is necessitated by Env being
created at the TestSuite level, not per test.

BUG=776514
TEST=covered by tests

Change-Id: Icb1b5342f962f44c03185a3e40097491532c4efe
Reviewed-on: https://chromium-review.googlesource.com/791821Reviewed-by: default avatarElliot Glaysher <erg@chromium.org>
Commit-Queue: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#519758}
parent 6972d1da
......@@ -4,9 +4,6 @@
#include "ash/test/ash_test_suite.h"
#include <memory>
#include <set>
#include "ash/public/cpp/config.h"
#include "ash/test/ash_test_environment.h"
#include "ash/test/ash_test_helper.h"
......@@ -16,80 +13,14 @@
#include "base/metrics/statistics_recorder.h"
#include "base/path_service.h"
#include "build/build_config.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/test_context_provider.h"
#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/test/aura_test_context_factory.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"
#include "ui/compositor/test/fake_context_factory.h"
#include "ui/gfx/gfx_paths.h"
#include "ui/gl/test/gl_surface_test_support.h"
namespace ash {
namespace {
class FrameSinkClient : public viz::TestLayerTreeFrameSinkClient {
public:
explicit FrameSinkClient(
scoped_refptr<viz::ContextProvider> display_context_provider)
: display_context_provider_(std::move(display_context_provider)) {}
std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurface(
scoped_refptr<viz::ContextProvider> compositor_context_provider)
override {
return cc::FakeOutputSurface::Create3d(
std::move(display_context_provider_));
}
void DisplayReceivedLocalSurfaceId(
const viz::LocalSurfaceId& local_surface_id) override {}
void DisplayReceivedCompositorFrame(
const viz::CompositorFrame& frame) override {}
void DisplayWillDrawAndSwap(
bool will_draw_and_swap,
const viz::RenderPassList& render_passes) override {}
void DisplayDidDrawAndSwap() override {}
private:
scoped_refptr<viz::ContextProvider> display_context_provider_;
DISALLOW_COPY_AND_ASSIGN(FrameSinkClient);
};
class AshTestContextFactory : public ui::FakeContextFactory {
public:
AshTestContextFactory() = default;
~AshTestContextFactory() override = default;
// ui::FakeContextFactory
void CreateLayerTreeFrameSink(
base::WeakPtr<ui::Compositor> compositor) override {
scoped_refptr<cc::TestContextProvider> context_provider =
cc::TestContextProvider::Create();
std::unique_ptr<FrameSinkClient> frame_sink_client =
std::make_unique<FrameSinkClient>(context_provider);
constexpr bool synchronous_composite = false;
constexpr bool disable_display_vsync = false;
const double refresh_rate = GetRefreshRate();
auto frame_sink = std::make_unique<viz::TestLayerTreeFrameSink>(
context_provider, cc::TestContextProvider::CreateWorker(), nullptr,
GetGpuMemoryBufferManager(), renderer_settings(),
base::ThreadTaskRunnerHandle::Get().get(), synchronous_composite,
disable_display_vsync, refresh_rate);
frame_sink->SetClient(frame_sink_client.get());
compositor->SetLayerTreeFrameSink(std::move(frame_sink));
frame_sink_clients_.insert(std::move(frame_sink_client));
}
private:
std::set<std::unique_ptr<viz::TestLayerTreeFrameSinkClient>>
frame_sink_clients_;
DISALLOW_COPY_AND_ASSIGN(AshTestContextFactory);
};
} // namespace
AshTestSuite::AshTestSuite(int argc, char** argv) : TestSuite(argc, argv) {}
......@@ -139,7 +70,7 @@ void AshTestSuite::Initialize() {
: aura::Env::Mode::LOCAL);
if (is_mus || is_mash) {
context_factory_ = std::make_unique<AshTestContextFactory>();
context_factory_ = std::make_unique<aura::test::AuraTestContextFactory>();
env_->set_context_factory(context_factory_.get());
env_->set_context_factory_private(nullptr);
}
......
......@@ -190,6 +190,7 @@ test("exo_unittests") {
"//mojo/edk/embedder:headers",
"//testing/gtest",
"//ui/aura",
"//ui/aura:test_support",
"//ui/base",
"//ui/compositor:test_support",
"//ui/gl:test_support",
......
......@@ -322,6 +322,7 @@ test("wayland_client_perftests") {
"//mojo/edk/embedder:headers",
"//testing/perf",
"//ui/aura",
"//ui/aura:test_support",
"//ui/base",
"//ui/compositor:test_support",
"//ui/events:gesture_detection",
......
......@@ -223,6 +223,8 @@ static_library("test_support") {
"test/aura_mus_test_base.h",
"test/aura_test_base.cc",
"test/aura_test_base.h",
"test/aura_test_context_factory.cc",
"test/aura_test_context_factory.h",
"test/aura_test_helper.cc",
"test/aura_test_helper.h",
"test/aura_test_utils.cc",
......@@ -270,6 +272,8 @@ static_library("test_support") {
]
deps = [
"//base/test:test_support",
"//cc:test_support",
"//components/viz/test:test_support",
"//services/ui/public/interfaces",
"//skia",
"//testing/gtest",
......
......@@ -208,7 +208,9 @@ WindowTreeClient::WindowTreeClient(
// Allow for a null request in tests.
if (request.is_pending())
binding_.Bind(std::move(request));
client::GetTransientWindowClient()->AddObserver(this);
// Some tests may not create a TransientWindowClient.
if (client::GetTransientWindowClient())
client::GetTransientWindowClient()->AddObserver(this);
if (window_manager_delegate)
window_manager_delegate->SetWindowManagerClient(this);
if (connector) { // |connector| can be null in tests.
......@@ -253,7 +255,9 @@ WindowTreeClient::~WindowTreeClient() {
capture_synchronizer_.reset();
client::GetTransientWindowClient()->RemoveObserver(this);
// Some tests may not create a TransientWindowClient.
if (client::GetTransientWindowClient())
client::GetTransientWindowClient()->RemoveObserver(this);
Env* env = Env::GetInstance();
if (compositor_context_factory_ &&
......@@ -515,9 +519,13 @@ void WindowTreeClient::CreateOrUpdateWindowFromWindowData(
if (window_data.transient_parent_id == kInvalidServerId)
return;
// Adjust the transient parent if necessary.
// Some tests may not create a TransientWindowClient.
client::TransientWindowClient* transient_window_client =
client::GetTransientWindowClient();
if (!transient_window_client)
return;
// Adjust the transient parent if necessary.
Window* existing_transient_parent =
transient_window_client->GetTransientParent(window->GetWindow());
WindowMus* new_transient_parent =
......
This diff is collapsed.
include_rules = [
"+cc/test",
"+components/viz/test",
"+mojo/edk/embedder/embedder.h",
"+ui/gl",
"+ui/wm/core/wm_state.h",
......
......@@ -16,16 +16,6 @@ void AuraMusWmTestBase::SetUp() {
// in env.
EnableMusWithTestWindowTree();
AuraTestBase::SetUp();
aura::Env* env = aura::Env::GetInstance();
DCHECK(env);
context_factory_to_restore_ = env->context_factory();
env->set_context_factory(&context_factory_);
}
void AuraMusWmTestBase::TearDown() {
aura::Env::GetInstance()->set_context_factory(context_factory_to_restore_);
AuraTestBase::TearDown();
}
AuraMusClientTestBase::AuraMusClientTestBase() {}
......@@ -38,16 +28,6 @@ void AuraMusClientTestBase::SetUp() {
EnableMusWithTestWindowTree();
set_window_manager_delegate(nullptr);
AuraTestBase::SetUp();
aura::Env* env = aura::Env::GetInstance();
DCHECK(env);
context_factory_to_restore_ = env->context_factory();
env->set_context_factory(&context_factory_);
}
void AuraMusClientTestBase::TearDown() {
aura::Env::GetInstance()->set_context_factory(context_factory_to_restore_);
AuraTestBase::TearDown();
}
} // namespace test
......
......@@ -7,7 +7,6 @@
#include "base/macros.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/compositor/test/fake_context_factory.h"
namespace aura {
namespace test {
......@@ -24,12 +23,8 @@ class AuraMusWmTestBase : public AuraTestBase {
// AuraTestBase:
void SetUp() override;
void TearDown() override;
private:
ui::FakeContextFactory context_factory_;
ui::ContextFactory* context_factory_to_restore_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(AuraMusWmTestBase);
};
......@@ -46,12 +41,8 @@ class AuraMusClientTestBase : public AuraTestBase {
// AuraTestBase:
void SetUp() override;
void TearDown() override;
private:
ui::FakeContextFactory context_factory_;
ui::ContextFactory* context_factory_to_restore_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(AuraMusClientTestBase);
};
......
......@@ -9,6 +9,7 @@
#include "ui/aura/mus/property_utils.h"
#include "ui/aura/mus/window_tree_client.h"
#include "ui/aura/mus/window_tree_host_mus.h"
#include "ui/aura/test/aura_test_context_factory.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/base/ime/input_method_initializer.h"
......@@ -77,11 +78,16 @@ void AuraTestBase::SetUp() {
ui::VelocityTracker::Strategy::LSQ2_RESTRICTED);
// The ContextFactory must exist before any Compositors are created.
bool enable_pixel_output = false;
ui::ContextFactory* context_factory = nullptr;
ui::ContextFactoryPrivate* context_factory_private = nullptr;
ui::InitializeContextFactoryForTests(enable_pixel_output, &context_factory,
&context_factory_private);
if (use_mus_) {
mus_context_factory_ = std::make_unique<AuraTestContextFactory>();
context_factory = mus_context_factory_.get();
} else {
const bool enable_pixel_output = false;
ui::InitializeContextFactoryForTests(enable_pixel_output, &context_factory,
&context_factory_private);
}
helper_ = std::make_unique<AuraTestHelper>();
if (use_mus_) {
......@@ -98,9 +104,18 @@ void AuraTestBase::TearDown() {
// and these tasks if un-executed would upset Valgrind.
RunAllPendingInMessageLoop();
window_tree_hosts_.clear();
// AuraTestHelper may own a WindowTreeHost, don't delete it here else
// AuraTestHelper will have use after frees.
for (size_t i = window_tree_hosts_.size(); i > 0; --i) {
if (window_tree_hosts_[i - 1].get() == helper_->host()) {
window_tree_hosts_[i - 1].release();
window_tree_hosts_.erase(window_tree_hosts_.begin() + i - 1);
break;
}
}
helper_->TearDown();
window_tree_hosts_.clear();
ui::TerminateContextFactoryForTests();
ui::ShutdownInputMethodForTesting();
testing::Test::TearDown();
......
......@@ -35,6 +35,8 @@ class FocusClient;
namespace test {
class AuraTestContextFactory;
enum class BackendType { CLASSIC, MUS };
// A base class for aura unit tests.
......@@ -169,6 +171,7 @@ class AuraTestBase : public testing::Test,
bool teardown_called_ = false;
PropertyConverter property_converter_;
std::unique_ptr<AuraTestHelper> helper_;
std::unique_ptr<AuraTestContextFactory> mus_context_factory_;
std::vector<std::unique_ptr<WindowTreeHostMus>> window_tree_hosts_;
std::vector<std::unique_ptr<ui::PointerEvent>> observed_pointer_events_;
......
// 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/test/aura_test_context_factory.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/test_context_provider.h"
#include "components/viz/test/test_layer_tree_frame_sink.h"
namespace aura {
namespace test {
namespace {
class FrameSinkClient : public viz::TestLayerTreeFrameSinkClient {
public:
explicit FrameSinkClient(
scoped_refptr<viz::ContextProvider> display_context_provider)
: display_context_provider_(std::move(display_context_provider)) {}
// viz::TestLayerTreeFrameSinkClient:
std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurface(
scoped_refptr<viz::ContextProvider> compositor_context_provider)
override {
return cc::FakeOutputSurface::Create3d(
std::move(display_context_provider_));
}
void DisplayReceivedLocalSurfaceId(
const viz::LocalSurfaceId& local_surface_id) override {}
void DisplayReceivedCompositorFrame(
const viz::CompositorFrame& frame) override {}
void DisplayWillDrawAndSwap(
bool will_draw_and_swap,
const viz::RenderPassList& render_passes) override {}
void DisplayDidDrawAndSwap() override {}
private:
scoped_refptr<viz::ContextProvider> display_context_provider_;
DISALLOW_COPY_AND_ASSIGN(FrameSinkClient);
};
} // namespace
AuraTestContextFactory::AuraTestContextFactory() = default;
AuraTestContextFactory::~AuraTestContextFactory() = default;
void AuraTestContextFactory::CreateLayerTreeFrameSink(
base::WeakPtr<ui::Compositor> compositor) {
scoped_refptr<cc::TestContextProvider> context_provider =
cc::TestContextProvider::Create();
std::unique_ptr<FrameSinkClient> frame_sink_client =
std::make_unique<FrameSinkClient>(context_provider);
constexpr bool synchronous_composite = false;
constexpr bool disable_display_vsync = false;
const double refresh_rate = GetRefreshRate();
auto frame_sink = std::make_unique<viz::TestLayerTreeFrameSink>(
context_provider, cc::TestContextProvider::CreateWorker(), nullptr,
GetGpuMemoryBufferManager(), renderer_settings(),
base::ThreadTaskRunnerHandle::Get().get(), synchronous_composite,
disable_display_vsync, refresh_rate);
frame_sink->SetClient(frame_sink_client.get());
compositor->SetLayerTreeFrameSink(std::move(frame_sink));
frame_sink_clients_.insert(std::move(frame_sink_client));
}
} // namespace test
} // namespace aura
// 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.
#ifndef UI_AURA_TEST_AURA_TEST_CONTEXT_FACTORY_H_
#define UI_AURA_TEST_AURA_TEST_CONTEXT_FACTORY_H_
#include <memory>
#include "base/macros.h"
#include "ui/compositor/test/fake_context_factory.h"
namespace viz {
class TestLayerTreeFrameSinkClient;
}
namespace aura {
namespace test {
class AuraTestContextFactory : public ui::FakeContextFactory {
public:
AuraTestContextFactory();
~AuraTestContextFactory() override;
// ui::FakeContextFactory
void CreateLayerTreeFrameSink(
base::WeakPtr<ui::Compositor> compositor) override;
private:
std::set<std::unique_ptr<viz::TestLayerTreeFrameSinkClient>>
frame_sink_clients_;
DISALLOW_COPY_AND_ASSIGN(AuraTestContextFactory);
};
} // namespace test
} // namespace aura
#endif // UI_AURA_TEST_AURA_TEST_CONTEXT_FACTORY_H_<
......@@ -109,6 +109,8 @@ void AuraTestHelper::SetUp(ui::ContextFactory* context_factory,
InitWindowTreeClient();
if (!Env::GetInstanceDontCreate())
env_ = Env::CreateInstance(env_mode);
else
env_mode_to_restore_ = Env::GetInstance()->mode();
EnvTestHelper env_helper;
// Always reset the mode. This really only matters for if Env was created
// above.
......@@ -117,6 +119,9 @@ void AuraTestHelper::SetUp(ui::ContextFactory* context_factory,
// Tests assume they can set the mouse location on Env() and have it reflected
// in tests.
env_helper.SetAlwaysUseLastMouseLocation(true);
context_factory_to_restore_ = Env::GetInstance()->context_factory();
context_factory_private_to_restore_ =
Env::GetInstance()->context_factory_private();
Env::GetInstance()->set_context_factory(context_factory);
Env::GetInstance()->set_context_factory_private(context_factory_private);
// Unit tests generally don't want to query the system, rather use the state
......@@ -133,20 +138,22 @@ void AuraTestHelper::SetUp(ui::ContextFactory* context_factory,
// This must be reset before creating TestScreen, which sets up the display
// scale factor for this test iteration.
display::Display::ResetForceDeviceScaleFactorForTesting();
test_screen_.reset(TestScreen::Create(host_size));
test_screen_.reset(TestScreen::Create(host_size, window_tree_client_));
if (!screen)
display::Screen::SetScreenInstance(test_screen_.get());
host_.reset(test_screen_->CreateHostForPrimaryDisplay());
host_->window()->SetEventTargeter(
std::unique_ptr<ui::EventTargeter>(new WindowTargeter()));
client::SetFocusClient(root_window(), focus_client_.get());
client::SetCaptureClient(root_window(), capture_client());
parenting_client_.reset(new TestWindowParentingClient(root_window()));
root_window()->Show();
// Ensure width != height so tests won't confuse them.
host()->SetBoundsInPixels(gfx::Rect(host_size));
if (env_mode == Env::Mode::LOCAL || window_manager_delegate_) {
host_.reset(test_screen_->CreateHostForPrimaryDisplay());
host_->window()->SetEventTargeter(
std::unique_ptr<ui::EventTargeter>(new WindowTargeter()));
client::SetFocusClient(root_window(), focus_client_.get());
client::SetCaptureClient(root_window(), capture_client());
parenting_client_.reset(new TestWindowParentingClient(root_window()));
root_window()->Show();
// Ensure width != height so tests won't confuse them.
host()->SetBoundsInPixels(gfx::Rect(host_size));
}
}
if (mode_ == Mode::MUS_CREATE_WINDOW_TREE_CLIENT) {
......@@ -162,7 +169,7 @@ void AuraTestHelper::TearDown() {
g_instance = nullptr;
teardown_called_ = true;
parenting_client_.reset();
if (mode_ != Mode::MUS) {
if (mode_ != Mode::MUS && root_window()) {
client::SetFocusClient(root_window(), nullptr);
client::SetCaptureClient(root_window(), nullptr);
host_.reset();
......@@ -174,12 +181,23 @@ void AuraTestHelper::TearDown() {
window_tree_client_setup_.reset();
focus_client_.reset();
capture_client_.reset();
} else {
if (display::Screen::GetScreen() == test_screen_.get())
display::Screen::SetScreenInstance(nullptr);
test_screen_.reset();
window_tree_client_setup_.reset();
}
ui::GestureRecognizer::Reset();
ui::ShutdownInputMethodForTesting();
if (env_)
if (env_) {
env_.reset();
} else {
Env::GetInstance()->set_context_factory(context_factory_to_restore_);
Env::GetInstance()->set_context_factory_private(
context_factory_private_to_restore_);
EnvTestHelper().SetMode(env_mode_to_restore_);
}
wm_state_.reset();
}
......
......@@ -14,6 +14,7 @@
namespace ui {
class ContextFactory;
class ContextFactoryPrivate;
class ScopedAnimationDurationScaleMode;
}
......@@ -76,7 +77,7 @@ class AuraTestHelper {
// Flushes message loop.
void RunAllPendingInMessageLoop();
Window* root_window() { return host_->window(); }
Window* root_window() { return host_ ? host_->window() : nullptr; }
ui::EventSink* event_sink() { return host_->event_sink(); }
WindowTreeHost* host() { return host_.get(); }
......@@ -114,7 +115,10 @@ class AuraTestHelper {
Mode mode_ = Mode::LOCAL;
bool setup_called_;
bool teardown_called_;
ui::ContextFactory* context_factory_to_restore_ = nullptr;
ui::ContextFactoryPrivate* context_factory_private_to_restore_ = nullptr;
std::unique_ptr<TestWindowTreeClientSetup> window_tree_client_setup_;
Env::Mode env_mode_to_restore_ = Env::Mode::LOCAL;
std::unique_ptr<aura::Env> env_;
std::unique_ptr<wm::WMState> wm_state_;
std::unique_ptr<WindowTreeHost> host_;
......
......@@ -38,7 +38,9 @@ WindowTreeHostMus* WindowTreeClientPrivate::CallWmNewDisplayAdded(
const display::Display& display) {
ui::mojom::WindowDataPtr root_data(ui::mojom::WindowData::New());
root_data->parent_id = 0;
root_data->window_id = next_window_id_++;
// Windows representing displays are owned by mus, which is identified by
// non-zero high word.
root_data->window_id = next_window_id_++ | 0x00010000;
root_data->visible = true;
root_data->bounds = gfx::Rect(display.bounds().size());
const bool parent_drawn = true;
......
......@@ -55,7 +55,9 @@ WindowTreeHost* TestScreen::CreateHostForPrimaryDisplay() {
// Makes sure InputMethod is default focused so that IME basics can work.
host_->GetInputMethod()->OnFocus();
host_->window()->AddObserver(this);
host_->InitHost();
// Other test code may have already initialized the compositor.
if (!host_->compositor()->root_layer())
host_->InitHost();
host_->window()->Show();
return host_;
}
......
......@@ -24,8 +24,8 @@
#include "services/service_manager/public/cpp/service_context.h"
#include "services/ui/common/switches.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/env.h"
#include "ui/aura/mus/window_tree_host_mus.h"
#include "ui/aura/test/env_test_helper.h"
#include "ui/aura/test/mus/input_method_mus_test_api.h"
#include "ui/aura/window.h"
#include "ui/compositor/test/fake_context_factory.h"
......@@ -68,16 +68,13 @@ class PlatformTestHelperMus : public PlatformTestHelper {
public:
PlatformTestHelperMus(service_manager::Connector* connector,
const service_manager::Identity& identity) {
aura::test::EnvTestHelper().SetWindowTreeClient(nullptr);
// It is necessary to recreate the MusClient for each test,
// since a new MessageLoop is created for each test.
mus_client_ = test::MusClientTestApi::Create(connector, identity);
ViewsDelegate::GetInstance()->set_native_widget_factory(base::Bind(
&PlatformTestHelperMus::CreateNativeWidget, base::Unretained(this)));
}
~PlatformTestHelperMus() override {
aura::test::EnvTestHelper().SetWindowTreeClient(nullptr);
}
~PlatformTestHelperMus() override {}
// PlatformTestHelper:
void OnTestHelperCreated(ViewsTestHelper* helper) override {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment