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.
This commit is contained in:
Athul Iddya 2023-10-12 04:17:27 -07:00 committed by GitHub
parent 7ab2a82166
commit 3c31246343
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 0 deletions

View file

@ -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

View file

@ -0,0 +1,73 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jan Grulich <grulja@gmail.com>
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 <grulja@gmail.com>
Reviewed-by: Alexander Cooper <alcooper@chromium.org>
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<uint>(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();