mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 22:00:47 +01:00

Now that we've added the ability to open and close the PipeWire picker to the DesktopCapture interface, we can split the picker back into a Window and a Screen picker rather than just having the one combined picker. This will allow for a better user experience, as we can create a picker targeted to what the users actually want to share. Bug: chromium:1351570 Change-Id: I5bec22912ae01c1b0b0709a4979b4698226a2a66 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/273541 Reviewed-by: Mark Foltz <mfoltz@chromium.org> Commit-Queue: Alexander Cooper <alcooper@chromium.org> Cr-Commit-Position: refs/heads/main@{#38000}
222 lines
9.3 KiB
C++
222 lines
9.3 KiB
C++
/*
|
|
* 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/portal_request_response.h"
|
|
#include "modules/desktop_capture/linux/wayland/screen_capture_portal_interface.h"
|
|
#include "modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.h"
|
|
#include "modules/desktop_capture/linux/wayland/xdg_session_details.h"
|
|
|
|
namespace webrtc {
|
|
|
|
class 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 source type property in
|
|
// xdg-desktop-portal/screencast
|
|
// https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml
|
|
// TODO(https://crbug.com/1359411): Make this private.
|
|
enum class CaptureSourceType : uint32_t {
|
|
kScreen = 0b01,
|
|
kWindow = 0b10,
|
|
kAnyScreenContent = kScreen | kWindow
|
|
};
|
|
|
|
// 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(https://crbug.com/1359411): Migrate downstream consumers off of
|
|
// CaptureSourceType and delete this.
|
|
ScreenCastPortal(CaptureSourceType source_type,
|
|
PortalNotifier* notifier,
|
|
ProxyRequestResponseHandler proxy_request_response_handler,
|
|
SourcesRequestResponseSignalHandler
|
|
sources_request_response_signal_handler,
|
|
gpointer user_data);
|
|
~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:
|
|
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_ = ScreenCastPortal::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_
|