Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use StartUpdating method for PipeWire capturer #38833

Merged
merged 2 commits into from
Jul 11, 2023

Conversation

aiddya
Copy link
Contributor

@aiddya aiddya commented Jun 18, 2023

Description of Change

Fixed a crash related to PipeWire capturer by adapting to Chromium's interface changes. Chromium expects a call to
NativeDesktopMediaList::StartUpdating with an implementation of DesktopMediaListObserver for delegated capturers like PipeWire. This interface allows listening to user permission events and listing sources only after the user has made a choice on the permission dialog.

The interface has been implemented by an inner class to allow listening to screen and window capture permissions concurrently using two instances of the class. A patch that was resetting the capturer on the first refresh has been changed to exclude PipeWire. PipeWire capturer object will follow the lifecycle of NativeDesktopMediaList, as is the case in Chromium.

Fixes #37463

Checklist

Release Notes

Notes: Fixed a crash when listing desktop capture sources on Wayland with PipeWire.

@aiddya aiddya requested a review from a team as a code owner June 18, 2023 21:30
@welcome
Copy link

welcome bot commented Jun 18, 2023

💖 Thanks for opening this pull request! 💖

We use semantic commit messages to streamline the release process. Before your pull request can be merged, you should update your pull request title to start with a semantic prefix.

Examples of commit messages with semantic prefixes:

  • fix: don't overwrite prevent_default if default wasn't prevented
  • feat: add app.isPackaged() method
  • docs: app.isDefaultProtocolClient is now available on Linux

Things that will help get your PR across the finish line:

  • Follow the JavaScript, C++, and Python coding style.
  • Run npm run lint locally to catch formatting errors earlier.
  • Document any user-facing changes you've made following the documentation styleguide.
  • Include tests when adding/changing behavior.
  • Include screenshots and animated GIFs whenever possible.

We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can.

@electron-cation electron-cation bot added the new-pr 🌱 PR opened in the last 24 hours label Jun 18, 2023
@aiddya aiddya changed the title fix: use StartUpdating method for PipeWire capturer (#37463) fix: use StartUpdating method for PipeWire capturer Jun 18, 2023
@codebytere codebytere added the semver/patch backwards-compatible bug fixes label Jun 19, 2023
@codebytere codebytere added target/23-x-y PR should also be added to the "23-x-y" branch. target/24-x-y PR should also be added to the "24-x-y" branch. target/25-x-y PR should also be added to the "25-x-y" branch. target/26-x-y PR should also be added to the "26-x-y" branch. labels Jun 19, 2023
@electron-cation electron-cation bot removed the new-pr 🌱 PR opened in the last 24 hours label Jun 19, 2023
@sunknudsen
Copy link

Not the right person to add value to this PR, but can’t wait for issue to be fixed. Thanks for working on this @aiddya!

@byquanton
Copy link

With this PR applied, it crashes somewhere else.

Thread 46 "DesktopMediaLis" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fff518656c0 (LWP 1905627)]
NativeDesktopMediaList::Worker::Refresh (this=0x2e3c0195d380, view_dialog_id=@0x2e3c0299af18: -1, 
    update_thumnails=true) at ../../chrome/browser/media/webrtc/native_desktop_media_list.cc:271

Before:

Thread 43 "DesktopMediaLis" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fff530686c0 (LWP 1911851)]
webrtc::BaseCapturerPipeWire::CaptureFrame (this=<optimized out>) at ../../third_party/webrtc/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc:163

@aiddya
Copy link
Contributor Author

aiddya commented Jun 21, 2023

@byquanton Can you share the following information?

  1. How did you test this patch? Can you share the electron code as a fiddle?
  2. Did you apply this patch on main or a branch?
  3. What OS and OS version did you test this with?
  4. What desktop environment are you using? If it's not GNOME or KDE, what portal implementation are you using?
  5. Did you run electron with any flags?
  6. Did you test this on Wayland?

@byquanton
Copy link

@byquanton Can you share the following information?

1. How did you test this patch? Can you share the electron code as a fiddle?

2. Did you apply this patch on main or a branch?

3. What OS and OS version did you test this with?

4. What desktop environment are you using? If it's not GNOME or KDE, what portal implementation are you using?

5. Did you run electron with any flags?

6. Did you test this on Wayland?
  1. I ran Element with it.
  2. Applied it on main
  3. Fedora 38
  4. GNOME (xdg-desktop-portal-gnome)
  5. Without any Flags
  6. Wayland

@aiddya
Copy link
Contributor Author

aiddya commented Jun 21, 2023

@byquanton I have no idea what Element is doing and its code base is too large to debug.

However, the crash message that you're seeing is expected if you don't apply the updated desktop_media_list.patch. Did you run gclient sync -f to reapply the Chomium patches after you applied my patch? Can you verify that chrome/browser/media/webrtc/native_desktop_media_list.cc reflects the changes made in this PR?

@aiddya
Copy link
Contributor Author

aiddya commented Jun 23, 2023

I pushed a commit to fix thumbnail generation. I've validated the fixes using a more extensive test case that lists sources, displays thumbnails and initiates a stream using the source ID: https://gist.github.com/aiddya/d368bc2cb7f72a9b030b918ee1332299

@byquanton
Copy link

@byquanton I have no idea what Element is doing and its code base is too large to debug.

However, the crash message that you're seeing is expected if you don't apply the updated desktop_media_list.patch. Did you run gclient sync -f to reapply the Chomium patches after you applied my patch? Can you verify that chrome/browser/media/webrtc/native_desktop_media_list.cc reflects the changes made in this PR?

Rebuild it again, and now it works.

@sunknudsen
Copy link

Hey @ckerr and @VerteDinde, has one of you had a chance to look into this PR?

Screen sharing is currently broken when using Linux/Wayland on Element, Jitsi and Signal which is affecting thousands is not millions of users.

Sending love to the universe… looking forward to a fix. 🙏

@theofficialgman
Copy link

This also affects https://github.com/SpacingBat3/WebCord with 35K installs from pi-apps alone with thousands more from other avenues. I agree this is likely affecting millions of users/application installs.

@ToasterUwU
Copy link

This also affects Armcord and Vencord Desktop. Which are both Linux focused Discord Clients.

@VerteDinde
Copy link
Member

VerteDinde commented Jul 3, 2023

@aiddya Thanks for the PR! Sorry, I was out of the office when you submitted the PR originally, I'll take a look at it this week 🙇‍♀️

Copy link
Member

@codebytere codebytere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this!

patches/chromium/desktop_media_list.patch Show resolved Hide resolved
have_selection_ = false;

// PipeWire returns a single source, so index is not relevant.
std::move(this->update_callback_).Run();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new logic applies cross-platform, though - is there a situation where we'd need this index?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not unless Chromium makes significant changes/refactors. PipeWire is the only delegated capturer right now. As a result, this code path will not be executed on other platforms.

Secondly, according to Chromium documentation, delegated capturers manage their own UI for source selection and will return a single source. This logic should hold even if there's a new delegated capturer in the future.

shell/browser/api/electron_api_desktop_capturer.cc Outdated Show resolved Hide resolved
shell/browser/api/electron_api_desktop_capturer.cc Outdated Show resolved Hide resolved
shell/browser/api/electron_api_desktop_capturer.cc Outdated Show resolved Hide resolved
shell/browser/api/electron_api_desktop_capturer.cc Outdated Show resolved Hide resolved
shell/browser/api/electron_api_desktop_capturer.cc Outdated Show resolved Hide resolved
Fixed a crash related to PipeWire capturer by adapting to Chromium's
interface changes. Chromium expects a call to
`NativeDesktopMediaList::StartUpdating` with an implementation of
`DesktopMediaListObserver` for delegated capturers like PipeWire. This
interface allows listening to user permission events and listing
sources only after the user has made a choice on the permission dialog.

The interface has been implemented by an inner class to allow listening
to screen and window capture permissions concurrently using two
instances of the class. A patch that was resetting the capturer on the
first refresh has been changed to exclude PipeWire. PipeWire capturer
object will follow the lifecycle of `NativeDesktopMediaList`, as is the
case in Chromium.

Fixes electron#37463
The PipeWire stream starts after the dialog is dismissed. If the sources
are listed immediately afterwards, the thumbnail may not have been
generated by that time. Explicitly wait for both thumbnail generation
and a selection on the source dialog before listing sources.
@trop trop bot added merged/24-x-y PR was merged to the "24-x-y" branch merged/25-x-y PR was merged to the "25-x-y" branch. merged/26-x-y PR was merged to the "26-x-y" branch. and removed in-flight/24-x-y in-flight/25-x-y in-flight/26-x-y labels Jul 11, 2023
@sunknudsen
Copy link

sunknudsen commented Jul 15, 2023

Hey!

Are others experiencing following issues on Ubuntu 22.04.1 LTS (or equivalent) and Electron 25.3.0 (which implements this PR)?

First, calling desktopCapturer.getSources triggers screen share prompt asking user to allow specific window (wasn’t the case before… screen share prompt was only triggered by navigator.mediaDevices.getUserMedia… that said, window names and thumbnails were not displayed which likely explains why prompt was not required).

const sources = await desktopCapturer.getSources({
  types: ["window"],
})

Then, calling navigator.mediaDevices.getUserMedia using following constraints triggers screen share prompt (again).

const constraints = {
    audio: false,
    video: {
      mandatory: {
        chromeMediaSource: "desktop",
        chromeMediaSourceId: sourceId, // Source ID from `sources`
        maxFrameRate: 24,
      },
    },
  }
}

await navigator.mediaDevices.getUserMedia(constraints)

This is pretty bad for user experience… and wasn’t the case on previous “working” versions of Electron (running on Ubuntu 22.04.1 LTS).

Second, when window is selected, moving app window causes app to crash with following error.

Dropping DMA-BUF modifier: 72057594037927935 and trying to renegotiate stream parameters
Segmentation fault (core dumped)

Third (niche use case), implementation is completely broken on Tails 5.15.1.

Puzzled…

@ToasterUwU
Copy link

@sunknudsen i think you are talking about the same thing that was mentioned in this very same PR earlier. There already is the Issue #39043 for resolving this bad experience stuff.

@sunknudsen
Copy link

@ToasterUwU Did you experience segmentation fault during testing?

@ToasterUwU
Copy link

@sunknudsen I have only tried it once for testing if it fixed the screenshare issue on a Discord Client, have not checked if it actually spits any errors while running. You can see the entire 40 second video i recorded of me trying it in Vencord/Vesktop#40, just so you know what exactly i did. It worked for me, even tho it was tedious to use. So if there was an error, it wasnt a fatal one (like Segmentation Fault typically is).

Im on PikaOS 23.04, which is Ubuntu based.

@aiddya aiddya deleted the pipewire-crash-fix branch July 15, 2023 15:47
@aiddya
Copy link
Contributor Author

aiddya commented Jul 15, 2023

@sunknudsen You should not see the second popup if the portal implementation you're using supports screencast restoration. That's supported by xdg-desktop-portal 1.12 and xdg-desktop-portal-gnome 42.

I tested moving and resizing the shared window with Electron 25.3.0, but I haven't seen any crash on Fedora 38. Do you see any of these issues on Chrome/Chromium? You can test using Mozilla's gUM example page.

@trop
Copy link
Contributor

trop bot commented Jul 16, 2023

@aiddya has manually backported this PR to "23-x-y", please check out #39116

@trop
Copy link
Contributor

trop bot commented Jul 16, 2023

@aiddya has manually backported this PR to "22-x-y", please check out #39117

@sunknudsen
Copy link

Hey @aiddya and @VerteDinde, thanks for helping out… please see #39131. Ideas?

@trop trop bot added merged/23-x-y PR was merged to the "23-x-y" branch. and removed in-flight/23-x-y labels Jul 24, 2023
MrHuangJser pushed a commit to MrHuangJser/electron that referenced this pull request Dec 11, 2023
* fix: use StartUpdating method for PipeWire capturer

Fixed a crash related to PipeWire capturer by adapting to Chromium's
interface changes. Chromium expects a call to
`NativeDesktopMediaList::StartUpdating` with an implementation of
`DesktopMediaListObserver` for delegated capturers like PipeWire. This
interface allows listening to user permission events and listing
sources only after the user has made a choice on the permission dialog.

The interface has been implemented by an inner class to allow listening
to screen and window capture permissions concurrently using two
instances of the class. A patch that was resetting the capturer on the
first refresh has been changed to exclude PipeWire. PipeWire capturer
object will follow the lifecycle of `NativeDesktopMediaList`, as is the
case in Chromium.

Fixes electron#37463

* fix: wait for thumbnails from PipeWire when necessary

The PipeWire stream starts after the dialog is dismissed. If the sources
are listed immediately afterwards, the thumbnail may not have been
generated by that time. Explicitly wait for both thumbnail generation
and a selection on the source dialog before listing sources.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged/23-x-y PR was merged to the "23-x-y" branch. merged/24-x-y PR was merged to the "24-x-y" branch merged/25-x-y PR was merged to the "25-x-y" branch. merged/26-x-y PR was merged to the "26-x-y" branch. semver/patch backwards-compatible bug fixes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: DesktopCapturer doesn't work in Ubuntu 22.04.2 LTS
8 participants