summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.h')
-rw-r--r--third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.h218
1 files changed, 218 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.h b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.h
new file mode 100644
index 0000000000..37e55815e1
--- /dev/null
+++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_SCREENCAST_PORTAL_H_
+#define MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_SCREENCAST_PORTAL_H_
+
+#include <gio/gio.h>
+
+#include <string>
+
+#include "modules/desktop_capture/desktop_capture_types.h"
+#include "modules/desktop_capture/linux/wayland/screen_capture_portal_interface.h"
+#include "modules/portal/portal_request_response.h"
+#include "modules/portal/xdg_desktop_portal_utils.h"
+#include "modules/portal/xdg_session_details.h"
+
+namespace webrtc {
+
+class RTC_EXPORT ScreenCastPortal
+ : public xdg_portal::ScreenCapturePortalInterface {
+ public:
+ using ProxyRequestResponseHandler = void (*)(GObject* object,
+ GAsyncResult* result,
+ gpointer user_data);
+
+ using SourcesRequestResponseSignalHandler =
+ void (*)(GDBusConnection* connection,
+ const char* sender_name,
+ const char* object_path,
+ const char* interface_name,
+ const char* signal_name,
+ GVariant* parameters,
+ gpointer user_data);
+
+ // Values are set based on cursor mode property in
+ // xdg-desktop-portal/screencast
+ // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml
+ enum class CursorMode : uint32_t {
+ // Mouse cursor will not be included in any form
+ kHidden = 0b01,
+ // Mouse cursor will be part of the screen content
+ kEmbedded = 0b10,
+ // Mouse cursor information will be send separately in form of metadata
+ kMetadata = 0b100
+ };
+
+ // Values are set based on persist mode property in
+ // xdg-desktop-portal/screencast
+ // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml
+ enum class PersistMode : uint32_t {
+ // Do not allow to restore stream
+ kDoNotPersist = 0b00,
+ // The restore token is valid as long as the application is alive. It's
+ // stored in memory and revoked when the application closes its DBus
+ // connection
+ kTransient = 0b01,
+ // The restore token is stored in disk and is valid until the user manually
+ // revokes it
+ kPersistent = 0b10
+ };
+
+ // Interface that must be implemented by the ScreenCastPortal consumers.
+ class PortalNotifier {
+ public:
+ virtual void OnScreenCastRequestResult(xdg_portal::RequestResponse result,
+ uint32_t stream_node_id,
+ int fd) = 0;
+ virtual void OnScreenCastSessionClosed() = 0;
+
+ protected:
+ PortalNotifier() = default;
+ virtual ~PortalNotifier() = default;
+ };
+
+ ScreenCastPortal(CaptureType type, PortalNotifier* notifier);
+ ScreenCastPortal(CaptureType type,
+ PortalNotifier* notifier,
+ ProxyRequestResponseHandler proxy_request_response_handler,
+ SourcesRequestResponseSignalHandler
+ sources_request_response_signal_handler,
+ gpointer user_data,
+ // TODO(chromium:1291247): Remove the default option once
+ // downstream has been adjusted.
+ bool prefer_cursor_embedded = false);
+
+ ~ScreenCastPortal();
+
+ // Initialize ScreenCastPortal with series of DBus calls where we try to
+ // obtain all the required information, like PipeWire file descriptor and
+ // PipeWire stream node ID.
+ //
+ // The observer will return whether the communication with xdg-desktop-portal
+ // was successful and only then you will be able to get all the required
+ // information in order to continue working with PipeWire.
+ void Start() override;
+ void Stop() override;
+ xdg_portal::SessionDetails GetSessionDetails() override;
+
+ // Method to notify the reason for failure of a portal request.
+ void OnPortalDone(xdg_portal::RequestResponse result) override;
+
+ // Sends a create session request to the portal.
+ void RequestSession(GDBusProxy* proxy) override;
+
+ // Set of methods leveraged by remote desktop portal to setup a common session
+ // with screen cast portal.
+ void SetSessionDetails(const xdg_portal::SessionDetails& session_details);
+ uint32_t pipewire_stream_node_id();
+ void SourcesRequest();
+ void OpenPipeWireRemote();
+
+ // ScreenCast specific methods for stream restoration
+ void SetPersistMode(ScreenCastPortal::PersistMode mode);
+ void SetRestoreToken(const std::string& token);
+ std::string RestoreToken() const;
+
+ private:
+ // Values are set based on source type property in
+ // xdg-desktop-portal/screencast
+ // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml
+ enum class CaptureSourceType : uint32_t {
+ kScreen = 0b01,
+ kWindow = 0b10,
+ kAnyScreenContent = kScreen | kWindow
+ };
+ static CaptureSourceType ToCaptureSourceType(CaptureType type);
+
+ PortalNotifier* notifier_;
+
+ // A PipeWire stream ID of stream we will be connecting to
+ uint32_t pw_stream_node_id_ = 0;
+ // A file descriptor of PipeWire socket
+ int pw_fd_ = -1;
+ // Restore token that can be used to restore previous session
+ std::string restore_token_;
+
+ CaptureSourceType capture_source_type_ =
+ ScreenCastPortal::CaptureSourceType::kScreen;
+
+ CursorMode cursor_mode_ = CursorMode::kMetadata;
+
+ PersistMode persist_mode_ = ScreenCastPortal::PersistMode::kDoNotPersist;
+
+ ProxyRequestResponseHandler proxy_request_response_handler_;
+ SourcesRequestResponseSignalHandler sources_request_response_signal_handler_;
+ gpointer user_data_;
+
+ GDBusConnection* connection_ = nullptr;
+ GDBusProxy* proxy_ = nullptr;
+ GCancellable* cancellable_ = nullptr;
+ std::string portal_handle_;
+ std::string session_handle_;
+ std::string sources_handle_;
+ std::string start_handle_;
+ guint session_request_signal_id_ = 0;
+ guint sources_request_signal_id_ = 0;
+ guint start_request_signal_id_ = 0;
+ guint session_closed_signal_id_ = 0;
+
+ void UnsubscribeSignalHandlers();
+ static void OnProxyRequested(GObject* object,
+ GAsyncResult* result,
+ gpointer user_data);
+ static void OnSessionRequested(GDBusProxy* proxy,
+ GAsyncResult* result,
+ gpointer user_data);
+ static void OnSessionRequestResponseSignal(GDBusConnection* connection,
+ const char* sender_name,
+ const char* object_path,
+ const char* interface_name,
+ const char* signal_name,
+ GVariant* parameters,
+ gpointer user_data);
+ static void OnSessionClosedSignal(GDBusConnection* connection,
+ const char* sender_name,
+ const char* object_path,
+ const char* interface_name,
+ const char* signal_name,
+ GVariant* parameters,
+ gpointer user_data);
+ static void OnSourcesRequested(GDBusProxy* proxy,
+ GAsyncResult* result,
+ gpointer user_data);
+ static void OnSourcesRequestResponseSignal(GDBusConnection* connection,
+ const char* sender_name,
+ const char* object_path,
+ const char* interface_name,
+ const char* signal_name,
+ GVariant* parameters,
+ gpointer user_data);
+
+ void StartRequest();
+ static void OnStartRequested(GDBusProxy* proxy,
+ GAsyncResult* result,
+ gpointer user_data);
+ static void OnStartRequestResponseSignal(GDBusConnection* connection,
+ const char* sender_name,
+ const char* object_path,
+ const char* interface_name,
+ const char* signal_name,
+ GVariant* parameters,
+ gpointer user_data);
+
+ static void OnOpenPipeWireRemoteRequested(GDBusProxy* proxy,
+ GAsyncResult* result,
+ gpointer user_data);
+};
+
+} // namespace webrtc
+
+#endif // MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_SCREENCAST_PORTAL_H_