#include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
#include <memory>
#include "base/check_op.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/task/bind_post_task.h"
#include "build/build_config.h"
#include "content/browser/media/media_devices_util.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "media/capture/mojom/video_capture_types.mojom.h"
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/features_generated.h"
#include "third_party/blink/public/common/mediastream/media_stream_request.h"
#include "third_party/blink/public/common/page/page_zoom.h"
#include "third_party/blink/public/mojom/mediastream/media_devices.mojom.h"
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
#include "url/origin.h"
#if !BUILDFLAG(IS_ANDROID)
#include "content/browser/media/capture/sub_capture_target_id_web_contents_helper.h"
#endif
namespace content {
namespace {
CapturedSurfaceControlResult;
void BindMediaStreamDeviceObserverReceiver(
GlobalRenderFrameHostId render_frame_host_id,
mojo::PendingReceiver<blink::mojom::MediaStreamDeviceObserver> receiver) { … }
std::unique_ptr<MediaStreamWebContentsObserver, BrowserThread::DeleteOnUIThread>
StartObservingWebContents(GlobalRenderFrameHostId render_frame_host_id,
base::RepeatingClosure focus_callback) { … }
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
bool MayApplySubCaptureTarget(GlobalRenderFrameHostId capturing_id,
GlobalRenderFrameHostId captured_id,
media::mojom::SubCaptureTargetType type,
const base::Token& target) { … }
MediaStreamDispatcherHost::ApplySubCaptureTargetCallback
WrapApplySubCaptureTarget(
MediaStreamDispatcherHost::ApplySubCaptureTargetCallback callback,
mojo::ReportBadMessageCallback bad_message_callback) { … }
#endif
bool AllowedStreamTypeCombination(
blink::mojom::MediaStreamType audio_stream_type,
blink::mojom::MediaStreamType video_stream_type) { … }
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
bool IsValidZoomLevel(int zoom_level) { … }
#endif
}
int MediaStreamDispatcherHost::next_requester_id_ = …;
struct MediaStreamDispatcherHost::PendingAccessRequest { … };
MediaStreamDispatcherHost::MediaStreamDispatcherHost(
GlobalRenderFrameHostId render_frame_host_id,
MediaStreamManager* media_stream_manager)
: … { … }
MediaStreamDispatcherHost::~MediaStreamDispatcherHost() { … }
void MediaStreamDispatcherHost::Create(
GlobalRenderFrameHostId render_frame_host_id,
MediaStreamManager* media_stream_manager,
mojo::PendingReceiver<blink::mojom::MediaStreamDispatcherHost> receiver) { … }
void MediaStreamDispatcherHost::SetWebContentsObserver(
std::unique_ptr<MediaStreamWebContentsObserver,
BrowserThread::DeleteOnUIThread> web_contents_observer) { … }
void MediaStreamDispatcherHost::OnDeviceStopped(
const std::string& label,
const blink::MediaStreamDevice& device) { … }
void MediaStreamDispatcherHost::OnDeviceChanged(
const std::string& label,
const blink::MediaStreamDevice& old_device,
const blink::MediaStreamDevice& new_device) { … }
void MediaStreamDispatcherHost::OnDeviceRequestStateChange(
const std::string& label,
const blink::MediaStreamDevice& device,
const blink::mojom::MediaStreamStateChange new_state) { … }
void MediaStreamDispatcherHost::OnDeviceCaptureConfigurationChange(
const std::string& label,
const blink::MediaStreamDevice& device) { … }
void MediaStreamDispatcherHost::OnDeviceCaptureHandleChange(
const std::string& label,
const blink::MediaStreamDevice& device) { … }
void MediaStreamDispatcherHost::OnZoomLevelChange(
const std::string& label,
const blink::MediaStreamDevice& device,
int zoom_level) { … }
void MediaStreamDispatcherHost::OnWebContentsFocused() { … }
void MediaStreamDispatcherHost::GenerateStreamsChecksOnUIThread(
GlobalRenderFrameHostId render_frame_host_id,
bool request_all_screens,
base::OnceCallback<void(MediaDeviceSaltAndOriginCallback)>
get_salt_and_origin_cb,
base::OnceCallback<void(GenerateStreamsUIThreadCheckResult)>
result_callback) { … }
void MediaStreamDispatcherHost::CheckRequestAllScreensAllowed(
base::OnceCallback<void(MediaDeviceSaltAndOriginCallback)>
get_salt_and_origin_cb,
base::OnceCallback<void(GenerateStreamsUIThreadCheckResult)>
result_callback,
GlobalRenderFrameHostId render_frame_host_id) { … }
void MediaStreamDispatcherHost::CheckStreamsPermissionResultReceived(
base::OnceCallback<void(MediaDeviceSaltAndOriginCallback)>
get_salt_and_origin_cb,
base::OnceCallback<void(GenerateStreamsUIThreadCheckResult)>
result_callback,
bool result) { … }
const mojo::Remote<blink::mojom::MediaStreamDeviceObserver>&
MediaStreamDispatcherHost::GetMediaStreamDeviceObserver() { … }
void MediaStreamDispatcherHost::OnMediaStreamDeviceObserverConnectionError() { … }
void MediaStreamDispatcherHost::CancelAllRequests() { … }
void MediaStreamDispatcherHost::GenerateStreams(
int32_t page_request_id,
const blink::StreamControls& controls,
bool user_gesture,
blink::mojom::StreamSelectionInfoPtr audio_stream_selection_info_ptr,
GenerateStreamsCallback callback) { … }
void MediaStreamDispatcherHost::DoGenerateStreams(
int32_t page_request_id,
const blink::StreamControls& controls,
bool user_gesture,
blink::mojom::StreamSelectionInfoPtr audio_stream_selection_info_ptr,
GenerateStreamsCallback callback,
GenerateStreamsUIThreadCheckResult ui_check_result) { … }
void MediaStreamDispatcherHost::CancelRequest(int page_request_id) { … }
void MediaStreamDispatcherHost::StopStreamDevice(
const std::string& device_id,
const std::optional<base::UnguessableToken>& session_id) { … }
void MediaStreamDispatcherHost::OpenDevice(int32_t page_request_id,
const std::string& device_id,
blink::mojom::MediaStreamType type,
OpenDeviceCallback callback) { … }
void MediaStreamDispatcherHost::DoOpenDevice(
int32_t page_request_id,
const std::string& device_id,
blink::mojom::MediaStreamType type,
OpenDeviceCallback callback,
const MediaDeviceSaltAndOrigin& salt_and_origin) { … }
void MediaStreamDispatcherHost::CloseDevice(const std::string& label) { … }
void MediaStreamDispatcherHost::SetCapturingLinkSecured(
const std::optional<base::UnguessableToken>& session_id,
blink::mojom::MediaStreamType type,
bool is_secure) { … }
void MediaStreamDispatcherHost::KeepDeviceAliveForTransfer(
const base::UnguessableToken& session_id,
const base::UnguessableToken& transfer_id,
KeepDeviceAliveForTransferCallback callback) { … }
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
void MediaStreamDispatcherHost::FocusCapturedSurface(const std::string& label,
bool focus) { … }
void MediaStreamDispatcherHost::ApplySubCaptureTarget(
const base::UnguessableToken& device_id,
media::mojom::SubCaptureTargetType type,
const base::Token& sub_capture_target,
uint32_t sub_capture_target_version,
ApplySubCaptureTargetCallback callback) { … }
void MediaStreamDispatcherHost::SendWheel(
const base::UnguessableToken& device_id,
blink::mojom::CapturedWheelActionPtr action,
SendWheelCallback callback) { … }
void MediaStreamDispatcherHost::SetZoomLevel(
const base::UnguessableToken& device_id,
int32_t zoom_level,
SetZoomLevelCallback callback) { … }
void MediaStreamDispatcherHost::RequestCapturedSurfaceControlPermission(
const base::UnguessableToken& session_id,
RequestCapturedSurfaceControlPermissionCallback callback) { … }
void MediaStreamDispatcherHost::OnSubCaptureTargetValidationComplete(
const base::UnguessableToken& session_id,
media::mojom::SubCaptureTargetType type,
const base::Token& target,
uint32_t sub_capture_target_version,
ApplySubCaptureTargetCallback callback,
bool target_passed_validation) { … }
#endif
void MediaStreamDispatcherHost::GetOpenDevice(
int32_t page_request_id,
const base::UnguessableToken& session_id,
const base::UnguessableToken& transfer_id,
GetOpenDeviceCallback callback) { … }
void MediaStreamDispatcherHost::DoGetOpenDevice(
int32_t page_request_id,
const base::UnguessableToken& session_id,
const base::UnguessableToken& transfer_id,
GetOpenDeviceCallback callback,
const MediaDeviceSaltAndOrigin& salt_and_origin) { … }
std::optional<bad_message::BadMessageReason>
MediaStreamDispatcherHost::ValidateControlsForGenerateStreams(
const blink::StreamControls& controls) { … }
void MediaStreamDispatcherHost::ReceivedBadMessage(
int render_process_id,
bad_message::BadMessageReason reason) { … }
void MediaStreamDispatcherHost::SetBadMessageCallbackForTesting(
base::RepeatingCallback<void(int, bad_message::BadMessageReason)>
callback) { … }
}