From 23cdf65c539bdc291f196690e32a4b7fefe6495b Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Tue, 26 Oct 2021 11:03:59 +1100 Subject: [PATCH] feat: add webContents.getMediaSourceId() method (#31204) * feat: add webContents.getMediaSourceId() method * fix: account for null frame_hosts in webContents.getMediaSourceId() * fix: move webContents.getMediaSourceId definition to be more organised * fix: move webContents.getMediaSourceId implementation * fix: move webContents.getMediaSourceId docs --- docs/api/web-contents.md | 8 +++++ .../browser/api/electron_api_web_contents.cc | 30 +++++++++++++++++++ shell/browser/api/electron_api_web_contents.h | 1 + spec-main/api-web-contents-spec.ts | 8 +++++ 4 files changed, 47 insertions(+) diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 9a9ffa319fca..1371d7083b00 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -1923,6 +1923,14 @@ Setting the WebRTC IP handling policy allows you to control which IPs are exposed via WebRTC. See [BrowserLeaks](https://browserleaks.com/webrtc) for more details. +#### `contents.getMediaSourceId(requestWebContents)` + +* `requestWebContents` WebContents - Web contents that the id will be registered to. + +Returns `String` - The identifier of a WebContents stream. This identifier can be used +with `navigator.mediaDevices.getUserMedia` using a `chromeMediaSource` of `tab`. +The identifier is restricted to the web contents that it is registered to and is only valid for 10 seconds. + #### `contents.getOSProcessId()` Returns `Integer` - The operating system `pid` of the associated renderer diff --git a/shell/browser/api/electron_api_web_contents.cc b/shell/browser/api/electron_api_web_contents.cc index a6ab707e6b63..c2a204816159 100644 --- a/shell/browser/api/electron_api_web_contents.cc +++ b/shell/browser/api/electron_api_web_contents.cc @@ -38,6 +38,8 @@ #include "content/browser/renderer_host/render_widget_host_view_base.h" // nogncheck #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/context_menu_params.h" +#include "content/public/browser/desktop_media_id.h" +#include "content/public/browser/desktop_streams_registry.h" #include "content/public/browser/download_request_utils.h" #include "content/public/browser/favicon_status.h" #include "content/public/browser/file_select_listener.h" @@ -2198,6 +2200,33 @@ void WebContents::SetWebRTCIPHandlingPolicy( web_contents()->SyncRendererPrefs(); } +std::string WebContents::GetMediaSourceID( + content::WebContents* request_web_contents) { + auto* frame_host = web_contents()->GetMainFrame(); + if (!frame_host) + return std::string(); + + content::DesktopMediaID media_id( + content::DesktopMediaID::TYPE_WEB_CONTENTS, + content::DesktopMediaID::kNullId, + content::WebContentsMediaCaptureId(frame_host->GetProcess()->GetID(), + frame_host->GetRoutingID())); + + auto* request_frame_host = request_web_contents->GetMainFrame(); + if (!request_frame_host) + return std::string(); + + std::string id = + content::DesktopStreamsRegistry::GetInstance()->RegisterStream( + request_frame_host->GetProcess()->GetID(), + request_frame_host->GetRoutingID(), + url::Origin::Create( + request_frame_host->GetLastCommittedURL().GetOrigin()), + media_id, "", content::kRegistryStreamTypeTab); + + return id; +} + bool WebContents::IsCrashed() const { return web_contents()->IsCrashed(); } @@ -3875,6 +3904,7 @@ v8::Local WebContents::FillObjectTemplate( .SetMethod("isBeingCaptured", &WebContents::IsBeingCaptured) .SetMethod("setWebRTCIPHandlingPolicy", &WebContents::SetWebRTCIPHandlingPolicy) + .SetMethod("getMediaSourceId", &WebContents::GetMediaSourceID) .SetMethod("getWebRTCIPHandlingPolicy", &WebContents::GetWebRTCIPHandlingPolicy) .SetMethod("takeHeapSnapshot", &WebContents::TakeHeapSnapshot) diff --git a/shell/browser/api/electron_api_web_contents.h b/shell/browser/api/electron_api_web_contents.h index ac1bbb49b86d..f91cc2737d11 100644 --- a/shell/browser/api/electron_api_web_contents.h +++ b/shell/browser/api/electron_api_web_contents.h @@ -185,6 +185,7 @@ class WebContents : public gin::Wrappable, int GetHistoryLength() const; const std::string GetWebRTCIPHandlingPolicy() const; void SetWebRTCIPHandlingPolicy(const std::string& webrtc_ip_handling_policy); + std::string GetMediaSourceID(content::WebContents* request_web_contents); bool IsCrashed() const; void ForcefullyCrashRenderer(); void SetUserAgent(const std::string& user_agent); diff --git a/spec-main/api-web-contents-spec.ts b/spec-main/api-web-contents-spec.ts index d81e62533907..87e238bd646b 100644 --- a/spec-main/api-web-contents-spec.ts +++ b/spec-main/api-web-contents-spec.ts @@ -838,6 +838,14 @@ describe('webContents module', () => { }); }); + describe('getMediaSourceId()', () => { + afterEach(closeAllWindows); + it('returns a valid stream id', () => { + const w = new BrowserWindow({ show: false }); + expect(w.webContents.getMediaSourceId(w.webContents)).to.be.a('string').that.is.not.empty(); + }); + }); + describe('userAgent APIs', () => { it('can set the user agent (functions)', () => { const w = new BrowserWindow({ show: false });