#include "third_party/blink/renderer/modules/mediastream/media_devices.h"
#include <utility>
#include "base/feature_list.h"
#include "base/metrics/histogram_functions.h"
#include "base/not_fatal_until.h"
#include "base/notreached.h"
#include "base/ranges/algorithm.h"
#include "base/strings/strcat.h"
#include "base/uuid.h"
#include "build/build_config.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/mediastream/media_devices.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
#include "third_party/blink/public/mojom/media/capture_handle_config.mojom-blink.h"
#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h"
#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-blink.h"
#include "third_party/blink/public/platform/browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver_with_tracker.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_capture_handle_config.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_display_media_stream_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_constraints.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_constraints.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_supported_constraints.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_union_boolean_mediatrackconstraints.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_union_domexception_overconstrainederror.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_user_media_stream_constraints.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/execution_context/agent.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/modules/mediastream/crop_target.h"
#include "third_party/blink/renderer/modules/mediastream/identifiability_metrics.h"
#include "third_party/blink/renderer/modules/mediastream/input_device_info.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/mediastream/navigator_media_stream.h"
#include "third_party/blink/renderer/modules/mediastream/restriction_target.h"
#include "third_party/blink/renderer/modules/mediastream/sub_capture_target.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_client.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h"
#include "third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.h"
#include "third_party/blink/renderer/platform/region_capture_crop_id.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/event_loop.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
BASE_FEATURE(…);
namespace {
const char kFeaturePolicyBlocked[] = …;
template <typename IDLResolvedType>
class PromiseResolverCallbacks final : public UserMediaRequest::Callbacks { … };
template <>
template <>
void PromiseResolverCallbacks<MediaStream>::OnSuccessImpl<MediaStream>(
const MediaStreamVector& streams,
CaptureController* capture_controller) { … }
template <>
template <>
void PromiseResolverCallbacks<IDLSequence<MediaStream>>::OnSuccessImpl<
IDLSequence<MediaStream>>(const MediaStreamVector& streams,
CaptureController* capture_controller) { … }
enum class DisplayCapturePolicyResult { … };
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
enum class ProduceTargetFunctionResult { … };
void RecordUma(SubCaptureTarget::Type type,
ProduceTargetFunctionResult result) { … }
enum class ProduceTargetPromiseResult { … };
void RecordUma(SubCaptureTarget::Type type, ProduceTargetPromiseResult result) { … }
#endif
enum class GetDisplayMediaTransientActivation { … };
void RecordUma(GetDisplayMediaTransientActivation activation) { … }
bool TransientActivationRequirementSatisfied(LocalDOMWindow* window) { … }
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
bool IsExtensionScreenSharingFunctionCall(const MediaStreamConstraints* options,
ExceptionState& exception_state) { … }
#endif
MediaStreamConstraints* ToMediaStreamConstraints(
const UserMediaStreamConstraints* source,
ExceptionState& exception_state) { … }
MediaStreamConstraints* ToMediaStreamConstraints(
const DisplayMediaStreamOptions* source) { … }
bool EqualDeviceForDeviceChange(const WebMediaDeviceInfo& lhs,
const WebMediaDeviceInfo& rhs) { … }
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
base::Token SubCaptureTargetIdToToken(const WTF::String& id) { … }
#endif
}
const char MediaDevices::kSupplementName[] = …;
MediaDevices* MediaDevices::mediaDevices(Navigator& navigator) { … }
MediaDevices::MediaDevices(Navigator& navigator)
: … { … }
MediaDevices::~MediaDevices() = default;
ScriptPromise<IDLSequence<MediaDeviceInfo>> MediaDevices::enumerateDevices(
ScriptState* script_state,
ExceptionState& exception_state) { … }
MediaTrackSupportedConstraints* MediaDevices::getSupportedConstraints() const { … }
ScriptPromise<MediaStream> MediaDevices::getUserMedia(
ScriptState* script_state,
const UserMediaStreamConstraints* options,
ExceptionState& exception_state) { … }
template <typename IDLResolvedType>
ScriptPromise<IDLResolvedType> MediaDevices::SendUserMediaRequest(
UserMediaRequestType media_type,
ScriptPromiseResolverWithTracker<UserMediaRequestResult, IDLResolvedType>*
resolver,
const MediaStreamConstraints* options,
ExceptionState& exception_state) { … }
ScriptPromise<IDLSequence<MediaStream>> MediaDevices::getAllScreensMedia(
ScriptState* script_state,
ExceptionState& exception_state) { … }
ScriptPromise<MediaStream> MediaDevices::getDisplayMedia(
ScriptState* script_state,
const DisplayMediaStreamOptions* options,
ExceptionState& exception_state) { … }
void MediaDevices::setCaptureHandleConfig(ScriptState* script_state,
const CaptureHandleConfig* config,
ExceptionState& exception_state) { … }
ScriptPromise<CropTarget> MediaDevices::ProduceCropTarget(
ScriptState* script_state,
Element* element,
ExceptionState& exception_state) { … }
ScriptPromise<RestrictionTarget> MediaDevices::ProduceRestrictionTarget(
ScriptState* script_state,
Element* element,
ExceptionState& exception_state) { … }
const AtomicString& MediaDevices::InterfaceName() const { … }
ExecutionContext* MediaDevices::GetExecutionContext() const { … }
void MediaDevices::RemoveAllEventListeners() { … }
void MediaDevices::AddedEventListener(
const AtomicString& event_type,
RegisteredEventListener& registered_listener) { … }
void MediaDevices::RemovedEventListener(
const AtomicString& event_type,
const RegisteredEventListener& registered_listener) { … }
bool MediaDevices::HasPendingActivity() const { … }
void MediaDevices::ContextDestroyed() { … }
void MediaDevices::OnDevicesChanged(
mojom::blink::MediaDeviceType type,
const Vector<WebMediaDeviceInfo>& device_infos) { … }
void MediaDevices::ScheduleDispatchEvent(Event* event) { … }
void MediaDevices::DispatchScheduledEvents() { … }
void MediaDevices::StartObserving() { … }
void MediaDevices::FinalizeStartObserving(
const Vector<Vector<WebMediaDeviceInfo>>& enumeration,
Vector<mojom::blink::VideoInputDeviceCapabilitiesPtr>
video_input_capabilities,
Vector<mojom::blink::AudioInputDeviceCapabilitiesPtr>
audio_input_capabilities) { … }
void MediaDevices::StopObserving() { … }
namespace {
void RecordEnumeratedDevices(ScriptState* script_state,
const MediaDeviceInfoVector& media_devices) { … }
}
void MediaDevices::DevicesEnumerated(
ScriptPromiseResolverWithTracker<EnumerateDevicesResult,
IDLSequence<MediaDeviceInfo>>*
result_tracker,
const Vector<Vector<WebMediaDeviceInfo>>& enumeration,
Vector<mojom::blink::VideoInputDeviceCapabilitiesPtr>
video_input_capabilities,
Vector<mojom::blink::AudioInputDeviceCapabilitiesPtr>
audio_input_capabilities) { … }
void MediaDevices::OnDispatcherHostConnectionError() { … }
mojom::blink::MediaDevicesDispatcherHost& MediaDevices::GetDispatcherHost(
LocalFrame* frame) { … }
void MediaDevices::SetDispatcherHostForTesting(
mojo::PendingRemote<mojom::blink::MediaDevicesDispatcherHost>
dispatcher_host) { … }
void MediaDevices::Trace(Visitor* visitor) const { … }
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
void MediaDevices::EnqueueMicrotaskToCloseFocusWindowOfOpportunity(
const String& id,
CaptureController* capture_controller) { … }
void MediaDevices::CloseFocusWindowOfOpportunity(
const String& id,
CaptureController* capture_controller) { … }
bool MediaDevices::MayProduceSubCaptureTarget(ScriptState* script_state,
Element* element,
ExceptionState& exception_state,
SubCaptureTarget::Type type) { … }
void MediaDevices::ResolveCropTargetPromise(Element* element,
const WTF::String& id) { … }
void MediaDevices::ResolveRestrictionTargetPromise(Element* element,
const WTF::String& id) { … }
#endif
}