diff --git a/modules/desktop_capture/BUILD.gn b/modules/desktop_capture/BUILD.gn index 34a5704b40..a496ce54c9 100644 --- a/modules/desktop_capture/BUILD.gn +++ b/modules/desktop_capture/BUILD.gn @@ -7,9 +7,7 @@ # be found in the AUTHORS file in the root of the source tree. import("//build/config/linux/gtk/gtk.gni") -import("//build/config/linux/pkg_config.gni") import("//build/config/ui.gni") -import("//tools/generate_stubs/rules.gni") import("../../webrtc.gni") use_desktop_capture_differ_sse2 = current_cpu == "x86" || current_cpu == "x64" @@ -84,7 +82,7 @@ if (rtc_include_tests) { ] if ((is_linux || is_chromeos) && rtc_use_pipewire) { - configs += [ ":gio" ] + configs += [ "../portal:gio" ] } public_configs = [ ":x11_config" ] @@ -105,14 +103,7 @@ if (rtc_include_tests) { "linux/wayland/test/test_screencast_stream_provider.h", ] - configs += [ - ":gio", - ":pipewire", - ":gbm", - ":egl", - ":epoxy", - ":libdrm", - ] + configs += [ "../portal:pipewire_all" ] deps = [ ":desktop_capture", @@ -122,6 +113,7 @@ if (rtc_include_tests) { "../../rtc_base:logging", "../../rtc_base:random", "../../rtc_base:timeutils", + "../portal", # TODO(bugs.webrtc.org/9987): Remove this dep on rtc_base:rtc_base once # rtc_base:threading is fully defined. @@ -135,11 +127,7 @@ if (rtc_include_tests) { "//rtc_base:rtc_event", ] - if (!rtc_link_pipewire) { - deps += [ ":pipewire_stubs" ] - } - - public_configs = [ ":pipewire_config" ] + public_configs = [ "../portal:pipewire_config" ] } group("pipewire_shared_screencast_stream_test") { @@ -178,7 +166,7 @@ if (rtc_include_tests) { ] if ((is_linux || is_chromeos) && rtc_use_pipewire) { - configs += [ ":gio" ] + configs += [ "../portal:gio" ] } deps = [ @@ -288,7 +276,7 @@ if (rtc_include_tests) { ] if ((is_linux || is_chromeos) && rtc_use_pipewire) { - configs += [ ":gio" ] + configs += [ "../portal:gio" ] } deps = [ @@ -299,71 +287,10 @@ if (rtc_include_tests) { } } -if (is_linux || is_chromeos) { - if (rtc_use_pipewire) { - pkg_config("gio") { - packages = [ - "gio-2.0", - "gio-unix-2.0", - ] - } - - pkg_config("pipewire") { - packages = [ "libpipewire-0.3" ] - if (!rtc_link_pipewire) { - ignore_libs = true - } - } - - pkg_config("gbm") { - packages = [ "gbm" ] - } - pkg_config("egl") { - packages = [ "egl" ] - } - pkg_config("epoxy") { - packages = [ "epoxy" ] - ignore_libs = true - } - pkg_config("libdrm") { - packages = [ "libdrm" ] - } - - if (!rtc_link_pipewire) { - # When libpipewire is not directly linked, use stubs to allow for dlopening of - # the binary. - generate_stubs("pipewire_stubs") { - configs = [ - "../../:common_config", - ":pipewire", - ] - deps = [ "../../rtc_base" ] - extra_header = "linux/wayland/pipewire_stub_header.fragment" - logging_function = "RTC_LOG(LS_VERBOSE)" - logging_include = "rtc_base/logging.h" - output_name = "linux/wayland/pipewire_stubs" - path_from_source = "modules/desktop_capture/linux/wayland" - sigs = [ "linux/wayland/pipewire.sigs" ] - if (!build_with_chromium) { - macro_include = "rtc_base/system/no_cfi_icall.h" - macro_deps = [ "../../rtc_base/system:no_cfi_icall" ] - } - } - } - - config("pipewire_config") { - defines = [ "WEBRTC_USE_PIPEWIRE" ] - if (!rtc_link_pipewire) { - defines += [ "WEBRTC_DLOPEN_PIPEWIRE" ] - } - - # Chromecast build config overrides `WEBRTC_USE_PIPEWIRE` even when - # `rtc_use_pipewire` is not set, which causes pipewire_config to not be - # included in targets. More details in: webrtc:13898 - if (is_linux && !is_castos) { - defines += [ "WEBRTC_USE_GIO" ] - } - } +# TODO(bugs.webrtc.org/14187): remove when all users are gone +if (is_linux && rtc_use_pipewire) { + config("pipewire_config") { + configs = [ "../portal:pipewire_config" ] } } @@ -644,12 +571,9 @@ rtc_library("desktop_capture") { "linux/wayland/egl_dmabuf.h", "linux/wayland/mouse_cursor_monitor_pipewire.cc", "linux/wayland/mouse_cursor_monitor_pipewire.h", - "linux/wayland/pipewire_utils.cc", - "linux/wayland/pipewire_utils.h", "linux/wayland/portal_request_response.h", "linux/wayland/restore_token_manager.cc", "linux/wayland/restore_token_manager.h", - "linux/wayland/scoped_glib.cc", "linux/wayland/scoped_glib.h", "linux/wayland/screen_capture_portal_interface.cc", "linux/wayland/screen_capture_portal_interface.h", @@ -659,27 +583,18 @@ rtc_library("desktop_capture") { "linux/wayland/screencast_stream_utils.h", "linux/wayland/shared_screencast_stream.cc", "linux/wayland/shared_screencast_stream.h", - "linux/wayland/xdg_desktop_portal_utils.cc", "linux/wayland/xdg_desktop_portal_utils.h", "linux/wayland/xdg_session_details.h", ] - configs += [ - ":gio", - ":pipewire", - ":gbm", - ":egl", - ":epoxy", - ":libdrm", + configs += [ "../portal:pipewire_all" ] + + public_configs += [ "../portal:pipewire_config" ] + + deps += [ + "../../rtc_base:sanitizer", + "../portal", ] - - if (!rtc_link_pipewire) { - deps += [ ":pipewire_stubs" ] - } - - public_configs += [ ":pipewire_config" ] - - deps += [ "../../rtc_base:sanitizer" ] } if (rtc_enable_win_wgc) { diff --git a/modules/desktop_capture/DEPS b/modules/desktop_capture/DEPS index 8c894c4430..d5f44878a7 100644 --- a/modules/desktop_capture/DEPS +++ b/modules/desktop_capture/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+common_video", "+system_wrappers", "+third_party/libyuv", ] diff --git a/modules/desktop_capture/desktop_capture_metadata.h b/modules/desktop_capture/desktop_capture_metadata.h index faca156e33..49a20e729c 100644 --- a/modules/desktop_capture/desktop_capture_metadata.h +++ b/modules/desktop_capture/desktop_capture_metadata.h @@ -12,7 +12,7 @@ #define MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_METADATA_H_ #if defined(WEBRTC_USE_GIO) -#include "modules/desktop_capture/linux/wayland/xdg_session_details.h" +#include "modules/portal/xdg_session_details.h" #endif // defined(WEBRTC_USE_GIO) namespace webrtc { diff --git a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc index a0af638d00..e9e45b57d2 100644 --- a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc +++ b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc @@ -12,9 +12,9 @@ #include "modules/desktop_capture/desktop_capture_options.h" #include "modules/desktop_capture/desktop_capturer.h" -#include "modules/desktop_capture/linux/wayland/pipewire_utils.h" #include "modules/desktop_capture/linux/wayland/restore_token_manager.h" -#include "modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.h" +#include "modules/portal/pipewire_utils.h" +#include "modules/portal/xdg_desktop_portal_utils.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" diff --git a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.h b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.h index d84718aea4..c5c122c14c 100644 --- a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.h +++ b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.h @@ -14,12 +14,12 @@ #include "modules/desktop_capture/delegated_source_list_controller.h" #include "modules/desktop_capture/desktop_capture_options.h" #include "modules/desktop_capture/desktop_capturer.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/screencast_portal.h" #include "modules/desktop_capture/linux/wayland/shared_screencast_stream.h" -#include "modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.h" -#include "modules/desktop_capture/linux/wayland/xdg_session_details.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 { diff --git a/modules/desktop_capture/linux/wayland/portal_request_response.h b/modules/desktop_capture/linux/wayland/portal_request_response.h index dde9ac5eff..2589479347 100644 --- a/modules/desktop_capture/linux/wayland/portal_request_response.h +++ b/modules/desktop_capture/linux/wayland/portal_request_response.h @@ -11,24 +11,7 @@ #ifndef MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_PORTAL_REQUEST_RESPONSE_H_ #define MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_PORTAL_REQUEST_RESPONSE_H_ -namespace webrtc { -namespace xdg_portal { +// TODO(bugs.webrtc.org/14187): remove when all users are gone +#include "modules/portal/portal_request_response.h" -// Contains type of responses that can be observed when making a request to -// a desktop portal interface. -enum class RequestResponse { - // Unknown, the initialized status. - kUnknown, - // Success, the request is carried out. - kSuccess, - // The user cancelled the interaction. - kUserCancelled, - // The user interaction was ended in some other way. - kError, - - kMaxValue = kError, -}; - -} // namespace xdg_portal -} // namespace webrtc #endif // MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_PORTAL_REQUEST_RESPONSE_H_ diff --git a/modules/desktop_capture/linux/wayland/scoped_glib.h b/modules/desktop_capture/linux/wayland/scoped_glib.h index 908bd6f77d..1361f84328 100644 --- a/modules/desktop_capture/linux/wayland/scoped_glib.h +++ b/modules/desktop_capture/linux/wayland/scoped_glib.h @@ -11,55 +11,7 @@ #ifndef MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_SCOPED_GLIB_H_ #define MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_SCOPED_GLIB_H_ -#include - -#include "rtc_base/checks.h" - -namespace webrtc { - -template -class Scoped { - public: - Scoped() {} - explicit Scoped(T* val) { ptr_ = val; } - ~Scoped() { RTC_DCHECK_NOTREACHED(); } - - T* operator->() const { return ptr_; } - - explicit operator bool() const { return ptr_ != nullptr; } - - bool operator!() const { return ptr_ == nullptr; } - - T* get() const { return ptr_; } - - T** receive() { - RTC_CHECK(!ptr_); - return &ptr_; - } - - Scoped& operator=(T* val) { - RTC_DCHECK(val); - ptr_ = val; - return *this; - } - - protected: - T* ptr_ = nullptr; -}; - -template <> -Scoped::~Scoped(); -template <> -Scoped::~Scoped(); -template <> -Scoped::~Scoped(); -template <> -Scoped::~Scoped(); -template <> -Scoped::~Scoped(); -template <> -Scoped::~Scoped(); - -} // namespace webrtc +// TODO(bugs.webrtc.org/14187): remove when all users are gone +#include "modules/portal/scoped_glib.h" #endif // MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_SCOPED_GLIB_H_ diff --git a/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc b/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc index 02d9d2e806..1c7cc379df 100644 --- a/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc +++ b/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc @@ -8,10 +8,10 @@ * be found in the AUTHORS file in the root of the source tree. */ #include "modules/desktop_capture/linux/wayland/screen_capture_portal_interface.h" -#include "modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.h" #include +#include "modules/portal/xdg_desktop_portal_utils.h" #include "rtc_base/logging.h" namespace webrtc { diff --git a/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.h b/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.h index 59aaf134e7..deb57a4707 100644 --- a/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.h +++ b/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.h @@ -15,10 +15,10 @@ #include -#include "modules/desktop_capture/linux/wayland/portal_request_response.h" -#include "modules/desktop_capture/linux/wayland/scoped_glib.h" -#include "modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.h" -#include "modules/desktop_capture/linux/wayland/xdg_session_details.h" +#include "modules/portal/portal_request_response.h" +#include "modules/portal/scoped_glib.h" +#include "modules/portal/xdg_desktop_portal_utils.h" +#include "modules/portal/xdg_session_details.h" namespace webrtc { namespace xdg_portal { diff --git a/modules/desktop_capture/linux/wayland/screencast_portal.cc b/modules/desktop_capture/linux/wayland/screencast_portal.cc index f9cdb08533..9848004363 100644 --- a/modules/desktop_capture/linux/wayland/screencast_portal.cc +++ b/modules/desktop_capture/linux/wayland/screencast_portal.cc @@ -13,8 +13,8 @@ #include #include -#include "modules/desktop_capture/linux/wayland/scoped_glib.h" -#include "modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.h" +#include "modules/portal/scoped_glib.h" +#include "modules/portal/xdg_desktop_portal_utils.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" diff --git a/modules/desktop_capture/linux/wayland/screencast_portal.h b/modules/desktop_capture/linux/wayland/screencast_portal.h index 96e4ba3ac9..c54d4821b4 100644 --- a/modules/desktop_capture/linux/wayland/screencast_portal.h +++ b/modules/desktop_capture/linux/wayland/screencast_portal.h @@ -16,10 +16,10 @@ #include #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" +#include "modules/portal/portal_request_response.h" +#include "modules/portal/xdg_desktop_portal_utils.h" +#include "modules/portal/xdg_session_details.h" namespace webrtc { diff --git a/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc b/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc index dc0784791d..0c4900d1cd 100644 --- a/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc +++ b/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc @@ -27,15 +27,6 @@ namespace webrtc { -PipeWireThreadLoopLock::PipeWireThreadLoopLock(pw_thread_loop* loop) - : loop_(loop) { - pw_thread_loop_lock(loop_); -} - -PipeWireThreadLoopLock::~PipeWireThreadLoopLock() { - pw_thread_loop_unlock(loop_); -} - PipeWireVersion PipeWireVersion::Parse(const absl::string_view& version) { std::vector parsed_version = rtc::split(version, '.'); diff --git a/modules/desktop_capture/linux/wayland/screencast_stream_utils.h b/modules/desktop_capture/linux/wayland/screencast_stream_utils.h index 70262c2e39..e04d7db931 100644 --- a/modules/desktop_capture/linux/wayland/screencast_stream_utils.h +++ b/modules/desktop_capture/linux/wayland/screencast_stream_utils.h @@ -18,23 +18,12 @@ #include "rtc_base/string_encode.h" -struct pw_thread_loop; struct spa_pod; struct spa_pod_builder; struct spa_rectangle; namespace webrtc { -// Locks pw_thread_loop in the current scope -class PipeWireThreadLoopLock { - public: - explicit PipeWireThreadLoopLock(pw_thread_loop* loop); - ~PipeWireThreadLoopLock(); - - private: - pw_thread_loop* const loop_; -}; - struct PipeWireVersion { static PipeWireVersion Parse(const absl::string_view& version); diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc index 4651486223..7a2b9ba212 100644 --- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc +++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc @@ -20,8 +20,8 @@ #include "absl/memory/memory.h" #include "modules/desktop_capture/linux/wayland/egl_dmabuf.h" -#include "modules/desktop_capture/linux/wayland/pipewire_utils.h" #include "modules/desktop_capture/linux/wayland/screencast_stream_utils.h" +#include "modules/portal/pipewire_utils.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/sanitizer.h" diff --git a/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc b/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc index bf212d0650..3b829959ac 100644 --- a/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc +++ b/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc @@ -20,7 +20,7 @@ #include #include -#include "modules/desktop_capture/linux/wayland/pipewire_utils.h" +#include "modules/portal/pipewire_utils.h" #include "rtc_base/logging.h" namespace webrtc { diff --git a/modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.h b/modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.h index f6ac92b5d1..b213e50308 100644 --- a/modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.h +++ b/modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.h @@ -11,101 +11,7 @@ #ifndef MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_XDG_DESKTOP_PORTAL_UTILS_H_ #define MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_XDG_DESKTOP_PORTAL_UTILS_H_ -#include -#include - -#include -#include - -#include "absl/strings/string_view.h" -#include "modules/desktop_capture/linux/wayland/portal_request_response.h" -#include "modules/desktop_capture/linux/wayland/scoped_glib.h" -#include "modules/desktop_capture/linux/wayland/xdg_session_details.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" - -namespace webrtc { -namespace xdg_portal { - -constexpr char kDesktopBusName[] = "org.freedesktop.portal.Desktop"; -constexpr char kDesktopObjectPath[] = "/org/freedesktop/portal/desktop"; -constexpr char kDesktopRequestObjectPath[] = - "/org/freedesktop/portal/desktop/request"; -constexpr char kSessionInterfaceName[] = "org.freedesktop.portal.Session"; -constexpr char kRequestInterfaceName[] = "org.freedesktop.portal.Request"; -constexpr char kScreenCastInterfaceName[] = "org.freedesktop.portal.ScreenCast"; - -using ProxyRequestCallback = void (*)(GObject*, GAsyncResult*, gpointer); -using SessionRequestCallback = void (*)(GDBusProxy*, GAsyncResult*, gpointer); -using SessionRequestResponseSignalHandler = void (*)(GDBusConnection*, - const char*, - const char*, - const char*, - const char*, - GVariant*, - gpointer); -using StartRequestResponseSignalHandler = void (*)(GDBusConnection*, - const char*, - const char*, - const char*, - const char*, - GVariant*, - gpointer); -using SessionStartRequestedHandler = void (*)(GDBusProxy*, - GAsyncResult*, - gpointer); - -std::string RequestResponseToString(RequestResponse request); - -RequestResponse RequestResponseFromPortalResponse(uint32_t portal_response); - -// Returns a string path for signal handle based on the provided connection and -// token. -std::string PrepareSignalHandle(absl::string_view token, - GDBusConnection* connection); - -// Sets up the callback to execute when a response signal is received for the -// given object. -uint32_t SetupRequestResponseSignal(absl::string_view object_path, - const GDBusSignalCallback callback, - gpointer user_data, - GDBusConnection* connection); - -void RequestSessionProxy(absl::string_view interface_name, - const ProxyRequestCallback proxy_request_callback, - GCancellable* cancellable, - gpointer user_data); - -void SetupSessionRequestHandlers( - absl::string_view portal_prefix, - const SessionRequestCallback session_request_callback, - const SessionRequestResponseSignalHandler request_response_signale_handler, - GDBusConnection* connection, - GDBusProxy* proxy, - GCancellable* cancellable, - std::string& portal_handle, - guint& session_request_signal_id, - gpointer user_data); - -void StartSessionRequest( - absl::string_view prefix, - absl::string_view session_handle, - const StartRequestResponseSignalHandler signal_handler, - const SessionStartRequestedHandler session_started_handler, - GDBusProxy* proxy, - GDBusConnection* connection, - GCancellable* cancellable, - guint& start_request_signal_id, - std::string& start_handle, - gpointer user_data); - -// Tears down the portal session and cleans up related objects. -void TearDownSession(absl::string_view session_handle, - GDBusProxy* proxy, - GCancellable* cancellable, - GDBusConnection* connection); - -} // namespace xdg_portal -} // namespace webrtc +// TODO(bugs.webrtc.org/14187): remove when all users are gone +#include "modules/portal/xdg_desktop_portal_utils.h" #endif // MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_XDG_DESKTOP_PORTAL_UTILS_H_ diff --git a/modules/desktop_capture/linux/wayland/xdg_session_details.h b/modules/desktop_capture/linux/wayland/xdg_session_details.h index b70ac4aa59..9feff5bdf7 100644 --- a/modules/desktop_capture/linux/wayland/xdg_session_details.h +++ b/modules/desktop_capture/linux/wayland/xdg_session_details.h @@ -11,23 +11,7 @@ #ifndef MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_XDG_SESSION_DETAILS_H_ #define MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_XDG_SESSION_DETAILS_H_ -#include - -#include - -namespace webrtc { -namespace xdg_portal { - -// Details of the session associated with XDG desktop portal session. Portal API -// calls can be invoked by utilizing the information here. -struct SessionDetails { - GDBusProxy* proxy = nullptr; - GCancellable* cancellable = nullptr; - std::string session_handle; - uint32_t pipewire_stream_node_id = 0; -}; - -} // namespace xdg_portal -} // namespace webrtc +// TODO(bugs.webrtc.org/14187): remove when all users are gone +#include "modules/portal/xdg_session_details.h" #endif // MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_XDG_SESSION_DETAILS_H_ diff --git a/modules/portal/BUILD.gn b/modules/portal/BUILD.gn new file mode 100644 index 0000000000..730d3275d6 --- /dev/null +++ b/modules/portal/BUILD.gn @@ -0,0 +1,124 @@ +# Copyright (c) 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. + +import("//build/config/linux/pkg_config.gni") +import("//tools/generate_stubs/rules.gni") +import("../../webrtc.gni") + +assert(is_linux) +assert(rtc_use_pipewire) + +pkg_config("gio") { + packages = [ + "gio-2.0", + "gio-unix-2.0", + ] +} + +pkg_config("pipewire") { + packages = [ "libpipewire-0.3" ] + if (!rtc_link_pipewire) { + ignore_libs = true + } +} + +pkg_config("gbm") { + packages = [ "gbm" ] +} +pkg_config("egl") { + packages = [ "egl" ] +} +pkg_config("epoxy") { + packages = [ "epoxy" ] + ignore_libs = true +} +pkg_config("libdrm") { + packages = [ "libdrm" ] +} + +if (!rtc_link_pipewire) { + # When libpipewire is not directly linked, use stubs to allow for dlopening of + # the binary. + generate_stubs("pipewire_stubs") { + configs = [ + "../../:common_config", + ":pipewire", + ] + deps = [ "../../rtc_base" ] + extra_header = "pipewire_stub_header.fragment" + logging_function = "RTC_LOG(LS_VERBOSE)" + logging_include = "rtc_base/logging.h" + output_name = "pipewire_stubs" + path_from_source = "modules/portal" + sigs = [ "pipewire.sigs" ] + if (!build_with_chromium) { + macro_include = "rtc_base/system/no_cfi_icall.h" + macro_deps = [ "../../rtc_base/system:no_cfi_icall" ] + } + } +} + +config("pipewire_base") { + configs = [ + ":gio", + ":pipewire", + ] +} + +config("pipewire_all") { + configs = [ + ":pipewire_base", + ":gbm", + ":egl", + ":epoxy", + ":libdrm", + ] +} + +config("pipewire_config") { + defines = [ "WEBRTC_USE_PIPEWIRE" ] + + # Chromecast build config overrides `WEBRTC_USE_PIPEWIRE` even when + # `rtc_use_pipewire` is not set, which causes pipewire_config to not be + # included in targets. More details in: webrtc:13898 + if (is_linux && !is_castos) { + defines += [ "WEBRTC_USE_GIO" ] + } +} + +rtc_library("portal") { + sources = [ + "pipewire_utils.cc", + "pipewire_utils.h", + "portal_request_response.h", + "scoped_glib.cc", + "scoped_glib.h", + "xdg_desktop_portal_utils.cc", + "xdg_desktop_portal_utils.h", + "xdg_session_details.h", + ] + + configs += [ + ":gio", + ":pipewire", + ":pipewire_config", + ] + + deps = [ + "../../rtc_base:checks", + "../../rtc_base:logging", + "../../rtc_base:sanitizer", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] + + if (!rtc_link_pipewire) { + defines = [ "WEBRTC_DLOPEN_PIPEWIRE" ] + + deps += [ ":pipewire_stubs" ] + } +} diff --git a/modules/portal/OWNERS b/modules/portal/OWNERS new file mode 100644 index 0000000000..e3bc32ee5c --- /dev/null +++ b/modules/portal/OWNERS @@ -0,0 +1,2 @@ +alcooper@chromium.org +mfoltz@chromium.org diff --git a/modules/desktop_capture/linux/wayland/pipewire.sigs b/modules/portal/pipewire.sigs similarity index 100% rename from modules/desktop_capture/linux/wayland/pipewire.sigs rename to modules/portal/pipewire.sigs diff --git a/modules/desktop_capture/linux/wayland/pipewire_stub_header.fragment b/modules/portal/pipewire_stub_header.fragment similarity index 100% rename from modules/desktop_capture/linux/wayland/pipewire_stub_header.fragment rename to modules/portal/pipewire_stub_header.fragment diff --git a/modules/desktop_capture/linux/wayland/pipewire_utils.cc b/modules/portal/pipewire_utils.cc similarity index 68% rename from modules/desktop_capture/linux/wayland/pipewire_utils.cc rename to modules/portal/pipewire_utils.cc index 878e459681..fd96b4a4db 100644 --- a/modules/desktop_capture/linux/wayland/pipewire_utils.cc +++ b/modules/portal/pipewire_utils.cc @@ -8,12 +8,14 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/desktop_capture/linux/wayland/pipewire_utils.h" +#include "modules/portal/pipewire_utils.h" + +#include #include "rtc_base/sanitizer.h" #if defined(WEBRTC_DLOPEN_PIPEWIRE) -#include "modules/desktop_capture/linux/wayland/pipewire_stubs.h" +#include "modules/portal/pipewire_stubs.h" #endif // defined(WEBRTC_DLOPEN_PIPEWIRE) namespace webrtc { @@ -23,10 +25,10 @@ bool InitializePipeWire() { #if defined(WEBRTC_DLOPEN_PIPEWIRE) static constexpr char kPipeWireLib[] = "libpipewire-0.3.so.0"; - using modules_desktop_capture_linux_wayland::InitializeStubs; - using modules_desktop_capture_linux_wayland::kModulePipewire; + using modules_portal::InitializeStubs; + using modules_portal::kModulePipewire; - modules_desktop_capture_linux_wayland::StubPathMap paths; + modules_portal::StubPathMap paths; // Check if the PipeWire library is available. paths[kModulePipewire].push_back(kPipeWireLib); @@ -39,4 +41,13 @@ bool InitializePipeWire() { #endif // defined(WEBRTC_DLOPEN_PIPEWIRE) } +PipeWireThreadLoopLock::PipeWireThreadLoopLock(pw_thread_loop* loop) + : loop_(loop) { + pw_thread_loop_lock(loop_); +} + +PipeWireThreadLoopLock::~PipeWireThreadLoopLock() { + pw_thread_loop_unlock(loop_); +} + } // namespace webrtc diff --git a/modules/desktop_capture/linux/wayland/pipewire_utils.h b/modules/portal/pipewire_utils.h similarity index 65% rename from modules/desktop_capture/linux/wayland/pipewire_utils.h rename to modules/portal/pipewire_utils.h index b785d395bd..0f5ccf3292 100644 --- a/modules/desktop_capture/linux/wayland/pipewire_utils.h +++ b/modules/portal/pipewire_utils.h @@ -8,8 +8,10 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_PIPEWIRE_UTILS_H_ -#define MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_PIPEWIRE_UTILS_H_ +#ifndef MODULES_PORTAL_PIPEWIRE_UTILS_H_ +#define MODULES_PORTAL_PIPEWIRE_UTILS_H_ + +struct pw_thread_loop; namespace webrtc { @@ -18,6 +20,16 @@ namespace webrtc { // running nor does it establish a connection to one. bool InitializePipeWire(); +// Locks pw_thread_loop in the current scope +class PipeWireThreadLoopLock { + public: + explicit PipeWireThreadLoopLock(pw_thread_loop* loop); + ~PipeWireThreadLoopLock(); + + private: + pw_thread_loop* const loop_; +}; + } // namespace webrtc -#endif // MODULES_DESKTOP_CAPTURE_LINUX_WAYLAND_PIPEWIRE_UTILS_H_ +#endif // MODULES_PORTAL_PIPEWIRE_UTILS_H_ diff --git a/modules/portal/portal_request_response.h b/modules/portal/portal_request_response.h new file mode 100644 index 0000000000..5fac4eb137 --- /dev/null +++ b/modules/portal/portal_request_response.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 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_PORTAL_PORTAL_REQUEST_RESPONSE_H_ +#define MODULES_PORTAL_PORTAL_REQUEST_RESPONSE_H_ + +namespace webrtc { +namespace xdg_portal { + +// Contains type of responses that can be observed when making a request to +// a desktop portal interface. +enum class RequestResponse { + // Unknown, the initialized status. + kUnknown, + // Success, the request is carried out. + kSuccess, + // The user cancelled the interaction. + kUserCancelled, + // The user interaction was ended in some other way. + kError, + + kMaxValue = kError, +}; + +} // namespace xdg_portal +} // namespace webrtc +#endif // MODULES_PORTAL_PORTAL_REQUEST_RESPONSE_H_ diff --git a/modules/desktop_capture/linux/wayland/scoped_glib.cc b/modules/portal/scoped_glib.cc similarity index 94% rename from modules/desktop_capture/linux/wayland/scoped_glib.cc rename to modules/portal/scoped_glib.cc index 0d9a87d7fd..cb4c80526e 100644 --- a/modules/desktop_capture/linux/wayland/scoped_glib.cc +++ b/modules/portal/scoped_glib.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/desktop_capture/linux/wayland/scoped_glib.h" +#include "modules/portal/scoped_glib.h" namespace webrtc { diff --git a/modules/portal/scoped_glib.h b/modules/portal/scoped_glib.h new file mode 100644 index 0000000000..b2aaa2eb3a --- /dev/null +++ b/modules/portal/scoped_glib.h @@ -0,0 +1,65 @@ +/* + * 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_PORTAL_SCOPED_GLIB_H_ +#define MODULES_PORTAL_SCOPED_GLIB_H_ + +#include + +#include "rtc_base/checks.h" + +namespace webrtc { + +template +class Scoped { + public: + Scoped() {} + explicit Scoped(T* val) { ptr_ = val; } + ~Scoped() { RTC_DCHECK_NOTREACHED(); } + + T* operator->() const { return ptr_; } + + explicit operator bool() const { return ptr_ != nullptr; } + + bool operator!() const { return ptr_ == nullptr; } + + T* get() const { return ptr_; } + + T** receive() { + RTC_CHECK(!ptr_); + return &ptr_; + } + + Scoped& operator=(T* val) { + RTC_DCHECK(val); + ptr_ = val; + return *this; + } + + protected: + T* ptr_ = nullptr; +}; + +template <> +Scoped::~Scoped(); +template <> +Scoped::~Scoped(); +template <> +Scoped::~Scoped(); +template <> +Scoped::~Scoped(); +template <> +Scoped::~Scoped(); +template <> +Scoped::~Scoped(); + +} // namespace webrtc + +#endif // MODULES_PORTAL_SCOPED_GLIB_H_ diff --git a/modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.cc b/modules/portal/xdg_desktop_portal_utils.cc similarity index 98% rename from modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.cc rename to modules/portal/xdg_desktop_portal_utils.cc index 75dbf2bdf3..271e084463 100644 --- a/modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.cc +++ b/modules/portal/xdg_desktop_portal_utils.cc @@ -7,12 +7,12 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.h" +#include "modules/portal/xdg_desktop_portal_utils.h" #include #include "absl/strings/string_view.h" -#include "modules/desktop_capture/linux/wayland/scoped_glib.h" +#include "modules/portal/scoped_glib.h" #include "rtc_base/logging.h" namespace webrtc { diff --git a/modules/portal/xdg_desktop_portal_utils.h b/modules/portal/xdg_desktop_portal_utils.h new file mode 100644 index 0000000000..8571c64a28 --- /dev/null +++ b/modules/portal/xdg_desktop_portal_utils.h @@ -0,0 +1,111 @@ +/* + * 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_PORTAL_XDG_DESKTOP_PORTAL_UTILS_H_ +#define MODULES_PORTAL_XDG_DESKTOP_PORTAL_UTILS_H_ + +#include +#include + +#include +#include + +#include "absl/strings/string_view.h" +#include "modules/portal/portal_request_response.h" +#include "modules/portal/scoped_glib.h" +#include "modules/portal/xdg_session_details.h" +#include "rtc_base/checks.h" +#include "rtc_base/logging.h" + +namespace webrtc { +namespace xdg_portal { + +constexpr char kDesktopBusName[] = "org.freedesktop.portal.Desktop"; +constexpr char kDesktopObjectPath[] = "/org/freedesktop/portal/desktop"; +constexpr char kDesktopRequestObjectPath[] = + "/org/freedesktop/portal/desktop/request"; +constexpr char kSessionInterfaceName[] = "org.freedesktop.portal.Session"; +constexpr char kRequestInterfaceName[] = "org.freedesktop.portal.Request"; +constexpr char kScreenCastInterfaceName[] = "org.freedesktop.portal.ScreenCast"; + +using ProxyRequestCallback = void (*)(GObject*, GAsyncResult*, gpointer); +using SessionRequestCallback = void (*)(GDBusProxy*, GAsyncResult*, gpointer); +using SessionRequestResponseSignalHandler = void (*)(GDBusConnection*, + const char*, + const char*, + const char*, + const char*, + GVariant*, + gpointer); +using StartRequestResponseSignalHandler = void (*)(GDBusConnection*, + const char*, + const char*, + const char*, + const char*, + GVariant*, + gpointer); +using SessionStartRequestedHandler = void (*)(GDBusProxy*, + GAsyncResult*, + gpointer); + +std::string RequestResponseToString(RequestResponse request); + +RequestResponse RequestResponseFromPortalResponse(uint32_t portal_response); + +// Returns a string path for signal handle based on the provided connection and +// token. +std::string PrepareSignalHandle(absl::string_view token, + GDBusConnection* connection); + +// Sets up the callback to execute when a response signal is received for the +// given object. +uint32_t SetupRequestResponseSignal(absl::string_view object_path, + const GDBusSignalCallback callback, + gpointer user_data, + GDBusConnection* connection); + +void RequestSessionProxy(absl::string_view interface_name, + const ProxyRequestCallback proxy_request_callback, + GCancellable* cancellable, + gpointer user_data); + +void SetupSessionRequestHandlers( + absl::string_view portal_prefix, + const SessionRequestCallback session_request_callback, + const SessionRequestResponseSignalHandler request_response_signale_handler, + GDBusConnection* connection, + GDBusProxy* proxy, + GCancellable* cancellable, + std::string& portal_handle, + guint& session_request_signal_id, + gpointer user_data); + +void StartSessionRequest( + absl::string_view prefix, + absl::string_view session_handle, + const StartRequestResponseSignalHandler signal_handler, + const SessionStartRequestedHandler session_started_handler, + GDBusProxy* proxy, + GDBusConnection* connection, + GCancellable* cancellable, + guint& start_request_signal_id, + std::string& start_handle, + gpointer user_data); + +// Tears down the portal session and cleans up related objects. +void TearDownSession(absl::string_view session_handle, + GDBusProxy* proxy, + GCancellable* cancellable, + GDBusConnection* connection); + +} // namespace xdg_portal +} // namespace webrtc + +#endif // MODULES_PORTAL_XDG_DESKTOP_PORTAL_UTILS_H_ diff --git a/modules/portal/xdg_session_details.h b/modules/portal/xdg_session_details.h new file mode 100644 index 0000000000..ab52508c2f --- /dev/null +++ b/modules/portal/xdg_session_details.h @@ -0,0 +1,33 @@ +/* + * 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_PORTAL_XDG_SESSION_DETAILS_H_ +#define MODULES_PORTAL_XDG_SESSION_DETAILS_H_ + +#include + +#include + +namespace webrtc { +namespace xdg_portal { + +// Details of the session associated with XDG desktop portal session. Portal API +// calls can be invoked by utilizing the information here. +struct SessionDetails { + GDBusProxy* proxy = nullptr; + GCancellable* cancellable = nullptr; + std::string session_handle; + uint32_t pipewire_stream_node_id = 0; +}; + +} // namespace xdg_portal +} // namespace webrtc + +#endif // MODULES_PORTAL_XDG_SESSION_DETAILS_H_