| // Copyright 2017 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/exo/server/wayland_server_controller.h" |
| |
| #include <memory> |
| |
| #include "base/atomic_sequence_num.h" |
| #include "base/command_line.h" |
| #include "base/files/file_util.h" |
| #include "base/files/scoped_temp_dir.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/task/current_thread.h" |
| #include "components/exo/data_exchange_delegate.h" |
| #include "components/exo/display.h" |
| #include "components/exo/input_method_surface_manager.h" |
| #include "components/exo/notification_surface_manager.h" |
| #include "components/exo/security_delegate.h" |
| #include "components/exo/server/wayland_server_handle.h" |
| #include "components/exo/toast_surface_manager.h" |
| #include "components/exo/wayland/server.h" |
| #include "components/exo/wm_helper.h" |
| |
| namespace exo { |
| |
| namespace { |
| WaylandServerController* g_instance = nullptr; |
| } // namespace |
| |
| // static |
| std::unique_ptr<WaylandServerController> |
| WaylandServerController::CreateIfNecessary( |
| std::unique_ptr<DataExchangeDelegate> data_exchange_delegate, |
| std::unique_ptr<NotificationSurfaceManager> notification_surface_manager, |
| std::unique_ptr<InputMethodSurfaceManager> input_method_surface_manager, |
| std::unique_ptr<ToastSurfaceManager> toast_surface_manager) { |
| return std::make_unique<WaylandServerController>( |
| std::move(data_exchange_delegate), |
| std::move(notification_surface_manager), |
| std::move(input_method_surface_manager), |
| std::move(toast_surface_manager)); |
| } |
| |
| // static |
| WaylandServerController* WaylandServerController::Get() { |
| DCHECK(g_instance); |
| return g_instance; |
| } |
| |
| WaylandServerController::~WaylandServerController() { |
| // TODO(https://crbug.com/1124106): Investigate if we can eliminate Shutdown |
| // methods. |
| display_->Shutdown(); |
| DCHECK_EQ(g_instance, this); |
| g_instance = nullptr; |
| } |
| |
| WaylandServerController::WaylandServerController( |
| std::unique_ptr<DataExchangeDelegate> data_exchange_delegate, |
| std::unique_ptr<NotificationSurfaceManager> notification_surface_manager, |
| std::unique_ptr<InputMethodSurfaceManager> input_method_surface_manager, |
| std::unique_ptr<ToastSurfaceManager> toast_surface_manager) |
| : wm_helper_(std::make_unique<WMHelper>()), |
| display_( |
| std::make_unique<Display>(std::move(notification_surface_manager), |
| std::move(input_method_surface_manager), |
| std::move(toast_surface_manager), |
| std::move(data_exchange_delegate))) { |
| DCHECK(!g_instance); |
| g_instance = this; |
| default_server_ = wayland::Server::Create( |
| display_.get(), SecurityDelegate::GetDefaultSecurityDelegate()); |
| default_server_->StartWithDefaultPath(base::BindOnce([](bool success) { |
| DCHECK(success) << "Failed to start the default wayland server."; |
| })); |
| } |
| |
| void WaylandServerController::ListenOnSocket( |
| std::unique_ptr<SecurityDelegate> security_delegate, |
| base::ScopedFD socket, |
| base::OnceCallback<void(std::unique_ptr<WaylandServerHandle>)> callback) { |
| std::unique_ptr<wayland::Server> server = |
| wayland::Server::Create(display_.get(), std::move(security_delegate)); |
| auto* server_ptr = server.get(); |
| auto start_callback = base::BindOnce(&WaylandServerController::OnSocketAdded, |
| weak_factory_.GetWeakPtr(), |
| std::move(server), std::move(callback)); |
| server_ptr->StartWithFdAsync(std::move(socket), std::move(start_callback)); |
| } |
| |
| void WaylandServerController::OnSocketAdded( |
| std::unique_ptr<wayland::Server> server, |
| base::OnceCallback<void(std::unique_ptr<WaylandServerHandle>)> callback, |
| bool success) { |
| if (!success) { |
| std::move(callback).Run(nullptr); |
| return; |
| } |
| |
| // WrapUnique() is needed since the constructor is private. |
| auto handle = base::WrapUnique(new WaylandServerHandle()); |
| on_demand_servers_.emplace(handle.get(), std::move(server)); |
| std::move(callback).Run(std::move(handle)); |
| } |
| |
| void WaylandServerController::CloseSocket(WaylandServerHandle* server) { |
| on_demand_servers_.erase(server); |
| } |
| |
| } // namespace exo |