mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
15 Commits
v39.3.0
...
sckp-macos
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { BrowserWindow } from 'electron/main';
|
||||
|
||||
const { createDesktopCapturer, isDisplayMediaSystemPickerAvailable } = process._linkedBinding('electron_browser_desktop_capturer');
|
||||
|
||||
const deepEqual = (a: ElectronInternal.GetSourcesOptions, b: ElectronInternal.GetSourcesOptions) => JSON.stringify(a) === JSON.stringify(b);
|
||||
@@ -16,7 +15,7 @@ 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();
|
||||
@@ -32,14 +31,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 +81,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({
|
||||
|
||||
@@ -1,26 +1,64 @@
|
||||
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) {
|
||||
|
||||
// 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);
|
||||
|
||||
// edit the first media stream's id to be window:${kMacOsNativePickerId}:${fakeVideoWindowId--}
|
||||
|
||||
if (mediaStreams.length === 0) {
|
||||
throw new Error('No media streams found');
|
||||
}
|
||||
|
||||
mediaStreams[0].id = `window:${kMacOsNativePickerId}:${fakeVideoWindowId--}`;
|
||||
|
||||
console.log("MEDIASREEAMS", mediaStreams);
|
||||
return mediaStreams[0];
|
||||
}
|
||||
|
||||
Session.prototype._init = function () {
|
||||
addIpcDispatchListeners(this);
|
||||
@@ -48,12 +86,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,6 @@ 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.patch
|
||||
feat_allow_desktop_capturer_to_return_either_screen_window_or_both.patch
|
||||
feat_make_macos_sccontentsharingpicker_work_in_electron_and_return_screen_window_or_both.patch
|
||||
|
||||
@@ -0,0 +1,852 @@
|
||||
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 85320190d406bdd37175ddb5d207d124b278b648..677dfdbc761dcc942b865ed073b16ea7c8a269da 100644
|
||||
--- a/chrome/browser/media/webrtc/capture_policy_utils.cc
|
||||
+++ b/chrome/browser/media/webrtc/capture_policy_utils.cc
|
||||
@@ -362,6 +362,7 @@ void FilterMediaList(std::vector<DesktopMediaList::Type>& media_types,
|
||||
media_types, [capture_level](const DesktopMediaList::Type& type) {
|
||||
switch (type) {
|
||||
case DesktopMediaList::Type::kNone:
|
||||
+ // 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.
|
||||
diff --git a/chrome/browser/media/webrtc/desktop_media_list_base.cc b/chrome/browser/media/webrtc/desktop_media_list_base.cc
|
||||
index 08400be4d1bae18502d19beed6b2d9057e55dd4f..d2ec9baf3219f4b38db4771a1ca1b3b5fd86dba0 100644
|
||||
--- a/chrome/browser/media/webrtc/desktop_media_list_base.cc
|
||||
+++ b/chrome/browser/media/webrtc/desktop_media_list_base.cc
|
||||
@@ -15,6 +15,7 @@
|
||||
#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"
|
||||
@@ -77,7 +78,13 @@ void DesktopMediaListBase::StartUpdating(DesktopMediaListObserver* observer) {
|
||||
void DesktopMediaListBase::Update(UpdateCallback callback, bool refresh_thumbnails) {
|
||||
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 0ac8e20073bd2db507e49200fd0b48f8535d666b..bdac26dcb020adb45731cecdfe0938c2334d0b51 100644
|
||||
--- a/chrome/browser/media/webrtc/native_desktop_media_list.cc
|
||||
+++ b/chrome/browser/media/webrtc/native_desktop_media_list.cc
|
||||
@@ -46,6 +46,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
|
||||
|
||||
@@ -181,14 +182,16 @@ BASE_FEATURE(kWindowCaptureMacV2,
|
||||
|
||||
content::DesktopMediaID::Type ConvertToDesktopMediaIDType(
|
||||
DesktopMediaList::Type type) {
|
||||
+ LOG(INFO) << "Inside ConvertToDesktopMediaIDType";
|
||||
switch (type) {
|
||||
case DesktopMediaList::Type::kScreen:
|
||||
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();
|
||||
@@ -201,6 +204,7 @@ content::DesktopMediaID::Id GetUpdatedWindowId(
|
||||
|
||||
// Use current value by default.
|
||||
content::DesktopMediaID::Id window_id = desktop_media_id.window_id;
|
||||
+ LOG(INFO) << "Inside GetUpdatedWindowId" << window_id;
|
||||
|
||||
// Update |window_id| if |desktop_media_id.id| corresponds to a
|
||||
// viz::FrameSinkId.
|
||||
@@ -411,8 +415,8 @@ NativeDesktopMediaList::Worker::Worker(
|
||||
nullptr) {
|
||||
DCHECK(capturer_);
|
||||
|
||||
- DCHECK(source_type_ == DesktopMediaID::Type::TYPE_WINDOW ||
|
||||
- !add_current_process_windows_);
|
||||
+ // DCHECK(source_type_ == DesktopMediaID::Type::TYPE_WINDOW ||
|
||||
+ // !add_current_process_windows_);
|
||||
}
|
||||
|
||||
NativeDesktopMediaList::Worker::~Worker() {
|
||||
@@ -430,12 +434,17 @@ void NativeDesktopMediaList::Worker::Start() {
|
||||
|
||||
void NativeDesktopMediaList::Worker::Refresh(bool update_thumbnails) {
|
||||
DCHECK(task_runner_->BelongsToCurrentThread());
|
||||
+ DLOG(INFO) << "Refresh";
|
||||
|
||||
webrtc::DesktopCapturer::SourceList sources;
|
||||
if (!capturer_->GetSourceList(&sources)) {
|
||||
// Will pass empty results list to RefreshForVizFrameSinkWindows().
|
||||
+ LOG(ERROR) << "Failed to get source list";
|
||||
sources.clear();
|
||||
}
|
||||
+ for (const auto& source : sources) {
|
||||
+ LOG(INFO) << "Source ID: " << source.id;
|
||||
+ }
|
||||
|
||||
if (capturer_->GetFrameDeliveryMethod() ==
|
||||
ThumbnailCapturer::FrameDeliveryMethod::kMultipleSourcesRecurrent) {
|
||||
@@ -532,7 +541,10 @@ NativeDesktopMediaList::Worker::FormatSources(
|
||||
std::vector<SourceDescription> source_descriptions;
|
||||
std::u16string title;
|
||||
for (size_t i = 0; i < sources.size(); ++i) {
|
||||
+ // LOG(INFO) << "source_type" << source_type;
|
||||
switch (source_type) {
|
||||
+ // case DesktopMediaID::Type::TYPE_NONE:
|
||||
+ // continue;
|
||||
case DesktopMediaID::Type::TYPE_SCREEN:
|
||||
// Just in case 'Screen' is inflected depending on the screen number,
|
||||
// use plural formatter.
|
||||
@@ -545,17 +557,38 @@ 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.
|
||||
+ LOG(INFO) << "ShouldUseSCContentSharingPicker: " << ShouldUseSCContentSharingPicker();
|
||||
+ if (ShouldUseSCContentSharingPicker()) {
|
||||
+ LOG(INFO) << "setting title to sources[i].title" << sources[i].title;
|
||||
+ title = base::UTF8ToUTF16(sources[i].title);
|
||||
+ } else if (sources[i].id == excluded_window_id) {
|
||||
+ LOG(INFO) << "skipping the picker dialog window";
|
||||
+ // 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:
|
||||
NOTREACHED();
|
||||
}
|
||||
DesktopMediaID source_id(source_type, sources[i].id);
|
||||
+ // for each source log its id
|
||||
+ for (size_t j = 0; j < sources.size(); ++j) {
|
||||
+ LOG(INFO) << "for loop source_id: " << sources[j].id;
|
||||
+ }
|
||||
+ LOG(INFO) << "source_id: " << source_id.id;
|
||||
#if BUILDFLAG(IS_CHROMEOS_LACROS)
|
||||
// We need to communicate this in_process_id to
|
||||
// |RefreshForVizFrameSinkWindows|, so we'll use the window_id. If
|
||||
@@ -820,14 +853,18 @@ NativeDesktopMediaList::NativeDesktopMediaList(
|
||||
is_source_list_delegated_(capturer->GetDelegatedSourceListController() !=
|
||||
nullptr) {
|
||||
type_ = type;
|
||||
-
|
||||
- DCHECK(type_ == DesktopMediaList::Type::kWindow ||
|
||||
- !add_current_process_windows_);
|
||||
+ LOG(INFO) << "is_source_list_delegated_: " << is_source_list_delegated_;
|
||||
+ LOG(INFO) << "Inside NativeDesktopMediaList, type of kwindow: " << static_cast<int>(DesktopMediaList::Type::kWindow) << ";";
|
||||
+ LOG(INFO) << "Inside NativeDesktopMediaList, type of kscreen: " << static_cast<int>(DesktopMediaList::Type::kScreen) << ";";
|
||||
+ LOG(INFO) << "Inside NativeDesktopMediaList, type of kwebcontents: " << static_cast<int>(DesktopMediaList::Type::kWebContents) << ";";
|
||||
+ LOG(INFO) << "Inside NativeDesktopMediaList, type of kcurrenttab: " << static_cast<int>(DesktopMediaList::Type::kCurrentTab) << ";";
|
||||
+ LOG(INFO) << "Inside NativeDesktopMediaList, type of knone: " << static_cast<int>(DesktopMediaList::Type::kNone) << ";";
|
||||
+ LOG(INFO) << "Inside NativeDesktopMediaList, type: " << static_cast<int>(type_) << ";";
|
||||
+ LOG(INFO) << "Inside NativeDesktopMediaList, add_current_process_windows: " << !add_current_process_windows_ << ";";
|
||||
+ // DCHECK(type_ == DesktopMediaList::Type::kWindow ||
|
||||
+ // !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;
|
||||
@@ -839,8 +876,11 @@ NativeDesktopMediaList::NativeDesktopMediaList(
|
||||
std::move(capturer), add_current_process_windows_,
|
||||
auto_show_delegated_source_list);
|
||||
|
||||
- if (!is_source_list_delegated_)
|
||||
+ if (!is_source_list_delegated_) {
|
||||
+ LOG(INFO) << "Inside NativeDesktopMediaList, is_source_list_delegated_: " << is_source_list_delegated_ << ";";
|
||||
+ LOG(INFO) << "start capture, sourcelist not delegated";
|
||||
StartCapturer();
|
||||
+ }
|
||||
}
|
||||
|
||||
NativeDesktopMediaList::~NativeDesktopMediaList() {
|
||||
@@ -892,11 +932,16 @@ bool NativeDesktopMediaList::IsSourceListDelegated() const {
|
||||
void NativeDesktopMediaList::StartDelegatedCapturer() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
DCHECK(IsSourceListDelegated());
|
||||
+ LOG(INFO) << "Inside NativeDesktopMediaList, StartDelegatedCapturer";
|
||||
+ // starting again, this time from the call "startupdating the delegated capturer";
|
||||
+ LOG(INFO) << "is_capturer_started_ we could be starting again: " << is_capturer_started_ << ";";
|
||||
StartCapturer();
|
||||
}
|
||||
|
||||
void NativeDesktopMediaList::StartCapturer() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
+ LOG(INFO) << "Inside NativeDesktopMediaList, StartCapturer";
|
||||
+ LOG(INFO) << "is_capturer_started_: " << is_capturer_started_ << ";";
|
||||
DCHECK(!is_capturer_started_);
|
||||
// base::Unretained is safe here because we own the lifetime of both the
|
||||
// worker and the thread and ensure that destroying the worker is the last
|
||||
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 47a5ad2b7e2bc86a614488fd3fe85da1e3e2d6f2..d6db4e5e22c568f70fb3e6c5f479807a2bfeecff 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"
|
||||
@@ -80,11 +81,12 @@
|
||||
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;
|
||||
+ // break;
|
||||
}
|
||||
NOTREACHED();
|
||||
}
|
||||
@@ -479,8 +481,9 @@ void OnCapturedFrame(base::apple::ScopedCFTypeRef<CGImageRef> image,
|
||||
max_frame_rate_(kThumbnailCapturerMacMaxFrameRate.Get()),
|
||||
minimum_window_size_(kThumbnailCapturerMacMinWindowSize.Get()),
|
||||
shareable_windows_([[NSArray<SCWindow*> alloc] init]) {
|
||||
+ LOG(INFO) << "ThumbnailCapturerMac::ThumbnailCapturerMac";
|
||||
CHECK(type_ == DesktopMediaList::Type::kWindow ||
|
||||
- type_ == DesktopMediaList::Type::kScreen);
|
||||
+ type_ == DesktopMediaList::Type::kScreen || type_ == DesktopMediaList::Type::kNone);
|
||||
}
|
||||
|
||||
ThumbnailCapturerMac::~ThumbnailCapturerMac() {
|
||||
@@ -761,17 +764,19 @@ 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;
|
||||
- }
|
||||
+ // if (base::FeatureList::IsEnabled(media::kUseSCContentSharingPicker)) {
|
||||
+ // return true;
|
||||
+ // }
|
||||
+ // TODO: turn on this flag
|
||||
+ return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
-} // namespace
|
||||
-
|
||||
bool ShouldUseThumbnailCapturerMac(DesktopMediaList::Type type) {
|
||||
// There was a bug in ScreenCaptureKit that was fixed in 14.4,
|
||||
// see b/40076027.
|
||||
@@ -785,6 +790,8 @@ bool ShouldUseThumbnailCapturerMac(DesktopMediaList::Type type) {
|
||||
return ShouldUseSCContentSharingPicker() ||
|
||||
base::FeatureList::IsEnabled(kScreenCaptureKitPickerScreen);
|
||||
case DesktopMediaList::Type::kNone:
|
||||
+ // TODO: george
|
||||
+ return true;
|
||||
case DesktopMediaList::Type::kCurrentTab:
|
||||
case DesktopMediaList::Type::kWebContents:
|
||||
return false;
|
||||
@@ -798,12 +805,15 @@ bool ShouldUseThumbnailCapturerMac(DesktopMediaList::Type type) {
|
||||
std::unique_ptr<ThumbnailCapturer> CreateThumbnailCapturerMac(
|
||||
DesktopMediaList::Type type) {
|
||||
CHECK(ShouldUseThumbnailCapturerMac(type));
|
||||
+ LOG(INFO) << "CreateThumbnailCapturerMac";
|
||||
if (ShouldUseSCContentSharingPicker()) {
|
||||
+ LOG(INFO) << "CreateThumbnailCapturerMac: SCContentSharingPicker";
|
||||
return std::make_unique<DesktopCapturerWrapper>(
|
||||
std::make_unique<DelegatedSourceListCapturer>(
|
||||
ConvertToDesktopMediaIDType(type)));
|
||||
}
|
||||
if (@available(macOS 14.4, *)) {
|
||||
+ LOG(INFO) << "CreateThumbnailCapturerMac: ThumbnailCapturerMac, no sccontentsharingpicker";
|
||||
return std::make_unique<ThumbnailCapturerMac>(type);
|
||||
}
|
||||
NOTREACHED();
|
||||
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.cc
|
||||
index 6508bad4af0d95e6dfc1eb4f688be71a5869af63..f24b12704b19c20fa12ec241481bc3e210f8bba8 100644
|
||||
--- a/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.cc
|
||||
+++ b/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.cc
|
||||
@@ -122,6 +122,7 @@ void DesktopMediaListController::FocusView() {
|
||||
}
|
||||
|
||||
void DesktopMediaListController::ShowDelegatedList() {
|
||||
+ LOG(INFO) << "ShowDelegatedList, controller";
|
||||
media_list_->ShowDelegatedList();
|
||||
dialog_->GetWidget()->Hide();
|
||||
}
|
||||
diff --git a/components/mirroring/browser/single_client_video_capture_host.cc b/components/mirroring/browser/single_client_video_capture_host.cc
|
||||
index 4208932ae390d7a5bf9370a24fb4c289c8f8e7a3..ae0567a464ae644c5d90ee464c893ac29dc1ebe3 100644
|
||||
--- a/components/mirroring/browser/single_client_video_capture_host.cc
|
||||
+++ b/components/mirroring/browser/single_client_video_capture_host.cc
|
||||
@@ -92,6 +92,7 @@ void SingleClientVideoCaptureHost::Start(
|
||||
std::unique_ptr<content::VideoCaptureDeviceLauncher> device_launcher =
|
||||
device_launcher_callback_.Run();
|
||||
content::VideoCaptureDeviceLauncher* launcher = device_launcher.get();
|
||||
+ DLOG(INFO) << "Launching device async : " << device_id_;
|
||||
launcher->LaunchDeviceAsync(
|
||||
device_id_, type_, params, weak_factory_.GetWeakPtr(),
|
||||
base::BindOnce(&SingleClientVideoCaptureHost::OnError,
|
||||
diff --git a/content/browser/media/capture/desktop_capture_device.cc b/content/browser/media/capture/desktop_capture_device.cc
|
||||
index 835c1e860501bcc8cb7c7dfe192c113de3d623ff..95950c348f2144761b960fef86390f6c8040de23 100644
|
||||
--- a/content/browser/media/capture/desktop_capture_device.cc
|
||||
+++ b/content/browser/media/capture/desktop_capture_device.cc
|
||||
@@ -808,7 +808,8 @@ std::unique_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
|
||||
result.reset(new DesktopCaptureDevice(std::move(capturer), source.type));
|
||||
return result;
|
||||
}
|
||||
-
|
||||
+ LOG(INFO) << "DesktopCaptureDevice::Create source.id=" << source.id;
|
||||
+ LOG(INFO) << "DesktopCaptureDevice::Create source.type=" << source.type;
|
||||
switch (source.type) {
|
||||
case DesktopMediaID::TYPE_SCREEN: {
|
||||
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer;
|
||||
@@ -829,17 +830,20 @@ 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 =
|
||||
webrtc::DesktopCapturer::CreateGenericCapturer(options);
|
||||
generic_capturer && generic_capturer->GetDelegatedSourceListController()) {
|
||||
+ LOG(INFO) << "DesktopCaptureDevice::Create generic_capturer";
|
||||
window_capturer = std::move(generic_capturer);
|
||||
} else {
|
||||
+ LOG(INFO) << "DesktopCaptureDevice::Create CreateWindowCapturer";
|
||||
window_capturer = webrtc::DesktopCapturer::CreateWindowCapturer(options);
|
||||
}
|
||||
if (window_capturer && window_capturer->SelectSource(source.id)) {
|
||||
+ LOG(INFO) << "DesktopCaptureDevice::Create DesktopAndCursorComposer";
|
||||
capturer = std::make_unique<webrtc::DesktopAndCursorComposer>(
|
||||
std::move(window_capturer), options);
|
||||
IncrementDesktopCaptureCounter(WINDOW_CAPTURER_CREATED);
|
||||
@@ -853,6 +857,7 @@ std::unique_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
|
||||
}
|
||||
|
||||
if (capturer)
|
||||
+ LOG(INFO) << "DesktopCaptureDevice::Create capturer success";
|
||||
result.reset(new DesktopCaptureDevice(std::move(capturer), source.type));
|
||||
|
||||
return result;
|
||||
diff --git a/content/browser/media/capture/native_screen_capture_picker.cc b/content/browser/media/capture/native_screen_capture_picker.cc
|
||||
index 152f3aa78032ee3f8c48fbefe052a2f1d85bed6b..400d7a2e7bb5d7d590181b9ada950f29f8b391bf 100644
|
||||
--- a/content/browser/media/capture/native_screen_capture_picker.cc
|
||||
+++ b/content/browser/media/capture/native_screen_capture_picker.cc
|
||||
@@ -7,18 +7,23 @@
|
||||
#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 {
|
||||
|
||||
std::unique_ptr<NativeScreenCapturePicker>
|
||||
MaybeCreateNativeScreenCapturePicker() {
|
||||
+ LOG(INFO) << "content::MaybeCreateNativeScreenCapturePicker()";
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
- if (base::FeatureList::IsEnabled(media::kUseSCContentSharingPicker)) {
|
||||
+
|
||||
+ // if (base::FeatureList::IsEnabled(media::kUseSCContentSharingPicker)) {
|
||||
+ LOG(INFO) << "content::MaybeCreateNativeScreenCapturePicker() - CreateNativeScreenCapturePickerMac()";
|
||||
return CreateNativeScreenCapturePickerMac();
|
||||
- }
|
||||
-#endif
|
||||
+ // }
|
||||
+#else
|
||||
return nullptr;
|
||||
+#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 f3dbdd0db5f6c3d07b600f3dfa3267d0a5a57b81..c61e1c9d4a67bc52deb69429abf2dc4bf9a79556 100644
|
||||
--- a/content/browser/media/capture/native_screen_capture_picker_mac.mm
|
||||
+++ b/content/browser/media/capture/native_screen_capture_picker_mac.mm
|
||||
@@ -99,6 +99,7 @@ void Open(DesktopMediaID::Type type,
|
||||
base::OnceCallback<void(Source)> picker_callback,
|
||||
base::OnceClosure cancel_callback,
|
||||
base::OnceClosure error_callback) override;
|
||||
+ // boolean use_system_picker) override;
|
||||
void Close(DesktopMediaID device_id) override;
|
||||
std::unique_ptr<media::VideoCaptureDevice> CreateDevice(
|
||||
const DesktopMediaID& source) override;
|
||||
@@ -138,8 +139,11 @@ void Open(DesktopMediaID::Type type,
|
||||
base::OnceClosure cancel_callback,
|
||||
base::OnceClosure error_callback) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
- CHECK(type == DesktopMediaID::Type::TYPE_SCREEN ||
|
||||
- type == DesktopMediaID::Type::TYPE_WINDOW);
|
||||
+ // 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_NONE);
|
||||
if (@available(macOS 14.0, *)) {
|
||||
NSNumber* source_id = @(next_id_);
|
||||
auto picker_observer = [[PickerObserver alloc]
|
||||
@@ -157,19 +161,26 @@ 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];
|
||||
- } else {
|
||||
- config.allowedPickerModes = SCContentSharingPickerModeSingleWindow;
|
||||
- picker.defaultConfiguration = config;
|
||||
- picker.maximumStreamCount = max_stream_count;
|
||||
- [picker presentPickerUsingContentStyle:SCShareableContentStyleWindow];
|
||||
- }
|
||||
+ // 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];
|
||||
+ // } else {
|
||||
+ picker.defaultConfiguration = config;
|
||||
+ picker.maximumStreamCount = max_stream_count;
|
||||
+ [picker present];
|
||||
+ // }
|
||||
} 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 ebfc2bb1006950dcff8e8f8792779c414c870a0b..2191337dae3c17c528bead5f250d4fa135477910 100644
|
||||
--- a/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
+++ b/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
@@ -333,7 +333,12 @@ void OnShareableContentCreated(SCShareableContent* content) {
|
||||
break;
|
||||
case DesktopMediaID::TYPE_WINDOW:
|
||||
for (SCWindow* window in content.windows) {
|
||||
- if (source_.id == window.windowID) {
|
||||
+ LOG(INFO) << "Window ID: " << window.windowID;
|
||||
+ LOG(INFO) << "Source ID: " << source_.id;
|
||||
+ // if (source_.id == window.windowID) {
|
||||
+ // if (source_.id == 0) {
|
||||
+ // if (2 == window.windowID) {
|
||||
+ LOG(INFO) << "Found window";
|
||||
filter = [[SCContentFilter alloc]
|
||||
initWithDesktopIndependentWindow:window];
|
||||
CGRect frame = window.frame;
|
||||
@@ -341,7 +346,8 @@ void OnShareableContentCreated(SCShareableContent* content) {
|
||||
if (!fullscreen_module_) {
|
||||
fullscreen_module_ = MaybeCreateScreenCaptureKitFullscreenModule(
|
||||
device_task_runner_, *this, window);
|
||||
- }
|
||||
+ break;
|
||||
+ // }
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -568,9 +574,13 @@ void OnStart(std::optional<bool> use_native_picker) override {
|
||||
|
||||
if (@available(macOS 15.0, *)) {
|
||||
constexpr bool DefaultUseNativePicker = true;
|
||||
+ LOG(INFO) << "ScreenCaptureKitDeviceMac::OnStart";
|
||||
+ LOG(INFO) << "source_.id: " << source_.id;
|
||||
if (use_native_picker.value_or(DefaultUseNativePicker) &&
|
||||
source_.id == DesktopMediaID::kMacOsNativePickerId &&
|
||||
source_.window_id < 0) {
|
||||
+ LOG(INFO) << "Using native picker";
|
||||
+ LOG(INFO) << "we should run into this codepath";
|
||||
auto* picker = [SCContentSharingPicker sharedPicker];
|
||||
ScreenCaptureKitDeviceMac::active_streams_++;
|
||||
picker.maximumStreamCount = @(ScreenCaptureKitDeviceMac::active_streams_);
|
||||
@@ -603,6 +613,7 @@ void OnStop() override {
|
||||
DCHECK(device_task_runner_->RunsTasksInCurrentSequence());
|
||||
|
||||
if (stream_) {
|
||||
+ DLOG(INFO) << "Stopping stream";
|
||||
auto stream_stopped_callback = base::BindPostTask(
|
||||
device_task_runner_,
|
||||
base::BindRepeating(&ScreenCaptureKitDeviceMac::OnStreamStopped,
|
||||
diff --git a/content/browser/media/capture/screen_capture_kit_fullscreen_module.mm b/content/browser/media/capture/screen_capture_kit_fullscreen_module.mm
|
||||
index b2de06333e3a3115af8baba393e92024ae3e070e..07c137fd8622d64f60146513633d386e34b5c214 100644
|
||||
--- a/content/browser/media/capture/screen_capture_kit_fullscreen_module.mm
|
||||
+++ b/content/browser/media/capture/screen_capture_kit_fullscreen_module.mm
|
||||
@@ -100,6 +100,7 @@ void API_AVAILABLE(macos(12.3))
|
||||
if ([kApplicationNamePowerPoint
|
||||
isEqualToString:original_window.owningApplication
|
||||
.applicationName]) {
|
||||
+ LOG(INFO) << "PowerPoint";
|
||||
return std::make_unique<ScreenCaptureKitFullscreenModule>(
|
||||
device_task_runner, reset_stream_interface, original_window.windowID,
|
||||
original_window.owningApplication.processID,
|
||||
@@ -108,6 +109,7 @@ void API_AVAILABLE(macos(12.3))
|
||||
if ([kApplicationNameKeynote
|
||||
isEqualToString:original_window.owningApplication
|
||||
.applicationName]) {
|
||||
+ LOG(INFO) << "Keynote";
|
||||
return std::make_unique<ScreenCaptureKitFullscreenModule>(
|
||||
device_task_runner, reset_stream_interface, original_window.windowID,
|
||||
original_window.owningApplication.processID,
|
||||
@@ -117,6 +119,7 @@ void API_AVAILABLE(macos(12.3))
|
||||
isEqualToString:original_window.owningApplication
|
||||
.applicationName] &&
|
||||
IsOpenOfficeImpressWindow(original_window.title)) {
|
||||
+ LOG(INFO) << "OpenOffice";
|
||||
return std::make_unique<ScreenCaptureKitFullscreenModule>(
|
||||
device_task_runner, reset_stream_interface, original_window.windowID,
|
||||
original_window.owningApplication.processID,
|
||||
@@ -125,11 +128,13 @@ void API_AVAILABLE(macos(12.3))
|
||||
if ([kApplicationNameLibreOffice
|
||||
isEqualToString:original_window.owningApplication
|
||||
.applicationName]) {
|
||||
+ LOG(INFO) << "LibreOffice";
|
||||
// TODO(crbug.com/40233195): Implement support for LibreOffice.
|
||||
LogModeToUma(ScreenCaptureKitFullscreenModule::Mode::kLibreOffice);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
+ LOG(INFO) << "Unsupported";
|
||||
LogModeToUma(ScreenCaptureKitFullscreenModule::Mode::kUnsupported);
|
||||
return nullptr;
|
||||
}
|
||||
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 ee080009f75a0b9e07a12f929086008454ef8621..704cf5c61918b99325e464ca5b5538ffd1ba5ac5 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
|
||||
@@ -187,15 +187,21 @@ DesktopCaptureImplementation CreatePlatformDependentVideoCaptureDevice(
|
||||
std::unique_ptr<media::VideoCaptureDevice>& device_out) {
|
||||
DCHECK_EQ(device_out.get(), nullptr);
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
+DLOG(INFO) << "CreatePlatformDependentVideoCaptureDevice";
|
||||
+DLOG(INFO) << "picker? " << picker;
|
||||
// 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);
|
||||
+ // DLOG(INFO) << "picker device created";
|
||||
+ // DLOG(INFO) << "device_out? " << device_out.get();
|
||||
+ // if (device_out) {
|
||||
+ // DLOG(INFO) << "picker device created, returning kscreencapturekitdevicemac";
|
||||
+ // return kScreenCaptureKitDeviceMac;
|
||||
+ // }
|
||||
+ // DLOG(INFO) << "picker device not created";
|
||||
+ // return kNoImplementation;
|
||||
+ // }
|
||||
|
||||
// Prefer using ScreenCaptureKit. After that try DesktopCaptureDeviceMac, and
|
||||
// if both fail, use the generic DesktopCaptureDevice.
|
||||
@@ -206,10 +212,14 @@ DesktopCaptureImplementation CreatePlatformDependentVideoCaptureDevice(
|
||||
base::FeatureList::IsEnabled(kScreenCaptureKitMacScreen))) {
|
||||
device_out = CreateScreenCaptureKitDeviceMac(desktop_id);
|
||||
if (device_out) {
|
||||
+ DLOG(INFO) << "ScreenCaptureKit device created by feature";
|
||||
return kScreenCaptureKitDeviceMac;
|
||||
}
|
||||
}
|
||||
if ((device_out = CreateDesktopCaptureDeviceMac(desktop_id))) {
|
||||
+ DLOG(INFO) << "DesktopCaptureDeviceMac device created";
|
||||
+ DLOG(INFO) << "device_out? " << device_out.get();
|
||||
+ DLOG(INFO) << "with device_id: " << desktop_id.id;
|
||||
return kDesktopCaptureDeviceMac;
|
||||
}
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
@@ -233,6 +243,7 @@ InProcessVideoCaptureDeviceLauncher::InProcessVideoCaptureDeviceLauncher(
|
||||
InProcessVideoCaptureDeviceLauncher::~InProcessVideoCaptureDeviceLauncher() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
DCHECK(state_ == State::READY_TO_LAUNCH);
|
||||
+ DLOG(INFO) << "destructor";
|
||||
}
|
||||
|
||||
void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
@@ -249,6 +260,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 "
|
||||
@@ -269,12 +283,14 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
base::BindPostTaskToCurrentDefault(base::BindOnce(
|
||||
&InProcessVideoCaptureDeviceLauncher::OnDeviceStarted,
|
||||
base::Unretained(this), callbacks, std::move(done_cb)));
|
||||
-
|
||||
+ LOG(INFO) << "stream type: " << stream_type;
|
||||
+ LOG(INFO) << "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(
|
||||
@@ -286,8 +302,12 @@ 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);
|
||||
+ DLOG(INFO) << "Desktop media ID: " << desktop_id.id;
|
||||
+ DLOG(INFO) << "Desktop media ID fakeid: " << DesktopMediaID::kFakeId;
|
||||
+ DLOG(INFO) << "Desktop media ID is null? " << desktop_id.is_null();
|
||||
if (desktop_id.is_null()) {
|
||||
DLOG(ERROR) << "Desktop media ID is null";
|
||||
start_capture_closure =
|
||||
@@ -308,6 +328,7 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
}
|
||||
|
||||
if (desktop_id.type == DesktopMediaID::TYPE_WEB_CONTENTS) {
|
||||
+ DLOG(INFO) << "Desktop media ID is web contents";
|
||||
after_start_capture_callback = base::BindOnce(
|
||||
[](const DesktopMediaID& device_id, ReceiveDeviceCallback callback,
|
||||
std::unique_ptr<media::VideoCaptureDevice> device) {
|
||||
@@ -320,6 +341,7 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
std::move(callback).Run(std::move(device));
|
||||
},
|
||||
desktop_id, std::move(after_start_capture_callback));
|
||||
+ DLOG(INFO) << "after start capture callback";
|
||||
start_capture_closure = base::BindOnce(
|
||||
&InProcessVideoCaptureDeviceLauncher::
|
||||
DoStartTabCaptureOnDeviceThread,
|
||||
@@ -330,7 +352,13 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
|
||||
#if defined(USE_AURA)
|
||||
bool allow_window_id = false;
|
||||
+ DLOG(INFO) << "use aura do not allow window id";
|
||||
#elif BUILDFLAG(IS_MAC)
|
||||
+ DLOG(INFO) << "use mac use nativepickerid";
|
||||
+ DLOG(INFO) << "desktop id id: " << desktop_id.id;
|
||||
+ DLOG(INFO) << "macos native picker id: " << DesktopMediaID::kMacOsNativePickerId;
|
||||
+ DLOG(INFO) << "desktop id window id: " << desktop_id.window_id;
|
||||
+
|
||||
bool allow_window_id =
|
||||
desktop_id.id == DesktopMediaID::kMacOsNativePickerId;
|
||||
#endif
|
||||
@@ -344,6 +372,7 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
TRACE_EVENT_INSTANT0(
|
||||
TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
|
||||
"UsingVizFrameSinkCapturer", TRACE_EVENT_SCOPE_THREAD);
|
||||
+ DLOG(INFO) << "binding start capture closure, do start viz frame sink window capture on device thread";
|
||||
start_capture_closure = base::BindOnce(
|
||||
&InProcessVideoCaptureDeviceLauncher::
|
||||
DoStartVizFrameSinkWindowCaptureOnDeviceThread,
|
||||
@@ -355,9 +384,11 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
|
||||
media::VideoCaptureParams updated_params = params;
|
||||
updated_params.use_native_picker = stream_type != blink::mojom::MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE;
|
||||
+ DLOG(INFO) << "use native picker: " << updated_params.use_native_picker.value();
|
||||
// All cases other than tab capture or Aura desktop/window capture.
|
||||
TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
|
||||
"UsingDesktopCapturer", TRACE_EVENT_SCOPE_THREAD);
|
||||
+ DLOG(INFO) << "binding start capture closure, do start desktop capture on device thread";
|
||||
start_capture_closure = base::BindOnce(
|
||||
&InProcessVideoCaptureDeviceLauncher::
|
||||
DoStartDesktopCaptureOnDeviceThread,
|
||||
@@ -366,11 +397,13 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
kMaxNumberOfBuffers, std::move(receiver),
|
||||
std::move(receiver_on_io_thread)),
|
||||
std::move(after_start_capture_callback));
|
||||
+ DLOG(INFO) << "start capture closure";
|
||||
break;
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_SCREEN_CAPTURE)
|
||||
|
||||
default:
|
||||
+ DLOG(ERROR) << "Unsupported stream type: " << stream_type;
|
||||
NOTREACHED() << "unsupported stream type=" << stream_type;
|
||||
}
|
||||
|
||||
@@ -517,7 +550,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) << "desktop id: " << desktop_id.id;
|
||||
+ // DCHECK(!desktop_id.is_null());
|
||||
|
||||
std::unique_ptr<media::VideoCaptureDevice> video_capture_device;
|
||||
DesktopCaptureImplementation implementation =
|
||||
@@ -529,6 +563,7 @@ void InProcessVideoCaptureDeviceLauncher::DoStartDesktopCaptureOnDeviceThread(
|
||||
if (video_capture_device)
|
||||
video_capture_device->AllocateAndStart(params, std::move(device_client));
|
||||
std::move(result_callback).Run(std::move(video_capture_device));
|
||||
+ DLOG(INFO) << "result callback";
|
||||
}
|
||||
|
||||
#endif // BUILDFLAG(ENABLE_SCREEN_CAPTURE)
|
||||
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..a9d87514b9f5099ee1ea9a3cc36a4e0df089c3ea 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,9 +9,10 @@
|
||||
#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 {
|
||||
-
|
||||
+// TODO: note here
|
||||
InProcessVideoCaptureProvider::InProcessVideoCaptureProvider(
|
||||
scoped_refptr<base::SingleThreadTaskRunner> device_task_runner)
|
||||
: native_screen_capture_picker_(MaybeCreateNativeScreenCapturePicker()),
|
||||
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc
|
||||
index 1caa2c3cef5cee4ea3f3c43ed375334a316bb0d0..69387e77b32872e29434d3e9a7415821aa9f05c8 100644
|
||||
--- a/content/browser/renderer_host/media/video_capture_controller.cc
|
||||
+++ b/content/browser/renderer_host/media/video_capture_controller.cc
|
||||
@@ -672,12 +672,15 @@ void VideoCaptureController::CreateAndStartDeviceAsync(
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
|
||||
"VideoCaptureController::CreateAndStartDeviceAsync");
|
||||
std::ostringstream string_stream;
|
||||
+ LOG(INFO) << "VideoCaptureController::CreateAndStartDeviceAsync: serial_id = "
|
||||
+ << serial_id() << ", device_id = " << device_id();
|
||||
string_stream
|
||||
<< "VideoCaptureController::CreateAndStartDeviceAsync: serial_id = "
|
||||
<< serial_id() << ", device_id = " << device_id();
|
||||
EmitLogMessage(string_stream.str(), 1);
|
||||
time_of_start_request_ = base::TimeTicks::Now();
|
||||
device_launch_observer_ = observer;
|
||||
+ DLOG(INFO) << "Launching device async : " << device_id_;
|
||||
device_launcher_->LaunchDeviceAsync(
|
||||
device_id_, stream_type_, params, GetWeakPtrForIOThread(),
|
||||
base::BindOnce(&VideoCaptureController::OnDeviceConnectionLost,
|
||||
diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc
|
||||
index 06681956d6a3b51f5c26dbfd77348d4cdc3d3ee3..1d233003afda69f92e501c64a08d980c3ff3ce43 100644
|
||||
--- a/content/browser/renderer_host/media/video_capture_manager.cc
|
||||
+++ b/content/browser/renderer_host/media/video_capture_manager.cc
|
||||
@@ -330,11 +330,13 @@ void VideoCaptureManager::ProcessDeviceStartRequestQueue() {
|
||||
// TODO(chfremer): Check if any production code actually depends on this
|
||||
// requirement. If not, relax the requirement in the test and remove the below
|
||||
// if block. See crbug.com/708251
|
||||
+ LOG(INFO) << "processdevicestartrequestqueue";
|
||||
if (controller->stream_type() ==
|
||||
blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE) {
|
||||
const media::VideoCaptureDeviceInfo* device_info =
|
||||
GetDeviceInfoById(controller->device_id());
|
||||
if (!device_info) {
|
||||
+ LOG(INFO) << "Device not found: " << controller->device_id();
|
||||
OnDeviceLaunchFailed(
|
||||
controller.get(),
|
||||
media::VideoCaptureError::
|
||||
@@ -363,6 +365,8 @@ void VideoCaptureManager::ProcessDeviceStartRequestQueue() {
|
||||
|
||||
void VideoCaptureManager::OnDeviceLaunched(VideoCaptureController* controller) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
+ LOG(INFO) << "launching device has succeeded. device_id = "
|
||||
+ << controller->device_id();
|
||||
std::ostringstream string_stream;
|
||||
string_stream << "Launching device has succeeded. device_id = "
|
||||
<< controller->device_id();
|
||||
@@ -391,6 +395,7 @@ void VideoCaptureManager::OnDeviceLaunched(VideoCaptureController* controller) {
|
||||
}
|
||||
|
||||
device_start_request_queue_.pop_front();
|
||||
+ LOG(INFO) << "processdevicestartrequestqueue";
|
||||
ProcessDeviceStartRequestQueue();
|
||||
}
|
||||
|
||||
diff --git a/content/public/browser/desktop_media_id.cc b/content/public/browser/desktop_media_id.cc
|
||||
index b39b684ff84baaf292eef1a23b7f9fb4585023c5..85ec7e489a1abdb6ce230684fdbdd987e228f9c7 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
|
||||
@@ -104,6 +105,8 @@ std::string DesktopMediaID::ToString() const {
|
||||
std::string prefix;
|
||||
switch (type) {
|
||||
case TYPE_NONE:
|
||||
+ prefix = kNonePrefix;
|
||||
+ break;
|
||||
NOTREACHED();
|
||||
case TYPE_SCREEN:
|
||||
prefix = kScreenPrefix;
|
||||
@@ -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"
|
||||
@@ -143,6 +145,22 @@ base::flat_map<int32_t, uint32_t> MonitorAtomIdToDisplayId() {
|
||||
}
|
||||
#endif
|
||||
|
||||
// std::unique_ptr<ThumbnailCapturer> MakeScreenAndWindowCapturer() {
|
||||
// LOG(INFO) << "MakeScreenAndWindowCapturer";
|
||||
// #if BUILDFLAG(IS_MAC)
|
||||
// if (ShouldUseThumbnailCapturerMac(DesktopMediaList::Type::kWindow)) {
|
||||
// LOG(INFO) << "Use the thumbnail capturer";
|
||||
// return CreateThumbnailCapturerMac(DesktopMediaList::Type::kWindow);
|
||||
// }
|
||||
// #endif // BUILDFLAG(IS_MAC)
|
||||
|
||||
// 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()
|
||||
@@ -276,29 +295,82 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
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()) {
|
||||
// std::unique_ptr<webrtc::DesktopCapturer> desktop_capturer =
|
||||
// webrtc::DesktopCapturer::CreateGenericCapturer(
|
||||
// content::desktop_capture::CreateDesktopCaptureOptions());
|
||||
LOG(INFO) << "capture_window && capture_screen";
|
||||
// auto capturer = desktop_capturer ?
|
||||
// std::make_unique<DesktopCapturerWrapper>(
|
||||
// std::move(desktop_capturer))
|
||||
// : nullptr;
|
||||
// if (capturer && capturer->GetDelegatedSourceListController()) {
|
||||
// LOG(INFO) << "Inside 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;
|
||||
// }
|
||||
|
||||
// TODO: Add flag for MacOS 15
|
||||
if (IsDisplayMediaSystemPickerAvailable()) {
|
||||
// auto capturer = MakeScreenAndWindowCapturer();
|
||||
auto capturer = MakeWindowCapturer();
|
||||
LOG(INFO) << "Inside the IsDisplayMediaSystemPickerAvailable logic";
|
||||
capture_screen_ = false;
|
||||
capture_window_ = capture_window;
|
||||
window_capturer_ = std::make_unique<NativeDesktopMediaList>(
|
||||
LOG(INFO) << "Capture Window: " << capture_window;
|
||||
screen_capturer_ = std::make_unique<NativeDesktopMediaList>(
|
||||
DesktopMediaList::Type::kWindow, std::move(capturer), true, true);
|
||||
window_capturer_->SetThumbnailSize(thumbnail_size);
|
||||
LOG(INFO) << "Made capturer?";
|
||||
screen_capturer_->SetThumbnailSize(thumbnail_size);
|
||||
LOG(INFO) << "Made thumbnails?";
|
||||
screen_capturer_->ShowDelegatedList();
|
||||
LOG(INFO) << "Showed delegated list?";
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
screen_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());
|
||||
OnceCallback failure_callback = base::BindOnce(
|
||||
&DesktopCapturer::HandleFailure, weak_ptr_factory_.GetWeakPtr());
|
||||
screen_capturer_.get());
|
||||
LOG(INFO) << "Updated source list?";
|
||||
|
||||
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()) {
|
||||
LOG(INFO) << "Source list is delegated...";
|
||||
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());
|
||||
LOG(INFO)
|
||||
<< "Screen listener made. Starting to update screen capturer...";
|
||||
screen_capturer_->StartUpdating(screen_listener_.get());
|
||||
} else {
|
||||
LOG(INFO) << "Updating screen capturer..., refreshing thumbnails";
|
||||
screen_capturer_->Update(std::move(update_callback),
|
||||
/* refresh_thumbnails = */ true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -320,10 +392,12 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
// Apply the new thumbnail size and restart capture.
|
||||
if (capture_window) {
|
||||
auto capturer = MakeWindowCapturer();
|
||||
LOG(INFO) << "Hello Capturer";
|
||||
if (capturer) {
|
||||
window_capturer_ = std::make_unique<NativeDesktopMediaList>(
|
||||
DesktopMediaList::Type::kWindow, std::move(capturer), true, true);
|
||||
window_capturer_->SetThumbnailSize(thumbnail_size);
|
||||
window_capturer_->ShowDelegatedList();
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
window_capturer_->skip_next_refresh_ =
|
||||
ShouldUseThumbnailCapturerMac(DesktopMediaList::Type::kWindow) ? 2
|
||||
@@ -334,11 +408,16 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
&DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),
|
||||
window_capturer_.get());
|
||||
|
||||
// Needed to force a refresh for the native MacOS Picker
|
||||
OnceCallback wrapped_update_callback = base::BindOnce(
|
||||
&DesktopCapturer::RequestUpdate, weak_ptr_factory_.GetWeakPtr(),
|
||||
window_capturer_.get(), std::move(update_callback));
|
||||
|
||||
if (window_capturer_->IsSourceListDelegated()) {
|
||||
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),
|
||||
std::move(wrapped_update_callback), std::move(failure_callback),
|
||||
thumbnail_size.IsEmpty());
|
||||
window_capturer_->StartUpdating(window_listener_.get());
|
||||
} else {
|
||||
@@ -350,10 +429,12 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
|
||||
if (capture_screen) {
|
||||
auto capturer = MakeScreenCapturer();
|
||||
LOG(INFO) << "Capture Screen...";
|
||||
if (capturer) {
|
||||
screen_capturer_ = std::make_unique<NativeDesktopMediaList>(
|
||||
DesktopMediaList::Type::kScreen, std::move(capturer));
|
||||
screen_capturer_->SetThumbnailSize(thumbnail_size);
|
||||
screen_capturer_->ShowDelegatedList();
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
screen_capturer_->skip_next_refresh_ =
|
||||
ShouldUseThumbnailCapturerMac(DesktopMediaList::Type::kScreen) ? 2
|
||||
@@ -364,11 +445,16 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
&DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),
|
||||
screen_capturer_.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(update_callback), std::move(failure_callback),
|
||||
std::move(wrapped_update_callback), std::move(failure_callback),
|
||||
thumbnail_size.IsEmpty());
|
||||
screen_capturer_->StartUpdating(screen_listener_.get());
|
||||
} else {
|
||||
@@ -380,10 +466,20 @@ 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) {
|
||||
LOG(INFO) << "UpdateSourcesList";
|
||||
LOG(INFO) << "capture_window: " << capture_window_;
|
||||
LOG(INFO) << "capture_screen: " << capture_screen_;
|
||||
if (capture_window_ &&
|
||||
list->GetMediaListType() == DesktopMediaList::Type::kWindow) {
|
||||
(list->GetMediaListType() == DesktopMediaList::Type::kWindow ||
|
||||
list->GetMediaListType() == DesktopMediaList::Type::kNone)) {
|
||||
capture_window_ = false;
|
||||
LOG(INFO) << "GetSourceCount (windows): " << list->GetSourceCount();
|
||||
std::vector<DesktopCapturer::Source> window_sources;
|
||||
window_sources.reserve(list->GetSourceCount());
|
||||
for (int i = 0; i < list->GetSourceCount(); i++) {
|
||||
@@ -395,8 +491,10 @@ 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;
|
||||
LOG(INFO) << "GetSourceCount (screens): " << list->GetSourceCount();
|
||||
std::vector<DesktopCapturer::Source> screen_sources;
|
||||
screen_sources.reserve(list->GetSourceCount());
|
||||
for (int i = 0; i < list->GetSourceCount(); i++) {
|
||||
@@ -465,7 +563,8 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
std::move(screen_sources.begin(), screen_sources.end(),
|
||||
std::back_inserter(captured_sources_));
|
||||
}
|
||||
|
||||
LOG(INFO) << "capture_window: " << capture_window_;
|
||||
LOG(INFO) << "capture_screen: " << capture_screen_;
|
||||
if (!capture_window_ && !capture_screen_)
|
||||
HandleSuccess();
|
||||
}
|
||||
@@ -495,6 +594,7 @@ void DesktopCapturer::HandleFailure() {
|
||||
|
||||
// static
|
||||
gin::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
|
||||
LOG(INFO) << "Creating DesktopCapturer...";
|
||||
auto handle = gin::CreateHandle(isolate, new DesktopCapturer(isolate));
|
||||
|
||||
// Keep reference alive until capturing has finished.
|
||||
|
||||
@@ -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 "";
|
||||
|
||||
29
shell/common/gin_converters/display_surface_converter.cc
Normal file
29
shell/common/gin_converters/display_surface_converter.cc
Normal file
@@ -0,0 +1,29 @@
|
||||
// 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_
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "shell/common/gin_converters/media_converter.h"
|
||||
|
||||
#include "shell/common/gin_converters/display_surface_converter.h"
|
||||
#include "content/public/browser/media_stream_request.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "gin/data_object_builder.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