#ifndef REMOTING_HOST_LINUX_GNOME_CAPTURE_STREAM_MANAGER_H_
#define REMOTING_HOST_LINUX_GNOME_CAPTURE_STREAM_MANAGER_H_
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <tuple>
#include "base/containers/circular_deque.h"
#include "base/containers/flat_map.h"
#include "base/containers/queue.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/sequence_checker.h"
#include "base/types/expected.h"
#include "remoting/host/base/loggable.h"
#include "remoting/host/base/screen_resolution.h"
#include "remoting/host/linux/capture_stream_manager.h"
#include "remoting/host/linux/gdbus_connection_ref.h"
#include "remoting/host/linux/gnome_display_config.h"
#include "remoting/host/linux/gnome_display_config_dbus_client.h"
#include "remoting/host/linux/gnome_display_config_monitor.h"
#include "remoting/host/linux/gvariant_ref.h"
#include "remoting/host/linux/pipewire_capture_stream.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h"
namespace remoting {
class GnomeCaptureStreamManager final : public CaptureStreamManager {
public:
using CaptureStreamManager::GetActiveStreams;
using CaptureStreamManager::GetStream;
GnomeCaptureStreamManager();
GnomeCaptureStreamManager& operator=(const GnomeCaptureStreamManager&) =
delete;
~GnomeCaptureStreamManager() override;
[[nodiscard]] Observer::Subscription AddObserver(Observer* observer) override;
base::WeakPtr<CaptureStream> GetStream(webrtc::ScreenId screen_id) override;
void AddVirtualStream(const ScreenResolution& initial_resolution,
AddStreamCallback callback) override;
void RemoveVirtualStream(webrtc::ScreenId screen_id) override;
base::flat_map<webrtc::ScreenId, base::WeakPtr<CaptureStream>>
GetActiveStreams() override;
void Init(GDBusConnectionRef* connection,
base::WeakPtr<GnomeDisplayConfigMonitor> display_config_monitor,
gvariant::ObjectPath screencast_session_path);
base::WeakPtr<GnomeCaptureStreamManager> GetWeakPtr();
private:
struct AddStreamRequest {
struct VirtualStreamInfo {
ScreenResolution initial_resolution;
};
struct MonitorStreamInfo {
std::string connector;
};
AddStreamRequest();
AddStreamRequest(AddStreamRequest&&);
AddStreamRequest(VirtualStreamInfo virtual_stream_info,
AddStreamCallback callback);
AddStreamRequest(MonitorStreamInfo monitor_stream_info,
AddStreamCallback callback);
~AddStreamRequest();
std::optional<VirtualStreamInfo> virtual_stream_info;
std::optional<MonitorStreamInfo> monitor_stream_info;
AddStreamCallback callback;
};
struct StreamInfo {
StreamInfo();
StreamInfo(StreamInfo&&);
StreamInfo& operator=(StreamInfo&&);
~StreamInfo();
std::unique_ptr<PipewireCaptureStream> stream;
gvariant::ObjectPath stream_path;
bool is_virtual_stream = true;
bool is_deleting = false;
};
template <typename SuccessType, typename String>
GDBusConnectionRef::CallCallback<SuccessType> CheckAddStreamResultAndContinue(
void (GnomeCaptureStreamManager::*success_method)(SuccessType),
String&& error_context);
void RemoveStream(webrtc::ScreenId screen_id, bool can_remove_monitor_stream);
void RemoveObserver(Observer* observer);
void MaybeAddStreamForCurrentRequest();
void MaybeAddMonitorStreams();
void RemoveInvalidStreams();
void RunCurrentAddStreamCallback(AddStreamResult result);
void OnAddStreamError(std::string_view what, Loggable why);
void OnStreamCreated(std::tuple<gvariant::ObjectPath> args);
void OnStreamParameters(GVariantRef<"a{sv}"> parameters);
void OnStreamStarted(std::tuple<> args);
void OnStreamStopped(webrtc::ScreenId screen_id,
base::expected<std::tuple<>, Loggable> result);
void OnPipeWireStreamAdded(std::string mapping_id,
std::tuple<std::uint32_t> args);
void OnGnomeDisplayConfigChanged(const GnomeDisplayConfig& config);
void AssociatePendingStream(webrtc::ScreenId screen_id);
void SetUseDamageRegion();
raw_ptr<GDBusConnectionRef> connection_ GUARDED_BY_CONTEXT(sequence_checker_);
base::WeakPtr<GnomeDisplayConfigMonitor> display_config_monitor_
GUARDED_BY_CONTEXT(sequence_checker_);
gvariant::ObjectPath screencast_session_path_
GUARDED_BY_CONTEXT(sequence_checker_);
std::unique_ptr<GnomeDisplayConfigMonitor::Subscription>
monitors_changed_subscription_;
std::optional<GnomeDisplayConfig> last_seen_display_config_
GUARDED_BY_CONTEXT(sequence_checker_);
base::flat_map<webrtc::ScreenId, StreamInfo> streams_
GUARDED_BY_CONTEXT(sequence_checker_);
base::circular_deque<AddStreamRequest> pending_add_stream_requests_
GUARDED_BY_CONTEXT(sequence_checker_);
std::unique_ptr<PipewireCaptureStream> pending_stream_
GUARDED_BY_CONTEXT(sequence_checker_);
gvariant::ObjectPath pending_stream_path_
GUARDED_BY_CONTEXT(sequence_checker_);
std::unique_ptr<GDBusConnectionRef::SignalSubscription>
pending_stream_added_signal_ GUARDED_BY_CONTEXT(sequence_checker_);
base::ObserverList<Observer> observers_ GUARDED_BY_CONTEXT(sequence_checker_);
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<GnomeCaptureStreamManager> weak_ptr_factory_{this};
};
}
#endif