Title: [217985] trunk
Revision
217985
Author
[email protected]
Date
2017-06-09 09:14:27 -0700 (Fri, 09 Jun 2017)

Log Message

fast/mediastream/MediaStream-page-muted.html times out and asserts
https://bugs.webkit.org/show_bug.cgi?id=170355
<rdar://problem/31376041>

Source/WebCore:

MediaStream and MediaStreamTrack need to prevent JS wrapper collection while it is possible
to fire an event or event listeners won't be notified.

Reviewed by Chris Dumez.

Test: fast/mediastream/media-stream-wrapper-collected.html

* Modules/mediastream/MediaStream.cpp:
(WebCore::MediaStream::MediaStream): Initialize ActiveDOMObject.
(WebCore::MediaStream::stop): New.
(WebCore::MediaStream::activeDOMObjectName): Ditto.
(WebCore::MediaStream::canSuspendForDocumentSuspension): Ditto.
(WebCore::MediaStream::hasPendingActivity): Ditto, prevent collection if there
are registered event listeners.
(WebCore::MediaStream::contextDestroyed): Deleted.
* Modules/mediastream/MediaStream.h:
* Modules/mediastream/MediaStream.idl:

* Modules/mediastream/MediaStreamTrack.cpp:
(WebCore::MediaStreamTrack::hasPendingActivity): Prevent collection if there
are registered event listeners.
* Modules/mediastream/MediaStreamTrack.h:

* testing/Internals.cpp:
(WebCore::Internals::removeMediaStreamTrack): stream.removeTrack doesn't generate a 'removetrack'
event, so call private method that does.
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

Reviewed by Chris Dumez.

* fast/mediastream/media-stream-wrapper-collected-expected.txt: Added.
* fast/mediastream/media-stream-wrapper-collected.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (217984 => 217985)


--- trunk/LayoutTests/ChangeLog	2017-06-09 16:13:34 UTC (rev 217984)
+++ trunk/LayoutTests/ChangeLog	2017-06-09 16:14:27 UTC (rev 217985)
@@ -1,3 +1,14 @@
+2017-06-09  Eric Carlson  <[email protected]>
+
+        fast/mediastream/MediaStream-page-muted.html times out and asserts
+        https://bugs.webkit.org/show_bug.cgi?id=170355
+        <rdar://problem/31376041>
+
+        Reviewed by Chris Dumez.
+
+        * fast/mediastream/media-stream-wrapper-collected-expected.txt: Added.
+        * fast/mediastream/media-stream-wrapper-collected.html: Added.
+
 2017-06-09  Charlie Turner  <[email protected]>
 
         [GTK] Fix test linter reported errors

Added: trunk/LayoutTests/fast/mediastream/media-stream-wrapper-collected-expected.txt (0 => 217985)


--- trunk/LayoutTests/fast/mediastream/media-stream-wrapper-collected-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/mediastream/media-stream-wrapper-collected-expected.txt	2017-06-09 16:14:27 UTC (rev 217985)
@@ -0,0 +1,5 @@
+
+PASS Create stream 
+PASS Test track 
+PASS Test stream 
+

Added: trunk/LayoutTests/fast/mediastream/media-stream-wrapper-collected.html (0 => 217985)


--- trunk/LayoutTests/fast/mediastream/media-stream-wrapper-collected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/mediastream/media-stream-wrapper-collected.html	2017-06-09 16:14:27 UTC (rev 217985)
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>MediaStreamTrack with event listener should not be collected.</title>
+    <script src=""
+    <script src=""
+    <script>
+
+    if (window.testRunner)
+        testRunner.setUserMediaPermission(true);
+
+    function forceGC()
+    {
+        if (window.GCController)
+            return GCController.collect();
+    
+        // Force garbage collection
+        for (var ndx = 0; ndx < 99000; ndx++)
+            var str = new String("1234");
+    }
+
+    promise_test((test) => {
+        return navigator.mediaDevices.getUserMedia({ video: true })
+            .then((stream) => {
+
+                promise_test((test) => {
+                    return new Promise((resolve, reject) => {
+                        let track = stream.getVideoTracks()[0];
+
+                        track._onmute_ = (evt) => {
+                            if (window.internals)
+                                internals.setMediaStreamTrackMuted(track, false);
+                        }
+                        track._onunmute_ = resolve;
+
+                        forceGC();
+
+                        if (window.internals)
+                            internals.setMediaStreamTrackMuted(track, true);
+
+                        setTimeout(() => reject("Track muted state did not change in .5 second"), 500);
+                    });
+                }, "Test track");
+
+                promise_test((test) => {
+                    return new Promise((resolve, reject) => {
+                        stream._onremovetrack_ = resolve;
+
+                        forceGC();
+
+                        if (window.internals)
+                            window.internals.removeMediaStreamTrack(stream, stream.getVideoTracks()[0]);
+
+                        setTimeout(() => reject("stream.onremovetrack did not fire in .5 second"), 500);
+                    });
+                }, "Test stream");
+
+            });
+    }, "Create stream");
+
+
+    </script>
+</head>
+<body>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (217984 => 217985)


--- trunk/Source/WebCore/ChangeLog	2017-06-09 16:13:34 UTC (rev 217984)
+++ trunk/Source/WebCore/ChangeLog	2017-06-09 16:14:27 UTC (rev 217985)
@@ -1,3 +1,38 @@
+2017-06-09  Eric Carlson  <[email protected]>
+
+        fast/mediastream/MediaStream-page-muted.html times out and asserts
+        https://bugs.webkit.org/show_bug.cgi?id=170355
+        <rdar://problem/31376041>
+
+        MediaStream and MediaStreamTrack need to prevent JS wrapper collection while it is possible
+        to fire an event or event listeners won't be notified.
+
+        Reviewed by Chris Dumez.
+
+        Test: fast/mediastream/media-stream-wrapper-collected.html
+
+        * Modules/mediastream/MediaStream.cpp:
+        (WebCore::MediaStream::MediaStream): Initialize ActiveDOMObject.
+        (WebCore::MediaStream::stop): New.
+        (WebCore::MediaStream::activeDOMObjectName): Ditto.
+        (WebCore::MediaStream::canSuspendForDocumentSuspension): Ditto.
+        (WebCore::MediaStream::hasPendingActivity): Ditto, prevent collection if there
+        are registered event listeners.
+        (WebCore::MediaStream::contextDestroyed): Deleted.
+        * Modules/mediastream/MediaStream.h:
+        * Modules/mediastream/MediaStream.idl:
+
+        * Modules/mediastream/MediaStreamTrack.cpp:
+        (WebCore::MediaStreamTrack::hasPendingActivity): Prevent collection if there
+        are registered event listeners.
+        * Modules/mediastream/MediaStreamTrack.h:
+
+        * testing/Internals.cpp:
+        (WebCore::Internals::removeMediaStreamTrack): stream.removeTrack doesn't generate a 'removetrack'
+        event, so call private method that does.
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2017-06-09  Daewoong Jang  <[email protected]>
 
         [cURL] Remove a call to Windows API

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp (217984 => 217985)


--- trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp	2017-06-09 16:13:34 UTC (rev 217984)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp	2017-06-09 16:14:27 UTC (rev 217985)
@@ -74,7 +74,7 @@
 }
 
 MediaStream::MediaStream(ScriptExecutionContext& context, const MediaStreamTrackVector& tracks)
-    : ContextDestructionObserver(&context)
+    : ActiveDOMObject(&context)
     , m_private(MediaStreamPrivate::create(createTrackPrivateVector(tracks)))
     , m_activityEventTimer(*this, &MediaStream::activityEventTimerFired)
     , m_mediaSession(PlatformMediaSession::create(*this))
@@ -91,10 +91,11 @@
     m_private->addObserver(*this);
     MediaStreamRegistry::shared().registerStream(*this);
     document()->addAudioProducer(this);
+    suspendIfNeeded();
 }
 
 MediaStream::MediaStream(ScriptExecutionContext& context, Ref<MediaStreamPrivate>&& streamPrivate)
-    : ContextDestructionObserver(&context)
+    : ActiveDOMObject(&context)
     , m_private(WTFMove(streamPrivate))
     , m_activityEventTimer(*this, &MediaStream::activityEventTimerFired)
     , m_mediaSession(PlatformMediaSession::create(*this))
@@ -111,6 +112,7 @@
         m_trackSet.add(track->id(), WTFMove(track));
     }
     document()->addAudioProducer(this);
+    suspendIfNeeded();
 }
 
 MediaStream::~MediaStream()
@@ -186,11 +188,6 @@
     return tracks;
 }
 
-void MediaStream::contextDestroyed()
-{
-    ContextDestructionObserver::contextDestroyed();
-}
-
 void MediaStream::trackDidEnd()
 {
     m_private->updateActiveState(MediaStreamPrivate::NotifyClientOption::Notify);
@@ -509,6 +506,27 @@
     return document() ? document()->processingUserGestureForMedia() : false;
 }
 
+void MediaStream::stop()
+{
+    m_isActive = false;
+    endCaptureTracks();
+}
+
+const char* MediaStream::activeDOMObjectName() const
+{
+    return "MediaStream";
+}
+
+bool MediaStream::canSuspendForDocumentSuspension() const
+{
+    return !hasPendingActivity();
+}
+
+bool MediaStream::hasPendingActivity() const
+{
+    return m_isActive || !m_scheduledActivityEvents.isEmpty();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(MEDIA_STREAM)

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStream.h (217984 => 217985)


--- trunk/Source/WebCore/Modules/mediastream/MediaStream.h	2017-06-09 16:13:34 UTC (rev 217984)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStream.h	2017-06-09 16:14:27 UTC (rev 217985)
@@ -29,7 +29,7 @@
 
 #if ENABLE(MEDIA_STREAM)
 
-#include "ContextDestructionObserver.h"
+#include "ActiveDOMObject.h"
 #include "EventTarget.h"
 #include "ExceptionBase.h"
 #include "MediaCanStartListener.h"
@@ -51,7 +51,7 @@
 class MediaStream final
     : public URLRegistrable
     , public EventTargetWithInlineData
-    , public ContextDestructionObserver
+    , public ActiveDOMObject
     , public MediaStreamTrack::Observer
     , public MediaStreamPrivate::Observer
     , private MediaProducer
@@ -110,15 +110,18 @@
 
     Document* document() const;
 
+    // ActiveDOMObject API.
+    bool hasPendingActivity() const final;
+
+    enum class StreamModifier { DomAPI, Platform };
+    bool internalAddTrack(Ref<MediaStreamTrack>&&, StreamModifier);
+    WEBCORE_EXPORT bool internalRemoveTrack(const String&, StreamModifier);
+
 protected:
     MediaStream(ScriptExecutionContext&, const MediaStreamTrackVector&);
     MediaStream(ScriptExecutionContext&, Ref<MediaStreamPrivate>&&);
 
-    // ContextDestructionObserver
-    void contextDestroyed() final;
-
 private:
-    enum class StreamModifier { DomAPI, Platform };
 
     // EventTarget
     void refEventTarget() final { ref(); }
@@ -155,8 +158,10 @@
     const Document* hostingDocument() const final { return document(); }
     bool processingUserGestureForMedia() const final;
 
-    bool internalAddTrack(Ref<MediaStreamTrack>&&, StreamModifier);
-    bool internalRemoveTrack(const String&, StreamModifier);
+    // ActiveDOMObject API.
+    void stop() final;
+    const char* activeDOMObjectName() const final;
+    bool canSuspendForDocumentSuspension() const final;
 
     void scheduleActiveStateChange();
     void activityEventTimerFired();

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStream.idl (217984 => 217985)


--- trunk/Source/WebCore/Modules/mediastream/MediaStream.idl	2017-06-09 16:13:34 UTC (rev 217984)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStream.idl	2017-06-09 16:14:27 UTC (rev 217985)
@@ -23,11 +23,13 @@
  */
 
 [
+    ActiveDOMObject,
     Conditional=MEDIA_STREAM,
     Constructor,
     Constructor(MediaStream stream),
     Constructor(sequence<MediaStreamTrack> tracks),
     ConstructorCallWith=ScriptExecutionContext,
+    ExportToWrappedFunction,
     PrivateIdentifier,
     PublicIdentifier
 ] interface MediaStream : EventTarget {

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp (217984 => 217985)


--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp	2017-06-09 16:13:34 UTC (rev 217984)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp	2017-06-09 16:14:27 UTC (rev 217985)
@@ -348,10 +348,14 @@
 
 bool MediaStreamTrack::canSuspendForDocumentSuspension() const
 {
-    // FIXME: We should try and do better here.
-    return false;
+    return !hasPendingActivity();
 }
 
+bool MediaStreamTrack::hasPendingActivity() const
+{
+    return !m_ended;
+}
+
 AudioSourceProvider* MediaStreamTrack::audioSourceProvider()
 {
     return m_private->audioSourceProvider();

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h (217984 => 217985)


--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h	2017-06-09 16:13:34 UTC (rev 217984)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h	2017-06-09 16:14:27 UTC (rev 217985)
@@ -57,7 +57,7 @@
     virtual bool isCanvas() const { return false; }
 
     const AtomicString& kind() const;
-    const String& id() const;
+    WEBCORE_EXPORT const String& id() const;
     const String& label() const;
 
     bool enabled() const;
@@ -121,6 +121,9 @@
     using RefCounted::ref;
     using RefCounted::deref;
 
+    // ActiveDOMObject API.
+    bool hasPendingActivity() const final;
+
 protected:
     MediaStreamTrack(ScriptExecutionContext&, Ref<MediaStreamTrackPrivate>&&);
 

Modified: trunk/Source/WebCore/testing/Internals.cpp (217984 => 217985)


--- trunk/Source/WebCore/testing/Internals.cpp	2017-06-09 16:13:34 UTC (rev 217984)
+++ trunk/Source/WebCore/testing/Internals.cpp	2017-06-09 16:14:27 UTC (rev 217985)
@@ -195,6 +195,7 @@
 #endif
 
 #if ENABLE(MEDIA_STREAM)
+#include "MediaStream.h"
 #include "MockRealtimeMediaSourceCenter.h"
 #endif
 
@@ -4092,6 +4093,11 @@
     track.source().setMuted(muted);
 }
 
+void Internals::removeMediaStreamTrack(MediaStream& stream, MediaStreamTrack& track)
+{
+    stream.internalRemoveTrack(track.id(), MediaStream::StreamModifier::Platform);
+}
+
 #endif
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/testing/Internals.h (217984 => 217985)


--- trunk/Source/WebCore/testing/Internals.h	2017-06-09 16:13:34 UTC (rev 217984)
+++ trunk/Source/WebCore/testing/Internals.h	2017-06-09 16:14:27 UTC (rev 217985)
@@ -62,6 +62,7 @@
 class InternalSettings;
 class MallocStatistics;
 class MediaSession;
+class MediaStream;
 class MediaStreamTrack;
 class MemoryInfo;
 class MockCDMFactory;
@@ -585,6 +586,7 @@
     void grabNextMediaStreamTrackFrame(TrackFramePromise&&);
     void delayMediaStreamTrackSamples(MediaStreamTrack&, float);
     void setMediaStreamTrackMuted(MediaStreamTrack&, bool);
+    void removeMediaStreamTrack(MediaStream&, MediaStreamTrack&);
 #endif
 
 private:

Modified: trunk/Source/WebCore/testing/Internals.idl (217984 => 217985)


--- trunk/Source/WebCore/testing/Internals.idl	2017-06-09 16:13:34 UTC (rev 217984)
+++ trunk/Source/WebCore/testing/Internals.idl	2017-06-09 16:14:27 UTC (rev 217985)
@@ -544,4 +544,5 @@
     [Conditional=MEDIA_STREAM, MayThrowException] void setMediaDeviceState(DOMString deviceID, DOMString property, boolean value);
     [Conditional=MEDIA_STREAM] void delayMediaStreamTrackSamples(MediaStreamTrack track, float delay);
     [Conditional=MEDIA_STREAM] void setMediaStreamTrackMuted(MediaStreamTrack track, boolean muted);
+    [Conditional=MEDIA_STREAM] void removeMediaStreamTrack(MediaStream stream, MediaStreamTrack track);
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to