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

* Adds a new observer method to DesktopMediaListObserver for
  desktop capture api.
* Backports https://chromium-review.googlesource.com/c/chromium/src/+/1199806
  that fixes crash with screen capturer, can be removed in 71.0.3539.0

diff --git a/chrome/browser/media/webrtc/desktop_media_list.h b/chrome/browser/media/webrtc/desktop_media_list.h
index 8e02a8a95eb07516162eacdf5b361231d3a02975..3497b85428a52c6019cfb5d30229071f99ecfb20 100644
--- a/chrome/browser/media/webrtc/desktop_media_list.h
+++ b/chrome/browser/media/webrtc/desktop_media_list.h
@@ -32,6 +32,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.
@@ -51,10 +54,11 @@ class DesktopMediaList {
   // enumerated. After the initial enumeration the model will be refreshed based
   // on the update period, and notifications generated only for changes in the
   // model.
-  virtual void StartUpdating(DesktopMediaListObserver* observer) = 0;
+  virtual void StartUpdating() = 0;
 
   virtual int GetSourceCount() const = 0;
   virtual const Source& GetSource(int index) const = 0;
+  virtual const std::vector<Source>& GetSources() const = 0;
 
   virtual content::DesktopMediaID::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 43dd95ef72f5b35b91471950cc114800d54945ab..d4662708f64934372422b853673eaaf8f05e4baf 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_base.cc
+++ b/chrome/browser/media/webrtc/desktop_media_list_base.cc
@@ -18,6 +18,11 @@ DesktopMediaListBase::DesktopMediaListBase(base::TimeDelta update_period)
 
 DesktopMediaListBase::~DesktopMediaListBase() {}
 
+void DesktopMediaListBase::AddObserver(DesktopMediaListObserver* observer) {
+  DCHECK(!observer_);
+  observer_ = observer;
+}
+
 void DesktopMediaListBase::SetUpdatePeriod(base::TimeDelta period) {
   DCHECK(!observer_);
   update_period_ = period;
@@ -31,10 +36,7 @@ void DesktopMediaListBase::SetViewDialogWindowId(DesktopMediaID dialog_id) {
   view_dialog_id_ = dialog_id;
 }
 
-void DesktopMediaListBase::StartUpdating(DesktopMediaListObserver* observer) {
-  DCHECK(!observer_);
-
-  observer_ = observer;
+void DesktopMediaListBase::StartUpdating() {
   Refresh();
 }
 
@@ -49,6 +51,11 @@ const DesktopMediaList::Source& DesktopMediaListBase::GetSource(
   return sources_[index];
 }
 
+const std::vector<DesktopMediaList::Source>& DesktopMediaListBase::GetSources()
+    const {
+  return sources_;
+}
+
 DesktopMediaID::Type DesktopMediaListBase::GetMediaListType() const {
   return type_;
 }
@@ -60,6 +67,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) {
@@ -132,6 +145,8 @@ void DesktopMediaListBase::UpdateSourceThumbnail(DesktopMediaID id,
 }
 
 void DesktopMediaListBase::ScheduleNextRefresh() {
+  if (!observer_->ShouldScheduleNextRefresh(this))
+    return;
   BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
                                  base::BindOnce(&DesktopMediaListBase::Refresh,
                                                 weak_factory_.GetWeakPtr()),
diff --git a/chrome/browser/media/webrtc/desktop_media_list_base.h b/chrome/browser/media/webrtc/desktop_media_list_base.h
index 746df1210aa92af5c9d4703112b4bd6c09b94fdf..461e0edf8509569d05c86f466c02b5035183d0df 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_base.h
+++ b/chrome/browser/media/webrtc/desktop_media_list_base.h
@@ -24,12 +24,14 @@ 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;
-  void StartUpdating(DesktopMediaListObserver* observer) override;
+  void StartUpdating() override;
   int GetSourceCount() const override;
   const Source& GetSource(int index) const override;
+  const std::vector<Source>& GetSources() const override;
   content::DesktopMediaID::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 47401abc984e6fe26c7f4c5399aa565c687060b0..ca6a527ffac877c27aac94337ec5a7b546e09768 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_observer.h
+++ b/chrome/browser/media/webrtc/desktop_media_list_observer.h
@@ -18,6 +18,10 @@ 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;
+  // Return value indicates whether the observer should continue listening
+  // for capture updates.
+  virtual bool ShouldScheduleNextRefresh(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 0c9ba953cb3c268930fb101105c22416ed3cae08..c2482774f0747a0300d72d7ef05ed429caaf7d19 100644
--- a/chrome/browser/media/webrtc/native_desktop_media_list.cc
+++ b/chrome/browser/media/webrtc/native_desktop_media_list.cc
@@ -5,11 +5,15 @@
 #include "chrome/browser/media/webrtc/native_desktop_media_list.h"
 
 #include "base/hash.h"
+#include "base/single_thread_task_runner.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task_scheduler/post_task.h"
+#include "base/threading/thread_restrictions.h"
+#include "build/build_config.h"
 #include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
-#include "chrome/grit/generated_resources.h"
 #include "content/public/browser/browser_thread.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"
@@ -76,11 +80,13 @@ gfx::ImageSkia ScaleDesktopFrame(std::unique_ptr<webrtc::DesktopFrame> frame,
 class NativeDesktopMediaList::Worker
     : public webrtc::DesktopCapturer::Callback {
  public:
-  Worker(base::WeakPtr<NativeDesktopMediaList> media_list,
+  Worker(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+         base::WeakPtr<NativeDesktopMediaList> media_list,
          DesktopMediaID::Type type,
          std::unique_ptr<webrtc::DesktopCapturer> capturer);
   ~Worker() override;
 
+  void Start();
   void Refresh(const DesktopMediaID::Id& view_dialog_id);
 
   void RefreshThumbnails(const std::vector<DesktopMediaID>& native_ids,
@@ -93,6 +99,9 @@ class NativeDesktopMediaList::Worker
   void OnCaptureResult(webrtc::DesktopCapturer::Result result,
                        std::unique_ptr<webrtc::DesktopFrame> frame) override;
 
+  // Task runner used for capturing operations.
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
   base::WeakPtr<NativeDesktopMediaList> media_list_;
 
   DesktopMediaID::Type type_;
@@ -106,17 +115,27 @@ class NativeDesktopMediaList::Worker
 };
 
 NativeDesktopMediaList::Worker::Worker(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     base::WeakPtr<NativeDesktopMediaList> media_list,
     DesktopMediaID::Type type,
     std::unique_ptr<webrtc::DesktopCapturer> capturer)
-    : media_list_(media_list), type_(type), capturer_(std::move(capturer)) {
-  capturer_->Start(this);
+    : task_runner_(task_runner),
+      media_list_(media_list),
+      type_(type),
+      capturer_(std::move(capturer)) {}
+
+NativeDesktopMediaList::Worker::~Worker() {
+  DCHECK(task_runner_->BelongsToCurrentThread());
 }
 
-NativeDesktopMediaList::Worker::~Worker() {}
+void NativeDesktopMediaList::Worker::Start() {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+  capturer_->Start(this);
+}
 
 void NativeDesktopMediaList::Worker::Refresh(
     const DesktopMediaID::Id& view_dialog_id) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
   std::vector<SourceDescription> result;
 
   webrtc::DesktopCapturer::SourceList sources;
@@ -163,6 +182,7 @@ void NativeDesktopMediaList::Worker::Refresh(
 void NativeDesktopMediaList::Worker::RefreshThumbnails(
     const std::vector<DesktopMediaID>& native_ids,
     const gfx::Size& thumbnail_size) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
   ImageHashesMap new_image_hashes;
 
   // Get a thumbnail for each native source.
@@ -210,17 +230,30 @@ NativeDesktopMediaList::NativeDesktopMediaList(
     std::unique_ptr<webrtc::DesktopCapturer> capturer)
     : DesktopMediaListBase(base::TimeDelta::FromMilliseconds(
           kDefaultNativeDesktopMediaListUpdatePeriod)),
+      thread_("DesktopMediaListCaptureThread"),
       weak_factory_(this) {
   type_ = type;
-  capture_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
-      {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
 
-  worker_.reset(
-      new Worker(weak_factory_.GetWeakPtr(), type, std::move(capturer)));
+#if defined(OS_WIN) || defined(OS_MACOSX)
+  // On Windows/OSX the thread must be a UI thread.
+  base::MessageLoop::Type thread_type = base::MessageLoop::TYPE_UI;
+#else
+  base::MessageLoop::Type thread_type = base::MessageLoop::TYPE_DEFAULT;
+#endif
+  thread_.StartWithOptions(base::Thread::Options(thread_type, 0));
+
+  worker_.reset(new Worker(thread_.task_runner(), weak_factory_.GetWeakPtr(),
+                           type, std::move(capturer)));
+
+  thread_.task_runner()->PostTask(
+      FROM_HERE,
+      base::BindOnce(&Worker::Start, base::Unretained(worker_.get())));
 }
 
 NativeDesktopMediaList::~NativeDesktopMediaList() {
-  capture_task_runner_->DeleteSoon(FROM_HERE, worker_.release());
+  base::ThreadRestrictions::ScopedAllowIO allow_io;
+  thread_.task_runner()->DeleteSoon(FROM_HERE, worker_.release());
+  thread_.Stop();
 }
 
 void NativeDesktopMediaList::Refresh() {
@@ -230,7 +263,7 @@ void NativeDesktopMediaList::Refresh() {
   new_aura_thumbnail_hashes_.clear();
 #endif
 
-  capture_task_runner_->PostTask(
+  thread_.task_runner()->PostTask(
       FROM_HERE,
       base::BindOnce(&Worker::Refresh, base::Unretained(worker_.get()),
                      view_dialog_id_.id));
@@ -280,7 +313,7 @@ void NativeDesktopMediaList::RefreshForAuraWindows(
 #if defined(USE_AURA)
     pending_native_thumbnail_capture_ = true;
 #endif
-    capture_task_runner_->PostTask(
+    thread_.task_runner()->PostTask(
         FROM_HERE, base::BindOnce(&Worker::RefreshThumbnails,
                                   base::Unretained(worker_.get()), native_ids,
                                   thumbnail_size_));
diff --git a/chrome/browser/media/webrtc/native_desktop_media_list.h b/chrome/browser/media/webrtc/native_desktop_media_list.h
index e6f0e17b05ee4dc45827dc2dd00d484201f74646..75c9ca04ce481ab79615515da948c29d449865dc 100644
--- a/chrome/browser/media/webrtc/native_desktop_media_list.h
+++ b/chrome/browser/media/webrtc/native_desktop_media_list.h
@@ -8,7 +8,7 @@
 #include <memory>
 
 #include "base/memory/weak_ptr.h"
-#include "base/sequenced_task_runner.h"
+#include "base/threading/thread.h"
 #include "chrome/browser/media/webrtc/desktop_media_list_base.h"
 #include "content/public/browser/desktop_media_id.h"
 #include "ui/gfx/image/image.h"
@@ -44,12 +44,7 @@ class NativeDesktopMediaList : public DesktopMediaListBase {
                                gfx::Image image);
 #endif
 
-  // Task runner used for the |worker_|.
-  scoped_refptr<base::SequencedTaskRunner> capture_task_runner_;
-
-  // An object that does all the work of getting list of sources on a background
-  // thread (see |capture_task_runner_|). Destroyed on |capture_task_runner_|
-  // after the model is destroyed.
+  base::Thread thread_;
   std::unique_ptr<Worker> worker_;
 
 #if defined(USE_AURA)
