blob: f03ec641615b7b09a205c4c90001a9ff78053f8e [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/lib/api-types/cpp/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.
//
// `display_id`, `vsync_config_stamp`, and `client_priority` must be valid.
void DispatchOnDisplayVsync(display::DisplayId display_id, zx::time_monotonic timestamp,
display::DriverConfigStamp vsync_config_stamp,
display::ClientPriority client_priority);
// Dispatches the event to all clients.
void DispatchOnCaptureComplete();
// Connects a client at the given priority level.
//
// After this method completes, the client will receive an OnDisplaysChanged
// event stating that the currently connected displays are those in
// `displays`.
//
// `controller` must be non-null and must outlive the ClientSet.
// `client_priority`, `coordinator_server_end`, and
// `coordinator_listener_client_end` must be valid.
zx::result<> ConnectClient(
Controller* controller, display::ClientPriority client_priority,
std::span<const display::DisplayId> current_display_ids,
fidl::ServerEnd<fuchsia_hardware_display::Coordinator> coordinator_server_end,
fidl::ClientEnd<fuchsia_hardware_display::CoordinatorListener>
coordinator_listener_client_end);
// `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 committed the display configuration.
//
// Returns nullopt if the committed configuration does not belong to any of the
// current clients. This happens if the client that committed the configuration
// has disconnected.
std::optional<display::ClientPriority> FindConfigStampSource(
display::DriverConfigStamp driver_config_stamp);
// Removes all clients, closing their connections.
//
// Must be called before the ClientSet is destroyed. No client must be added
// between the last Clear() call and the ClientSet's destruction.
void Clear();
// Returns null if no client owns the displays.
Client* GetClientOwningDisplays() const;
private:
// Recomputes the client that owns the displays.
//
// Must be called at least once when the set of connected clients changes, and
// when the virtcon mode changes.
//
// This method is idempotent.
void HandleClientOwnershipChanges();
std::list<std::unique_ptr<Client>> clients_;
// Points into `clients_`.
//
// Updated by `HandleClientOwnershipChanges()`.
Client* client_owning_displays_ = nullptr;
ClientId next_client_id_ = ClientId(1);
// The inspect node that lists all client connections.
inspect::Node root_node_;
};
} // namespace display_coordinator
#endif // SRC_GRAPHICS_DISPLAY_DRIVERS_COORDINATOR_CLIENT_SET_H_