blob: ff68eb8c686f7e98122b0390dd2b14837a721a23 [file] [log] [blame]
// 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/views/test/platform_test_helper_mus.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/threading/simple_thread.h"
#include "services/service_manager/background_service_manager.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/constants.h"
#include "services/service_manager/public/cpp/manifest_builder.h"
#include "services/service_manager/public/cpp/service.h"
#include "services/service_manager/public/cpp/service_binding.h"
#include "services/ws/ime/test_ime_driver/public/cpp/manifest.h"
#include "services/ws/public/mojom/constants.mojom.h"
#include "services/ws/test_ws/test_manifest.h"
#include "testing/gtest/include/gtest/gtest.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/base/ui_base_features.h"
#include "ui/views/mus/desktop_window_tree_host_mus.h"
#include "ui/views/mus/mus_client.h"
#include "ui/views/test/views_test_helper_aura.h"
#include "ui/views/views_delegate.h"
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#include "ui/views/widget/native_widget_aura.h"
namespace views {
namespace {
NativeWidget* CreateNativeWidget(const Widget::InitParams& init_params,
internal::NativeWidgetDelegate* delegate) {
NativeWidget* native_widget =
MusClient::Get()->CreateNativeWidget(init_params, delegate);
if (!native_widget)
return nullptr;
// Disable sending KeyEvents to IME as tests aren't set up to wait for an
// ack (and tests run concurrently).
aura::WindowTreeHostMus* window_tree_host_mus =
static_cast<aura::WindowTreeHostMus*>(
static_cast<DesktopNativeWidgetAura*>(native_widget)->host());
aura::InputMethodMusTestApi::Disable(window_tree_host_mus->input_method());
return native_widget;
}
} // namespace
class PlatformTestHelperMus::ServiceManagerConnection {
public:
ServiceManagerConnection()
: thread_("Persistent service_manager connections"),
default_service_binding_(&default_service_) {
base::WaitableEvent wait(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
base::Thread::Options options;
thread_.StartWithOptions(options);
thread_.task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
&ServiceManagerConnection::SetUpConnectionsOnBackgroundThread,
base::Unretained(this), &wait));
wait.Wait();
}
~ServiceManagerConnection() {
base::WaitableEvent wait(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
thread_.task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
&ServiceManagerConnection::TearDownConnectionsOnBackgroundThread,
base::Unretained(this), &wait));
wait.Wait();
}
std::unique_ptr<MusClient> CreateMusClient() {
MusClient::InitParams params;
params.connector = GetConnector();
params.identity = service_manager_identity_;
// The window tree client might have been created already by the test suite
// (e.g. AuraTestSuiteSetup).
params.window_tree_client =
aura::test::EnvTestHelper().GetWindowTreeClient();
params.running_in_ws_process = features::IsSingleProcessMash();
return std::make_unique<MusClient>(params);
}
private:
service_manager::Connector* GetConnector() {
service_manager_connector_.reset();
base::WaitableEvent wait(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&ServiceManagerConnection::CloneConnector,
base::Unretained(this), &wait));
wait.Wait();
DCHECK(service_manager_connector_);
return service_manager_connector_.get();
}
void CloneConnector(base::WaitableEvent* wait) {
service_manager_connector_ =
default_service_binding_.GetConnector()->Clone();
wait->Signal();
}
void SetUpConnectionsOnBackgroundThread(base::WaitableEvent* wait) {
static const char* kServiceName = "views_unittests";
background_service_manager_ =
std::make_unique<service_manager::BackgroundServiceManager>(
std::vector<service_manager::Manifest>{
test_ws::GetManifest(), test_ime_driver::GetManifest(),
service_manager::ManifestBuilder()
.WithServiceName(kServiceName)
.RequireCapability("*", "app")
.RequireCapability("*", "test")
.Build()});
service_manager::mojom::ServicePtr service;
default_service_binding_.Bind(mojo::MakeRequest(&service));
// The service name matches the name field in unittests_manifest.json.
background_service_manager_->RegisterService(
service_manager::Identity(kServiceName,
service_manager::kSystemInstanceGroup,
base::Token{}, base::Token::CreateRandom()),
std::move(service), nullptr);
service_manager_connector_ =
default_service_binding_.GetConnector()->Clone();
service_manager_identity_ = default_service_binding_.identity();
wait->Signal();
}
void TearDownConnectionsOnBackgroundThread(base::WaitableEvent* wait) {
default_service_binding_.Close();
background_service_manager_.reset();
wait->Signal();
}
base::Thread thread_;
std::unique_ptr<service_manager::BackgroundServiceManager>
background_service_manager_;
service_manager::Service default_service_;
service_manager::ServiceBinding default_service_binding_;
std::unique_ptr<service_manager::Connector> service_manager_connector_;
service_manager::Identity service_manager_identity_;
DISALLOW_COPY_AND_ASSIGN(ServiceManagerConnection);
};
PlatformTestHelperMus::PlatformTestHelperMus() {
service_manager_connection_ = std::make_unique<ServiceManagerConnection>();
mus_client_ = service_manager_connection_->CreateMusClient();
ViewsDelegate::GetInstance()->set_native_widget_factory(
base::BindRepeating(&CreateNativeWidget));
}
PlatformTestHelperMus::~PlatformTestHelperMus() = default;
void PlatformTestHelperMus::OnTestHelperCreated(ViewsTestHelper* helper) {
static_cast<ViewsTestHelperAura*>(helper)->EnableMusWithWindowTreeClient(
mus_client_->window_tree_client());
}
void PlatformTestHelperMus::SimulateNativeDestroy(Widget* widget) {
aura::WindowTreeHostMus* window_tree_host =
static_cast<aura::WindowTreeHostMus*>(widget->GetNativeView()->GetHost());
static_cast<aura::WindowTreeClientDelegate*>(mus_client_.get())
->OnEmbedRootDestroyed(window_tree_host);
}
void PlatformTestHelperMus::InitializeContextFactory(
ui::ContextFactory** context_factory,
ui::ContextFactoryPrivate** context_factory_private) {
*context_factory = &context_factory_;
*context_factory_private = nullptr;
}
} // namespace views