From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Thu, 18 Oct 2018 17:07:01 -0700
Subject: desktop_media_list.patch

Our current desktop capturer api is a one-shot call to the underlying
implementation, i.e. a user calls desktopCapturer.getSources with the
interested source type, we then return a promise that will eventually
resolve with the sources and their thumbnails which are returned from
the implementation in a given frame.

* The core of this work is done by NativeDesktopMediaList in //chrome/browser/media/webrtc/native_desktop_media_list.cc.
* DesktopMediaListObserver (//chrome/browser/media/webrtc/desktop_media_list_observer.h)
  is the observer class that gets signalled with the sources from
  NativeDesktopMediaList, our desktopcapturer api class is an
  implementation of the DesktopMediaListObserver to receive those
  signals.
* To set the observer on NativeDesktopMediaList  we had to call
  DesktopMediaList::StartUpdating https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/media/webrtc/desktop_media_list.h;l=74;drc=09a4396a448775456084fe36bb84662f5757d988;
  but this call is not a one-shot but rather repeats the observer
  signals for every frame. This is the call which chrome currently
  uses.
* Disabled WindowCaptureMacV2 feature for https://github.com/electron/electron/pull/30507

This patch allows us to get the one-shot effect with the above classes.

diff --git a/chrome/browser/media/webrtc/desktop_media_list.h b/chrome/browser/media/webrtc/desktop_media_list.h
index d9737047f54bbf3811ae2a347790f6b3d286da3d..6a038c68bb7f31b8fe145a4a345d95a3e659cd48 100644
--- a/chrome/browser/media/webrtc/desktop_media_list.h
+++ b/chrome/browser/media/webrtc/desktop_media_list.h
@@ -59,6 +59,9 @@ class DesktopMediaList {
 
   virtual ~DesktopMediaList() {}
 
+  // Allows listening to notifications generated by the model.
+  virtual void AddObserver(DesktopMediaListObserver* observer) = 0;
+
   // Sets time interval between updates. By default list of sources and their
   // thumbnail are updated once per second. If called after StartUpdating() then
   // it will take effect only after the next update.
@@ -90,6 +93,7 @@ class DesktopMediaList {
 
   virtual int GetSourceCount() const = 0;
   virtual const Source& GetSource(int index) const = 0;
+  virtual const std::vector<Source>& GetSources() const = 0;
 
   virtual Type GetMediaListType() const = 0;
 };
diff --git a/chrome/browser/media/webrtc/desktop_media_list_base.cc b/chrome/browser/media/webrtc/desktop_media_list_base.cc
index a3e1de40e843b5450f417a0455e0e7d7dee1d1bd..2f7f96a5d56d503fc231ca3c96be243cf7cbb389 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_base.cc
+++ b/chrome/browser/media/webrtc/desktop_media_list_base.cc
@@ -24,6 +24,11 @@ DesktopMediaListBase::DesktopMediaListBase(base::TimeDelta update_period,
 
 DesktopMediaListBase::~DesktopMediaListBase() = default;
 
+void DesktopMediaListBase::AddObserver(DesktopMediaListObserver* observer) {
+  DCHECK(!observer_);
+  observer_ = observer;
+}
+
 void DesktopMediaListBase::SetUpdatePeriod(base::TimeDelta period) {
   DCHECK(!observer_);
   update_period_ = period;
@@ -58,7 +63,7 @@ void DesktopMediaListBase::Update(UpdateCallback callback) {
   DCHECK(sources_.empty());
   DCHECK(!refresh_callback_);
   refresh_callback_ = std::move(callback);
-  Refresh(false);
+  Refresh(true);
 }
 
 int DesktopMediaListBase::GetSourceCount() const {
@@ -72,6 +77,11 @@ const DesktopMediaList::Source& DesktopMediaListBase::GetSource(
   return sources_[index];
 }
 
+const std::vector<DesktopMediaList::Source>& DesktopMediaListBase::GetSources()
+    const {
+  return sources_;
+}
+
 DesktopMediaList::Type DesktopMediaListBase::GetMediaListType() const {
   return type_;
 }
@@ -83,6 +93,12 @@ DesktopMediaListBase::SourceDescription::SourceDescription(
 
 void DesktopMediaListBase::UpdateSourcesList(
     const std::vector<SourceDescription>& new_sources) {
+  // Notify observer when there was no new source captured.
+  if (new_sources.empty()) {
+    observer_->OnSourceUnchanged(this);
+    return;
+  }
+
   typedef std::set<DesktopMediaID> SourceSet;
   SourceSet new_source_set;
   for (size_t i = 0; i < new_sources.size(); ++i) {
diff --git a/chrome/browser/media/webrtc/desktop_media_list_base.h b/chrome/browser/media/webrtc/desktop_media_list_base.h
index a1038183d5b44ca760576bff55534b5841e2e9d2..d036a4e630e9ba8311cf7670a53b12ac33fdd2ef 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_base.h
+++ b/chrome/browser/media/webrtc/desktop_media_list_base.h
@@ -27,6 +27,7 @@ class DesktopMediaListBase : public DesktopMediaList {
   ~DesktopMediaListBase() override;
 
   // DesktopMediaList interface.
+  void AddObserver(DesktopMediaListObserver* observer) override;
   void SetUpdatePeriod(base::TimeDelta period) override;
   void SetThumbnailSize(const gfx::Size& thumbnail_size) override;
   void SetViewDialogWindowId(content::DesktopMediaID dialog_id) override;
@@ -34,6 +35,7 @@ class DesktopMediaListBase : public DesktopMediaList {
   void Update(UpdateCallback callback) override;
   int GetSourceCount() const override;
   const Source& GetSource(int index) const override;
+  const std::vector<Source>& GetSources() const override;
   DesktopMediaList::Type GetMediaListType() const override;
 
   static uint32_t GetImageHash(const gfx::Image& image);
diff --git a/chrome/browser/media/webrtc/desktop_media_list_observer.h b/chrome/browser/media/webrtc/desktop_media_list_observer.h
index ad7f766a36b1b6b2a8bc0f96369f1aaadf6681f7..f6c6c14a0937430df62c9b9c1132c5916a9f2009 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_observer.h
+++ b/chrome/browser/media/webrtc/desktop_media_list_observer.h
@@ -20,6 +20,7 @@ class DesktopMediaListObserver {
                              int new_index) = 0;
   virtual void OnSourceNameChanged(DesktopMediaList* list, int index) = 0;
   virtual void OnSourceThumbnailChanged(DesktopMediaList* list, int index) = 0;
+  virtual void OnSourceUnchanged(DesktopMediaList* list) = 0;
 
  protected:
   virtual ~DesktopMediaListObserver() {}
diff --git a/chrome/browser/media/webrtc/native_desktop_media_list.cc b/chrome/browser/media/webrtc/native_desktop_media_list.cc
index b1885b413b217553f972a97f559300d67c822472..7687bad18acad2cd607d14d3d3ac39f81e7dcc8a 100644
--- a/chrome/browser/media/webrtc/native_desktop_media_list.cc
+++ b/chrome/browser/media/webrtc/native_desktop_media_list.cc
@@ -11,15 +11,16 @@
 #include "base/hash/hash.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/single_thread_task_runner.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "chrome/browser/media/webrtc/desktop_media_list.h"
-#include "chrome/grit/generated_resources.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/content_features.h"
+#include "electron/grit/electron_resources.h"
 #include "media/base/video_util.h"
 #include "third_party/libyuv/include/libyuv/scale_argb.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -94,6 +95,7 @@ gfx::ImageSkia ScaleDesktopFrame(std::unique_ptr<webrtc::DesktopFrame> frame,
 }
 
 #if defined(OS_MAC)
+// Refs https://github.com/electron/electron/pull/30507
 const base::Feature kWindowCaptureMacV2{"WindowCaptureMacV2",
                                         base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
@@ -271,6 +273,8 @@ void NativeDesktopMediaList::Worker::RefreshNextThumbnail() {
       FROM_HERE,
       base::BindOnce(&NativeDesktopMediaList::UpdateNativeThumbnailsFinished,
                      media_list_));
+
+  capturer_.reset();
 }
 
 void NativeDesktopMediaList::Worker::OnCaptureResult(
