// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_DESKTOP_CAPTURER_LACROS_H_
#define CONTENT_BROWSER_MEDIA_CAPTURE_DESKTOP_CAPTURER_LACROS_H_
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/synchronization/lock.h"
#include "chromeos/crosapi/mojom/screen_manager.mojom.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_capturer.h"
#include "ui/aura/env_observer.h"
#include "ui/gfx/native_widget_types.h"
namespace content {
// This class is responsible for communicating with ash-chrome to get snapshots
// of the desktop.
//
// NOTE: Instances of this class may be allocated and configured on one affine
// sequence and then transferred to another affine sequence (e.g., a worker
// 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,
public aura::EnvObserver {
public:
enum CaptureType { kScreen, kWindow };
DesktopCapturerLacros(CaptureType capture_type,
const webrtc::DesktopCaptureOptions& options);
DesktopCapturerLacros(const DesktopCapturerLacros&) = delete;
DesktopCapturerLacros& operator=(const DesktopCapturerLacros&) = delete;
~DesktopCapturerLacros() override;
// DesktopCapturer:
void Start(Callback* callback) override;
void CaptureFrame() override;
bool GetSourceList(SourceList* sources) override;
bool SelectSource(SourceId id) override;
bool FocusOnSelectedSource() override;
bool IsOccluded(const webrtc::DesktopVector& pos) override;
void SetSharedMemoryFactory(std::unique_ptr<webrtc::SharedMemoryFactory>
shared_memory_factory) override;
void SetExcludedWindow(webrtc::WindowId window) override;
private:
// Callback for when ash-chrome returns a snapshot of the screen or window as
// a bitmap.
void DidTakeSnapshot(bool success, const SkBitmap& snapshot);
void InitializeWidgetMap();
// EnvObserver and Window Observer overrides. Note that these will *not* be
// called on the affine sequence.
void OnHostInitialized(aura::WindowTreeHost* host) override;
void OnHostDestroyed(aura::WindowTreeHost* host) override;
SEQUENCE_CHECKER(sequence_checker_);
// Whether this object is capturing screens or windows.
const CaptureType capture_type_;
// TODO(crbug.com/40135428): The webrtc options for screen/display
// capture are currently ignored.
const webrtc::DesktopCaptureOptions options_;
// For window capture, this is the source that we want to capture.
SourceId selected_source_;
// The webrtc::DesktopCapturer interface expects the implementation to hold
// onto and call a Callback* object. This instance relies on the assumption
// that Callback* will outlive this instance.
//
// The current media capture implementation expects that the implementation of
// CaptureFrame() synchronously invokes |callback_| in a re-entrant fashion.
// Thus, we do not worry about thread safety when invoking callback_.
raw_ptr<Callback> callback_ = nullptr;
// A remote for an ash interface that is responsible for either capturing
// screen snapshots or window snapshots.
mojo::Remote<crosapi::mojom::SnapshotCapturer> snapshot_capturer_;
// A lock and map to map the unique window ID to a corresponding accelerated
// widget. This helps speed up our lookup of Aura windows in GetSourceList,
// because we're provided the unique window ID by ash, and need to pass along
// the Accelerated Widget if it's found.
base::Lock widget_map_lock_;
std::map<std::string, gfx::AcceleratedWidget> widget_map_
GUARDED_BY(widget_map_lock_);
#if DCHECK_IS_ON()
bool capturing_frame_ = false;
#endif
base::WeakPtrFactory<DesktopCapturerLacros> weak_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_MEDIA_CAPTURE_DESKTOP_CAPTURER_LACROS_H_