Commit e195bbe5 authored by Darin Fisher's avatar Darin Fisher Committed by Commit Bot

Lazily initialize ScreenManager connection

This enables us to replace usage of mojo::SharedRemote and the thread
pool usage with an ordinary mojo::Remote. This should be a performance
improvement as it eliminates a hop through the thread pool.

Adds usage of sequence checker to assert thread safety expectations.

Change-Id: I93a681a2a6543fed417dcffbd0b43da121caddf5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2439559Reviewed-by: default avatarSergey Ulanov <sergeyu@chromium.org>
Reviewed-by: default avatarErik Chen <erikchen@chromium.org>
Commit-Queue: Darin Fisher <darin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812414}
parent d52db894
...@@ -16,26 +16,17 @@ DesktopCapturerLacros::DesktopCapturerLacros( ...@@ -16,26 +16,17 @@ DesktopCapturerLacros::DesktopCapturerLacros(
CaptureType capture_type, CaptureType capture_type,
const webrtc::DesktopCaptureOptions& options) const webrtc::DesktopCaptureOptions& options)
: capture_type_(capture_type), options_(options) { : capture_type_(capture_type), options_(options) {
mojo::PendingRemote<crosapi::mojom::ScreenManager> pending_screen_manager; // Allow this class to be constructed on any sequence.
mojo::PendingReceiver<crosapi::mojom::ScreenManager> pending_receiver = DETACH_FROM_SEQUENCE(sequence_checker_);
pending_screen_manager.InitWithNewPipeAndPassReceiver();
// The lacros chrome service exists at all times except during early start-up
// and late shut-down. This class should never be used in those two times.
auto* lacros_chrome_service = chromeos::LacrosChromeServiceImpl::Get();
DCHECK(lacros_chrome_service);
lacros_chrome_service->BindScreenManagerReceiver(std::move(pending_receiver));
// We create a SharedRemote that binds the underlying Remote onto a
// dedicated sequence.
screen_manager_ = mojo::SharedRemote<crosapi::mojom::ScreenManager>(
std::move(pending_screen_manager),
base::ThreadPool::CreateSequencedTaskRunner({}));
} }
DesktopCapturerLacros::~DesktopCapturerLacros() = default; DesktopCapturerLacros::~DesktopCapturerLacros() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
bool DesktopCapturerLacros::GetSourceList(SourceList* sources) { bool DesktopCapturerLacros::GetSourceList(SourceList* sources) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (capture_type_ == kScreen) { if (capture_type_ == kScreen) {
// TODO(https://crbug.com/1094460): Implement this source list // TODO(https://crbug.com/1094460): Implement this source list
// appropriately. // appropriately.
...@@ -45,6 +36,8 @@ bool DesktopCapturerLacros::GetSourceList(SourceList* sources) { ...@@ -45,6 +36,8 @@ bool DesktopCapturerLacros::GetSourceList(SourceList* sources) {
return true; return true;
} }
EnsureScreenManager();
std::vector<crosapi::mojom::WindowDetailsPtr> windows; std::vector<crosapi::mojom::WindowDetailsPtr> windows;
{ {
mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call; mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call;
...@@ -61,6 +54,11 @@ bool DesktopCapturerLacros::GetSourceList(SourceList* sources) { ...@@ -61,6 +54,11 @@ bool DesktopCapturerLacros::GetSourceList(SourceList* sources) {
} }
bool DesktopCapturerLacros::SelectSource(SourceId id) { bool DesktopCapturerLacros::SelectSource(SourceId id) {
#if DCHECK_IS_ON()
// OK to modify on any thread prior to calling Start.
DCHECK(!callback_ || sequence_checker_.CalledOnValidSequence());
#endif
selected_source_ = id; selected_source_ = id;
return true; return true;
} }
...@@ -70,10 +68,15 @@ bool DesktopCapturerLacros::FocusOnSelectedSource() { ...@@ -70,10 +68,15 @@ bool DesktopCapturerLacros::FocusOnSelectedSource() {
} }
void DesktopCapturerLacros::Start(Callback* callback) { void DesktopCapturerLacros::Start(Callback* callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
callback_ = callback; callback_ = callback;
} }
void DesktopCapturerLacros::CaptureFrame() { void DesktopCapturerLacros::CaptureFrame() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
EnsureScreenManager();
if (capture_type_ == kScreen) { if (capture_type_ == kScreen) {
crosapi::Bitmap snapshot; crosapi::Bitmap snapshot;
{ {
...@@ -104,8 +107,24 @@ void DesktopCapturerLacros::SetSharedMemoryFactory( ...@@ -104,8 +107,24 @@ void DesktopCapturerLacros::SetSharedMemoryFactory(
void DesktopCapturerLacros::SetExcludedWindow(webrtc::WindowId window) {} void DesktopCapturerLacros::SetExcludedWindow(webrtc::WindowId window) {}
void DesktopCapturerLacros::EnsureScreenManager() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (screen_manager_)
return;
// The lacros chrome service exists at all times except during early start-up
// and late shut-down. This class should never be used in those two times.
auto* lacros_chrome_service = chromeos::LacrosChromeServiceImpl::Get();
DCHECK(lacros_chrome_service);
lacros_chrome_service->BindScreenManagerReceiver(
screen_manager_.BindNewPipeAndPassReceiver());
}
void DesktopCapturerLacros::DidTakeSnapshot(bool success, void DesktopCapturerLacros::DidTakeSnapshot(bool success,
const crosapi::Bitmap& snapshot) { const crosapi::Bitmap& snapshot) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!success) { if (!success) {
callback_->OnCaptureResult(Result::ERROR_PERMANENT, callback_->OnCaptureResult(Result::ERROR_PERMANENT,
std::unique_ptr<webrtc::DesktopFrame>()); std::unique_ptr<webrtc::DesktopFrame>());
......
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_DESKTOP_CAPTURER_LACROS_H_ #ifndef CONTENT_BROWSER_MEDIA_CAPTURE_DESKTOP_CAPTURER_LACROS_H_
#define CONTENT_BROWSER_MEDIA_CAPTURE_DESKTOP_CAPTURER_LACROS_H_ #define CONTENT_BROWSER_MEDIA_CAPTURE_DESKTOP_CAPTURER_LACROS_H_
#include "base/memory/weak_ptr.h" #include "base/sequence_checker.h"
#include "chromeos/crosapi/mojom/screen_manager.mojom.h" #include "chromeos/crosapi/mojom/screen_manager.mojom.h"
#include "mojo/public/cpp/bindings/shared_remote.h" #include "mojo/public/cpp/bindings/remote.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h" #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
...@@ -18,11 +18,13 @@ struct Bitmap; ...@@ -18,11 +18,13 @@ struct Bitmap;
namespace content { namespace content {
// This class is responsible for communicating with ash-chrome to get snapshots // This class is responsible for communicating with ash-chrome to get snapshots
// of the desktop. This class is used on several different threads with no clear // of the desktop.
// signaling. This is a contextual requirement of the current implementation of //
// the media capture code. We do our best to: // NOTE: Instances of this class may be allocated and configured on one affine
// * Minimize state stored in this class. // sequence and then transferred to another affine sequence (e.g., a worker
// * Ensure that stored state is accessed safely. // thread) where |Start| gets called. Subsequent methods are allowed to do
// blocking I/O or other expensive operations. The instance, when no longer
// needed, is deleted on the same affine sequence on which |Start| was called.
class DesktopCapturerLacros : public webrtc::DesktopCapturer { class DesktopCapturerLacros : public webrtc::DesktopCapturer {
public: public:
enum CaptureType { kScreen, kWindow }; enum CaptureType { kScreen, kWindow };
...@@ -44,10 +46,16 @@ class DesktopCapturerLacros : public webrtc::DesktopCapturer { ...@@ -44,10 +46,16 @@ class DesktopCapturerLacros : public webrtc::DesktopCapturer {
void SetExcludedWindow(webrtc::WindowId window) override; void SetExcludedWindow(webrtc::WindowId window) override;
private: private:
// This method is used to lazily initialize screen_manager_ on the same
// affine sequence on which |Start| is called.
void EnsureScreenManager();
// Callback for when ash-chrome returns a snapshot of the screen or window as // Callback for when ash-chrome returns a snapshot of the screen or window as
// a bitmap. // a bitmap.
void DidTakeSnapshot(bool success, const crosapi::Bitmap& snapshot); void DidTakeSnapshot(bool success, const crosapi::Bitmap& snapshot);
SEQUENCE_CHECKER(sequence_checker_);
// Whether this object is capturing screens or windows. // Whether this object is capturing screens or windows.
const CaptureType capture_type_; const CaptureType capture_type_;
...@@ -67,10 +75,8 @@ class DesktopCapturerLacros : public webrtc::DesktopCapturer { ...@@ -67,10 +75,8 @@ class DesktopCapturerLacros : public webrtc::DesktopCapturer {
// Thus, we do not worry about thread safety when invoking callback_. // Thus, we do not worry about thread safety when invoking callback_.
Callback* callback_ = nullptr; Callback* callback_ = nullptr;
// This remote is thread safe. Callbacks are invoked on the calling sequence. // The remote connection to the screen manager.
mojo::SharedRemote<crosapi::mojom::ScreenManager> screen_manager_; mojo::Remote<crosapi::mojom::ScreenManager> screen_manager_;
base::WeakPtrFactory<DesktopCapturerLacros> weak_factory_{this};
}; };
} // namespace content } // namespace content
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment