blob: 9fd7c859df8edb039aaa8e6d820eec0b0a125e90 [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/public/browser/desktop_capture.h"
#include "base/feature_list.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "content/common/features.h"
#include "content/public/common/content_features.h"
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "content/browser/media/capture/desktop_capturer_lacros.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "content/browser/media/capture/aura_window_to_mojo_device_adapter.h"
#include "content/browser/media/capture/desktop_capturer_ash.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#endif
#if defined(WEBRTC_USE_PIPEWIRE)
#include "base/environment.h"
#include "base/nix/xdg_util.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "base/win/windows_version.h"
#endif
#if BUILDFLAG(IS_MAC)
#include "base/mac/mac_util.h"
BASE_FEATURE(kUseCGDisplayStreamCreateSonoma,
"UseCGDisplayStreamCreateSonoma",
base::FEATURE_DISABLED_BY_DEFAULT);
// CGDisplayStreamCreate() is marked as deprecated from macOS 14 (Sonoma), so
// don't use unless the feature flag is set.
bool CGDisplayStreamCreateIsAvailable() {
if (base::mac::MacOSMajorVersion() >= 14) {
return base::FeatureList::IsEnabled(kUseCGDisplayStreamCreateSonoma);
}
return true;
}
#endif // BUILDFLAG(IS_MAC)
namespace content::desktop_capture {
webrtc::DesktopCaptureOptions CreateDesktopCaptureOptions() {
auto options = webrtc::DesktopCaptureOptions::CreateDefault();
// Leave desktop effects enabled during WebRTC captures.
options.set_disable_effects(false);
#if BUILDFLAG(IS_WIN)
// TODO(crbug.com/webrtc/15045): Possibly remove this flag. Keeping for now
// to force fallback to GDI.
static BASE_FEATURE(kDirectXCapturer, "DirectXCapturer",
base::FEATURE_ENABLED_BY_DEFAULT);
if (base::FeatureList::IsEnabled(kDirectXCapturer)) {
// Results in DirectX as main capture API and GDI as fallback solution.
options.set_allow_directx_capturer(true);
}
options.set_enumerate_current_process_windows(
ShouldEnumerateCurrentProcessWindows());
#elif BUILDFLAG(IS_MAC)
// Enabling IO surface capturer means that we will be using the
// CGDisplayStreamCreate() API. This is marked as deprecated from macOS 14
// (Sonoma), only use it if it's available.
if (base::FeatureList::IsEnabled(features::kIOSurfaceCapturer) &&
CGDisplayStreamCreateIsAvailable()) {
options.set_allow_iosurface(true);
}
#endif
#if defined(WEBRTC_USE_PIPEWIRE)
if (base::FeatureList::IsEnabled(features::kWebRtcPipeWireCapturer)) {
options.set_allow_pipewire(true);
}
#endif // defined(WEBRTC_USE_PIPEWIRE)
return options;
}
std::unique_ptr<webrtc::DesktopCapturer> CreateScreenCapturer(
bool allow_wgc_screen_capturer) {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
return std::make_unique<DesktopCapturerLacros>(
DesktopCapturerLacros::CaptureType::kScreen,
webrtc::DesktopCaptureOptions());
#elif BUILDFLAG(IS_CHROMEOS_ASH)
return std::make_unique<DesktopCapturerAsh>();
#else
auto options = desktop_capture::CreateDesktopCaptureOptions();
#if defined(RTC_ENABLE_WIN_WGC)
if (allow_wgc_screen_capturer) {
options.set_allow_wgc_screen_capturer(true);
}
#endif // defined(RTC_ENABLE_WIN_WGC)
return webrtc::DesktopCapturer::CreateScreenCapturer(options);
#endif
}
std::unique_ptr<webrtc::DesktopCapturer> CreateWindowCapturer() {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
return std::make_unique<DesktopCapturerLacros>(
DesktopCapturerLacros::CaptureType::kWindow,
webrtc::DesktopCaptureOptions());
#else
auto options = desktop_capture::CreateDesktopCaptureOptions();
#if defined(RTC_ENABLE_WIN_WGC)
options.set_allow_wgc_capturer_fallback(true);
#endif
return webrtc::DesktopCapturer::CreateWindowCapturer(options);
#endif
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
void BindAuraWindowCapturer(
mojo::PendingReceiver<video_capture::mojom::Device> receiver,
const content::DesktopMediaID& id) {
mojo::MakeSelfOwnedReceiver(
std::make_unique<AuraWindowToMojoDeviceAdapter>(id), std::move(receiver));
}
#endif
bool CanUsePipeWire() {
#if defined(WEBRTC_USE_PIPEWIRE)
static base::nix::SessionType session_type = base::nix::SessionType::kUnset;
if (session_type == base::nix::SessionType::kUnset) {
std::unique_ptr<base::Environment> env = base::Environment::Create();
session_type = base::nix::GetSessionType(*env);
}
return session_type == base::nix::SessionType::kWayland &&
base::FeatureList::IsEnabled(features::kWebRtcPipeWireCapturer);
#else
return false;
#endif
}
bool ShouldEnumerateCurrentProcessWindows() {
#if BUILDFLAG(IS_WIN)
return false;
#else
return true;
#endif
}
} // namespace content::desktop_capture