Browse Source

fix: add capability to use ScreenCaptureKit for thumbnail generation (#41329)

This aligns us with Chromiums flags / capabilities in regards to using SCK for
everything. Currently on 14.4 Electron apps will pop warnings for usage of
deprecated APIs.  With this change and a few "enable-features" toggles.

`--enable-features="ScreenCaptureKitMac,ScreenCaptureKitStreamPickerSonoma,ThumbnailCapturerMac:capture_mode/sc_screenshot_manager"`

As Chromium enables these by default Electron will inherit those changes, apps wishing to skip ahead can apply these flags early.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <[email protected]>
trop[bot] 1 year ago
parent
commit
5c71377f40

+ 2 - 0
chromium_src/BUILD.gn

@@ -242,6 +242,8 @@ static_library("chrome") {
       "//chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm",
       "//chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.h",
       "//chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.mm",
+      "//chrome/browser/media/webrtc/thumbnail_capturer_mac.h",
+      "//chrome/browser/media/webrtc/thumbnail_capturer_mac.mm",
       "//chrome/browser/media/webrtc/window_icon_util_mac.mm",
       "//chrome/browser/platform_util_mac.mm",
       "//chrome/browser/process_singleton_mac.mm",

+ 1 - 0
patches/chromium/.patches

@@ -130,3 +130,4 @@ build_run_reclient_cfg_generator_after_chrome.patch
 fix_suppress_clang_-wimplicit-const-int-float-conversion_in.patch
 cherry-pick-e7ffe20ebfac.patch
 fix_getcursorscreenpoint_wrongly_returns_0_0.patch
+fix_add_support_for_skipping_first_no-op_refresh_in_thumb_cap.patch

+ 38 - 0
patches/chromium/fix_add_support_for_skipping_first_no-op_refresh_in_thumb_cap.patch

@@ -0,0 +1,38 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Samuel Attard <[email protected]>
+Date: Tue, 13 Feb 2024 17:40:15 -0800
+Subject: fix: add support for skipping first no-op refresh in thumb cap
+
+Fixes a bug in the SCK thumbnail capturer, will be reported upstream for a hopefully
+less hacky fix.
+
+diff --git a/chrome/browser/media/webrtc/desktop_media_list.h b/chrome/browser/media/webrtc/desktop_media_list.h
+index 0c6fccf16a11bbaff10115308e4b489490e5d3e6..3b541e6830ca902cf45483a3193376c0e559185e 100644
+--- a/chrome/browser/media/webrtc/desktop_media_list.h
++++ b/chrome/browser/media/webrtc/desktop_media_list.h
+@@ -143,6 +143,8 @@ class DesktopMediaList {
+   // important when IsSourceDelegated() returns true, as it helps to notify the
+   // delegated source list when it should be hidden.
+   virtual void HideList() = 0;
++
++  bool skip_next_refresh_ = false;
+ };
+ 
+ #endif  // CHROME_BROWSER_MEDIA_WEBRTC_DESKTOP_MEDIA_LIST_H_
+diff --git a/chrome/browser/media/webrtc/desktop_media_list_base.cc b/chrome/browser/media/webrtc/desktop_media_list_base.cc
+index 780927301744ea7312f230cec76a24a33d71f767..321d3ff46cbb67e880d5414d83a199fb16457038 100644
+--- a/chrome/browser/media/webrtc/desktop_media_list_base.cc
++++ b/chrome/browser/media/webrtc/desktop_media_list_base.cc
+@@ -230,7 +230,11 @@ uint32_t DesktopMediaListBase::GetImageHash(const gfx::Image& image) {
+ void DesktopMediaListBase::OnRefreshComplete() {
+   DCHECK_CURRENTLY_ON(BrowserThread::UI);
+   DCHECK(refresh_callback_);
+-  std::move(refresh_callback_).Run();
++  if (skip_next_refresh_) {
++    skip_next_refresh_ = false;
++  } else {
++    std::move(refresh_callback_).Run();
++  }
+ }
+ 
+ void DesktopMediaListBase::ScheduleNextRefresh() {

+ 43 - 12
shell/browser/api/electron_api_desktop_capturer.cc

@@ -14,6 +14,7 @@
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/media/webrtc/desktop_capturer_wrapper.h"
 #include "chrome/browser/media/webrtc/desktop_media_list.h"
+#include "chrome/browser/media/webrtc/thumbnail_capturer_mac.h"
 #include "chrome/browser/media/webrtc/window_icon_util.h"
 #include "content/public/browser/desktop_capture.h"
 #include "gin/object_template_builder.h"
@@ -136,6 +137,38 @@ std::map<int32_t, uint32_t> MonitorAtomIdToDisplayId() {
 }
 #endif
 
+namespace {
+
+std::unique_ptr<ThumbnailCapturer> MakeWindowCapturer() {
+#if BUILDFLAG(IS_MAC)
+  if (ShouldUseThumbnailCapturerMac(DesktopMediaList::Type::kWindow)) {
+    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> MakeScreenCapturer() {
+#if BUILDFLAG(IS_MAC)
+  if (ShouldUseThumbnailCapturerMac(DesktopMediaList::Type::kScreen)) {
+    return CreateThumbnailCapturerMac(DesktopMediaList::Type::kScreen);
+  }
+#endif  // BUILDFLAG(IS_MAC)
+
+  std::unique_ptr<webrtc::DesktopCapturer> screen_capturer =
+      content::desktop_capture::CreateScreenCapturer();
+  return screen_capturer ? std::make_unique<DesktopCapturerWrapper>(
+                               std::move(screen_capturer))
+                         : nullptr;
+}
+
+}  // namespace
+
 namespace gin {
 
 template <>
@@ -265,16 +298,15 @@ void DesktopCapturer::StartHandling(bool capture_window,
     // Initialize the source list.
     // Apply the new thumbnail size and restart capture.
     if (capture_window) {
-      std::unique_ptr<webrtc::DesktopCapturer> window_capturer =
-          content::desktop_capture::CreateWindowCapturer();
-      auto capturer = window_capturer
-                          ? std::make_unique<DesktopCapturerWrapper>(
-                                std::move(window_capturer))
-                          : nullptr;
+      auto capturer = MakeWindowCapturer();
       if (capturer) {
         window_capturer_ = std::make_unique<NativeDesktopMediaList>(
             DesktopMediaList::Type::kWindow, std::move(capturer));
         window_capturer_->SetThumbnailSize(thumbnail_size);
+#if BUILDFLAG(IS_MAC)
+        window_capturer_->skip_next_refresh_ =
+            ShouldUseThumbnailCapturerMac(DesktopMediaList::Type::kWindow);
+#endif
 
         OnceCallback update_callback = base::BindOnce(
             &DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),
@@ -295,16 +327,15 @@ void DesktopCapturer::StartHandling(bool capture_window,
     }
 
     if (capture_screen) {
-      std::unique_ptr<webrtc::DesktopCapturer> screen_capturer =
-          content::desktop_capture::CreateScreenCapturer();
-      auto capturer = screen_capturer
-                          ? std::make_unique<DesktopCapturerWrapper>(
-                                std::move(screen_capturer))
-                          : nullptr;
+      auto capturer = MakeScreenCapturer();
       if (capturer) {
         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);
+#endif
 
         OnceCallback update_callback = base::BindOnce(
             &DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),