From 4d0202a47bba5dd0f6f6afcdf443354d94ff550f Mon Sep 17 00:00:00 2001 From: Przemyslaw Gorszkowski Date: Fri, 12 Jun 2026 05:04:33 -0700 Subject: [PATCH] navigator.mediaCapabilities wrapper should not become GC-collectable before its navigator object https://bugs.webkit.org/show_bug.cgi?id=315684 Reviewed by Ryosuke Niwa. navigator.mediaCapabilities wrapper should not become GC-collectable before its navigator object. The MediaCapabilities interface is annotated [SameObject] in the spec: https://www.w3.org/TR/media-capabilities/#idl-index It means that navigator.mediaCapabilities must return the same object on every access. See: https://github.com/WebPlatformForEmbedded/WPEWebKit/pull/1678 Original author: Andrzej Surdej (https://github.com/asurdej-comcast) Updated existing LayoutTest with mediaCapabilities case. * LayoutTests/fast/dom/navigator-property-gc-after-frame-detach-expected.txt: * LayoutTests/fast/dom/navigator-property-gc-after-frame-detach.html: * Source/WebCore/Modules/mediacapabilities/MediaCapabilities.cpp: (WebCore::MediaCapabilities::MediaCapabilities): (WebCore::MediaCapabilities::navigator): * Source/WebCore/Modules/mediacapabilities/MediaCapabilities.h: (WebCore::MediaCapabilities::create): * Source/WebCore/Modules/mediacapabilities/MediaCapabilities.idl: * Source/WebCore/Modules/mediacapabilities/NavigatorMediaCapabilities.cpp: (WebCore::NavigatorMediaCapabilities::NavigatorMediaCapabilities): (WebCore::NavigatorMediaCapabilities::from): * Source/WebCore/Modules/mediacapabilities/NavigatorMediaCapabilities.h: * Source/WebCore/Modules/mediacapabilities/WorkerNavigatorMediaCapabilities.cpp: (WebCore::WorkerNavigatorMediaCapabilities::WorkerNavigatorMediaCapabilities): (WebCore::WorkerNavigatorMediaCapabilities::from): * Source/WebCore/Modules/mediacapabilities/WorkerNavigatorMediaCapabilities.h: Canonical link: https://commits.webkit.org/315088@main --- ...igator-property-gc-after-frame-detach-expected.txt | 3 +++ .../dom/navigator-property-gc-after-frame-detach.html | 2 +- .../Modules/mediacapabilities/MediaCapabilities.cpp | 11 +++++++++++ .../Modules/mediacapabilities/MediaCapabilities.h | 8 ++++++-- .../Modules/mediacapabilities/MediaCapabilities.idl | 3 ++- .../mediacapabilities/NavigatorMediaCapabilities.cpp | 6 +++--- .../mediacapabilities/NavigatorMediaCapabilities.h | 2 +- .../WorkerNavigatorMediaCapabilities.cpp | 6 +++--- .../WorkerNavigatorMediaCapabilities.h | 2 +- 9 files changed, 31 insertions(+), 12 deletions(-) diff --git a/LayoutTests/fast/dom/navigator-property-gc-after-frame-detach-expected.txt b/LayoutTests/fast/dom/navigator-property-gc-after-frame-detach-expected.txt index f8468fc483242..165718d91ebf5 100644 --- a/LayoutTests/fast/dom/navigator-property-gc-after-frame-detach-expected.txt +++ b/LayoutTests/fast/dom/navigator-property-gc-after-frame-detach-expected.txt @@ -3,16 +3,19 @@ Tests that Navigator properties do not get GC'd before their Navigator object. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". +PASS frameNavigator.mediaCapabilities.foo is 1 PASS frameNavigator.geolocation.foo is 1 PASS frameNavigator.mimeTypes.foo is 1 PASS frameNavigator.plugins.foo is 1 PASS frameNavigator.serviceWorker.foo is 1 +PASS frameNavigator.mediaCapabilities.foo is 1 PASS frameNavigator.geolocation.foo is 1 PASS frameNavigator.mimeTypes.foo is 1 PASS frameNavigator.plugins.foo is 1 PASS frameNavigator.serviceWorker.foo is 1 +PASS frameNavigator.mediaCapabilities.foo is 1 PASS frameNavigator.geolocation.foo is 1 PASS frameNavigator.mimeTypes.foo is 1 PASS frameNavigator.plugins.foo is 1 diff --git a/LayoutTests/fast/dom/navigator-property-gc-after-frame-detach.html b/LayoutTests/fast/dom/navigator-property-gc-after-frame-detach.html index 86fb3032a476a..e92fbe1b35178 100644 --- a/LayoutTests/fast/dom/navigator-property-gc-after-frame-detach.html +++ b/LayoutTests/fast/dom/navigator-property-gc-after-frame-detach.html @@ -7,7 +7,7 @@ description("Tests that Navigator properties do not get GC'd before their Navigator object."); jsTestIsAsync = true; -var navigatorProperties = [ "geolocation", "mimeTypes", "plugins" ]; +var navigatorProperties = [ "mediaCapabilities", "geolocation", "mimeTypes", "plugins" ]; if (navigator.serviceWorker) navigatorProperties.push("serviceWorker"); diff --git a/Source/WebCore/Modules/mediacapabilities/MediaCapabilities.cpp b/Source/WebCore/Modules/mediacapabilities/MediaCapabilities.cpp index 6eca6dd6b30f4..b51aaf99a1770 100644 --- a/Source/WebCore/Modules/mediacapabilities/MediaCapabilities.cpp +++ b/Source/WebCore/Modules/mediacapabilities/MediaCapabilities.cpp @@ -39,6 +39,7 @@ #include "MediaDecodingConfiguration.h" #include "MediaEncodingConfiguration.h" #include "MediaEngineConfigurationFactory.h" +#include "NavigatorBase.h" #include "Page.h" #include "Settings.h" #include "WebRTCProvider.h" @@ -47,6 +48,16 @@ namespace WebCore { +MediaCapabilities::MediaCapabilities(NavigatorBase& navigator) + : m_navigator(navigator) +{ +} + +NavigatorBase* MediaCapabilities::navigator() +{ + return m_navigator.get(); +} + static bool isValidMediaMIMEType(const ContentType& contentType) { // A "bucket" MIME types is one whose container type does not uniquely specify a codec. diff --git a/Source/WebCore/Modules/mediacapabilities/MediaCapabilities.h b/Source/WebCore/Modules/mediacapabilities/MediaCapabilities.h index b9579019c1a75..0ab7a7ad3c44e 100644 --- a/Source/WebCore/Modules/mediacapabilities/MediaCapabilities.h +++ b/Source/WebCore/Modules/mediacapabilities/MediaCapabilities.h @@ -33,18 +33,22 @@ namespace WebCore { class DeferredPromise; +class NavigatorBase; class ScriptExecutionContext; class MediaCapabilities : public RefCounted, public CanMakeWeakPtr { public: - static Ref create() { return adoptRef(*new MediaCapabilities); } + static Ref create(NavigatorBase& navigator) { return adoptRef(*new MediaCapabilities(navigator)); } + + NavigatorBase* navigator(); void decodingInfo(ScriptExecutionContext&, MediaDecodingConfiguration&&, Ref&&); void encodingInfo(ScriptExecutionContext&, MediaEncodingConfiguration&&, Ref&&); private: - MediaCapabilities() = default; + explicit MediaCapabilities(NavigatorBase&); + WeakPtr m_navigator; uint64_t m_nextTaskIdentifier { 0 }; HashMap m_decodingTasks; HashMap m_encodingTasks; diff --git a/Source/WebCore/Modules/mediacapabilities/MediaCapabilities.idl b/Source/WebCore/Modules/mediacapabilities/MediaCapabilities.idl index 05fc7ea634a8e..02c367959f194 100644 --- a/Source/WebCore/Modules/mediacapabilities/MediaCapabilities.idl +++ b/Source/WebCore/Modules/mediacapabilities/MediaCapabilities.idl @@ -25,7 +25,8 @@ [ EnabledBySetting=MediaCapabilitiesEnabled, - Exposed=(Window,DedicatedWorker) + Exposed=(Window,DedicatedWorker), + GenerateIsReachable=ReachableFromNavigator ] interface MediaCapabilities { [CallWith=CurrentScriptExecutionContext] Promise decodingInfo(MediaDecodingConfiguration configuration); [CallWith=CurrentScriptExecutionContext] Promise encodingInfo(MediaEncodingConfiguration configuration); diff --git a/Source/WebCore/Modules/mediacapabilities/NavigatorMediaCapabilities.cpp b/Source/WebCore/Modules/mediacapabilities/NavigatorMediaCapabilities.cpp index fce51add8aa6f..6608175e10949 100644 --- a/Source/WebCore/Modules/mediacapabilities/NavigatorMediaCapabilities.cpp +++ b/Source/WebCore/Modules/mediacapabilities/NavigatorMediaCapabilities.cpp @@ -31,8 +31,8 @@ namespace WebCore { -NavigatorMediaCapabilities::NavigatorMediaCapabilities() - : m_mediaCapabilities(MediaCapabilities::create()) +NavigatorMediaCapabilities::NavigatorMediaCapabilities(Navigator& navigator) + : m_mediaCapabilities(MediaCapabilities::create(navigator)) { } @@ -47,7 +47,7 @@ NavigatorMediaCapabilities& NavigatorMediaCapabilities::from(Navigator& navigato { NavigatorMediaCapabilities* supplement = static_cast(Supplement::from(&navigator, supplementName())); if (!supplement) { - auto newSupplement = makeUnique(); + auto newSupplement = makeUnique(navigator); supplement = newSupplement.get(); provideTo(&navigator, supplementName(), WTFMove(newSupplement)); } diff --git a/Source/WebCore/Modules/mediacapabilities/NavigatorMediaCapabilities.h b/Source/WebCore/Modules/mediacapabilities/NavigatorMediaCapabilities.h index 76d598e18af9d..3b8baad4b592c 100644 --- a/Source/WebCore/Modules/mediacapabilities/NavigatorMediaCapabilities.h +++ b/Source/WebCore/Modules/mediacapabilities/NavigatorMediaCapabilities.h @@ -35,7 +35,7 @@ class Navigator; class NavigatorMediaCapabilities final : public Supplement { WTF_MAKE_FAST_ALLOCATED; public: - NavigatorMediaCapabilities(); + explicit NavigatorMediaCapabilities(Navigator&); ~NavigatorMediaCapabilities(); static MediaCapabilities& mediaCapabilities(Navigator&); diff --git a/Source/WebCore/Modules/mediacapabilities/WorkerNavigatorMediaCapabilities.cpp b/Source/WebCore/Modules/mediacapabilities/WorkerNavigatorMediaCapabilities.cpp index 7a617b33a87b1..1c4606d27ba16 100644 --- a/Source/WebCore/Modules/mediacapabilities/WorkerNavigatorMediaCapabilities.cpp +++ b/Source/WebCore/Modules/mediacapabilities/WorkerNavigatorMediaCapabilities.cpp @@ -31,8 +31,8 @@ namespace WebCore { -WorkerNavigatorMediaCapabilities::WorkerNavigatorMediaCapabilities() - : m_mediaCapabilities(MediaCapabilities::create()) +WorkerNavigatorMediaCapabilities::WorkerNavigatorMediaCapabilities(WorkerNavigator& navigator) + : m_mediaCapabilities(MediaCapabilities::create(navigator)) { } @@ -47,7 +47,7 @@ WorkerNavigatorMediaCapabilities& WorkerNavigatorMediaCapabilities::from(WorkerN { auto* supplement = static_cast(Supplement::from(&navigator, supplementName())); if (!supplement) { - auto newSupplement = makeUnique(); + auto newSupplement = makeUnique(navigator); supplement = newSupplement.get(); provideTo(&navigator, supplementName(), WTFMove(newSupplement)); } diff --git a/Source/WebCore/Modules/mediacapabilities/WorkerNavigatorMediaCapabilities.h b/Source/WebCore/Modules/mediacapabilities/WorkerNavigatorMediaCapabilities.h index 98fffdb050961..f1d698e73cf90 100644 --- a/Source/WebCore/Modules/mediacapabilities/WorkerNavigatorMediaCapabilities.h +++ b/Source/WebCore/Modules/mediacapabilities/WorkerNavigatorMediaCapabilities.h @@ -35,7 +35,7 @@ class WorkerNavigator; class WorkerNavigatorMediaCapabilities final : public Supplement { WTF_MAKE_FAST_ALLOCATED; public: - WorkerNavigatorMediaCapabilities(); + explicit WorkerNavigatorMediaCapabilities(WorkerNavigator&); ~WorkerNavigatorMediaCapabilities(); static MediaCapabilities& mediaCapabilities(WorkerNavigator&);