diff options
Diffstat (limited to 'third_party/libwebrtc/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc')
-rw-r--r-- | third_party/libwebrtc/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc new file mode 100644 index 0000000000..1c7cc379df --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc @@ -0,0 +1,127 @@ +/* + * 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. + */ +#include "modules/desktop_capture/linux/wayland/screen_capture_portal_interface.h" + +#include <string> + +#include "modules/portal/xdg_desktop_portal_utils.h" +#include "rtc_base/logging.h" + +namespace webrtc { +namespace xdg_portal { + +void ScreenCapturePortalInterface::RequestSessionUsingProxy( + GAsyncResult* result) { + Scoped<GError> error; + GDBusProxy* proxy = g_dbus_proxy_new_finish(result, error.receive()); + if (!proxy) { + // Ignore the error caused by user cancelling the request via `cancellable_` + if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + RTC_LOG(LS_ERROR) << "Failed to get a proxy for the portal: " + << error->message; + OnPortalDone(RequestResponse::kError); + return; + } + + RTC_LOG(LS_INFO) << "Successfully created proxy for the portal."; + RequestSession(proxy); +} + +void ScreenCapturePortalInterface::OnSessionRequestResult( + GDBusProxy* proxy, + GAsyncResult* result) { + Scoped<GError> error; + Scoped<GVariant> variant( + g_dbus_proxy_call_finish(proxy, result, error.receive())); + if (!variant) { + // Ignore the error caused by user cancelling the request via `cancellable_` + if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + RTC_LOG(LS_ERROR) << "Failed to request session: " << error->message; + OnPortalDone(RequestResponse::kError); + return; + } + + RTC_LOG(LS_INFO) << "Initializing the session."; + + Scoped<char> handle; + g_variant_get_child(variant.get(), /*index=*/0, /*format_string=*/"o", + &handle); + if (!handle) { + RTC_LOG(LS_ERROR) << "Failed to initialize the session."; + OnPortalDone(RequestResponse::kError); + return; + } +} + +void ScreenCapturePortalInterface::RegisterSessionClosedSignalHandler( + const SessionClosedSignalHandler session_close_signal_handler, + GVariant* parameters, + GDBusConnection* connection, + std::string& session_handle, + guint& session_closed_signal_id) { + uint32_t portal_response = 2; + Scoped<GVariant> response_data; + g_variant_get(parameters, /*format_string=*/"(u@a{sv})", &portal_response, + response_data.receive()); + + if (RequestResponseFromPortalResponse(portal_response) != + RequestResponse::kSuccess) { + RTC_LOG(LS_ERROR) << "Failed to request the session subscription."; + OnPortalDone(RequestResponse::kError); + return; + } + + Scoped<GVariant> g_session_handle( + g_variant_lookup_value(response_data.get(), /*key=*/"session_handle", + /*expected_type=*/nullptr)); + session_handle = g_variant_get_string( + /*value=*/g_session_handle.get(), /*length=*/nullptr); + + if (session_handle.empty()) { + RTC_LOG(LS_ERROR) << "Could not get session handle despite valid response"; + OnPortalDone(RequestResponse::kError); + return; + } + + session_closed_signal_id = g_dbus_connection_signal_subscribe( + connection, kDesktopBusName, kSessionInterfaceName, /*member=*/"Closed", + session_handle.c_str(), /*arg0=*/nullptr, G_DBUS_SIGNAL_FLAGS_NONE, + session_close_signal_handler, this, /*user_data_free_func=*/nullptr); +} + +void ScreenCapturePortalInterface::OnStartRequestResult(GDBusProxy* proxy, + GAsyncResult* result) { + Scoped<GError> error; + Scoped<GVariant> variant( + g_dbus_proxy_call_finish(proxy, result, error.receive())); + if (!variant) { + if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + RTC_LOG(LS_ERROR) << "Failed to start the portal session: " + << error->message; + OnPortalDone(RequestResponse::kError); + return; + } + + Scoped<char> handle; + g_variant_get_child(variant.get(), 0, "o", handle.receive()); + if (!handle) { + RTC_LOG(LS_ERROR) << "Failed to initialize the start portal session."; + OnPortalDone(RequestResponse::kError); + return; + } + + RTC_LOG(LS_INFO) << "Subscribed to the start signal."; +} + +} // namespace xdg_portal +} // namespace webrtc |