blob: 19e6ed5b74c4768f49b50ab8ad804b3239fbf7e3 [file] [log] [blame]
// Copyright 2026 The Fuchsia 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 SRC_GRAPHICS_DISPLAY_DRIVERS_COORDINATOR_CLIENT_SET_H_
#define SRC_GRAPHICS_DISPLAY_DRIVERS_COORDINATOR_CLIENT_SET_H_
#include <fidl/fuchsia.hardware.display/cpp/wire.h>
#include <lib/inspect/cpp/vmo/types.h>
#include <lib/zx/result.h>
#include <zircon/time.h>
#include <list>
#include <memory>
#include <span>
#include "src/graphics/display/drivers/coordinator/client-id.h"
#include "src/graphics/display/drivers/coordinator/client-priority.h"
#include "src/graphics/display/lib/api-types/cpp/display-id.h"
#include "src/graphics/display/lib/api-types/cpp/driver-config-stamp.h"
namespace display_coordinator {
class Client;
class Controller;
// Manages all of a Display Coordinator's client connections.
//
// Instances are not thread-safe.
class ClientSet {
public:
// Creates an empty set.
//
// `root_node` will be populated with one sub-node per connected client.
explicit ClientSet(inspect::Node root_node);
ClientSet(const ClientSet&) = delete;
ClientSet(ClientSet&&) = delete;
ClientSet& operator=(const ClientSet&) = delete;
ClientSet& operator=(ClientSet&&) = delete;
~ClientSet();
// Dispatches the changes to all clients.
void DispatchOnDisplaysChanged(std::span<const display::DisplayId> added_display_ids,
std::span<const display::DisplayId> removed_display_ids);
// Dispatches the VSync to the client that submitted the configuration.
void DispatchOnDisplayVsync(display::DisplayId display_id, zx::time_monotonic timestamp,
display::DriverConfigStamp vsync_config_stamp,
ClientPriority client_priority);
// Dispatches the event to all clients.
void DispatchOnCaptureComplete();
// May change the client that owns the displays.
void SetVirtconMode(fuchsia_hardware_display::wire::VirtconMode virtcon_mode);
// `controller` must be null and must outlive the ClientSet.
zx::result<ClientId> ConnectClient(
Controller* controller, ClientPriority client_priority,
fidl::ServerEnd<fuchsia_hardware_display::Coordinator> coordinator_server_end,
fidl::ClientEnd<fuchsia_hardware_display::CoordinatorListener>
coordinator_listener_client_end);
// Transmits the initial set of connected displays to a client.
//
// After this method completes, the client will receive an OnDisplaysChanged
// event that describes all the currently connected displays.
//
// This method is a no-op if there is no client with the given `client_id`.
// This simplifies handling clients who disconnect before receiving the
// initial set of displays.
void SendInitialState(ClientId client_id,
std::span<const display::DisplayId> current_display_ids);
// `client` must point to a proxy associated with a client in this set.
//
// This method must be called at most once for a client.
void OnClientDisconnected(Client* client);
// Returns the priority of the client that applied the display configuration.
//
// Returns nullopt if the applied configuration does not belong to any of the
// current clients. This happens if the client that applied the configuration
// has disconnected.
std::optional<ClientPriority> FindConfigStampSource(
display::DriverConfigStamp driver_config_stamp);
// Closes all the client connections.
//
// The ClientSet will be cleared asynchronously. Each client's FIDL
// disconnection handler will remove the client from the set.
void CloseAll();
// Returns null if no client owns the displays.
Client* GetClientOwningDisplays() const;
private:
void HandleClientOwnershipChanges();
std::list<std::unique_ptr<Client>> clients_;
ClientId next_client_id_ = ClientId(1);
// The inspect node that lists all client connections.
inspect::Node root_node_;
// Pointers to instances owned by `clients_`.
Client* client_owning_displays_ = nullptr;
Client* virtcon_client_ = nullptr;
Client* primary_client_ = nullptr;
// True iff the corresponding client can dispatch FIDL events.
bool virtcon_client_ready_ = false;
bool primary_client_ready_ = false;
fuchsia_hardware_display::wire::VirtconMode virtcon_mode_ =
fuchsia_hardware_display::wire::VirtconMode::kFallback;
};
} // namespace display_coordinator
#endif // SRC_GRAPHICS_DISPLAY_DRIVERS_COORDINATOR_CLIENT_SET_H_