diff --git a/atom/browser/api/atom_api_desktop_capturer.cc b/atom/browser/api/atom_api_desktop_capturer.cc index 81817dfd1c80..a87759da8547 100644 --- a/atom/browser/api/atom_api_desktop_capturer.cc +++ b/atom/browser/api/atom_api_desktop_capturer.cc @@ -8,20 +8,17 @@ #include #include -using base::PlatformThreadRef; - #include "atom/common/api/atom_api_native_image.h" #include "atom/common/native_mate_converters/gfx_converter.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_task_runner_handle.h" -#include "chrome/browser/media/desktop_media_list.h" -#include "content/public/browser/browser_thread.h" +#include "base/threading/thread_restrictions.h" +#include "chrome/browser/media/webrtc/desktop_media_list.h" #include "content/public/browser/desktop_capture.h" #include "native_mate/dictionary.h" #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h" #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" + #if defined(OS_WIN) #include "third_party/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h" #include "third_party/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h" @@ -51,63 +48,121 @@ struct Converter { } // namespace mate -namespace { +namespace atom { -void EmitFinished( - const std::vector& sources, - atom::api::DesktopCapturer* cap) { - cap->Emit("finished", sources); +namespace api { + +DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) { + Init(isolate); } -void StartHandlingTask(bool capture_window, - bool capture_screen, - const gfx::Size& thumbnail_size, - atom::api::DesktopCapturer* cap) { +DesktopCapturer::~DesktopCapturer() {} + +void DesktopCapturer::StartHandling(bool capture_window, + bool capture_screen, + const gfx::Size& thumbnail_size) { #if defined(OS_WIN) if (content::desktop_capture::CreateDesktopCaptureOptions() .allow_directx_capturer()) { // DxgiDuplicatorController should be alive in this scope according to // screen_capturer_win.cc. auto duplicator = webrtc::DxgiDuplicatorController::Instance(); - cap->using_directx_capturer_ = - webrtc::ScreenCapturerWinDirectx::IsSupported(); + using_directx_capturer_ = webrtc::ScreenCapturerWinDirectx::IsSupported(); } #endif // defined(OS_WIN) - std::unique_ptr screen_capturer( - capture_screen ? content::desktop_capture::CreateScreenCapturer() - : nullptr); - std::unique_ptr window_capturer( - capture_window ? content::desktop_capture::CreateWindowCapturer() - : nullptr); - cap->media_list_.reset(new NativeDesktopMediaList( - std::move(screen_capturer), std::move(window_capturer))); - cap->media_list_->SetThumbnailSize(thumbnail_size); - cap->media_list_->StartUpdating(cap); + // clear any existing captured sources. + captured_sources_.clear(); + + // Start listening for captured sources. + capture_window_ = capture_window; + capture_screen_ = capture_screen; + + { + // Remove this once + // https://bugs.chromium.org/p/chromium/issues/detail?id=795340 is fixed. + base::ScopedAllowBaseSyncPrimitivesForTesting + scoped_allow_base_sync_primitives; + // Initialize the source list. + // Apply the new thumbnail size and restart capture. + if (capture_window) { + window_capturer_.reset(new NativeDesktopMediaList( + content::DesktopMediaID::TYPE_WINDOW, + content::desktop_capture::CreateWindowCapturer())); + window_capturer_->SetThumbnailSize(thumbnail_size); + window_capturer_->AddObserver(this); + window_capturer_->StartUpdating(); + } + + if (capture_screen) { + screen_capturer_.reset(new NativeDesktopMediaList( + content::DesktopMediaID::TYPE_SCREEN, + content::desktop_capture::CreateScreenCapturer())); + screen_capturer_->SetThumbnailSize(thumbnail_size); + screen_capturer_->AddObserver(this); + screen_capturer_->StartUpdating(); + } + } } -void OnRefreshFinishedTask(atom::api::DesktopCapturer* cap) { - const auto media_list_sources = cap->media_list_->GetSources(); - std::vector sources; - for (const auto& media_list_source : media_list_sources) { - sources.emplace_back( - atom::api::DesktopCapturer::Source{media_list_source, std::string()}); +void DesktopCapturer::OnSourceAdded(DesktopMediaList* list, int index) {} + +void DesktopCapturer::OnSourceRemoved(DesktopMediaList* list, int index) {} + +void DesktopCapturer::OnSourceMoved(DesktopMediaList* list, + int old_index, + int new_index) {} + +void DesktopCapturer::OnSourceNameChanged(DesktopMediaList* list, int index) {} + +void DesktopCapturer::OnSourceThumbnailChanged(DesktopMediaList* list, + int index) {} + +void DesktopCapturer::OnSourceUnchanged(DesktopMediaList* list) { + UpdateSourcesList(list); +} + +bool DesktopCapturer::ShouldScheduleNextRefresh(DesktopMediaList* list) { + UpdateSourcesList(list); + return false; +} + +void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) { + std::vector window_sources; + if (capture_window_ && + list->GetMediaListType() == content::DesktopMediaID::TYPE_WINDOW) { + capture_window_ = false; + const auto& media_list_sources = list->GetSources(); + for (const auto& media_list_source : media_list_sources) { + window_sources.emplace_back( + DesktopCapturer::Source{media_list_source, std::string()}); + } + std::move(window_sources.begin(), window_sources.end(), + std::back_inserter(captured_sources_)); } + std::vector screen_sources; + if (capture_screen_ && + list->GetMediaListType() == content::DesktopMediaID::TYPE_SCREEN) { + capture_screen_ = false; + const auto& media_list_sources = list->GetSources(); + for (const auto& media_list_source : media_list_sources) { + screen_sources.emplace_back( + DesktopCapturer::Source{media_list_source, std::string()}); + } #if defined(OS_WIN) - // Gather the same unique screen IDs used by the electron.screen API in order - // to provide an association between it and desktopCapturer/getUserMedia. - // This is only required when using the DirectX capturer, otherwise the IDs - // across the APIs already match. - if (cap->using_directx_capturer_) { - std::vector device_names; - // Crucially, this list of device names will be in the same order as - // |media_list_sources|. - webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(&device_names); - int device_name_index = 0; - for (auto& source : sources) { - if (source.media_list_source.id.type == - content::DesktopMediaID::TYPE_SCREEN) { + // Gather the same unique screen IDs used by the electron.screen API in + // order to provide an association between it and + // desktopCapturer/getUserMedia. This is only required when using the + // DirectX capturer, otherwise the IDs across the APIs already match. + if (using_directx_capturer_) { + std::vector device_names; + // Crucially, this list of device names will be in the same order as + // |media_list_sources|. + webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames( + &device_names); + int device_name_index = 0; + for (auto& source : screen_sources) { const auto& device_name = device_names[device_name_index++]; std::wstring wide_device_name; base::UTF8ToWide(device_name.c_str(), device_name.size(), @@ -118,61 +173,21 @@ void OnRefreshFinishedTask(atom::api::DesktopCapturer* cap) { source.display_id = base::Int64ToString(device_id); } } - } #elif defined(OS_MACOSX) - // On Mac, the IDs across the APIs match. - for (auto& source : sources) { - if (source.media_list_source.id.type == - content::DesktopMediaID::TYPE_SCREEN) { + // On Mac, the IDs across the APIs match. + for (auto& source : screen_sources) { source.display_id = base::Int64ToString(source.media_list_source.id.id); } - } #endif // defined(OS_WIN) - // TODO(ajmacd): Add Linux support. The IDs across APIs differ but Chrome only - // supports capturing the entire desktop on Linux. Revisit this if individual - // screen support is added. + // TODO(ajmacd): Add Linux support. The IDs across APIs differ but Chrome + // only supports capturing the entire desktop on Linux. Revisit this if + // individual screen support is added. + std::move(screen_sources.begin(), screen_sources.end(), + std::back_inserter(captured_sources_)); + } - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, - base::Bind(EmitFinished, sources, cap)); -} - -} // namespace - -namespace atom { - -namespace api { - -DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) { - Init(isolate); - capture_thread_ = base::CreateSequencedTaskRunnerWithTraits( - {base::WithBaseSyncPrimitives(), base::MayBlock(), - base::TaskPriority::USER_VISIBLE}); -} - -DesktopCapturer::~DesktopCapturer() {} - -void DesktopCapturer::StartHandling(bool capture_window, - bool capture_screen, - const gfx::Size& thumbnail_size) { - capture_thread_->PostTask( - FROM_HERE, base::BindOnce(StartHandlingTask, capture_window, - capture_screen, thumbnail_size, this)); -} - -void DesktopCapturer::OnSourceAdded(int index) {} - -void DesktopCapturer::OnSourceRemoved(int index) {} - -void DesktopCapturer::OnSourceMoved(int old_index, int new_index) {} - -void DesktopCapturer::OnSourceNameChanged(int index) {} - -void DesktopCapturer::OnSourceThumbnailChanged(int index) {} - -bool DesktopCapturer::OnRefreshFinished() { - capture_thread_->PostTask(FROM_HERE, - base::BindOnce(OnRefreshFinishedTask, this)); - return false; + if (!capture_window_ && !capture_screen_) + Emit("finished", captured_sources_); } // static diff --git a/atom/browser/api/atom_api_desktop_capturer.h b/atom/browser/api/atom_api_desktop_capturer.h index 388fd7452a47..22be4c7710c6 100644 --- a/atom/browser/api/atom_api_desktop_capturer.h +++ b/atom/browser/api/atom_api_desktop_capturer.h @@ -7,10 +7,11 @@ #include #include +#include #include "atom/browser/api/event_emitter.h" -#include "chrome/browser/media/desktop_media_list_observer.h" -#include "chrome/browser/media/native_desktop_media_list.h" +#include "chrome/browser/media/webrtc/desktop_media_list_observer.h" +#include "chrome/browser/media/webrtc/native_desktop_media_list.h" #include "native_mate/handle.h" namespace atom { @@ -35,25 +36,32 @@ class DesktopCapturer : public mate::EventEmitter, bool capture_screen, const gfx::Size& thumbnail_size); - std::unique_ptr media_list_; -#if defined(OS_WIN) - bool using_directx_capturer_ = false; -#endif // defined(OS_WIN) - protected: explicit DesktopCapturer(v8::Isolate* isolate); ~DesktopCapturer() override; // DesktopMediaListObserver overrides. - void OnSourceAdded(int index) override; - void OnSourceRemoved(int index) override; - void OnSourceMoved(int old_index, int new_index) override; - void OnSourceNameChanged(int index) override; - void OnSourceThumbnailChanged(int index) override; - bool OnRefreshFinished() override; + void OnSourceAdded(DesktopMediaList* list, int index) override; + void OnSourceRemoved(DesktopMediaList* list, int index) override; + void OnSourceMoved(DesktopMediaList* list, + int old_index, + int new_index) override; + void OnSourceNameChanged(DesktopMediaList* list, int index) override; + void OnSourceThumbnailChanged(DesktopMediaList* list, int index) override; + void OnSourceUnchanged(DesktopMediaList* list) override; + bool ShouldScheduleNextRefresh(DesktopMediaList* list) override; private: - scoped_refptr capture_thread_; + void UpdateSourcesList(DesktopMediaList* list); + + std::unique_ptr window_capturer_; + std::unique_ptr screen_capturer_; + std::vector captured_sources_; + bool capture_window_ = false; + bool capture_screen_ = false; +#if defined(OS_WIN) + bool using_directx_capturer_ = false; +#endif // defined(OS_WIN) DISALLOW_COPY_AND_ASSIGN(DesktopCapturer); }; diff --git a/chromium_src/BUILD.gn b/chromium_src/BUILD.gn index 843e5e2b03f3..9f067d0f550e 100644 --- a/chromium_src/BUILD.gn +++ b/chromium_src/BUILD.gn @@ -2,6 +2,8 @@ # Use of this source code is governed by the MIT license that can be # found in the LICENSE file. +import("//electron/buildflags/buildflags.gni") + # Builds some of the chrome sources that Electron depends # on unconditionally. source_set("chrome") { @@ -10,6 +12,22 @@ source_set("chrome") { "//chrome/browser/ssl/security_state_tab_helper.cc", "//chrome/browser/ssl/security_state_tab_helper.h", ] - public_deps = [ "//content/public/browser" ] - deps = [ "//components/security_state/content" ] + public_deps = [ + "//content/public/browser", + ] + deps = [ + "//components/security_state/content", + ] + + if (enable_desktop_capturer) { + sources += [ + "//chrome/browser/media/webrtc/desktop_media_list.h", + "//chrome/browser/media/webrtc/desktop_media_list_base.cc", + "//chrome/browser/media/webrtc/desktop_media_list_base.h", + "//chrome/browser/media/webrtc/desktop_media_list_observer.h", + "//chrome/browser/media/webrtc/native_desktop_media_list.cc", + "//chrome/browser/media/webrtc/native_desktop_media_list.h", + ] + deps += [ "//ui/snapshot" ] + } } diff --git a/chromium_src/chrome/browser/media/desktop_media_list.h b/chromium_src/chrome/browser/media/desktop_media_list.h deleted file mode 100644 index 6572e792a122..000000000000 --- a/chromium_src/chrome/browser/media/desktop_media_list.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_H_ -#define CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_H_ - -#include "base/strings/string16.h" -#include "base/time/time.h" -#include "content/public/browser/desktop_media_id.h" -#include "ui/gfx/image/image_skia.h" - -class DesktopMediaListObserver; - -// DesktopMediaList provides the list of desktop media source (screens, windows, -// tabs), and their thumbnails, to the desktop media picker dialog. It -// transparently updates the list in the background, and notifies the desktop -// media picker when something changes. -class DesktopMediaList { - public: - // Struct used to represent each entry in the list. - struct Source { - // Id of the source. - content::DesktopMediaID id; - - // Name of the source that should be shown to the user. - base::string16 name; - - // The thumbnail for the source. - gfx::ImageSkia thumbnail; - }; - - virtual ~DesktopMediaList() {} - - // 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. - virtual void SetUpdatePeriod(base::TimeDelta period) = 0; - - // Sets size to which the thumbnails should be scaled. If called after - // StartUpdating() then some thumbnails may be still scaled to the old size - // until they are updated. - virtual void SetThumbnailSize(const gfx::Size& thumbnail_size) = 0; - - // Sets ID of the hosting desktop picker dialog. The window with this ID will - // be filtered out from the list of sources. - virtual void SetViewDialogWindowId(content::DesktopMediaID::Id dialog_id) = 0; - - // Starts updating the model. The model is initially empty, so OnSourceAdded() - // notifications will be generated for each existing source as it is - // 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 int GetSourceCount() const = 0; - virtual const Source& GetSource(int index) const = 0; - virtual std::vector GetSources() const = 0; -}; - -#endif // CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_H_ diff --git a/chromium_src/chrome/browser/media/desktop_media_list_observer.h b/chromium_src/chrome/browser/media/desktop_media_list_observer.h deleted file mode 100644 index 5df6f4f8b0e5..000000000000 --- a/chromium_src/chrome/browser/media/desktop_media_list_observer.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_OBSERVER_H_ -#define CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_OBSERVER_H_ - -// Interface implemented by the desktop media picker dialog to receive -// notifications about changes in DesktopMediaList. -class DesktopMediaListObserver { - public: - virtual void OnSourceAdded(int index) = 0; - virtual void OnSourceRemoved(int index) = 0; - virtual void OnSourceMoved(int old_index, int new_index) = 0; - virtual void OnSourceNameChanged(int index) = 0; - virtual void OnSourceThumbnailChanged(int index) = 0; - - // Return false to stop refreshing. The associated |DesktopMediaList| should - // no longer be used. - virtual bool OnRefreshFinished() = 0; - - protected: - virtual ~DesktopMediaListObserver() {} -}; - -#endif // CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_OBSERVER_H_ diff --git a/chromium_src/chrome/browser/media/native_desktop_media_list.cc b/chromium_src/chrome/browser/media/native_desktop_media_list.cc deleted file mode 100644 index 2945f3e6d7ef..000000000000 --- a/chromium_src/chrome/browser/media/native_desktop_media_list.cc +++ /dev/null @@ -1,367 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/media/native_desktop_media_list.h" - -#include -#include -#include - -using base::PlatformThreadRef; - -#include "base/hash.h" -#include "base/logging.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/task_scheduler/post_task.h" -#include "chrome/browser/media/desktop_media_list_observer.h" -#include "content/public/browser/browser_thread.h" -#include "media/base/video_util.h" -#include "third_party/libyuv/include/libyuv/scale_argb.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" -#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/gfx/skia_util.h" - -using content::BrowserThread; -using content::DesktopMediaID; - -namespace { - -// Update the list every second. -const int kDefaultUpdatePeriod = 1000; - -// Returns a hash of a DesktopFrame content to detect when image for a desktop -// media source has changed. -uint32_t GetFrameHash(webrtc::DesktopFrame* frame) { - int data_size = frame->stride() * frame->size().height(); - return base::Hash(frame->data(), data_size); -} - -gfx::ImageSkia ScaleDesktopFrame(std::unique_ptr frame, - gfx::Size size) { - gfx::Rect scaled_rect = media::ComputeLetterboxRegion( - gfx::Rect(0, 0, size.width(), size.height()), - gfx::Size(frame->size().width(), frame->size().height())); - - SkBitmap result; - result.allocN32Pixels(scaled_rect.width(), scaled_rect.height(), true); - - uint8* pixels_data = reinterpret_cast(result.getPixels()); - libyuv::ARGBScale(frame->data(), frame->stride(), frame->size().width(), - frame->size().height(), pixels_data, result.rowBytes(), - scaled_rect.width(), scaled_rect.height(), - libyuv::kFilterBilinear); - - // Set alpha channel values to 255 for all pixels. - // TODO(sergeyu): Fix screen/window capturers to capture alpha channel and - // remove this code. Currently screen/window capturers (at least some - // implementations) only capture R, G and B channels and set Alpha to 0. - // crbug.com/264424 - for (int y = 0; y < result.height(); ++y) { - for (int x = 0; x < result.width(); ++x) { - pixels_data[result.rowBytes() * y + x * result.bytesPerPixel() + 3] = - 0xff; - } - } - - return gfx::ImageSkia::CreateFrom1xBitmap(result); -} - -} // namespace - -NativeDesktopMediaList::SourceDescription::SourceDescription( - DesktopMediaID id, - const base::string16& name) - : id(id), name(name) {} - -class NativeDesktopMediaList::Worker - : public webrtc::DesktopCapturer::Callback { - public: - Worker(base::WeakPtr media_list, - std::unique_ptr screen_capturer, - std::unique_ptr window_capturer); - ~Worker() override; - - void Refresh(const gfx::Size& thumbnail_size, - content::DesktopMediaID::Id view_dialog_id); - - private: - typedef std::map ImageHashesMap; - - // webrtc::DesktopCapturer::Callback interface. - void OnCaptureResult(webrtc::DesktopCapturer::Result result, - std::unique_ptr frame) override; - - base::WeakPtr media_list_; - - std::unique_ptr screen_capturer_; - std::unique_ptr window_capturer_; - - std::unique_ptr current_frame_; - - ImageHashesMap image_hashes_; - - DISALLOW_COPY_AND_ASSIGN(Worker); -}; - -NativeDesktopMediaList::Worker::Worker( - base::WeakPtr media_list, - std::unique_ptr screen_capturer, - std::unique_ptr window_capturer) - : media_list_(media_list), - screen_capturer_(std::move(screen_capturer)), - window_capturer_(std::move(window_capturer)) { - if (screen_capturer_) - screen_capturer_->Start(this); - if (window_capturer_) - window_capturer_->Start(this); -} - -NativeDesktopMediaList::Worker::~Worker() {} - -void NativeDesktopMediaList::Worker::Refresh( - const gfx::Size& thumbnail_size, - content::DesktopMediaID::Id view_dialog_id) { - std::vector sources; - - if (screen_capturer_) { - webrtc::DesktopCapturer::SourceList screens; - if (screen_capturer_->GetSourceList(&screens)) { - bool mutiple_screens = screens.size() > 1; - base::string16 title; - for (size_t i = 0; i < screens.size(); ++i) { - if (mutiple_screens) { - title = base::UTF8ToUTF16("Screen " + base::IntToString(i + 1)); - } else { - title = base::UTF8ToUTF16("Entire screen"); - } - sources.push_back(SourceDescription( - DesktopMediaID(DesktopMediaID::TYPE_SCREEN, screens[i].id), title)); - } - } - } - - if (window_capturer_) { - webrtc::DesktopCapturer::SourceList windows; - if (window_capturer_->GetSourceList(&windows)) { - for (auto it = windows.begin(); it != windows.end(); ++it) { - // Skip the picker dialog window. - if (it->id != view_dialog_id) { - sources.push_back(SourceDescription( - DesktopMediaID(DesktopMediaID::TYPE_WINDOW, it->id), - base::UTF8ToUTF16(it->title))); - } - } - } - } - // Update list of windows before updating thumbnails. - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&NativeDesktopMediaList::OnSourcesList, media_list_, sources)); - - ImageHashesMap new_image_hashes; - - // Get a thumbnail for each source. - for (size_t i = 0; i < sources.size(); ++i) { - SourceDescription& source = sources[i]; - switch (source.id.type) { - case DesktopMediaID::TYPE_SCREEN: - if (!screen_capturer_->SelectSource(source.id.id)) - continue; - screen_capturer_->CaptureFrame(); - break; - - case DesktopMediaID::TYPE_WINDOW: - if (!window_capturer_->SelectSource(source.id.id)) - continue; - window_capturer_->CaptureFrame(); - break; - - default: - NOTREACHED(); - } - - // Expect that DesktopCapturer to always captures frames synchronously. - // |current_frame_| may be NULL if capture failed (e.g. because window has - // been closed). - if (current_frame_) { - uint32_t frame_hash = GetFrameHash(current_frame_.get()); - new_image_hashes[source.id] = frame_hash; - - // Scale the image only if it has changed. - ImageHashesMap::iterator it = image_hashes_.find(source.id); - if (it == image_hashes_.end() || it->second != frame_hash) { - gfx::ImageSkia thumbnail = - ScaleDesktopFrame(std::move(current_frame_), thumbnail_size); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&NativeDesktopMediaList::OnSourceThumbnail, media_list_, - i, thumbnail)); - } - } - } - - image_hashes_.swap(new_image_hashes); - - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&NativeDesktopMediaList::OnRefreshFinished, media_list_)); - - // Destroy capturers when done. - screen_capturer_.reset(); - window_capturer_.reset(); -} - -void NativeDesktopMediaList::Worker::OnCaptureResult( - webrtc::DesktopCapturer::Result result, - std::unique_ptr frame) { - current_frame_ = std::move(frame); -} - -NativeDesktopMediaList::NativeDesktopMediaList( - std::unique_ptr screen_capturer, - std::unique_ptr window_capturer) - : screen_capturer_(std::move(screen_capturer)), - window_capturer_(std::move(window_capturer)), - update_period_(base::TimeDelta::FromMilliseconds(kDefaultUpdatePeriod)), - thumbnail_size_(100, 100), - view_dialog_id_(-1), - observer_(NULL), - weak_factory_(this) { - capture_task_runner_ = base::CreateSequencedTaskRunnerWithTraits( - {base::WithBaseSyncPrimitives(), base::MayBlock(), - base::TaskPriority::USER_VISIBLE}); -} - -NativeDesktopMediaList::~NativeDesktopMediaList() { - capture_task_runner_->DeleteSoon(FROM_HERE, worker_.release()); -} - -void NativeDesktopMediaList::SetUpdatePeriod(base::TimeDelta period) { - DCHECK(!observer_); - update_period_ = period; -} - -void NativeDesktopMediaList::SetThumbnailSize(const gfx::Size& thumbnail_size) { - thumbnail_size_ = thumbnail_size; -} - -void NativeDesktopMediaList::SetViewDialogWindowId( - content::DesktopMediaID::Id dialog_id) { - view_dialog_id_ = dialog_id; -} - -void NativeDesktopMediaList::StartUpdating(DesktopMediaListObserver* observer) { - DCHECK(!observer_); - DCHECK(screen_capturer_ || window_capturer_); - - observer_ = observer; - - worker_.reset(new Worker(weak_factory_.GetWeakPtr(), - std::move(screen_capturer_), - std::move(window_capturer_))); - Refresh(); -} - -int NativeDesktopMediaList::GetSourceCount() const { - return sources_.size(); -} - -const DesktopMediaList::Source& NativeDesktopMediaList::GetSource( - int index) const { - return sources_[index]; -} - -std::vector NativeDesktopMediaList::GetSources() - const { - return sources_; -} - -void NativeDesktopMediaList::Refresh() { - capture_task_runner_->PostTask( - FROM_HERE, base::Bind(&Worker::Refresh, base::Unretained(worker_.get()), - thumbnail_size_, view_dialog_id_)); -} - -void NativeDesktopMediaList::OnSourcesList( - const std::vector& new_sources) { - typedef std::set SourceSet; - SourceSet new_source_set; - for (size_t i = 0; i < new_sources.size(); ++i) { - new_source_set.insert(new_sources[i].id); - } - // Iterate through the old sources to find the removed sources. - for (size_t i = 0; i < sources_.size(); ++i) { - if (new_source_set.find(sources_[i].id) == new_source_set.end()) { - observer_->OnSourceRemoved(i); - sources_.erase(sources_.begin() + i); - --i; - } - } - // Iterate through the new sources to find the added sources. - if (new_sources.size() > sources_.size()) { - SourceSet old_source_set; - for (size_t i = 0; i < sources_.size(); ++i) { - old_source_set.insert(sources_[i].id); - } - - for (size_t i = 0; i < new_sources.size(); ++i) { - if (old_source_set.find(new_sources[i].id) == old_source_set.end()) { - sources_.insert(sources_.begin() + i, Source()); - sources_[i].id = new_sources[i].id; - sources_[i].name = new_sources[i].name; - observer_->OnSourceAdded(i); - } - } - } - DCHECK_EQ(new_sources.size(), sources_.size()); - - // Find the moved/changed sources. - size_t pos = 0; - while (pos < sources_.size()) { - if (!(sources_[pos].id == new_sources[pos].id)) { - // Find the source that should be moved to |pos|, starting from |pos + 1| - // of |sources_|, because entries before |pos| should have been sorted. - size_t old_pos = pos + 1; - for (; old_pos < sources_.size(); ++old_pos) { - if (sources_[old_pos].id == new_sources[pos].id) - break; - } - DCHECK(sources_[old_pos].id == new_sources[pos].id); - - // Move the source from |old_pos| to |pos|. - Source temp = sources_[old_pos]; - sources_.erase(sources_.begin() + old_pos); - sources_.insert(sources_.begin() + pos, temp); - - observer_->OnSourceMoved(old_pos, pos); - } - - if (sources_[pos].name != new_sources[pos].name) { - sources_[pos].name = new_sources[pos].name; - observer_->OnSourceNameChanged(pos); - } - ++pos; - } -} - -void NativeDesktopMediaList::OnSourceThumbnail(int index, - const gfx::ImageSkia& image) { - DCHECK_LT(index, static_cast(sources_.size())); - sources_[index].thumbnail = image; - observer_->OnSourceThumbnailChanged(index); -} - -void NativeDesktopMediaList::OnRefreshFinished() { - // Give a chance to the observer to stop the refresh work. - bool is_continue = observer_->OnRefreshFinished(); - if (is_continue) { - BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE, - base::Bind(&NativeDesktopMediaList::Refresh, - weak_factory_.GetWeakPtr()), - update_period_); - } -} diff --git a/chromium_src/chrome/browser/media/native_desktop_media_list.h b/chromium_src/chrome/browser/media/native_desktop_media_list.h deleted file mode 100644 index 270377520bd9..000000000000 --- a/chromium_src/chrome/browser/media/native_desktop_media_list.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_MEDIA_NATIVE_DESKTOP_MEDIA_LIST_H_ -#define CHROME_BROWSER_MEDIA_NATIVE_DESKTOP_MEDIA_LIST_H_ - -#include "base/memory/weak_ptr.h" -#include "base/sequenced_task_runner.h" -#include "chrome/browser/media/desktop_media_list.h" -#include "content/public/browser/desktop_media_id.h" -#include "ui/gfx/image/image_skia.h" - -namespace webrtc { -class DesktopCapturer; -} - -// Implementation of DesktopMediaList that shows native screens and -// native windows. -class NativeDesktopMediaList : public DesktopMediaList { - public: - // Caller may pass NULL for either of the arguments in case when only some - // types of sources the model should be populated with (e.g. it will only - // contain windows, if |screen_capturer| is NULL). - NativeDesktopMediaList( - std::unique_ptr screen_capturer, - std::unique_ptr window_capturer); - ~NativeDesktopMediaList() override; - - // DesktopMediaList interface. - void SetUpdatePeriod(base::TimeDelta period) override; - void SetThumbnailSize(const gfx::Size& thumbnail_size) override; - void StartUpdating(DesktopMediaListObserver* observer) override; - int GetSourceCount() const override; - const Source& GetSource(int index) const override; - std::vector GetSources() const override; - void SetViewDialogWindowId(content::DesktopMediaID::Id dialog_id) override; - - private: - class Worker; - friend class Worker; - - // Struct used to represent sources list the model gets from the Worker. - struct SourceDescription { - SourceDescription(content::DesktopMediaID id, const base::string16& name); - - content::DesktopMediaID id; - base::string16 name; - }; - - // Order comparator for sources. Used to sort list of sources. - static bool CompareSources(const SourceDescription& a, - const SourceDescription& b); - - // Post a task for the |worker_| to update list of windows and get thumbnails. - void Refresh(); - - // Called by |worker_| to refresh the model. First it posts tasks for - // OnSourcesList() with the fresh list of sources, then follows with - // OnSourceThumbnail() for each changed thumbnail and then calls - // OnRefreshFinished() at the end. - void OnSourcesList(const std::vector& sources); - void OnSourceThumbnail(int index, const gfx::ImageSkia& thumbnail); - void OnRefreshFinished(); - - // Capturers specified in SetCapturers() and passed to the |worker_| later. - std::unique_ptr screen_capturer_; - std::unique_ptr window_capturer_; - - // Time interval between mode updates. - base::TimeDelta update_period_; - - // Size of thumbnails generated by the model. - gfx::Size thumbnail_size_; - - // ID of the hosting dialog. - content::DesktopMediaID::Id view_dialog_id_; - - // The observer passed to StartUpdating(). - DesktopMediaListObserver* observer_; - - // Task runner used for the |worker_|. - scoped_refptr 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. - std::unique_ptr worker_; - - // Current list of sources. - std::vector sources_; - - base::WeakPtrFactory weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(NativeDesktopMediaList); -}; - -#endif // CHROME_BROWSER_MEDIA_NATIVE_DESKTOP_MEDIA_LIST_H_ diff --git a/filenames.gni b/filenames.gni index 17438ea70280..0b653be11591 100644 --- a/filenames.gni +++ b/filenames.gni @@ -587,10 +587,6 @@ filenames = { "chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.h", "chromium_src/chrome/browser/extensions/global_shortcut_listener_win.cc", "chromium_src/chrome/browser/extensions/global_shortcut_listener_win.h", - "chromium_src/chrome/browser/media/desktop_media_list.h", - "chromium_src/chrome/browser/media/desktop_media_list_observer.h", - "chromium_src/chrome/browser/media/native_desktop_media_list.cc", - "chromium_src/chrome/browser/media/native_desktop_media_list.h", "chromium_src/chrome/browser/printing/print_job.cc", "chromium_src/chrome/browser/printing/print_job.h", "chromium_src/chrome/browser/printing/print_job_manager.cc", diff --git a/patches/common/chromium/.patches.yaml b/patches/common/chromium/.patches.yaml index 034194858bbc..dc7cb505ae8d 100644 --- a/patches/common/chromium/.patches.yaml +++ b/patches/common/chromium/.patches.yaml @@ -469,3 +469,11 @@ patches: * Fixes a main_application_delegate SDK change * Fixes a non-null SDK change in a net unittest. This is needed for Electron to compile with XCode 10.0. +- + author: deepak1556 + file: desktop_media_list.patch + description: | + * 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/patches/common/chromium/desktop_media_list.patch b/patches/common/chromium/desktop_media_list.patch new file mode 100644 index 000000000000..ba1d9b93f29d --- /dev/null +++ b/patches/common/chromium/desktop_media_list.patch @@ -0,0 +1,304 @@ +diff --git a/chrome/browser/media/webrtc/desktop_media_list.h b/chrome/browser/media/webrtc/desktop_media_list.h +index 8e02a8a95eb0..3497b85428a5 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& 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 43dd95ef72f5..d4662708f649 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& 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& new_sources) { ++ // Notify observer when there was no new source captured. ++ if (new_sources.empty()) { ++ observer_->OnSourceUnchanged(this); ++ return; ++ } ++ + typedef std::set 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 746df1210aa9..461e0edf8509 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& 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 47401abc984e..ca6a527ffac8 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 0c9ba953cb3c..5a2d853aeeac 100644 +--- a/chrome/browser/media/webrtc/native_desktop_media_list.cc ++++ b/chrome/browser/media/webrtc/native_desktop_media_list.cc +@@ -5,10 +5,16 @@ + #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" ++#if 0 + #include "chrome/grit/generated_resources.h" ++#endif + #include "content/public/browser/browser_thread.h" + #include "media/base/video_util.h" + #include "third_party/libyuv/include/libyuv/scale_argb.h" +@@ -76,11 +82,13 @@ gfx::ImageSkia ScaleDesktopFrame(std::unique_ptr frame, + class NativeDesktopMediaList::Worker + : public webrtc::DesktopCapturer::Callback { + public: +- Worker(base::WeakPtr media_list, ++ Worker(scoped_refptr task_runner, ++ base::WeakPtr media_list, + DesktopMediaID::Type type, + std::unique_ptr capturer); + ~Worker() override; + ++ void Start(); + void Refresh(const DesktopMediaID::Id& view_dialog_id); + + void RefreshThumbnails(const std::vector& native_ids, +@@ -93,6 +101,9 @@ class NativeDesktopMediaList::Worker + void OnCaptureResult(webrtc::DesktopCapturer::Result result, + std::unique_ptr frame) override; + ++ // Task runner used for capturing operations. ++ scoped_refptr task_runner_; ++ + base::WeakPtr media_list_; + + DesktopMediaID::Type type_; +@@ -106,17 +117,27 @@ class NativeDesktopMediaList::Worker + }; + + NativeDesktopMediaList::Worker::Worker( ++ scoped_refptr task_runner, + base::WeakPtr media_list, + DesktopMediaID::Type type, + std::unique_ptr 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 result; + + webrtc::DesktopCapturer::SourceList sources; +@@ -133,11 +154,8 @@ void NativeDesktopMediaList::Worker::Refresh( + // Just in case 'Screen' is inflected depending on the screen number, + // use plural formatter. + title = mutiple_sources +- ? l10n_util::GetPluralStringFUTF16( +- IDS_DESKTOP_MEDIA_PICKER_MULTIPLE_SCREEN_NAME, +- static_cast(i + 1)) +- : l10n_util::GetStringUTF16( +- IDS_DESKTOP_MEDIA_PICKER_SINGLE_SCREEN_NAME); ++ ? base::UTF8ToUTF16("Screen " + base::IntToString(i + 1)) ++ : base::UTF8ToUTF16("Entire screen"); + break; + + case DesktopMediaID::TYPE_WINDOW: +@@ -163,6 +181,7 @@ void NativeDesktopMediaList::Worker::Refresh( + void NativeDesktopMediaList::Worker::RefreshThumbnails( + const std::vector& native_ids, + const gfx::Size& thumbnail_size) { ++ DCHECK(task_runner_->BelongsToCurrentThread()); + ImageHashesMap new_image_hashes; + + // Get a thumbnail for each native source. +@@ -210,17 +229,30 @@ NativeDesktopMediaList::NativeDesktopMediaList( + std::unique_ptr 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 +262,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 +312,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 e6f0e17b05ee..75c9ca04ce48 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 + + #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 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_; + + #if defined(USE_AURA) diff --git a/patches/common/webrtc/.patches.yaml b/patches/common/webrtc/.patches.yaml index 78aa4b177a92..3fed69afe5e6 100644 --- a/patches/common/webrtc/.patches.yaml +++ b/patches/common/webrtc/.patches.yaml @@ -1,13 +1,5 @@ repo: src/third_party/webrtc patches: -- - author: null - file: webrtc-desktop_capturer_mac.patch - description: null -- - author: null - file: webrtc-rwlock_null.patch - description: null - author: Nitish Sakhawalkar file: disable-warning-win.patch diff --git a/patches/common/webrtc/webrtc-desktop_capturer_mac.patch b/patches/common/webrtc/webrtc-desktop_capturer_mac.patch deleted file mode 100644 index 28984b56bd71..000000000000 --- a/patches/common/webrtc/webrtc-desktop_capturer_mac.patch +++ /dev/null @@ -1,117 +0,0 @@ -diff --git a/modules/desktop_capture/mac/screen_capturer_mac.mm b/modules/desktop_capture/mac/screen_capturer_mac.mm -index df18777226..6a1e3da6ab 100644 ---- a/modules/desktop_capture/mac/screen_capturer_mac.mm -+++ b/modules/desktop_capture/mac/screen_capturer_mac.mm -@@ -16,6 +16,7 @@ - #include "rtc_base/checks.h" - #include "rtc_base/constructormagic.h" - #include "rtc_base/logging.h" -+#include "rtc_base/synchronization/rw_lock_wrapper.h" - #include "rtc_base/timeutils.h" - #include "sdk/objc/Framework/Classes/Common/scoped_cftyperef.h" - -@@ -28,18 +29,31 @@ namespace webrtc { - // destroy itself once it's done. - class DisplayStreamManager { - public: -- int GetUniqueId() { return ++unique_id_generator_; } -- void DestroyStream(int unique_id) { -- auto it = display_stream_wrappers_.find(unique_id); -- RTC_CHECK(it != display_stream_wrappers_.end()); -- RTC_CHECK(!it->second.active); -- CFRelease(it->second.stream); -- display_stream_wrappers_.erase(it); -+ DisplayStreamManager() : rw_lock_(RWLockWrapper::CreateRWLock()) {} -+ RWLockWrapper* GetLock() {return rw_lock_.get();}; - -- if (ready_for_self_destruction_ && display_stream_wrappers_.empty()) delete this; -+ int GetUniqueId() { -+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_); -+ return ++unique_id_generator_; -+ } -+ void DestroyStream(int unique_id) { -+ bool finalize; -+ { -+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_); -+ auto it = display_stream_wrappers_.find(unique_id); -+ RTC_CHECK(it != display_stream_wrappers_.end()); -+ RTC_CHECK(!it->second.active); -+ CFRelease(it->second.stream); -+ display_stream_wrappers_.erase(it); -+ finalize = ready_for_self_destruction_ && display_stream_wrappers_.empty(); -+ } -+ if (finalize) { -+ delete this; -+ } - } - - void SaveStream(int unique_id, CGDisplayStreamRef stream) { -+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_); - RTC_CHECK(unique_id <= unique_id_generator_); - DisplayStreamWrapper wrapper; - wrapper.stream = stream; -@@ -47,6 +61,7 @@ class DisplayStreamManager { - } - - void UnregisterActiveStreams() { -+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_); - for (auto& pair : display_stream_wrappers_) { - DisplayStreamWrapper& wrapper = pair.second; - if (wrapper.active) { -@@ -61,12 +76,23 @@ class DisplayStreamManager { - void PrepareForSelfDestruction() { - ready_for_self_destruction_ = true; - -- if (display_stream_wrappers_.empty()) delete this; -+ bool finalize; -+ { -+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_); -+ ready_for_self_destruction_ = true; -+ finalize = display_stream_wrappers_.empty(); -+ } -+ if (finalize) { -+ delete this; -+ } - } - - // Once the DisplayStreamManager is ready for destruction, the - // ScreenCapturerMac is no longer present. Any updates should be ignored. -- bool ShouldIgnoreUpdates() { return ready_for_self_destruction_; } -+ // Note: not thread-safe! Acquire and release a lock manually. -+ bool ShouldIgnoreUpdates() { -+ return ready_for_self_destruction_; -+ } - - private: - struct DisplayStreamWrapper { -@@ -81,6 +107,7 @@ class DisplayStreamManager { - std::map display_stream_wrappers_; - int unique_id_generator_ = 0; - bool ready_for_self_destruction_ = false; -+ std::unique_ptr rw_lock_; - }; - - namespace { -@@ -507,8 +534,6 @@ bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() { - return; - } - -- if (manager->ShouldIgnoreUpdates()) return; -- - // Only pay attention to frame updates. - if (status != kCGDisplayStreamFrameStatusFrameComplete) return; - -@@ -518,7 +543,12 @@ bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() { - if (count != 0) { - // According to CGDisplayStream.h, it's safe to call - // CGDisplayStreamStop() from within the callback. -- ScreenRefresh(count, rects, display_origin); -+ manager->GetLock()->AcquireLockShared(); -+ bool screen_capturer_mac_invalidated = manager->ShouldIgnoreUpdates(); -+ if (!screen_capturer_mac_invalidated) { -+ ScreenRefresh(count, rects, display_origin); -+ } -+ manager->GetLock()->ReleaseLockShared(); - } - }; - diff --git a/patches/common/webrtc/webrtc-rwlock_null.patch b/patches/common/webrtc/webrtc-rwlock_null.patch deleted file mode 100644 index c5278ad00664..000000000000 --- a/patches/common/webrtc/webrtc-rwlock_null.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff --git a/rtc_base/synchronization/rw_lock_wrapper.cc b/rtc_base/synchronization/rw_lock_wrapper.cc -index c8cd17edb8..50c6e25ad9 100644 ---- a/rtc_base/synchronization/rw_lock_wrapper.cc -+++ b/rtc_base/synchronization/rw_lock_wrapper.cc -@@ -11,6 +11,9 @@ - #include "rtc_base/synchronization/rw_lock_wrapper.h" - - #include -+#include -+ -+#include "system_wrappers/include/sleep.h" - - #if defined(_WIN32) - #include "rtc_base/synchronization/rw_lock_win.h" -@@ -21,11 +23,19 @@ - namespace webrtc { - - RWLockWrapper* RWLockWrapper::CreateRWLock() { -+ RWLockWrapper* rw_lock_ptr; - #ifdef _WIN32 -- return RWLockWin::Create(); -+ rw_lock_ptr = RWLockWin::Create(); - #else -- return RWLockPosix::Create(); -+ rw_lock_ptr = RWLockPosix::Create(); - #endif -+ if (rw_lock_ptr != NULL) { -+ return rw_lock_ptr; -+ } else { -+ int msec_wait = 10 + (rand() % 90); -+ SleepMs(msec_wait); -+ return CreateRWLock(); -+ } - } - - } // namespace webrtc