diff options
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.h | 218 |
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_ |