mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
26 Commits
ci/ai-mode
...
sckp-macos
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e364a20ba1 | ||
|
|
6b6ef0b9ef | ||
|
|
bb092132be | ||
|
|
0cdf1012bb | ||
|
|
eaa952361c | ||
|
|
8ef66cade3 | ||
|
|
2fb1bfec42 | ||
|
|
65864f6203 | ||
|
|
75eb7aabd6 | ||
|
|
f8aae32c6c | ||
|
|
3e6834099e | ||
|
|
3d5d5f5cb0 | ||
|
|
3268c6ba76 | ||
|
|
50f96692df | ||
|
|
53a7802e95 | ||
|
|
b6c4c727d1 | ||
|
|
4aa9773388 | ||
|
|
7b6b5bf224 | ||
|
|
bd1ed17c02 | ||
|
|
813fc3af58 | ||
|
|
e7675a1a1c | ||
|
|
729ca429b8 | ||
|
|
da56809b62 | ||
|
|
12ca8b30be | ||
|
|
56d4433e46 | ||
|
|
0ee7150832 |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -30,7 +30,7 @@ on:
|
||||
required: false
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- sckp-macos15
|
||||
- '[1-9][0-9]-x-y'
|
||||
pull_request:
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ app.whenReady().then(() => {
|
||||
|
||||
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
|
||||
desktopCapturer.getSources({ types: ['screen'] }).then((sources) => {
|
||||
// Grant access to the first screen found.
|
||||
// Your app shows some UI, but in this example
|
||||
// grant access to the first screen found.
|
||||
callback({ video: sources[0], audio: 'loopback' })
|
||||
})
|
||||
// If true, use the system picker if available.
|
||||
@@ -42,7 +43,8 @@ startButton.addEventListener('click', () => {
|
||||
video: {
|
||||
width: 320,
|
||||
height: 240,
|
||||
frameRate: 30
|
||||
frameRate: 30,
|
||||
displaySurface: 'monitor'
|
||||
}
|
||||
}).then(stream => {
|
||||
video.srcObject = stream
|
||||
@@ -98,6 +100,16 @@ which can detected by [`systemPreferences.getMediaAccessStatus`][].
|
||||
[`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia
|
||||
[`systemPreferences.getMediaAccessStatus`]: system-preferences.md#systempreferencesgetmediaaccessstatusmediatype-windows-macos
|
||||
|
||||
### `desktopCapturer.isDisplayMediaSystemPickerAvailable()` _Experimental_ _macOS_
|
||||
|
||||
Returns `Boolean`, whether or not requesting desktop content via
|
||||
the system picker is supported on this platform.
|
||||
|
||||
Currently this will only return `true` on macOS 14.4 and higher. When
|
||||
true, use the `getNativePickerSource` method to return the system picker's
|
||||
selected media stream. Not doing so may cause a warning dialog to your users
|
||||
on macOS 15 and higher.
|
||||
|
||||
## Caveats
|
||||
|
||||
`navigator.mediaDevices.getUserMedia` does not work on macOS for audio capture due to a fundamental limitation whereby apps that want to access the system's audio require a [signed kernel extension](https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/KernelExtensions/KernelExtensions.html). Chromium, and by extension Electron, does not provide this.
|
||||
|
||||
@@ -971,6 +971,7 @@ session.fromPartition('some-partition').setPermissionCheckHandler((webContents,
|
||||
* `videoRequested` Boolean - true if the web content requested a video stream.
|
||||
* `audioRequested` Boolean - true if the web content requested an audio stream.
|
||||
* `userGesture` Boolean - Whether a user gesture was active when this request was triggered.
|
||||
* `preferredDisplaySurface` String - The preferred display used for sharing screen in this request.
|
||||
* `callback` Function
|
||||
* `streams` Object
|
||||
* `video` Object | [WebFrameMain](web-frame-main.md) (optional)
|
||||
|
||||
@@ -594,6 +594,8 @@ filenames = {
|
||||
"shell/common/gin_converters/callback_converter.h",
|
||||
"shell/common/gin_converters/content_converter.cc",
|
||||
"shell/common/gin_converters/content_converter.h",
|
||||
"shell/common/gin_converters/display_surface_converter.cc",
|
||||
"shell/common/gin_converters/display_surface_converter.h",
|
||||
"shell/common/gin_converters/file_dialog_converter.cc",
|
||||
"shell/common/gin_converters/file_dialog_converter.h",
|
||||
"shell/common/gin_converters/file_path_converter.h",
|
||||
|
||||
@@ -16,13 +16,13 @@ function isValid (options: Electron.SourcesOptions) {
|
||||
|
||||
export { isDisplayMediaSystemPickerAvailable };
|
||||
|
||||
export async function getSources (args: Electron.SourcesOptions) {
|
||||
export async function getSources (args: Electron.SourcesOptions, useSystemPicker: boolean = false) {
|
||||
if (!isValid(args)) throw new Error('Invalid options');
|
||||
|
||||
const resizableValues = new Map();
|
||||
if (process.platform === 'darwin') {
|
||||
// Fix for bug in ScreenCaptureKit that modifies a window's styleMask the first time
|
||||
// it captures a non-resizable window. We record each non-resizable window's styleMask,
|
||||
// it captures a non-resizable window. We record each non-resizable window's styleMask
|
||||
// and we restore modified styleMasks later, after the screen capture.
|
||||
for (const win of BrowserWindow.getAllWindows()) {
|
||||
resizableValues.set([win.id], win.resizable);
|
||||
@@ -32,14 +32,15 @@ export async function getSources (args: Electron.SourcesOptions) {
|
||||
const captureWindow = args.types.includes('window');
|
||||
const captureScreen = args.types.includes('screen');
|
||||
|
||||
const { thumbnailSize = { width: 150, height: 150 } } = args;
|
||||
const { thumbnailSize = { width: 0, height: 0 } } = args;
|
||||
const { fetchWindowIcons = false } = args;
|
||||
|
||||
const options = {
|
||||
captureWindow,
|
||||
captureScreen,
|
||||
thumbnailSize,
|
||||
fetchWindowIcons
|
||||
fetchWindowIcons,
|
||||
useSystemPicker
|
||||
};
|
||||
|
||||
for (const running of currentlyRunning) {
|
||||
@@ -81,7 +82,7 @@ export async function getSources (args: Electron.SourcesOptions) {
|
||||
resolve(sources);
|
||||
};
|
||||
|
||||
capturer.startHandling(captureWindow, captureScreen, thumbnailSize, fetchWindowIcons);
|
||||
capturer.startHandling(captureWindow, captureScreen, thumbnailSize, fetchWindowIcons, useSystemPicker);
|
||||
});
|
||||
|
||||
currentlyRunning.push({
|
||||
|
||||
@@ -2,25 +2,61 @@ import { fetchWithSession } from '@electron/internal/browser/api/net-fetch';
|
||||
import { addIpcDispatchListeners } from '@electron/internal/browser/ipc-dispatch';
|
||||
import * as deprecate from '@electron/internal/common/deprecate';
|
||||
|
||||
import { net } from 'electron/main';
|
||||
import { desktopCapturer, net } from 'electron/main';
|
||||
|
||||
const { fromPartition, fromPath, Session } = process._linkedBinding('electron_browser_session');
|
||||
const { isDisplayMediaSystemPickerAvailable } = process._linkedBinding('electron_browser_desktop_capturer');
|
||||
|
||||
// Fake video window that activates the native system picker
|
||||
// This is used to get around the need for a screen/window
|
||||
// id in Chrome's desktopCapturer.
|
||||
let fakeVideoWindowId = -1;
|
||||
// See content/public/browser/desktop_media_id.h
|
||||
const kMacOsNativePickerId = -4;
|
||||
const systemPickerVideoSource = Object.create(null);
|
||||
Object.defineProperty(systemPickerVideoSource, 'id', {
|
||||
get () {
|
||||
return `window:${kMacOsNativePickerId}:${fakeVideoWindowId--}`;
|
||||
async function getNativePickerSource (preferredDisplaySurface: string) {
|
||||
console.log('SESSION.TS getNativePickerSource');
|
||||
// Fake video window that activates the native system picker
|
||||
// This is used to get around the need for a screen/window
|
||||
// id in Chrome's desktopCapturer.
|
||||
let fakeVideoWindowId = -1;
|
||||
const kMacOsNativePickerId = -4;
|
||||
|
||||
if (process.platform !== 'darwin') {
|
||||
throw new Error('Native system picker option is currently only supported on MacOS');
|
||||
}
|
||||
});
|
||||
systemPickerVideoSource.name = '';
|
||||
Object.freeze(systemPickerVideoSource);
|
||||
|
||||
if (!isDisplayMediaSystemPickerAvailable) {
|
||||
throw new Error(`Native system picker unavailable.
|
||||
Note: This is an experimental API; please check the API documentation for updated restrictions`);
|
||||
}
|
||||
|
||||
let types: Electron.SourcesOptions['types'];
|
||||
switch (preferredDisplaySurface) {
|
||||
case 'no_preference':
|
||||
types = ['screen', 'window'];
|
||||
break;
|
||||
case 'monitor':
|
||||
types = ['screen'];
|
||||
break;
|
||||
case 'window':
|
||||
types = ['window'];
|
||||
break;
|
||||
default:
|
||||
types = ['screen', 'window'];
|
||||
}
|
||||
|
||||
// Pass in the needed options for a more native experience
|
||||
// screen & windows by default, no thumbnails, since the native picker doesn't return them
|
||||
const options: Electron.SourcesOptions = {
|
||||
types,
|
||||
thumbnailSize: { width: 0, height: 0 },
|
||||
fetchWindowIcons: false
|
||||
};
|
||||
|
||||
const mediaStreams = await desktopCapturer.getSources(options);
|
||||
|
||||
if (mediaStreams.length === 0) {
|
||||
throw new Error('No media streams found');
|
||||
}
|
||||
|
||||
mediaStreams[0].id = `none:${kMacOsNativePickerId}:${fakeVideoWindowId--}`;
|
||||
console.log('SESSION.TS mediaStreams', mediaStreams);
|
||||
return mediaStreams[0];
|
||||
}
|
||||
|
||||
Session.prototype._init = function () {
|
||||
addIpcDispatchListeners(this);
|
||||
@@ -48,12 +84,12 @@ Session.prototype.fetch = function (input: RequestInfo, init?: RequestInit) {
|
||||
Session.prototype.setDisplayMediaRequestHandler = function (handler, opts) {
|
||||
if (!handler) return this._setDisplayMediaRequestHandler(handler, opts);
|
||||
|
||||
this._setDisplayMediaRequestHandler(async (req, callback) => {
|
||||
this._setDisplayMediaRequestHandler(async (request, callback) => {
|
||||
if (opts && opts.useSystemPicker && isDisplayMediaSystemPickerAvailable()) {
|
||||
return callback({ video: systemPickerVideoSource });
|
||||
return callback({ video: await getNativePickerSource(request.preferredDisplaySurface) });
|
||||
}
|
||||
|
||||
return handler(req, callback);
|
||||
return handler(request, callback);
|
||||
}, opts);
|
||||
};
|
||||
|
||||
|
||||
@@ -143,3 +143,4 @@ fix_win32_synchronous_spellcheck.patch
|
||||
fix_enable_wrap_iter_in_string_view_and_array.patch
|
||||
fix_linter_error.patch
|
||||
fix_take_snapped_status_into_account_when_showing_a_window.patch
|
||||
feat_make_macos_sccontentsharingpicker_work_in_electron_and_return_screen_window_or_both.patch
|
||||
|
||||
@@ -0,0 +1,733 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Keeley Hammond <khammond@slack-corp.com>
|
||||
Date: Tue, 14 Jan 2025 15:50:29 -0800
|
||||
Subject: feat: allow desktop capturer to return either screen, window or both
|
||||
and make MacOS SCContentSharingPicker work in Electron
|
||||
|
||||
This patch is a work in progress that contains assorted changes to make the MacOS SCContentSharingPicker upstream implementation work within Electron. If this comment is still in this patch during PR review, it is not ready for prime time
|
||||
|
||||
This patch can be removed after our desktopCapturer is refactored.
|
||||
|
||||
diff --git a/chrome/browser/media/webrtc/capture_policy_utils.cc b/chrome/browser/media/webrtc/capture_policy_utils.cc
|
||||
index 36797f37627d534bd446e0d8270618722ed9a2fa..32222cb526dc047a02cd9382814edd71cca0a378 100644
|
||||
--- a/chrome/browser/media/webrtc/capture_policy_utils.cc
|
||||
+++ b/chrome/browser/media/webrtc/capture_policy_utils.cc
|
||||
@@ -356,7 +356,9 @@ void FilterMediaList(std::vector<DesktopMediaList::Type>& media_types,
|
||||
media_types, [capture_level](const DesktopMediaList::Type& type) {
|
||||
switch (type) {
|
||||
case DesktopMediaList::Type::kNone:
|
||||
- NOTREACHED();
|
||||
+ //TODO(review): are we able to remove this?
|
||||
+ return capture_level < AllowedScreenCaptureLevel::kDesktop;
|
||||
+ // NOTREACHED();
|
||||
// SameOrigin is more restrictive than just Tabs, so as long as
|
||||
// at least SameOrigin is allowed, these entries should stay.
|
||||
// They should be filtered later by the caller.
|
||||
diff --git a/chrome/browser/media/webrtc/desktop_media_list_base.cc b/chrome/browser/media/webrtc/desktop_media_list_base.cc
|
||||
index 08400be4d1bae18502d19beed6b2d9057e55dd4f..4df1a9f44959db1f73d6a8a535d297343f7f0c00 100644
|
||||
--- a/chrome/browser/media/webrtc/desktop_media_list_base.cc
|
||||
+++ b/chrome/browser/media/webrtc/desktop_media_list_base.cc
|
||||
@@ -12,9 +12,11 @@
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
+#include "base/logging.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/hash/hash.h"
|
||||
#include "chrome/browser/media/webrtc/desktop_media_list.h"
|
||||
+#include "chrome/browser/media/webrtc/thumbnail_capturer_mac.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
@@ -60,24 +62,34 @@ void DesktopMediaListBase::StartUpdating(DesktopMediaListObserver* observer) {
|
||||
// If there is a delegated source list, it may not have been started yet.
|
||||
if (IsSourceListDelegated())
|
||||
StartDelegatedCapturer();
|
||||
+ LOG(ERROR) << "start delegated capturer";
|
||||
|
||||
// Process sources previously discovered by a call to Update().
|
||||
if (observer_) {
|
||||
for (size_t i = 0; i < sources_.size(); i++) {
|
||||
observer_->OnSourceAdded(i);
|
||||
+ LOG(ERROR) << "OnSourceAdded, i: " << i;
|
||||
}
|
||||
}
|
||||
-
|
||||
+ LOG(INFO)<< "Refresh callback_ is null: " << refresh_callback_.is_null() << ";";
|
||||
DCHECK(!refresh_callback_);
|
||||
+ LOG(INFO) << "dcheck passed";
|
||||
refresh_callback_ = base::BindOnce(&DesktopMediaListBase::ScheduleNextRefresh,
|
||||
weak_factory_.GetWeakPtr());
|
||||
Refresh(true);
|
||||
}
|
||||
|
||||
void DesktopMediaListBase::Update(UpdateCallback callback, bool refresh_thumbnails) {
|
||||
+ LOG(ERROR) << "Update";
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
DCHECK(sources_.empty());
|
||||
- DCHECK(!refresh_callback_);
|
||||
+ #if BUILDFLAG(IS_MAC)
|
||||
+ if (!ShouldUseSCContentSharingPicker()) {
|
||||
+ DCHECK(!refresh_callback_);
|
||||
+ };
|
||||
+ #else
|
||||
+ DCHECK(!refresh_callback_);
|
||||
+ #endif
|
||||
refresh_callback_ = std::move(callback);
|
||||
Refresh(refresh_thumbnails);
|
||||
}
|
||||
diff --git a/chrome/browser/media/webrtc/native_desktop_media_list.cc b/chrome/browser/media/webrtc/native_desktop_media_list.cc
|
||||
index 312882d656f9f6b3d3fd98128131cea63f818e0d..f61697e1717fcfa0500974e8523438389fbab5ae 100644
|
||||
--- a/chrome/browser/media/webrtc/native_desktop_media_list.cc
|
||||
+++ b/chrome/browser/media/webrtc/native_desktop_media_list.cc
|
||||
@@ -45,6 +45,7 @@
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
+#include "chrome/browser/media/webrtc/thumbnail_capturer_mac.h"
|
||||
#include "components/remote_cocoa/browser/scoped_cg_window_id.h"
|
||||
#endif
|
||||
|
||||
@@ -162,9 +163,10 @@ content::DesktopMediaID::Type ConvertToDesktopMediaIDType(
|
||||
return content::DesktopMediaID::Type::TYPE_SCREEN;
|
||||
case DesktopMediaList::Type::kWindow:
|
||||
return content::DesktopMediaID::Type::TYPE_WINDOW;
|
||||
+ case DesktopMediaList::Type::kNone:
|
||||
+ return content::DesktopMediaID::Type::TYPE_NONE;
|
||||
case DesktopMediaList::Type::kWebContents:
|
||||
case DesktopMediaList::Type::kCurrentTab:
|
||||
- case DesktopMediaList::Type::kNone:
|
||||
break;
|
||||
}
|
||||
NOTREACHED();
|
||||
@@ -372,7 +374,8 @@ NativeDesktopMediaList::Worker::Worker(
|
||||
nullptr) {
|
||||
DCHECK(capturer_);
|
||||
|
||||
- DCHECK(source_type_ == DesktopMediaID::Type::TYPE_WINDOW ||
|
||||
+ DCHECK(source_type_ == DesktopMediaID::Type::TYPE_WINDOW || source_type_ ==
|
||||
+ DesktopMediaID::Type::TYPE_NONE ||
|
||||
!add_current_process_windows_);
|
||||
}
|
||||
|
||||
@@ -505,11 +508,27 @@ NativeDesktopMediaList::Worker::FormatSources(
|
||||
break;
|
||||
|
||||
case DesktopMediaID::Type::TYPE_WINDOW:
|
||||
+ case DesktopMediaID::Type::TYPE_NONE:
|
||||
+ #if BUILDFLAG(IS_MAC)
|
||||
+ // If using NativeScreenCapturePickerMac,
|
||||
+ // skipping the picker will skip the first window selection.
|
||||
+ if (ShouldUseSCContentSharingPicker()) {
|
||||
+ title = base::UTF8ToUTF16(sources[i].title);
|
||||
+ LOG(ERROR) << "formatting native picker source, id: " << sources[i].id << " title: " << title;
|
||||
+ LOG(ERROR) << "sources size: " << sources.size();
|
||||
+ LOG(ERROR) << "excluded window id: " << excluded_window_id;
|
||||
+ } else if (sources[i].id == excluded_window_id) {
|
||||
+ // Skip the picker dialog window.
|
||||
+ continue;
|
||||
+ }
|
||||
+ title = base::UTF8ToUTF16(sources[i].title);
|
||||
+ #else
|
||||
// Skip the picker dialog window.
|
||||
if (sources[i].id == excluded_window_id) {
|
||||
continue;
|
||||
}
|
||||
title = base::UTF8ToUTF16(sources[i].title);
|
||||
+ #endif
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -775,14 +794,10 @@ NativeDesktopMediaList::NativeDesktopMediaList(
|
||||
is_source_list_delegated_(capturer->GetDelegatedSourceListController() !=
|
||||
nullptr) {
|
||||
type_ = type;
|
||||
-
|
||||
- DCHECK(type_ == DesktopMediaList::Type::kWindow ||
|
||||
+ DCHECK(type_ == DesktopMediaList::Type::kWindow || type_ == DesktopMediaList::Type::kNone ||
|
||||
!add_current_process_windows_);
|
||||
|
||||
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
|
||||
- // webrtc::DesktopCapturer implementations on Windows, MacOS and Fuchsia
|
||||
- // expect to run on a thread with a UI message pump. Under Fuchsia the
|
||||
- // capturer needs an async loop to support FIDL I/O.
|
||||
base::MessagePumpType thread_type = base::MessagePumpType::UI;
|
||||
#else
|
||||
base::MessagePumpType thread_type = base::MessagePumpType::DEFAULT;
|
||||
@@ -794,8 +809,9 @@ NativeDesktopMediaList::NativeDesktopMediaList(
|
||||
std::move(capturer), add_current_process_windows_,
|
||||
auto_show_delegated_source_list);
|
||||
|
||||
- if (!is_source_list_delegated_)
|
||||
+ if (!is_source_list_delegated_) {
|
||||
StartCapturer();
|
||||
+ }
|
||||
}
|
||||
|
||||
NativeDesktopMediaList::~NativeDesktopMediaList() {
|
||||
@@ -903,7 +919,7 @@ void NativeDesktopMediaList::ShowDelegatedList() {
|
||||
}
|
||||
|
||||
void NativeDesktopMediaList::Refresh(bool update_thumbnails) {
|
||||
- DCHECK(can_refresh());
|
||||
+ DCHECK(can_refresh());
|
||||
|
||||
#if defined(USE_AURA)
|
||||
DCHECK_EQ(pending_aura_capture_requests_, 0);
|
||||
diff --git a/chrome/browser/media/webrtc/thumbnail_capturer_mac.h b/chrome/browser/media/webrtc/thumbnail_capturer_mac.h
|
||||
index 12a74f8f32cc00a7f3d7802865ae4b309961341d..acbcfb08ae8c44e24a04b326096289428bc6ff60 100644
|
||||
--- a/chrome/browser/media/webrtc/thumbnail_capturer_mac.h
|
||||
+++ b/chrome/browser/media/webrtc/thumbnail_capturer_mac.h
|
||||
@@ -8,6 +8,9 @@
|
||||
#include "chrome/browser/media/webrtc/desktop_media_list.h"
|
||||
#include "chrome/browser/media/webrtc/thumbnail_capturer.h"
|
||||
|
||||
+// Returns true if the SCK sharing picker is available and enabled.
|
||||
+bool ShouldUseSCContentSharingPicker();
|
||||
+
|
||||
// Returns true if the SCK thumbnail capturer is available and enabled.
|
||||
bool ShouldUseThumbnailCapturerMac(DesktopMediaList::Type type);
|
||||
|
||||
diff --git a/chrome/browser/media/webrtc/thumbnail_capturer_mac.mm b/chrome/browser/media/webrtc/thumbnail_capturer_mac.mm
|
||||
index 744f2447dc2d43c4f6be695bf561474993468705..bb5781b0f0df11422f8355dcc59f5f0f46ebcf89 100644
|
||||
--- a/chrome/browser/media/webrtc/thumbnail_capturer_mac.mm
|
||||
+++ b/chrome/browser/media/webrtc/thumbnail_capturer_mac.mm
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
|
||||
+#include "base/logging.h"
|
||||
#include "base/apple/bridging.h"
|
||||
#include "base/apple/foundation_util.h"
|
||||
#include "base/apple/scoped_cftyperef.h"
|
||||
@@ -71,11 +72,11 @@
|
||||
return content::DesktopMediaID::Type::TYPE_SCREEN;
|
||||
case DesktopMediaList::Type::kWindow:
|
||||
return content::DesktopMediaID::Type::TYPE_WINDOW;
|
||||
+ case DesktopMediaList::Type::kNone:
|
||||
+ return content::DesktopMediaID::Type::TYPE_NONE;
|
||||
case DesktopMediaList::Type::kWebContents:
|
||||
case DesktopMediaList::Type::kCurrentTab:
|
||||
return content::DesktopMediaID::Type::TYPE_WEB_CONTENTS;
|
||||
- case DesktopMediaList::Type::kNone:
|
||||
- break;
|
||||
}
|
||||
NOTREACHED();
|
||||
}
|
||||
@@ -442,7 +443,7 @@ void OnCapturedFrame(base::apple::ScopedCFTypeRef<CGImageRef> image,
|
||||
max_frame_rate_(kThumbnailCapturerMacMaxFrameRate),
|
||||
shareable_windows_([[NSArray<SCWindow*> alloc] init]) {
|
||||
CHECK(type_ == DesktopMediaList::Type::kWindow ||
|
||||
- type_ == DesktopMediaList::Type::kScreen);
|
||||
+ type_ == DesktopMediaList::Type::kScreen || type_ == DesktopMediaList::Type::kNone);
|
||||
}
|
||||
|
||||
ThumbnailCapturerMac::~ThumbnailCapturerMac() {
|
||||
@@ -680,17 +681,15 @@ void OnCapturedFrame(base::apple::ScopedCFTypeRef<CGImageRef> image,
|
||||
source_id);
|
||||
}
|
||||
|
||||
+} // namespace
|
||||
+
|
||||
bool ShouldUseSCContentSharingPicker() {
|
||||
if (@available(macOS 15.0, *)) {
|
||||
- if (base::FeatureList::IsEnabled(media::kUseSCContentSharingPicker)) {
|
||||
- return true;
|
||||
- }
|
||||
+ return base::FeatureList::IsEnabled(media::kUseSCContentSharingPicker);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
-} // namespace
|
||||
-
|
||||
bool ShouldUseThumbnailCapturerMac(DesktopMediaList::Type type) {
|
||||
// There was a bug in ScreenCaptureKit that was fixed in 14.4,
|
||||
// see b/40076027.
|
||||
@@ -704,6 +703,9 @@ bool ShouldUseThumbnailCapturerMac(DesktopMediaList::Type type) {
|
||||
return ShouldUseSCContentSharingPicker() ||
|
||||
base::FeatureList::IsEnabled(kScreenCaptureKitPickerScreen);
|
||||
case DesktopMediaList::Type::kNone:
|
||||
+ return ShouldUseSCContentSharingPicker() ||
|
||||
+ base::FeatureList::IsEnabled(kScreenCaptureKitStreamPickerSonoma) ||
|
||||
+ base::FeatureList::IsEnabled(kScreenCaptureKitPickerScreen);
|
||||
case DesktopMediaList::Type::kCurrentTab:
|
||||
case DesktopMediaList::Type::kWebContents:
|
||||
return false;
|
||||
diff --git a/content/browser/media/capture/desktop_capture_device.cc b/content/browser/media/capture/desktop_capture_device.cc
|
||||
index b4b1e9ee805a8565a04737e0898ad8e46709c4d8..7b856f89028fe8f5594c1ff35900019250865ab5 100644
|
||||
--- a/content/browser/media/capture/desktop_capture_device.cc
|
||||
+++ b/content/browser/media/capture/desktop_capture_device.cc
|
||||
@@ -899,7 +899,6 @@ std::unique_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
|
||||
result.reset(new DesktopCaptureDevice(std::move(capturer), source.type));
|
||||
return result;
|
||||
}
|
||||
-
|
||||
switch (source.type) {
|
||||
case DesktopMediaID::TYPE_SCREEN: {
|
||||
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer;
|
||||
@@ -920,7 +919,7 @@ std::unique_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
|
||||
}
|
||||
break;
|
||||
}
|
||||
-
|
||||
+ case DesktopMediaID::TYPE_NONE:
|
||||
case DesktopMediaID::TYPE_WINDOW: {
|
||||
std::unique_ptr<webrtc::DesktopCapturer> window_capturer;
|
||||
if (auto generic_capturer =
|
||||
diff --git a/content/browser/media/capture/native_screen_capture_picker.cc b/content/browser/media/capture/native_screen_capture_picker.cc
|
||||
index 152f3aa78032ee3f8c48fbefe052a2f1d85bed6b..d57df80dff9c6867cddf669efe3f90c43c03a0a7 100644
|
||||
--- a/content/browser/media/capture/native_screen_capture_picker.cc
|
||||
+++ b/content/browser/media/capture/native_screen_capture_picker.cc
|
||||
@@ -7,6 +7,7 @@
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#include "content/browser/media/capture/native_screen_capture_picker_mac.h"
|
||||
#include "media/base/media_switches.h"
|
||||
+#include "base/logging.h"
|
||||
#endif
|
||||
|
||||
namespace content {
|
||||
diff --git a/content/browser/media/capture/native_screen_capture_picker_mac.mm b/content/browser/media/capture/native_screen_capture_picker_mac.mm
|
||||
index 0dbc7ebc4ba6066eb6b20f8e66f50a1dff4d94f3..17d658ee011b81208b77ee1e65925ae9ad1e68f7 100644
|
||||
--- a/content/browser/media/capture/native_screen_capture_picker_mac.mm
|
||||
+++ b/content/browser/media/capture/native_screen_capture_picker_mac.mm
|
||||
@@ -206,8 +206,12 @@ void Open(DesktopMediaID::Type type,
|
||||
base::OnceClosure cancel_callback,
|
||||
base::OnceClosure error_callback) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
+ LOG(ERROR) << "Open";
|
||||
+ // Chrome doesn't allow both screens & windows in their picker,
|
||||
+ // but Electron does - add a check for TYPE_NONE.
|
||||
CHECK(type == DesktopMediaID::Type::TYPE_SCREEN ||
|
||||
- type == DesktopMediaID::Type::TYPE_WINDOW);
|
||||
+ type == DesktopMediaID::Type::TYPE_WINDOW ||
|
||||
+ type == DesktopMediaID::Type::TYPE_NONE);
|
||||
if (@available(macOS 14.0, *)) {
|
||||
NSNumber* source_id = @(next_id_);
|
||||
PickerObserver* picker_observer = [[PickerObserver alloc]
|
||||
@@ -226,25 +230,32 @@ void Open(DesktopMediaID::Type type,
|
||||
// TODO(https://crbug.com/360781940): Add support for changing selected
|
||||
// content. The problem to solve is how this should interact with stream
|
||||
// restart.
|
||||
- config.allowsChangingSelectedContent = false;
|
||||
+ config.allowsChangingSelectedContent = true;
|
||||
NSNumber* max_stream_count = @(kMaxContentShareCountValue.Get());
|
||||
- if (type == DesktopMediaID::Type::TYPE_SCREEN) {
|
||||
- config.allowedPickerModes = SCContentSharingPickerModeSingleDisplay;
|
||||
- picker.defaultConfiguration = config;
|
||||
- picker.maximumStreamCount = max_stream_count;
|
||||
- [picker presentPickerUsingContentStyle:SCShareableContentStyleDisplay];
|
||||
- VLOG(1) << "NSCPM: Show screen-sharing picker for source_id = "
|
||||
- << source_id.longValue;
|
||||
- LogToUma(SCContentSharingPickerOperation::kPresentScreen_Start);
|
||||
- } else {
|
||||
- config.allowedPickerModes = SCContentSharingPickerModeSingleWindow;
|
||||
- picker.defaultConfiguration = config;
|
||||
- picker.maximumStreamCount = max_stream_count;
|
||||
- [picker presentPickerUsingContentStyle:SCShareableContentStyleWindow];
|
||||
- VLOG(1) << "NSCPM: Show window-sharing picker for source_id = "
|
||||
- << source_id.longValue;
|
||||
- LogToUma(SCContentSharingPickerOperation::kPresentWindow_Start);
|
||||
- }
|
||||
+ // LOG(ERROR) << "Type: " << type;
|
||||
+ // Chrome doesn't allow both screens & windows in their picker,
|
||||
+ // but Electron does; we patch out the MediaID::Type conditional here
|
||||
+ // if (type == DesktopMediaID::Type::TYPE_SCREEN) {
|
||||
+ // config.allowedPickerModes = SCContentSharingPickerModeSingleDisplay;
|
||||
+ // picker.defaultConfiguration = config;
|
||||
+ // picker.maximumStreamCount = max_stream_count;
|
||||
+ // [picker presentPickerUsingContentStyle:SCShareableContentStyleDisplay];
|
||||
+ // } else if (type == DesktopMediaID::Type::TYPE_WINDOW) {
|
||||
+ // config.allowedPickerModes = SCContentSharingPickerModeSingleWindow;
|
||||
+ // picker.defaultConfiguration = config;
|
||||
+ // picker.maximumStreamCount = max_stream_count;
|
||||
+ // [picker presentPickerUsingContentStyle:SCShareableContentStyleWindow];
|
||||
+ // VLOG(1) << "NSCPM: Show screen-sharing picker for source_id = "
|
||||
+ // << source_id.longValue;
|
||||
+ // LogToUma(SCContentSharingPickerOperation::kPresentScreen_Start);
|
||||
+ // } else {
|
||||
+ picker.defaultConfiguration = config;
|
||||
+ picker.maximumStreamCount = max_stream_count;
|
||||
+ [picker present];
|
||||
+ // VLOG(1) << "NSCPM: Show window-sharing picker for source_id = "
|
||||
+ // << source_id.longValue;
|
||||
+ // LogToUma(SCContentSharingPickerOperation::kPresentWindow_Start);
|
||||
+ // }
|
||||
} else {
|
||||
NOTREACHED();
|
||||
}
|
||||
diff --git a/content/browser/media/capture/screen_capture_kit_device_mac.mm b/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
index 0e4a68f2fd8179640f877cb258b4049610fd49da..0fb8d036b7696e5303fbcd463114114aa3227a08 100644
|
||||
--- a/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
+++ b/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
@@ -364,6 +364,7 @@ void OnShareableContentCreated(SCShareableContent* content) {
|
||||
if (!fullscreen_module_) {
|
||||
fullscreen_module_ = MaybeCreateScreenCaptureKitFullscreenModule(
|
||||
device_task_runner_, *this, window);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -728,6 +729,7 @@ void ResetStreamTo(SCWindow* window) override {
|
||||
SCContentFilter* filter) {
|
||||
switch (source.type) {
|
||||
case DesktopMediaID::TYPE_SCREEN:
|
||||
+ case DesktopMediaID::TYPE_NONE:
|
||||
// ScreenCaptureKitDeviceMac only supports a single display at a time.
|
||||
// It will not stitch desktops together. If
|
||||
// kScreenCaptureKitFullDesktopFallback is enabled, we will fallback to
|
||||
diff --git a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
index f0f08a834f06c7669da6030640434308a5cbd056..a34dcdbad1c3d32de59a1574de485bd831599aa1 100644
|
||||
--- a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
+++ b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
@@ -177,19 +177,20 @@ DesktopCaptureImplementation CreatePlatformDependentVideoCaptureDevice(
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
// Use ScreenCaptureKit with picker if specified. `desktop_id` for the picker
|
||||
// is not compatible with the other implementations.
|
||||
- if (picker) {
|
||||
- device_out = picker->CreateDevice(desktop_id);
|
||||
- if (device_out) {
|
||||
- return kScreenCaptureKitDeviceMac;
|
||||
- }
|
||||
- return kNoImplementation;
|
||||
- }
|
||||
+ // if (picker) {
|
||||
+ // device_out = picker->CreateDevice(desktop_id);
|
||||
+ // if (device_out) {
|
||||
+ // return kScreenCaptureKitDeviceMac;
|
||||
+ // }
|
||||
+ // return kNoImplementation;
|
||||
+ // }
|
||||
|
||||
// Prefer using ScreenCaptureKit. After that try DesktopCaptureDeviceMac, and
|
||||
// if both fail, use the generic DesktopCaptureDevice.
|
||||
if (desktop_id.type == DesktopMediaID::TYPE_WINDOW ||
|
||||
(desktop_id.type == DesktopMediaID::TYPE_SCREEN &&
|
||||
- base::FeatureList::IsEnabled(kScreenCaptureKitMacScreen))) {
|
||||
+ base::FeatureList::IsEnabled(kScreenCaptureKitMacScreen)) ||
|
||||
+ (desktop_id.type == DesktopMediaID::TYPE_NONE && base::FeatureList::IsEnabled(kScreenCaptureKitMacScreen))) {
|
||||
device_out = CreateScreenCaptureKitDeviceMac(desktop_id);
|
||||
if (device_out) {
|
||||
return kScreenCaptureKitDeviceMac;
|
||||
@@ -237,6 +238,9 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
DCHECK(state_ == State::READY_TO_LAUNCH);
|
||||
|
||||
if (receiver_on_io_thread) {
|
||||
+ LOG(INFO) << "InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync: Posting "
|
||||
+ "start request to device thread for device_id = "
|
||||
+ << device_id;
|
||||
std::ostringstream string_stream;
|
||||
string_stream
|
||||
<< "InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync: Posting "
|
||||
@@ -244,7 +248,7 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
<< device_id;
|
||||
receiver_on_io_thread->OnLog(string_stream.str());
|
||||
}
|
||||
-
|
||||
+ LOG(ERROR) << "receiver_on_io_thread: ";
|
||||
// Wrap the receiver, to trampoline all its method calls from the device
|
||||
// to the IO thread.
|
||||
auto receiver = std::make_unique<media::VideoFrameReceiverOnTaskRunner>(
|
||||
@@ -257,12 +261,14 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
base::BindPostTaskToCurrentDefault(base::BindOnce(
|
||||
&InProcessVideoCaptureDeviceLauncher::OnDeviceStarted,
|
||||
base::Unretained(this), callbacks, std::move(done_cb)));
|
||||
-
|
||||
+ LOG(ERROR) << "stream type: " << stream_type;
|
||||
+ LOG(ERROR) << "gum tab video capture: " << blink::mojom::MediaStreamType::GUM_TAB_VIDEO_CAPTURE;
|
||||
switch (stream_type) {
|
||||
- case blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE:
|
||||
- // Only the Service-based device launcher is supported for device capture
|
||||
- // from cameras etc.
|
||||
- NOTREACHED();
|
||||
+ // case blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE:
|
||||
+ // // Only the Service-based device launcher is supported for device capture
|
||||
+ // // from cameras etc.
|
||||
+ // LOG(INFO) << "device video capture not reached";
|
||||
+ // NOTREACHED();
|
||||
#if BUILDFLAG(ENABLE_SCREEN_CAPTURE)
|
||||
case blink::mojom::MediaStreamType::GUM_TAB_VIDEO_CAPTURE:
|
||||
start_capture_closure = base::BindOnce(
|
||||
@@ -274,10 +280,14 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
case blink::mojom::MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE:
|
||||
case blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE:
|
||||
case blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE_THIS_TAB:
|
||||
+ case blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE:
|
||||
case blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE_SET: {
|
||||
const DesktopMediaID desktop_id = DesktopMediaID::Parse(device_id);
|
||||
- if (desktop_id.is_null()) {
|
||||
- DLOG(ERROR) << "Desktop media ID is null";
|
||||
+ LOG(ERROR) << "desktop_id.is_null(): " << desktop_id.is_null();
|
||||
+ LOG(ERROR) << "desktop_id.id: " << desktop_id.id;
|
||||
+ LOG(ERROR) << "DesktopMediaID::kMacOsNativePickerId: " << DesktopMediaID::kMacOsNativePickerId;
|
||||
+ if (desktop_id.is_null() && desktop_id.id != DesktopMediaID::kMacOsNativePickerId) {
|
||||
+ LOG(ERROR) << "in null case";
|
||||
start_capture_closure =
|
||||
base::BindOnce(std::move(after_start_capture_callback), nullptr);
|
||||
break;
|
||||
@@ -319,13 +329,18 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
#if defined(USE_AURA)
|
||||
bool allow_window_id = false;
|
||||
#elif BUILDFLAG(IS_MAC)
|
||||
+
|
||||
bool allow_window_id =
|
||||
desktop_id.id == DesktopMediaID::kMacOsNativePickerId;
|
||||
+
|
||||
+ LOG(ERROR) << "allow_window_id: " << allow_window_id << " desktop_id.id: " << desktop_id.id;
|
||||
#endif
|
||||
|
||||
#if defined(USE_AURA) || BUILDFLAG(IS_MAC)
|
||||
+ LOG(ERROR) << "in if block";
|
||||
if (!allow_window_id &&
|
||||
desktop_id.window_id != DesktopMediaID::kNullId) {
|
||||
+ LOG(ERROR) << "allow_window_id: " << allow_window_id << " desktop_id.window_id: " << desktop_id.window_id;
|
||||
// For the other capturers, when a bug reports the type of capture it's
|
||||
// easy enough to determine which capturer was used, but it's a little
|
||||
// fuzzier with window capture.
|
||||
@@ -354,6 +369,7 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
kMaxNumberOfBuffers, std::move(receiver),
|
||||
std::move(receiver_on_io_thread)),
|
||||
std::move(after_start_capture_callback));
|
||||
+ LOG(ERROR) << "capture closure";
|
||||
break;
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_SCREEN_CAPTURE)
|
||||
@@ -368,6 +384,7 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
// above are NOTREACHED() then.
|
||||
#if BUILDFLAG(ENABLE_SCREEN_CAPTURE)
|
||||
state_ = State::DEVICE_START_IN_PROGRESS;
|
||||
+ LOG(ERROR) << "start capture closure";
|
||||
device_task_runner_->PostTask(FROM_HERE, std::move(start_capture_closure));
|
||||
#endif
|
||||
}
|
||||
@@ -418,9 +435,11 @@ void InProcessVideoCaptureDeviceLauncher::OnDeviceStarted(
|
||||
base::OnceClosure done_cb,
|
||||
std::unique_ptr<media::VideoCaptureDevice> device) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
+ LOG(ERROR) << "on device started";
|
||||
State state_copy = state_;
|
||||
state_ = State::READY_TO_LAUNCH;
|
||||
if (!device) {
|
||||
+ LOG(ERROR) << "device is null";
|
||||
switch (state_copy) {
|
||||
case State::DEVICE_START_IN_PROGRESS:
|
||||
callbacks->OnDeviceLaunchFailed(
|
||||
@@ -439,13 +458,15 @@ void InProcessVideoCaptureDeviceLauncher::OnDeviceStarted(
|
||||
|
||||
auto launched_device = std::make_unique<InProcessLaunchedVideoCaptureDevice>(
|
||||
std::move(device), device_task_runner_);
|
||||
-
|
||||
+ LOG(ERROR) << "launched device";
|
||||
switch (state_copy) {
|
||||
case State::DEVICE_START_IN_PROGRESS:
|
||||
+ LOG(ERROR) << "on device started, case 1";
|
||||
callbacks->OnDeviceLaunched(std::move(launched_device));
|
||||
std::move(done_cb).Run();
|
||||
return;
|
||||
case State::DEVICE_START_ABORTING:
|
||||
+ LOG(ERROR) << "on device started, case 2";
|
||||
launched_device.reset();
|
||||
callbacks->OnDeviceLaunchAborted();
|
||||
std::move(done_cb).Run();
|
||||
@@ -505,7 +526,8 @@ void InProcessVideoCaptureDeviceLauncher::DoStartDesktopCaptureOnDeviceThread(
|
||||
std::unique_ptr<media::VideoCaptureDeviceClient> device_client,
|
||||
ReceiveDeviceCallback result_callback) {
|
||||
DCHECK(device_task_runner_->BelongsToCurrentThread());
|
||||
- DCHECK(!desktop_id.is_null());
|
||||
+ LOG(INFO) << "DO START DESKTOP CAPTURE ON DEVICE THREAD " << desktop_id.id;
|
||||
+ DCHECK(!desktop_id.is_null() || desktop_id.id == DesktopMediaID::kMacOsNativePickerId);
|
||||
|
||||
std::unique_ptr<media::VideoCaptureDevice> video_capture_device;
|
||||
DesktopCaptureImplementation implementation =
|
||||
@@ -514,8 +536,10 @@ void InProcessVideoCaptureDeviceLauncher::DoStartDesktopCaptureOnDeviceThread(
|
||||
DVLOG(1) << __func__ << " implementation " << implementation << " type "
|
||||
<< desktop_id.type;
|
||||
ReportDesktopCaptureImplementationAndType(implementation, desktop_id.type);
|
||||
- if (video_capture_device)
|
||||
+ if (video_capture_device) {
|
||||
+ LOG(ERROR) << "allocate and start capture device";
|
||||
video_capture_device->AllocateAndStart(params, std::move(device_client));
|
||||
+ }
|
||||
std::move(result_callback).Run(std::move(video_capture_device));
|
||||
}
|
||||
|
||||
diff --git a/content/browser/renderer_host/media/in_process_video_capture_provider.cc b/content/browser/renderer_host/media/in_process_video_capture_provider.cc
|
||||
index 4462efa154a2be9cc25f82688fdbc7edf71a7bb1..4207dd1a79c16df5cc972943da32699f414f81fa 100644
|
||||
--- a/content/browser/renderer_host/media/in_process_video_capture_provider.cc
|
||||
+++ b/content/browser/renderer_host/media/in_process_video_capture_provider.cc
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/task/single_thread_task_runner.h"
|
||||
#include "content/browser/renderer_host/media/in_process_video_capture_device_launcher.h"
|
||||
+#include "content/browser/media/capture/native_screen_capture_picker.h"
|
||||
|
||||
namespace content {
|
||||
|
||||
diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc
|
||||
index 2949c2abd5f97e66719ec0f77cb23813865bb701..bd11a0fcdc084da00407c80e4ee229a130fdedc8 100644
|
||||
--- a/content/browser/renderer_host/media/video_capture_manager.cc
|
||||
+++ b/content/browser/renderer_host/media/video_capture_manager.cc
|
||||
@@ -283,6 +283,7 @@ void VideoCaptureManager::QueueStartDevice(
|
||||
mojo::PendingRemote<media::mojom::ReadonlyVideoEffectsManager>
|
||||
readonly_video_effects_manager) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
+ LOG(ERROR) << "QueueStartDevice";
|
||||
DCHECK(lock_time_.is_null());
|
||||
device_start_request_queue_.push_back(
|
||||
CaptureDeviceStartRequest(std::move(controller), session_id, params,
|
||||
@@ -297,6 +298,7 @@ void VideoCaptureManager::DoStopDevice(VideoCaptureController* controller) {
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
|
||||
"VideoCaptureManager::DoStopDevice");
|
||||
DCHECK(base::Contains(controllers_, controller));
|
||||
+ LOG(ERROR) << "DoStopDevice called for stream type: " << controller->stream_type();
|
||||
|
||||
// If start request has not yet started processing, i.e. if it is not at the
|
||||
// beginning of the queue, remove it from the queue.
|
||||
@@ -327,6 +329,7 @@ void VideoCaptureManager::DoStopDevice(VideoCaptureController* controller) {
|
||||
|
||||
void VideoCaptureManager::ProcessDeviceStartRequestQueue() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
+ LOG(ERROR) << "ProcessDeviceStartRequestQueue";
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
|
||||
"VideoCaptureManager::ProcessDeviceStartRequestQueue");
|
||||
auto request = device_start_request_queue_.begin();
|
||||
@@ -335,7 +338,7 @@ void VideoCaptureManager::ProcessDeviceStartRequestQueue() {
|
||||
|
||||
scoped_refptr<VideoCaptureController> const controller =
|
||||
request->controller();
|
||||
-
|
||||
+ LOG(ERROR) << "ProcessDeviceStartRequestQueue, controller: " << controller->device_id();
|
||||
EmitLogMessage("VideoCaptureManager::ProcessDeviceStartRequestQueue", 3);
|
||||
// The unit test VideoCaptureManagerTest.OpenNotExisting requires us to fail
|
||||
// synchronously if the stream_type is MEDIA_DEVICE_VIDEO_CAPTURE and no
|
||||
@@ -351,6 +354,7 @@ void VideoCaptureManager::ProcessDeviceStartRequestQueue() {
|
||||
const media::VideoCaptureDeviceInfo* device_info =
|
||||
GetDeviceInfoById(controller->device_id());
|
||||
if (!device_info) {
|
||||
+ LOG(ERROR) << "ProcessDeviceStartRequestQueue, device_info not found";
|
||||
OnDeviceLaunchFailed(
|
||||
controller.get(),
|
||||
media::VideoCaptureError::
|
||||
@@ -381,6 +385,7 @@ void VideoCaptureManager::ProcessDeviceStartRequestQueue() {
|
||||
void VideoCaptureManager::OnDeviceLaunched(VideoCaptureController* controller) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
std::ostringstream string_stream;
|
||||
+ LOG(ERROR) << "OnDeviceLaunched";
|
||||
string_stream << "Launching device has succeeded. device_id = "
|
||||
<< controller->device_id();
|
||||
EmitLogMessage(string_stream.str(), 1);
|
||||
@@ -391,7 +396,9 @@ void VideoCaptureManager::OnDeviceLaunched(VideoCaptureController* controller) {
|
||||
if (blink::IsVideoDesktopCaptureMediaType(controller->stream_type())) {
|
||||
const media::VideoCaptureSessionId session_id =
|
||||
device_start_request_queue_.front().session_id();
|
||||
+ LOG(ERROR) << "isvideodesktopcapturemediatype";
|
||||
DCHECK_NE(session_id, FakeSessionId());
|
||||
+ LOG(ERROR) << "maybe post desktop capture window id";
|
||||
MaybePostDesktopCaptureWindowId(session_id);
|
||||
}
|
||||
|
||||
@@ -407,7 +414,9 @@ void VideoCaptureManager::OnDeviceLaunched(VideoCaptureController* controller) {
|
||||
}
|
||||
}
|
||||
|
||||
+ LOG(ERROR) << "OnDeviceLaunched, device_start_request_queue_.pop_front";
|
||||
device_start_request_queue_.pop_front();
|
||||
+ LOG(ERROR) << "OnDeviceLaunched, ProcessDeviceStartRequestQueue";
|
||||
ProcessDeviceStartRequestQueue();
|
||||
}
|
||||
|
||||
@@ -467,6 +476,7 @@ void VideoCaptureManager::ConnectClient(
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
|
||||
"VideoCaptureManager::ConnectClient");
|
||||
+ LOG(ERROR) << "ConnectClient";
|
||||
{
|
||||
std::ostringstream string_stream;
|
||||
string_stream << "ConnectClient: session_id = " << session_id
|
||||
@@ -479,6 +489,7 @@ void VideoCaptureManager::ConnectClient(
|
||||
scoped_refptr<VideoCaptureController> controller =
|
||||
GetOrCreateController(session_id, params);
|
||||
if (!controller) {
|
||||
+ LOG(ERROR) << "ConnectClient, controller not found";
|
||||
std::move(done_cb).Run(nullptr);
|
||||
return;
|
||||
}
|
||||
@@ -502,6 +513,7 @@ void VideoCaptureManager::ConnectClient(
|
||||
string_stream
|
||||
<< "VideoCaptureManager queueing device start for device_id = "
|
||||
<< controller->device_id();
|
||||
+ LOG(ERROR) << "ConnectClient, videocapturemanager queueing device start for device_id = " << controller->device_id();
|
||||
EmitLogMessage(string_stream.str(), 1);
|
||||
mojo::PendingRemote<video_effects::mojom::VideoEffectsProcessor>
|
||||
video_effects_processor;
|
||||
@@ -524,6 +536,7 @@ void VideoCaptureManager::ConnectClient(
|
||||
readonly_video_effects_manager.InitWithNewPipeAndPassReceiver());
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_VIDEO_EFFECTS)
|
||||
+ LOG(ERROR) << "ConnectClient, videocapturemanager queueing device start for device_id = " << controller->device_id();
|
||||
QueueStartDevice(session_id, controller, params,
|
||||
std::move(video_effects_processor),
|
||||
std::move(readonly_video_effects_manager));
|
||||
diff --git a/content/public/browser/desktop_media_id.cc b/content/public/browser/desktop_media_id.cc
|
||||
index b39b684ff84baaf292eef1a23b7f9fb4585023c5..55507f7a782a9472800221f1e908618a5bad2914 100644
|
||||
--- a/content/public/browser/desktop_media_id.cc
|
||||
+++ b/content/public/browser/desktop_media_id.cc
|
||||
@@ -21,6 +21,7 @@ namespace content {
|
||||
|
||||
const char kScreenPrefix[] = "screen";
|
||||
const char kWindowPrefix[] = "window";
|
||||
+const char kNonePrefix[] = "none";
|
||||
|
||||
#if defined(USE_AURA) || BUILDFLAG(IS_MAC)
|
||||
// static
|
||||
@@ -82,6 +83,8 @@ DesktopMediaID DesktopMediaID::Parse(const std::string& str) {
|
||||
type = TYPE_SCREEN;
|
||||
} else if (parts[0] == kWindowPrefix) {
|
||||
type = TYPE_WINDOW;
|
||||
+ } else if (parts[0] == kNonePrefix) {
|
||||
+ type = TYPE_NONE;
|
||||
} else {
|
||||
return DesktopMediaID();
|
||||
}
|
||||
@@ -104,6 +107,8 @@ std::string DesktopMediaID::ToString() const {
|
||||
std::string prefix;
|
||||
switch (type) {
|
||||
case TYPE_NONE:
|
||||
+ prefix = kNonePrefix;
|
||||
+ break;
|
||||
NOTREACHED();
|
||||
case TYPE_SCREEN:
|
||||
prefix = kScreenPrefix;
|
||||
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
|
||||
index c458c1e87dc46cf4f92d5c4423ab837f29067aa0..1749fb96bbd0c69ad5c6377eabb4bbab12e3f7c3 100644
|
||||
--- a/media/base/media_switches.cc
|
||||
+++ b/media/base/media_switches.cc
|
||||
@@ -356,7 +356,7 @@ BASE_FEATURE(kMacLoopbackAudioForScreenShare,
|
||||
// is required to avoid recurring permission dialogs.
|
||||
BASE_FEATURE(kUseSCContentSharingPicker,
|
||||
"UseSCContentSharingPicker",
|
||||
- base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
+ base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
diff --git a/media/capture/video/file_video_capture_device.cc b/media/capture/video/file_video_capture_device.cc
|
||||
index 5090aae198e4e0e52212eb502bb4de0475c79b04..c74887a14bcc4249e433d2afd545029d36f744bf 100644
|
||||
--- a/media/capture/video/file_video_capture_device.cc
|
||||
+++ b/media/capture/video/file_video_capture_device.cc
|
||||
@@ -482,6 +482,7 @@ void FileVideoCaptureDevice::AllocateAndStart(
|
||||
CHECK(!capture_thread_.IsRunning());
|
||||
|
||||
capture_thread_.Start();
|
||||
+ LOG(ERROR) << "allocate and start file video capture device";
|
||||
capture_thread_.task_runner()->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&FileVideoCaptureDevice::OnAllocateAndStart,
|
||||
@@ -604,6 +605,7 @@ void FileVideoCaptureDevice::TakePhoto(TakePhotoCallback callback) {
|
||||
void FileVideoCaptureDevice::OnAllocateAndStart(
|
||||
const VideoCaptureParams& params,
|
||||
std::unique_ptr<VideoCaptureDevice::Client> client) {
|
||||
+ LOG(ERROR) << "on allocate and start file video capture device";
|
||||
DCHECK(capture_thread_.task_runner()->BelongsToCurrentThread());
|
||||
|
||||
client_ = std::move(client);
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/containers/flat_map.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "chrome/browser/media/webrtc/desktop_capturer_wrapper.h"
|
||||
@@ -18,6 +20,7 @@
|
||||
#include "content/public/browser/desktop_capture.h"
|
||||
#include "gin/handle.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "media/base/media_switches.h"
|
||||
#include "shell/browser/javascript_environment.h"
|
||||
#include "shell/common/api/electron_api_native_image.h"
|
||||
#include "shell/common/gin_converters/gfx_converter.h"
|
||||
@@ -143,6 +146,21 @@ base::flat_map<int32_t, uint32_t> MonitorAtomIdToDisplayId() {
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<ThumbnailCapturer> MakeScreenAndWindowCapturer() {
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
if (ShouldUseThumbnailCapturerMac(DesktopMediaList::Type::kNone)) {
|
||||
LOG(ERROR) << "creating thumbnail capturer, knone *****";
|
||||
return CreateThumbnailCapturerMac(DesktopMediaList::Type::kNone);
|
||||
}
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
LOG(ERROR) << "should not hit this *****";
|
||||
std::unique_ptr<webrtc::DesktopCapturer> window_capturer =
|
||||
content::desktop_capture::CreateWindowCapturer();
|
||||
return window_capturer ? std::make_unique<DesktopCapturerWrapper>(
|
||||
std::move(window_capturer))
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<ThumbnailCapturer> MakeWindowCapturer() {
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
if (ShouldUseThumbnailCapturerMac(DesktopMediaList::Type::kWindow)) {
|
||||
@@ -258,7 +276,8 @@ void DesktopCapturer::DesktopListListener::OnDelegatedSourceListDismissed() {
|
||||
void DesktopCapturer::StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
const gfx::Size& thumbnail_size,
|
||||
bool fetch_window_icons) {
|
||||
bool fetch_window_icons,
|
||||
bool use_system_picker) {
|
||||
fetch_window_icons_ = fetch_window_icons;
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
if (content::desktop_capture::CreateDesktopCaptureOptions()
|
||||
@@ -272,35 +291,76 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
|
||||
// clear any existing captured sources.
|
||||
captured_sources_.clear();
|
||||
|
||||
LOG(ERROR) << "capture_window: " << capture_window << " capture_screen: " << capture_screen;
|
||||
if (capture_window && capture_screen) {
|
||||
// Some capturers like PipeWire support a single capturer for both screens
|
||||
// and windows. Use it if possible, treating both as window capture
|
||||
std::unique_ptr<webrtc::DesktopCapturer> desktop_capturer =
|
||||
webrtc::DesktopCapturer::CreateGenericCapturer(
|
||||
content::desktop_capture::CreateDesktopCaptureOptions());
|
||||
auto capturer = desktop_capturer ? std::make_unique<DesktopCapturerWrapper>(
|
||||
std::move(desktop_capturer))
|
||||
: nullptr;
|
||||
if (capturer && capturer->GetDelegatedSourceListController()) {
|
||||
capture_screen_ = false;
|
||||
if (IsDisplayMediaSystemPickerAvailable()) {
|
||||
auto capturer = MakeScreenAndWindowCapturer();
|
||||
capture_screen_ = capture_screen;
|
||||
capture_window_ = capture_window;
|
||||
window_capturer_ = std::make_unique<NativeDesktopMediaList>(
|
||||
DesktopMediaList::Type::kWindow, std::move(capturer), true, true);
|
||||
window_capturer_->SetThumbnailSize(thumbnail_size);
|
||||
// TODO(review): Maybe just call this a capturer
|
||||
screen_capturer_ = std::make_unique<NativeDesktopMediaList>(
|
||||
DesktopMediaList::Type::kNone, std::move(capturer), true, true);
|
||||
screen_capturer_->SetThumbnailSize(thumbnail_size);
|
||||
screen_capturer_->ShowDelegatedList();
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
screen_capturer_->skip_next_refresh_ =
|
||||
ShouldUseThumbnailCapturerMac(DesktopMediaList::Type::kNone) ? 2 : 0;
|
||||
LOG(ERROR) << "SET SKIP NEXT REFRESH TO 2";
|
||||
#endif
|
||||
|
||||
LOG(ERROR) << "screen_capturer_->skip_next_refresh_ " << screen_capturer_->skip_next_refresh_;
|
||||
OnceCallback update_callback = base::BindOnce(
|
||||
&DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),
|
||||
window_capturer_.get());
|
||||
OnceCallback failure_callback = base::BindOnce(
|
||||
&DesktopCapturer::HandleFailure, weak_ptr_factory_.GetWeakPtr());
|
||||
screen_capturer_.get());
|
||||
|
||||
window_listener_ = std::make_unique<DesktopListListener>(
|
||||
std::move(update_callback), std::move(failure_callback),
|
||||
thumbnail_size.IsEmpty());
|
||||
window_capturer_->StartUpdating(window_listener_.get());
|
||||
// Needed to force a refresh for the native MacOS Picker
|
||||
OnceCallback wrapped_update_callback = base::BindOnce(
|
||||
&DesktopCapturer::RequestUpdate, weak_ptr_factory_.GetWeakPtr(),
|
||||
screen_capturer_.get(), std::move(update_callback));
|
||||
|
||||
if (screen_capturer_->IsSourceListDelegated()) {
|
||||
OnceCallback failure_callback = base::BindOnce(
|
||||
&DesktopCapturer::HandleFailure, weak_ptr_factory_.GetWeakPtr());
|
||||
screen_listener_ = std::make_unique<DesktopListListener>(
|
||||
std::move(wrapped_update_callback), std::move(failure_callback),
|
||||
thumbnail_size.IsEmpty());
|
||||
screen_capturer_->StartUpdating(screen_listener_.get());
|
||||
} else {
|
||||
screen_capturer_->Update(std::move(update_callback),
|
||||
/* refresh_thumbnails = */ true);
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
// Some capturers like PipeWire support a single capturer for both screens
|
||||
// and windows. Use it if possible, treating both as window capture
|
||||
std::unique_ptr<webrtc::DesktopCapturer> desktop_capturer =
|
||||
webrtc::DesktopCapturer::CreateGenericCapturer(
|
||||
content::desktop_capture::CreateDesktopCaptureOptions());
|
||||
auto capturer = desktop_capturer
|
||||
? std::make_unique<DesktopCapturerWrapper>(
|
||||
std::move(desktop_capturer))
|
||||
: nullptr;
|
||||
if (capturer && capturer->GetDelegatedSourceListController()) {
|
||||
capture_screen_ = false;
|
||||
capture_window_ = capture_window;
|
||||
window_capturer_ = std::make_unique<NativeDesktopMediaList>(
|
||||
DesktopMediaList::Type::kWindow, std::move(capturer));
|
||||
window_capturer_->SetThumbnailSize(thumbnail_size);
|
||||
|
||||
OnceCallback update_callback = base::BindOnce(
|
||||
&DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),
|
||||
window_capturer_.get());
|
||||
OnceCallback failure_callback = base::BindOnce(
|
||||
&DesktopCapturer::HandleFailure, weak_ptr_factory_.GetWeakPtr());
|
||||
|
||||
window_listener_ = std::make_unique<DesktopListListener>(
|
||||
std::move(update_callback), std::move(failure_callback),
|
||||
thumbnail_size.IsEmpty());
|
||||
window_capturer_->StartUpdating(window_listener_.get());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,21 +379,30 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
// Initialize the source list.
|
||||
// Apply the new thumbnail size and restart capture.
|
||||
if (capture_window) {
|
||||
LOG(ERROR) << "WE SHOULDNT BE HERE *****";
|
||||
auto capturer = MakeWindowCapturer();
|
||||
if (capturer) {
|
||||
window_capturer_ = std::make_unique<NativeDesktopMediaList>(
|
||||
DesktopMediaList::Type::kWindow, std::move(capturer), true, true);
|
||||
window_capturer_->SetThumbnailSize(thumbnail_size);
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
window_capturer_->skip_next_refresh_ =
|
||||
ShouldUseThumbnailCapturerMac(DesktopMediaList::Type::kWindow) ? 2
|
||||
: 0;
|
||||
#endif
|
||||
|
||||
OnceCallback update_callback = base::BindOnce(
|
||||
&DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),
|
||||
window_capturer_.get());
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
window_capturer_->skip_next_refresh_ =
|
||||
ShouldUseThumbnailCapturerMac(DesktopMediaList::Type::kWindow) ? 2
|
||||
: 0;
|
||||
|
||||
if (base::FeatureList::IsEnabled(media::kUseSCContentSharingPicker)) {
|
||||
window_capturer_->ShowDelegatedList();
|
||||
// Needed to force a refresh for the native MacOS Picker
|
||||
update_callback = base::BindOnce(
|
||||
&DesktopCapturer::RequestUpdate, weak_ptr_factory_.GetWeakPtr(),
|
||||
window_capturer_.get(), std::move(update_callback));
|
||||
}
|
||||
#endif
|
||||
if (window_capturer_->IsSourceListDelegated()) {
|
||||
OnceCallback failure_callback = base::BindOnce(
|
||||
&DesktopCapturer::HandleFailure, weak_ptr_factory_.GetWeakPtr());
|
||||
@@ -354,16 +423,25 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
screen_capturer_ = std::make_unique<NativeDesktopMediaList>(
|
||||
DesktopMediaList::Type::kScreen, std::move(capturer));
|
||||
screen_capturer_->SetThumbnailSize(thumbnail_size);
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
screen_capturer_->skip_next_refresh_ =
|
||||
ShouldUseThumbnailCapturerMac(DesktopMediaList::Type::kScreen) ? 2
|
||||
: 0;
|
||||
#endif
|
||||
|
||||
OnceCallback update_callback = base::BindOnce(
|
||||
&DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),
|
||||
screen_capturer_.get());
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
screen_capturer_->skip_next_refresh_ =
|
||||
ShouldUseThumbnailCapturerMac(DesktopMediaList::Type::kScreen) ? 2
|
||||
: 0;
|
||||
|
||||
if (base::FeatureList::IsEnabled(media::kUseSCContentSharingPicker)) {
|
||||
screen_capturer_->ShowDelegatedList();
|
||||
// Needed to force a refresh for the native MacOS Picker
|
||||
update_callback = base::BindOnce(
|
||||
&DesktopCapturer::RequestUpdate, weak_ptr_factory_.GetWeakPtr(),
|
||||
screen_capturer_.get(), std::move(update_callback));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (screen_capturer_->IsSourceListDelegated()) {
|
||||
OnceCallback failure_callback = base::BindOnce(
|
||||
&DesktopCapturer::HandleFailure, weak_ptr_factory_.GetWeakPtr());
|
||||
@@ -380,9 +458,15 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
}
|
||||
}
|
||||
|
||||
void DesktopCapturer::RequestUpdate(DesktopMediaList* list,
|
||||
OnceCallback update_callback) {
|
||||
list->Update(std::move(update_callback));
|
||||
}
|
||||
|
||||
void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
if (capture_window_ &&
|
||||
list->GetMediaListType() == DesktopMediaList::Type::kWindow) {
|
||||
(list->GetMediaListType() == DesktopMediaList::Type::kWindow ||
|
||||
list->GetMediaListType() == DesktopMediaList::Type::kNone)) {
|
||||
capture_window_ = false;
|
||||
std::vector<DesktopCapturer::Source> window_sources;
|
||||
window_sources.reserve(list->GetSourceCount());
|
||||
@@ -395,7 +479,8 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
}
|
||||
|
||||
if (capture_screen_ &&
|
||||
list->GetMediaListType() == DesktopMediaList::Type::kScreen) {
|
||||
(list->GetMediaListType() == DesktopMediaList::Type::kScreen ||
|
||||
list->GetMediaListType() == DesktopMediaList::Type::kNone)) {
|
||||
capture_screen_ = false;
|
||||
std::vector<DesktopCapturer::Source> screen_sources;
|
||||
screen_sources.reserve(list->GetSourceCount());
|
||||
@@ -465,7 +550,6 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
std::move(screen_sources.begin(), screen_sources.end(),
|
||||
std::back_inserter(captured_sources_));
|
||||
}
|
||||
|
||||
if (!capture_window_ && !capture_screen_)
|
||||
HandleSuccess();
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@ class DesktopCapturer final : public gin::Wrappable<DesktopCapturer>,
|
||||
void StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
const gfx::Size& thumbnail_size,
|
||||
bool fetch_window_icons);
|
||||
bool fetch_window_icons,
|
||||
bool use_system_picker);
|
||||
|
||||
// gin::Wrappable
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
@@ -94,6 +95,7 @@ class DesktopCapturer final : public gin::Wrappable<DesktopCapturer>,
|
||||
bool have_thumbnail_ = false;
|
||||
};
|
||||
|
||||
void RequestUpdate(DesktopMediaList* list, OnceCallback update_callback);
|
||||
void UpdateSourcesList(DesktopMediaList* list);
|
||||
void HandleFailure();
|
||||
void HandleSuccess();
|
||||
|
||||
@@ -26,6 +26,27 @@ std::string EnablePlatformSpecificFeatures() {
|
||||
#else
|
||||
return "ScreenCaptureKitPickerScreen,ScreenCaptureKitStreamPickerSonoma,"
|
||||
"ThumbnailCapturerMac:capture_mode/sc_screenshot_manager";
|
||||
#endif
|
||||
}
|
||||
if (@available(macOS 15.0, *)) {
|
||||
// These flags aren't exported so reference them by name directly, they are
|
||||
// used to ensure that screen and window capture exclusive use
|
||||
// ScreenCaptureKit APIs to avoid warning dialogs on macOS 15.0 and higher.
|
||||
// kScreenCaptureKitPickerScreen,
|
||||
// chrome/browser/media/webrtc/thumbnail_capturer_mac.mm
|
||||
// kScreenCaptureKitStreamPickerSonoma,
|
||||
// chrome/browser/media/webrtc/thumbnail_capturer_mac.mm
|
||||
// kThumbnailCapturerMac,
|
||||
// chrome/browser/media/webrtc/thumbnail_capturer_mac.mm
|
||||
// kUseSCContentSharingPicker,
|
||||
// chrome/browser/media/webrtc/thumbnail_capturer_mac.mm
|
||||
#if DCHECK_IS_ON()
|
||||
return "ScreenCaptureKitPickerScreen,ScreenCaptureKitStreamPickerSonoma,"
|
||||
"UseSCContentSharingPicker";
|
||||
#else
|
||||
return "ScreenCaptureKitPickerScreen,ScreenCaptureKitStreamPickerSonoma,"
|
||||
"UseSCContentSharingPicker,"
|
||||
"ThumbnailCapturerMac:capture_mode/sc_screenshot_manager";
|
||||
#endif
|
||||
}
|
||||
return "";
|
||||
|
||||
30
shell/common/gin_converters/display_surface_converter.cc
Normal file
30
shell/common/gin_converters/display_surface_converter.cc
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2021 Slack Technologies, LLC.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/common/gin_converters/display_surface_converter.h"
|
||||
|
||||
#include "content/public/browser/media_stream_request.h"
|
||||
#include "gin/data_object_builder.h"
|
||||
#include "shell/common/gin_converters/frame_converter.h"
|
||||
#include "shell/common/gin_converters/gurl_converter.h"
|
||||
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
|
||||
|
||||
namespace gin {
|
||||
|
||||
v8::Local<v8::Value> Converter<blink::mojom::PreferredDisplaySurface>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
blink::mojom::PreferredDisplaySurface type) {
|
||||
switch (type) {
|
||||
case blink::mojom::PreferredDisplaySurface::NO_PREFERENCE:
|
||||
return StringToV8(isolate, "no_preference");
|
||||
case blink::mojom::PreferredDisplaySurface::MONITOR:
|
||||
return StringToV8(isolate, "monitor");
|
||||
case blink::mojom::PreferredDisplaySurface::WINDOW:
|
||||
return StringToV8(isolate, "window");
|
||||
default:
|
||||
return StringToV8(isolate, "unknown");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gin
|
||||
36
shell/common/gin_converters/display_surface_converter.h
Normal file
36
shell/common/gin_converters/display_surface_converter.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2024 Slack, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ELECTRON_SHELL_BROWSER_API_DISPLAY_SOURCE_CONVERTER_H_
|
||||
#define ELECTRON_SHELL_BROWSER_API_DISPLAY_SOURCE_CONVERTER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "gin/converter.h"
|
||||
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
// cf:
|
||||
// Chrome also allows browser here, but Electron does not.
|
||||
enum PreferredDisplaySurface {
|
||||
NO_PREFERENCE,
|
||||
MONITOR,
|
||||
WINDOW,
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
namespace gin {
|
||||
|
||||
template <>
|
||||
struct Converter<blink::mojom::PreferredDisplaySurface> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
blink::mojom::PreferredDisplaySurface val);
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
|
||||
#endif // ELECTRON_SHELL_BROWSER_DISPLAY_SOURCE_CONVERTER_H_
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "content/public/browser/media_stream_request.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "gin/data_object_builder.h"
|
||||
#include "shell/common/gin_converters/display_surface_converter.h"
|
||||
#include "shell/common/gin_converters/frame_converter.h"
|
||||
#include "shell/common/gin_converters/gurl_converter.h"
|
||||
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
|
||||
@@ -22,6 +23,7 @@ v8::Local<v8::Value> Converter<content::MediaStreamRequest>::ToV8(
|
||||
.Set("frame", rfh)
|
||||
.Set("securityOrigin", request.security_origin)
|
||||
.Set("userGesture", request.user_gesture)
|
||||
.Set("preferredDisplaySurface", request.preferred_display_surface)
|
||||
.Set("videoRequested",
|
||||
request.video_type != blink::mojom::MediaStreamType::NO_SERVICE)
|
||||
.Set("audioRequested",
|
||||
|
||||
6
typings/internal-electron.d.ts
vendored
6
typings/internal-electron.d.ts
vendored
@@ -149,6 +149,10 @@ declare namespace Electron {
|
||||
_setDisplayMediaRequestHandler: Electron.Session['setDisplayMediaRequestHandler'];
|
||||
}
|
||||
|
||||
interface DisplayMediaRequestHandlerOpts {
|
||||
userSystemPicker: boolean,
|
||||
}
|
||||
|
||||
type CreateWindowFunction = (options: BrowserWindowConstructorOptions) => WebContents;
|
||||
|
||||
interface Menu {
|
||||
@@ -262,7 +266,7 @@ declare namespace Electron {
|
||||
|
||||
declare namespace ElectronInternal {
|
||||
interface DesktopCapturer {
|
||||
startHandling(captureWindow: boolean, captureScreen: boolean, thumbnailSize: Electron.Size, fetchWindowIcons: boolean): void;
|
||||
startHandling(captureWindow: boolean, captureScreen: boolean, thumbnailSize: Electron.Size, fetchWindowIcons: boolean, useSystemPicker: boolean): void;
|
||||
_onerror?: (error: string) => void;
|
||||
_onfinished?: (sources: Electron.DesktopCapturerSource[], fetchWindowIcons: boolean) => void;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user