mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-05-11 09:27:00 +02:00
Previously we were inconsistent by generating code for enum definitions but not generating code for dictionaries. With future changes to the IDL generator to expose helpers to convert to and from IDL values this produced circular depdendencies. To solve this problem, also generate the dictionary definitions in bindings headers.
187 lines
6.3 KiB
C++
187 lines
6.3 KiB
C++
/*
|
|
* Copyright (c) 2026, The Ladybird developers
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibJS/Runtime/Value.h>
|
|
#include <LibWeb/Bindings/Intrinsics.h>
|
|
#include <LibWeb/Bindings/MediaStreamTrack.h>
|
|
#include <LibWeb/Crypto/Crypto.h>
|
|
#include <LibWeb/DOM/Event.h>
|
|
#include <LibWeb/HTML/EventNames.h>
|
|
#include <LibWeb/MediaCapture/MediaStreamTrack.h>
|
|
#include <LibWeb/WebIDL/Promise.h>
|
|
|
|
namespace Web::MediaCapture {
|
|
|
|
GC_DEFINE_ALLOCATOR(MediaStreamTrack);
|
|
|
|
Atomic<u64> MediaStreamTrack::s_next_provider_id { 1 };
|
|
|
|
static constexpr auto audio_track_kind = static_cast<Bindings::MediaStreamTrackKind>(0);
|
|
static constexpr auto video_track_kind = static_cast<Bindings::MediaStreamTrackKind>(1);
|
|
|
|
MediaStreamTrack::MediaStreamTrack(JS::Realm& realm)
|
|
: DOM::EventTarget(realm)
|
|
{
|
|
}
|
|
|
|
// https://w3c.github.io/mediacapture-main/#mediastreamtrack
|
|
GC::Ref<MediaStreamTrack> MediaStreamTrack::create(JS::Realm& realm, Bindings::MediaStreamTrackKind kind, Optional<String> label, bool muted)
|
|
{
|
|
// https://w3c.github.io/mediacapture-main/#dfn-create-a-mediastreamtrack
|
|
// 1. Let track be a new object of type source's MediaStreamTrack source type.
|
|
auto track = realm.create<MediaStreamTrack>(realm);
|
|
|
|
// Initialize track with the following internal slots.
|
|
// FIXME: [[Source]], initialized to source.
|
|
|
|
// [[Id]]: See MediaStream.id attribute for guidelines on how to generate such an identifier.
|
|
track->m_id = Crypto::generate_random_uuid();
|
|
|
|
// [[Kind]]: "audio" if source is an audio source, or "video" if source is a video source.
|
|
track->m_kind = kind;
|
|
|
|
// [[Label]]: source label or empty string.
|
|
track->m_label = label.value_or(""_string);
|
|
|
|
// [[ReadyState]]: "live".
|
|
track->m_state = Bindings::MediaStreamTrackState::Live;
|
|
|
|
// [[Enabled]]: true.
|
|
track->m_enabled = true;
|
|
|
|
// [[Muted]]: true if source is muted, false otherwise.
|
|
track->m_muted = muted;
|
|
|
|
// [[Capabilities]], [[Constraints]], and [[Settings]], all initialized as specified in the ConstrainablePattern.
|
|
// [[Restrictable]], initialized to false.
|
|
track->m_provider_id = s_next_provider_id.fetch_add(1, AK::MemoryOrder::memory_order_relaxed);
|
|
|
|
// FIXME: 2. If mediaDevicesToTieSourceTo is not null, tie track source to MediaDevices with source and mediaDevicesToTieSourceTo.
|
|
// FIXME: 3. Run source's MediaStreamTrack source-specific construction steps with track as parameter.
|
|
|
|
// 4. Return track.
|
|
return track;
|
|
}
|
|
|
|
void MediaStreamTrack::set_settings(Bindings::MediaTrackSettings settings)
|
|
{
|
|
m_settings = move(settings);
|
|
}
|
|
|
|
void MediaStreamTrack::initialize(JS::Realm& realm)
|
|
{
|
|
WEB_SET_PROTOTYPE_FOR_INTERFACE(MediaStreamTrack);
|
|
Base::initialize(realm);
|
|
}
|
|
|
|
// https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-stop
|
|
void MediaStreamTrack::stop()
|
|
{
|
|
// 1. Let track be the current MediaStreamTrack object.
|
|
// 2. If track's [[ReadyState]] is "ended", then abort these steps.
|
|
if (m_state == Bindings::MediaStreamTrackState::Ended)
|
|
return;
|
|
|
|
// FIXME: 3. Notify track's source that track is ended.
|
|
|
|
// 4. Set track's [[ReadyState]] to "ended".
|
|
m_state = Bindings::MediaStreamTrackState::Ended;
|
|
|
|
// AD-HOC: Until track sources are modeled, stop() is the only implemented end-of-life path.
|
|
// Preserve the observable ended event instead of dropping it on the floor.
|
|
dispatch_event(DOM::Event::create(realm(), HTML::EventNames::ended));
|
|
}
|
|
|
|
// https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-clone
|
|
GC::Ref<MediaStreamTrack> MediaStreamTrack::clone() const
|
|
{
|
|
// When the clone() method is invoked, the User Agent MUST return the result of clone a track with this.
|
|
// https://w3c.github.io/mediacapture-main/#clone-a-track
|
|
// 1. Let track be the MediaStreamTrack object to be cloned.
|
|
//
|
|
// FIXME: 2. Let source be track's [[Source]].
|
|
|
|
// 3. Let trackClone be the result of creating a MediaStreamTrack with source and null.
|
|
auto track_clone = create(realm(), m_kind, m_label, m_muted);
|
|
|
|
// 4. Set trackClone's [[ReadyState]] to track's [[ReadyState]] value.
|
|
track_clone->m_state = m_state;
|
|
// 5. Set trackClone's [[Capabilities]] to a clone of track's [[Capabilities]].
|
|
track_clone->m_capabilities = m_capabilities;
|
|
// 6. Set trackClone's [[Constraints]] to a clone of track's [[Constraints]].
|
|
track_clone->m_constraints = m_constraints;
|
|
// 7. Set trackClone's [[Settings]] to a clone of track's [[Settings]].
|
|
track_clone->m_settings = m_settings;
|
|
|
|
// Initialize the remaining internal slots to match the source track.
|
|
track_clone->m_enabled = m_enabled;
|
|
track_clone->m_provider_id = s_next_provider_id.fetch_add(1, AK::MemoryOrder::memory_order_relaxed);
|
|
|
|
// FIXME: 8. Run source MediaStreamTrack source-specific clone steps with track and trackClone as parameters.
|
|
|
|
// 9. Return trackClone.
|
|
return track_clone;
|
|
}
|
|
|
|
bool MediaStreamTrack::is_audio() const
|
|
{
|
|
return m_kind == audio_track_kind;
|
|
}
|
|
|
|
bool MediaStreamTrack::is_video() const
|
|
{
|
|
return m_kind == video_track_kind;
|
|
}
|
|
|
|
Optional<String> MediaStreamTrack::device_id() const
|
|
{
|
|
return m_settings.device_id;
|
|
}
|
|
|
|
u32 MediaStreamTrack::sample_rate_hz() const
|
|
{
|
|
if (m_settings.sample_rate.has_value())
|
|
return *m_settings.sample_rate;
|
|
return 0;
|
|
}
|
|
|
|
u32 MediaStreamTrack::channel_count() const
|
|
{
|
|
if (m_settings.channel_count.has_value())
|
|
return *m_settings.channel_count;
|
|
return 0;
|
|
}
|
|
|
|
// https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-getcapabilities
|
|
Bindings::MediaTrackCapabilities MediaStreamTrack::get_capabilities() const
|
|
{
|
|
return m_capabilities;
|
|
}
|
|
|
|
// https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-getconstraints
|
|
Bindings::MediaTrackConstraints MediaStreamTrack::get_constraints() const
|
|
{
|
|
return m_constraints;
|
|
}
|
|
|
|
// https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-getsettings
|
|
Bindings::MediaTrackSettings MediaStreamTrack::get_settings() const
|
|
{
|
|
return m_settings;
|
|
}
|
|
|
|
// https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-applyconstraints
|
|
GC::Ref<WebIDL::Promise> MediaStreamTrack::apply_constraints(Optional<Bindings::MediaTrackConstraints> const& constraints)
|
|
{
|
|
if (constraints.has_value())
|
|
m_constraints = constraints.value();
|
|
|
|
// FIXME: Apply constraints to the underlying source and update settings.
|
|
return WebIDL::create_resolved_promise(realm(), JS::js_undefined());
|
|
}
|
|
|
|
}
|