Skip to content

Commit

Permalink
fix: MediaDevices missing DisplayMediaInformation
Browse files Browse the repository at this point in the history
  • Loading branch information
codebytere committed May 19, 2023
1 parent b35ec4a commit f4b3afb
Showing 1 changed file with 115 additions and 9 deletions.
124 changes: 115 additions & 9 deletions shell/browser/electron_browser_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include "shell/common/gin_helper/error_thrower.h"
#include "shell/common/options_switches.h"
#include "shell/common/thread_restrictions.h"
#include "third_party/blink/public/mojom/media/capture_handle_config.mojom.h"
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"

#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
Expand Down Expand Up @@ -91,6 +92,105 @@ namespace electron {

namespace {

// Copied from chrome/browser/media/webrtc/desktop_capture_devices_util.cc.
media::mojom::CaptureHandlePtr CreateCaptureHandle(
content::WebContents* capturer,
const url::Origin& capturer_origin,
const content::DesktopMediaID& captured_id) {
if (capturer_origin.opaque()) {
return nullptr;
}

content::RenderFrameHost* const captured_rfh =
content::RenderFrameHost::FromID(
captured_id.web_contents_id.render_process_id,
captured_id.web_contents_id.main_render_frame_id);
if (!captured_rfh || !captured_rfh->IsActive()) {
return nullptr;
}

content::WebContents* const captured =
content::WebContents::FromRenderFrameHost(captured_rfh);
if (!captured) {
return nullptr;
}

const auto& captured_config = captured->GetCaptureHandleConfig();
if (!captured_config.all_origins_permitted &&
base::ranges::none_of(
captured_config.permitted_origins,
[capturer_origin](const url::Origin& permitted_origin) {
return capturer_origin.IsSameOriginWith(permitted_origin);
})) {
return nullptr;
}

// Observing CaptureHandle when either the capturing or the captured party
// is incognito is disallowed, except for self-capture.
if (capturer->GetPrimaryMainFrame() != captured->GetPrimaryMainFrame()) {
if (capturer->GetBrowserContext()->IsOffTheRecord() ||
captured->GetBrowserContext()->IsOffTheRecord()) {
return nullptr;
}
}

if (!captured_config.expose_origin &&
captured_config.capture_handle.empty()) {
return nullptr;
}

auto result = media::mojom::CaptureHandle::New();
if (captured_config.expose_origin) {
result->origin = captured->GetPrimaryMainFrame()->GetLastCommittedOrigin();
}
result->capture_handle = captured_config.capture_handle;

return result;
}

// Copied from chrome/browser/media/webrtc/desktop_capture_devices_util.cc.
media::mojom::DisplayMediaInformationPtr
DesktopMediaIDToDisplayMediaInformation(
content::WebContents* capturer,
const url::Origin& capturer_origin,
const content::DesktopMediaID& media_id) {
media::mojom::DisplayCaptureSurfaceType display_surface =
media::mojom::DisplayCaptureSurfaceType::MONITOR;
bool logical_surface = true;
media::mojom::CursorCaptureType cursor =
media::mojom::CursorCaptureType::NEVER;
#if defined(USE_AURA)
const bool uses_aura =
media_id.window_id != content::DesktopMediaID::kNullId ? true : false;
#else
const bool uses_aura = false;
#endif // defined(USE_AURA)

media::mojom::CaptureHandlePtr capture_handle;
switch (media_id.type) {
case content::DesktopMediaID::TYPE_SCREEN:
display_surface = media::mojom::DisplayCaptureSurfaceType::MONITOR;
cursor = uses_aura ? media::mojom::CursorCaptureType::MOTION
: media::mojom::CursorCaptureType::ALWAYS;
break;
case content::DesktopMediaID::TYPE_WINDOW:
display_surface = media::mojom::DisplayCaptureSurfaceType::WINDOW;
cursor = uses_aura ? media::mojom::CursorCaptureType::MOTION
: media::mojom::CursorCaptureType::ALWAYS;
break;
case content::DesktopMediaID::TYPE_WEB_CONTENTS:
display_surface = media::mojom::DisplayCaptureSurfaceType::BROWSER;
cursor = media::mojom::CursorCaptureType::MOTION;
capture_handle = CreateCaptureHandle(capturer, capturer_origin, media_id);
break;
case content::DesktopMediaID::TYPE_NONE:
break;
}

return media::mojom::DisplayMediaInformation::New(
display_surface, logical_surface, cursor, std::move(capture_handle));
}

// Convert string to lower case and escape it.
std::string MakePartitionName(const std::string& input) {
return base::EscapePath(base::ToLowerASCII(input));
Expand Down Expand Up @@ -478,16 +578,22 @@ void ElectronBrowserContext::DisplayMediaDeviceChosen(
content::RenderFrameHost* rfh;
if (result_dict.Get("video", &video_dict) && video_dict.Get("id", &id) &&
video_dict.Get("name", &name)) {
devices.video_device =
blink::MediaStreamDevice(request.video_type, id, name);
blink::MediaStreamDevice video_device(request.video_type, id, name);
video_device.display_media_info = DesktopMediaIDToDisplayMediaInformation(
nullptr, url::Origin::Create(request.security_origin),
content::DesktopMediaID::Parse(id));
devices.video_device = video_device;
} else if (result_dict.Get("video", &rfh)) {
devices.video_device = blink::MediaStreamDevice(
request.video_type,
content::WebContentsMediaCaptureId(rfh->GetProcess()->GetID(),
rfh->GetRoutingID())
.ToString(),
base::UTF16ToUTF8(
content::WebContents::FromRenderFrameHost(rfh)->GetTitle()));
auto* web_contents = content::WebContents::FromRenderFrameHost(rfh);
auto media_id = content::WebContentsMediaCaptureId(
rfh->GetProcess()->GetID(), rfh->GetRoutingID());
blink::MediaStreamDevice video_device(
request.video_type, media_id.ToString(),
base::UTF16ToUTF8(web_contents->GetTitle()));
video_device.display_media_info = DesktopMediaIDToDisplayMediaInformation(
web_contents, url::Origin::Create(request.security_origin),
content::DesktopMediaID::Parse(media_id.ToString()));
devices.video_device = video_device;
} else {
gin_helper::ErrorThrower(args->isolate())
.ThrowTypeError(
Expand Down

0 comments on commit f4b3afb

Please sign in to comment.