Revert "Add plumbing to control PipeWire picker visibility"

This reverts commit fbea8c519684577a38cb35b9287ba4645a905094.

Reason for revert: Breaks WebRTC import into Chromium, e.g:
https://chromium-review.googlesource.com/c/chromium/src/+/3863998/

Original change's description:
> Add plumbing to control PipeWire picker visibility
>
> Introduces the notion of a "delegated source list" and corresponding
> controller. This is used by desktop capturers (currently just the
> PipeWire capturer), who control selecting the source through their own
> (often system-level) UI, rather than returning a source list with all
> available options that can then be selected by the embedder.
>
> Adds a method to get the controller which serves to also tell embedders
> if the capturer makes use of a delegated source list. The controller
> currently allows the embedder to request that the delegated source list
> be shown or hidden, and will in the future be used to expose events
> from the source list (e.g. selection, dismissal, error).
>
> Bug: chromium:1351572
> Change-Id: Ie1d36ed654013f59b8d9095deef01a4705fd5bde
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/272621
> Reviewed-by: Mark Foltz <mfoltz@chromium.org>
> Commit-Queue: Alexander Cooper <alcooper@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#37956}

Bug: chromium:1351572
Change-Id: I06f76ab9c8bc1aa303dae177d48698951fdc5ecd
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/273703
Auto-Submit: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Henrik Andreassson <henrika@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37964}
This commit is contained in:
Henrik Boström
2022-08-31 09:08:21 +00:00
committed by WebRTC LUCI CQ
parent d6c7ee734b
commit 0098a441e3
10 changed files with 25 additions and 156 deletions

View File

@ -29,11 +29,6 @@ namespace webrtc {
DesktopCapturer::~DesktopCapturer() = default;
DelegatedSourceListController*
DesktopCapturer::GetDelegatedSourceListController() {
return nullptr;
}
void DesktopCapturer::SetSharedMemoryFactory(
std::unique_ptr<SharedMemoryFactory> shared_memory_factory) {}

View File

@ -32,31 +32,6 @@ namespace webrtc {
class DesktopCaptureOptions;
class DesktopFrame;
// A controller to be implemented and returned by
// GetDelegatedSourceListController in capturers that require showing their own
// source list and managing user selection there. Apart from ensuring the
// visibility of the source list, these capturers should largely be interacted
// with the same as a normal capturer, though there may be some caveats for
// some DesktopCapturer methods. See GetDelegatedSourceListController for more
// information.
class RTC_EXPORT DelegatedSourceListController {
public:
// Used to prompt the capturer to show the delegated source list. If the
// source list is already visible, this will be a no-op. Must be called after
// starting the DesktopCapturer.
//
// Note that any selection from a previous invocation of the source list may
// be cleared when this method is called.
virtual void EnsureVisible() = 0;
// Used to prompt the capturer to hide the delegated source list. If the
// source list is already hidden, this will be a no-op.
virtual void EnsureHidden() = 0;
protected:
virtual ~DelegatedSourceListController() {}
};
// Abstract interface for screen and window capturers.
class RTC_EXPORT DesktopCapturer {
public:
@ -113,18 +88,6 @@ class RTC_EXPORT DesktopCapturer {
// valid until capturer is destroyed.
virtual void Start(Callback* callback) = 0;
// Returns a valid pointer if the capturer requires the user to make a
// selection from a source list provided by the capturer.
// Returns nullptr if the capturer does not provide a UI for the user to make
// a selection.
//
// Callers should not take ownership of the returned pointer, but it is
// guaranteed to be valid as long as the desktop_capturer is valid.
// Note that consumers should still use GetSourceList and SelectSource, but
// their behavior may be modified if this returns a value. See those methods
// for a more in-depth discussion of those potential modifications.
virtual DelegatedSourceListController* GetDelegatedSourceListController();
// Sets SharedMemoryFactory that will be used to create buffers for the
// captured frames. The factory can be invoked on a thread other than the one
// where CaptureFrame() is called. It will be destroyed on the same thread.
@ -153,19 +116,10 @@ class RTC_EXPORT DesktopCapturer {
// should return monitors.
// For DesktopCapturer implementations to capture windows, this function
// should only return root windows owned by applications.
//
// Note that capturers who use a delegated source list will return a
// SourceList with exactly one value, but it may not be viable for capture
// (e.g. CaptureFrame will return ERROR_TEMPORARY) until a selection has been
// made.
virtual bool GetSourceList(SourceList* sources);
// Selects a source to be captured. Returns false in case of a failure (e.g.
// if there is no source with the specified type and id.)
//
// Note that some capturers with delegated source lists may also support
// selecting a SourceID that is not in the returned source list as a form of
// restore token.
virtual bool SelectSource(SourceId id);
// Brings the selected source to the front and sets the input focus on it.

View File

@ -16,6 +16,8 @@
#include "modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/random.h"
#include "rtc_base/time_utils.h"
namespace webrtc {
@ -42,7 +44,8 @@ BaseCapturerPipeWire::BaseCapturerPipeWire(
: options_(options),
is_screencast_portal_(false),
portal_(std::move(portal)) {
source_id_ = RestoreTokenManager::GetInstance().GetUnusedId();
Random random(rtc::TimeMicros());
source_id_ = static_cast<SourceId>(random.Rand(1, INT_MAX));
}
BaseCapturerPipeWire::~BaseCapturerPipeWire() {}
@ -50,11 +53,6 @@ BaseCapturerPipeWire::~BaseCapturerPipeWire() {}
void BaseCapturerPipeWire::OnScreenCastRequestResult(RequestResponse result,
uint32_t stream_node_id,
int fd) {
is_portal_open_ = false;
// Reset the value of capturer_failed_ in case we succeed below. If we fail,
// then it'll set it to the right value again soon enough.
capturer_failed_ = false;
if (result != RequestResponse::kSuccess ||
!options_.screencast_stream()->StartScreenCastStream(
stream_node_id, fd, options_.get_width(), options_.get_height())) {
@ -97,15 +95,11 @@ void BaseCapturerPipeWire::Start(Callback* callback) {
}
}
is_portal_open_ = true;
portal_->Start();
}
void BaseCapturerPipeWire::CaptureFrame() {
if (capturer_failed_) {
// This could be recoverable if the source list is re-summoned; but for our
// purposes this is fine, since it requires intervention to resolve and
// essentially starts a new capture.
callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
return;
}
@ -143,35 +137,6 @@ bool BaseCapturerPipeWire::SelectSource(SourceId id) {
return true;
}
DelegatedSourceListController*
BaseCapturerPipeWire::GetDelegatedSourceListController() {
return this;
}
void BaseCapturerPipeWire::EnsureVisible() {
RTC_DCHECK(callback_);
if (is_portal_open_)
return;
// Clear any previously selected state/capture
portal_->Cleanup();
options_.screencast_stream()->StopScreenCastStream();
// Get a new source id to reflect that the source has changed.
source_id_ = RestoreTokenManager::GetInstance().GetUnusedId();
is_portal_open_ = true;
portal_->Start();
}
void BaseCapturerPipeWire::EnsureHidden() {
if (!is_portal_open_)
return;
is_portal_open_ = false;
portal_->Cleanup();
}
SessionDetails BaseCapturerPipeWire::GetSessionDetails() {
return portal_->GetSessionDetails();
}

View File

@ -23,7 +23,6 @@
namespace webrtc {
class BaseCapturerPipeWire : public DesktopCapturer,
public DelegatedSourceListController,
public ScreenCastPortal::PortalNotifier {
public:
explicit BaseCapturerPipeWire(const DesktopCaptureOptions& options);
@ -40,11 +39,6 @@ class BaseCapturerPipeWire : public DesktopCapturer,
void CaptureFrame() override;
bool GetSourceList(SourceList* sources) override;
bool SelectSource(SourceId id) override;
DelegatedSourceListController* GetDelegatedSourceListController() override;
// DelegatedSourceListController
void EnsureVisible() override;
void EnsureHidden() override;
// ScreenCastPortal::PortalNotifier interface.
void OnScreenCastRequestResult(xdg_portal::RequestResponse result,
@ -62,7 +56,6 @@ class BaseCapturerPipeWire : public DesktopCapturer,
Callback* callback_ = nullptr;
bool capturer_failed_ = false;
bool is_screencast_portal_ = false;
bool is_portal_open_ = false;
// SourceId that is selected using SelectSource() and that we previously
// returned in GetSourceList(). This should be a SourceId that has a restore

View File

@ -30,8 +30,4 @@ std::string RestoreTokenManager::TakeToken(DesktopCapturer::SourceId id) {
return token;
}
DesktopCapturer::SourceId RestoreTokenManager::GetUnusedId() {
return ++last_source_id_;
}
} // namespace webrtc

View File

@ -29,15 +29,10 @@ class RestoreTokenManager {
void AddToken(DesktopCapturer::SourceId id, const std::string& token);
std::string TakeToken(DesktopCapturer::SourceId id);
// Returns a source ID which does not have any token associated with it yet.
DesktopCapturer::SourceId GetUnusedId();
private:
RestoreTokenManager() = default;
~RestoreTokenManager() = default;
DesktopCapturer::SourceId last_source_id_ = 0;
std::unordered_map<DesktopCapturer::SourceId, std::string> restore_tokens_;
};

View File

@ -42,9 +42,6 @@ class ScreenCapturePortalInterface {
virtual xdg_portal::SessionDetails GetSessionDetails() { return {}; }
// Starts the portal setup.
virtual void Start() {}
virtual void Cleanup() {}
// Notifies observers about the success/fail state of the portal
// request/response.
virtual void OnPortalDone(xdg_portal::RequestResponse result) {}

View File

@ -66,11 +66,9 @@ void ScreenCastPortal::Cleanup() {
session_handle_ = "";
cancellable_ = nullptr;
proxy_ = nullptr;
restore_token_ = "";
if (pw_fd_ != -1) {
close(pw_fd_);
pw_fd_ = -1;
}
}

View File

@ -112,7 +112,7 @@ class ScreenCastPortal : public xdg_portal::ScreenCapturePortalInterface {
// Sends a create session request to the portal.
void RequestSession(GDBusProxy* proxy) override;
void Cleanup() override;
void Cleanup();
// Set of methods leveraged by remote desktop portal to setup a common session
// with screen cast portal.

View File

@ -98,9 +98,6 @@ class SharedScreenCastStreamPrivate {
DesktopVector CaptureCursorPosition();
private:
// Stops the streams and cleans up any in-use elements.
void StopAndCleanupStream();
uint32_t pw_stream_node_id_ = 0;
DesktopSize stream_size_ = {};
@ -366,7 +363,25 @@ void SharedScreenCastStreamPrivate::OnRenegotiateFormat(void* data, uint64_t) {
SharedScreenCastStreamPrivate::SharedScreenCastStreamPrivate() {}
SharedScreenCastStreamPrivate::~SharedScreenCastStreamPrivate() {
StopAndCleanupStream();
if (pw_main_loop_) {
pw_thread_loop_stop(pw_main_loop_);
}
if (pw_stream_) {
pw_stream_destroy(pw_stream_);
}
if (pw_core_) {
pw_core_disconnect(pw_core_);
}
if (pw_context_) {
pw_context_destroy(pw_context_);
}
if (pw_main_loop_) {
pw_thread_loop_destroy(pw_main_loop_);
}
}
RTC_NO_SANITIZE("cfi-icall")
@ -535,54 +550,15 @@ void SharedScreenCastStreamPrivate::UpdateScreenCastStreamResolution(
}
void SharedScreenCastStreamPrivate::StopScreenCastStream() {
StopAndCleanupStream();
}
void SharedScreenCastStreamPrivate::StopAndCleanupStream() {
// We get buffers on the PipeWire thread, but this is called from the capturer
// thread, so we need to wait on and stop the pipewire thread before we
// disconnect the stream so that we can guarantee we aren't in the middle of
// processing a new frame.
// Even if we *do* somehow have the other objects without a pipewire thread,
// destroying them without a thread causes a crash.
if (!pw_main_loop_)
return;
// While we can stop the thread now, we cannot destroy it until we've cleaned
// up the other members.
pw_thread_loop_wait(pw_main_loop_);
pw_thread_loop_stop(pw_main_loop_);
if (pw_stream_) {
pw_stream_disconnect(pw_stream_);
pw_stream_destroy(pw_stream_);
pw_stream_ = nullptr;
{
webrtc::MutexLock lock(&queue_lock_);
queue_.Reset();
}
}
if (pw_core_) {
pw_core_disconnect(pw_core_);
pw_core_ = nullptr;
}
if (pw_context_) {
pw_context_destroy(pw_context_);
pw_context_ = nullptr;
}
pw_thread_loop_destroy(pw_main_loop_);
pw_main_loop_ = nullptr;
}
std::unique_ptr<DesktopFrame> SharedScreenCastStreamPrivate::CaptureFrame() {
webrtc::MutexLock lock(&queue_lock_);
if (!pw_stream_ || !queue_.current_frame()) {
if (!queue_.current_frame()) {
return std::unique_ptr<DesktopFrame>{};
}