From 3c31246343b3b4e9457d4672eebe46d64c673d0a Mon Sep 17 00:00:00 2001 From: Athul Iddya Date: Thu, 12 Oct 2023 04:17:27 -0700 Subject: [PATCH] fix: store portal restore token under the right source ID (#40098) XDG Desktop Portal provides restore tokens to restore a previously selected PipeWire stream instead of prompting the user again. This restore token is single use only and it has to be replaced when the stream is completed/stopped. BaseCapturerPipewire maintains two source IDs: one is initialized by the constructor for new sources (source_id_) and another is for capturing previously selected sources (selected_source_id_). The restore token was always being stored under `source_id_`, even if the capture was ongoing for `selected_source_id_`. This prevents a stream from being restored more than once. Fix that by storing the restore token under the selected source ID if it exists. --- patches/webrtc/.patches | 1 + ..._tokens_re-usable_more_than_one_time.patch | 73 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 patches/webrtc/pipewire_capturer_make_restore_tokens_re-usable_more_than_one_time.patch diff --git a/patches/webrtc/.patches b/patches/webrtc/.patches index 63f7e05ecd6b..f6b71af744db 100644 --- a/patches/webrtc/.patches +++ b/patches/webrtc/.patches @@ -1,3 +1,4 @@ fix_fallback_to_x11_capturer_on_wayland.patch fix_mark_pipewire_capturer_as_failed_after_session_is_closed.patch fix_check_pipewire_init_before_creating_generic_capturer.patch +pipewire_capturer_make_restore_tokens_re-usable_more_than_one_time.patch diff --git a/patches/webrtc/pipewire_capturer_make_restore_tokens_re-usable_more_than_one_time.patch b/patches/webrtc/pipewire_capturer_make_restore_tokens_re-usable_more_than_one_time.patch new file mode 100644 index 000000000000..9efbb686287b --- /dev/null +++ b/patches/webrtc/pipewire_capturer_make_restore_tokens_re-usable_more_than_one_time.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jan Grulich +Date: Mon, 9 Oct 2023 18:54:31 +0200 +Subject: PipeWire capturer: make restore tokens re-usable more than one time + +Do not automatically remove all tokens once we attempt to use them. This +mitigates an issue with Google Meet where an additional instance of a +DesktopCapturer is created and destroyed right away, taking away the +token we would use otherwise. Also save the token under same SourceId +once we get a new (but could be same) token from the restored session. + +Bug: webrtc:15544 +Change-Id: I565b22f5bf6a4d8a3b7d6d757f9c1046c7a0557d +Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/322621 +Commit-Queue: Jan Grulich +Reviewed-by: Alexander Cooper +Cr-Commit-Position: refs/heads/main@{#40892} + +diff --git a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc +index 5a67c18c1d1f62aa5e3162d9778ca665bac4a1bb..a5df76b0cdecd1e2e68f2f25c80c6b17de8bc808 100644 +--- a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc ++++ b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc +@@ -82,8 +82,10 @@ void BaseCapturerPipeWire::OnScreenCastRequestResult(RequestResponse result, + << static_cast(result); + } else if (ScreenCastPortal* screencast_portal = GetScreenCastPortal()) { + if (!screencast_portal->RestoreToken().empty()) { ++ const SourceId token_id = ++ selected_source_id_ ? selected_source_id_ : source_id_; + RestoreTokenManager::GetInstance().AddToken( +- source_id_, screencast_portal->RestoreToken()); ++ token_id, screencast_portal->RestoreToken()); + } + } + +@@ -138,7 +140,7 @@ void BaseCapturerPipeWire::Start(Callback* callback) { + ScreenCastPortal::PersistMode::kTransient); + if (selected_source_id_) { + screencast_portal->SetRestoreToken( +- RestoreTokenManager::GetInstance().TakeToken(selected_source_id_)); ++ RestoreTokenManager::GetInstance().GetToken(selected_source_id_)); + } + } + +diff --git a/modules/desktop_capture/linux/wayland/restore_token_manager.cc b/modules/desktop_capture/linux/wayland/restore_token_manager.cc +index 5ca9b957a9e4f436bc09d4bc16019b169ae9ba9f..a17d9a49bb031efa340bfd61b4a6f8f5a86d09da 100644 +--- a/modules/desktop_capture/linux/wayland/restore_token_manager.cc ++++ b/modules/desktop_capture/linux/wayland/restore_token_manager.cc +@@ -23,10 +23,8 @@ void RestoreTokenManager::AddToken(DesktopCapturer::SourceId id, + restore_tokens_.insert({id, token}); + } + +-std::string RestoreTokenManager::TakeToken(DesktopCapturer::SourceId id) { +- std::string token = restore_tokens_[id]; +- // Remove the token as it cannot be used anymore +- restore_tokens_.erase(id); ++std::string RestoreTokenManager::GetToken(DesktopCapturer::SourceId id) { ++ const std::string token = restore_tokens_[id]; + return token; + } + +diff --git a/modules/desktop_capture/linux/wayland/restore_token_manager.h b/modules/desktop_capture/linux/wayland/restore_token_manager.h +index 174bef121f74b7b2b529d681b86c4fb4218586ea..ad4f74790f2a5cfba304fc11d47c9924db9013d8 100644 +--- a/modules/desktop_capture/linux/wayland/restore_token_manager.h ++++ b/modules/desktop_capture/linux/wayland/restore_token_manager.h +@@ -27,7 +27,7 @@ class RestoreTokenManager { + static RestoreTokenManager& GetInstance(); + + void AddToken(DesktopCapturer::SourceId id, const std::string& token); +- std::string TakeToken(DesktopCapturer::SourceId id); ++ std::string GetToken(DesktopCapturer::SourceId id); + + // Returns a source ID which does not have any token associated with it yet. + DesktopCapturer::SourceId GetUnusedId();