Changeset 249574 in webkit


Ignore:
Timestamp:
Sep 6, 2019 8:49:39 AM (5 years ago)
Author:
youenn@apple.com
Message:

Remove MediaStreamPrivate::scheduleDeferredTask
https://bugs.webkit.org/show_bug.cgi?id=200975

Reviewed by Eric Carlson.

LayoutTests/imported/w3c:

  • web-platform-tests/mediacapture-streams/MediaStream-finished-add.https-expected.txt:

Source/WebCore:

All calls to scheduleDeferredTask are done on the main thread.
This was initially done to trigger less reconfiguration.
But this makes the implementation significantly more complex.

For instance, we have to wait for the document to update its media state
and send it to UIProcess before calling the allow completion handler.

Covered by existing tests.

  • Modules/mediastream/MediaStream.cpp:

(WebCore::MediaStream::MediaStream):
Make sure to update the document media state once the tracks have been added, similarly to the other constructor.
This ensures the document media state is computed with the new MediaStreamTrack.

  • Modules/mediastream/UserMediaRequest.cpp:

(WebCore::isMediaStreamCorrectlyStarted):
(WebCore::UserMediaRequest::allow):
(WebCore::UserMediaRequest::stop):
(WebCore::UserMediaRequest::mediaStreamDidFail):

  • Modules/mediastream/UserMediaRequest.h:
  • page/MediaProducer.h:

(WebCore::MediaProducer::isCapturing):
Make sure to include getDisplayMedia as part of capture check.

  • platform/mediastream/MediaStreamPrivate.cpp:

(WebCore::MediaStreamPrivate::trackMutedChanged):
(WebCore::MediaStreamPrivate::trackEnabledChanged):
(WebCore::MediaStreamPrivate::trackStarted):
(WebCore::MediaStreamPrivate::trackEnded):

  • platform/mediastream/MediaStreamPrivate.h:
Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r249572 r249574  
     12019-09-06  Youenn Fablet  <youenn@apple.com>
     2
     3        Remove MediaStreamPrivate::scheduleDeferredTask
     4        https://bugs.webkit.org/show_bug.cgi?id=200975
     5
     6        Reviewed by Eric Carlson.
     7
     8        * web-platform-tests/mediacapture-streams/MediaStream-finished-add.https-expected.txt:
     9
    1102019-09-06  Rob Buis  <rbuis@igalia.com>
    211
  • trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStream-finished-add.https-expected.txt

    r223189 r249574  
    66
    77
    8 FAIL Tests that adding a track to an inactive MediaStream is allowed assert_false: audio stream is inactive after stopping its only audio track expected false got true
     8PASS Tests that adding a track to an inactive MediaStream is allowed
    99
  • trunk/Source/WebCore/ChangeLog

    r249572 r249574  
     12019-09-06  Youenn Fablet  <youenn@apple.com>
     2
     3        Remove MediaStreamPrivate::scheduleDeferredTask
     4        https://bugs.webkit.org/show_bug.cgi?id=200975
     5
     6        Reviewed by Eric Carlson.
     7
     8        All calls to scheduleDeferredTask are done on the main thread.
     9        This was initially done to trigger less reconfiguration.
     10        But this makes the implementation significantly more complex.
     11
     12        For instance, we have to wait for the document to update its media state
     13        and send it to UIProcess before calling the allow completion handler.
     14
     15        Covered by existing tests.
     16
     17        * Modules/mediastream/MediaStream.cpp:
     18        (WebCore::MediaStream::MediaStream):
     19        Make sure to update the document media state once the tracks have been added, similarly to the other constructor.
     20        This ensures the document media state is computed with the new MediaStreamTrack.
     21        * Modules/mediastream/UserMediaRequest.cpp:
     22        (WebCore::isMediaStreamCorrectlyStarted):
     23        (WebCore::UserMediaRequest::allow):
     24        (WebCore::UserMediaRequest::stop):
     25        (WebCore::UserMediaRequest::mediaStreamDidFail):
     26        * Modules/mediastream/UserMediaRequest.h:
     27        * page/MediaProducer.h:
     28        (WebCore::MediaProducer::isCapturing):
     29        Make sure to include getDisplayMedia as part of capture check.
     30        * platform/mediastream/MediaStreamPrivate.cpp:
     31        (WebCore::MediaStreamPrivate::trackMutedChanged):
     32        (WebCore::MediaStreamPrivate::trackEnabledChanged):
     33        (WebCore::MediaStreamPrivate::trackStarted):
     34        (WebCore::MediaStreamPrivate::trackEnded):
     35        * platform/mediastream/MediaStreamPrivate.h:
     36
    1372019-09-06  Rob Buis  <rbuis@igalia.com>
    238
  • trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp

    r248467 r249574  
    102102    ALWAYS_LOG(LOGIDENTIFIER);
    103103
    104     setIsActive(m_private->active());
    105     m_private->addObserver(*this);
    106 
    107104    for (auto& trackPrivate : m_private->tracks()) {
    108105        auto track = MediaStreamTrack::create(document, *trackPrivate);
     
    110107        m_trackSet.add(track->id(), WTFMove(track));
    111108    }
     109
     110    setIsActive(m_private->active());
     111    m_private->addObserver(*this);
    112112    suspendIfNeeded();
    113113}
  • trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp

    r248896 r249574  
    216216}
    217217
     218static inline bool isMediaStreamCorrectlyStarted(const MediaStream& stream)
     219{
     220    if (stream.getTracks().isEmpty())
     221        return false;
     222
     223    return WTF::allOf(stream.getTracks(), [](auto& track) {
     224        return !track->source().captureDidFail();
     225    });
     226}
     227
    218228void UserMediaRequest::allow(CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, String&& deviceIdentifierHashSalt, CompletionHandler<void()>&& completionHandler)
    219229{
     
    221231
    222232    auto callback = [this, protector = makePendingActivity(*this), completionHandler = WTFMove(completionHandler)](RefPtr<MediaStreamPrivate>&& privateStream) mutable {
    223         auto scopeExit = makeScopeExit([&] {
     233        auto scopeExit = makeScopeExit([completionHandler = WTFMove(completionHandler)]() mutable {
    224234            completionHandler();
    225235        });
    226         if (!m_scriptExecutionContext)
     236        if (isContextStopped())
    227237            return;
    228238
     
    232242            return;
    233243        }
    234         privateStream->monitorOrientation(downcast<Document>(m_scriptExecutionContext)->orientationNotifier());
    235 
    236         auto stream = MediaStream::create(*downcast<Document>(m_scriptExecutionContext), privateStream.releaseNonNull());
    237         if (stream->getTracks().isEmpty()) {
     244
     245        auto& document = downcast<Document>(*m_scriptExecutionContext);
     246        privateStream->monitorOrientation(document.orientationNotifier());
     247
     248        auto stream = MediaStream::create(document, privateStream.releaseNonNull());
     249        stream->startProducingData();
     250
     251        if (!isMediaStreamCorrectlyStarted(stream)) {
    238252            deny(MediaAccessDenialReason::HardwareError);
    239253            return;
    240254        }
    241255
    242         scopeExit.release();
    243         m_pendingActivationMediaStream = makeUnique<PendingActivationMediaStream>(WTFMove(protector), *this, WTFMove(stream), WTFMove(completionHandler));
     256        ASSERT(document.isCapturing());
     257        stream->document()->setHasCaptureMediaStreamTrack();
     258        m_promise.resolve(WTFMove(stream));
    244259    };
    245260
     
    311326void UserMediaRequest::stop()
    312327{
    313     // Protecting 'this' since nulling m_pendingActivationMediaStream might destroy it.
    314     Ref<UserMediaRequest> protectedThis(*this);
    315 
    316     m_pendingActivationMediaStream = nullptr;
    317 
    318328    auto& document = downcast<Document>(*m_scriptExecutionContext);
    319329    if (auto* controller = UserMediaController::from(document.page()))
     
    334344{
    335345    return downcast<Document>(m_scriptExecutionContext);
    336 }
    337 
    338 UserMediaRequest::PendingActivationMediaStream::PendingActivationMediaStream(Ref<PendingActivity<UserMediaRequest>>&& protectingUserMediaRequest, UserMediaRequest& userMediaRequest, Ref<MediaStream>&& stream, CompletionHandler<void()>&& completionHandler)
    339     : m_protectingUserMediaRequest(WTFMove(protectingUserMediaRequest))
    340     , m_userMediaRequest(userMediaRequest)
    341     , m_mediaStream(WTFMove(stream))
    342     , m_completionHandler(WTFMove(completionHandler))
    343 {
    344     m_mediaStream->privateStream().addObserver(*this);
    345     m_mediaStream->startProducingData();
    346 }
    347 
    348 UserMediaRequest::PendingActivationMediaStream::~PendingActivationMediaStream()
    349 {
    350     m_mediaStream->privateStream().removeObserver(*this);
    351     m_completionHandler();
    352     if (auto* document = m_mediaStream->document())
    353         document->updateIsPlayingMedia();
    354 }
    355 
    356 void UserMediaRequest::PendingActivationMediaStream::characteristicsChanged()
    357 {
    358     if (!m_userMediaRequest.m_pendingActivationMediaStream)
    359         return;
    360 
    361     for (auto& track : m_mediaStream->privateStream().tracks()) {
    362         if (track->source().captureDidFail()) {
    363             m_userMediaRequest.mediaStreamDidFail(track->source().type());
    364             return;
    365         }
    366     }
    367 
    368     if (m_mediaStream->privateStream().hasVideo() || m_mediaStream->privateStream().hasAudio()) {
    369         m_userMediaRequest.mediaStreamIsReady(WTFMove(m_mediaStream));
    370         return;
    371     }
    372 }
    373 
    374 void UserMediaRequest::mediaStreamIsReady(Ref<MediaStream>&& stream)
    375 {
    376     RELEASE_LOG(MediaStream, "UserMediaRequest::mediaStreamIsReady");
    377     stream->document()->setHasCaptureMediaStreamTrack();
    378     m_promise.resolve(WTFMove(stream));
    379     m_pendingActivationMediaStream = nullptr;
    380346}
    381347
     
    396362    }
    397363    m_promise.reject(NotReadableError, makeString("Failed starting capture of a "_s, typeDescription, " track"_s));
    398     m_pendingActivationMediaStream = nullptr;
    399364}
    400365
  • trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.h

    r248896 r249574  
    8080    bool canSuspendForDocumentSuspension() const final;
    8181
    82     void mediaStreamIsReady(Ref<MediaStream>&&);
    8382    void mediaStreamDidFail(RealtimeMediaSource::Type);
    84 
    85     class PendingActivationMediaStream : private MediaStreamPrivate::Observer {
    86         WTF_MAKE_FAST_ALLOCATED;
    87     public:
    88         PendingActivationMediaStream(Ref<PendingActivity<UserMediaRequest>>&&, UserMediaRequest&, Ref<MediaStream>&&, CompletionHandler<void()>&&);
    89         ~PendingActivationMediaStream();
    90 
    91     private:
    92         void characteristicsChanged() final;
    93 
    94         Ref<PendingActivity<UserMediaRequest>> m_protectingUserMediaRequest;
    95         UserMediaRequest& m_userMediaRequest;
    96         Ref<MediaStream> m_mediaStream;
    97         CompletionHandler<void()> m_completionHandler;
    98     };
    9983
    10084    Vector<String> m_videoDeviceUIDs;
     
    10286
    10387    DOMPromiseDeferred<IDLInterface<MediaStream>> m_promise;
    104     std::unique_ptr<PendingActivationMediaStream> m_pendingActivationMediaStream;
    10588    MediaStreamRequest m_request;
    10689};
  • trunk/Source/WebCore/page/MediaProducer.h

    r244815 r249574  
    5959        VideoCaptureMask = HasActiveVideoCaptureDevice | HasMutedVideoCaptureDevice | HasInterruptedVideoCaptureDevice,
    6060        DisplayCaptureMask = HasActiveDisplayCaptureDevice | HasMutedDisplayCaptureDevice | HasInterruptedDisplayCaptureDevice,
     61        ActiveCaptureMask = HasActiveAudioCaptureDevice | HasActiveVideoCaptureDevice | HasActiveDisplayCaptureDevice,
    6162        MutedCaptureMask =  HasMutedAudioCaptureDevice | HasMutedVideoCaptureDevice | HasMutedDisplayCaptureDevice,
    6263        MediaCaptureMask = AudioCaptureMask | VideoCaptureMask | DisplayCaptureMask,
     
    6465    typedef unsigned MediaStateFlags;
    6566
    66     static bool isCapturing(MediaStateFlags state) { return (state & HasActiveAudioCaptureDevice) || (state & HasActiveVideoCaptureDevice) || (state & HasMutedAudioCaptureDevice) || (state & HasMutedVideoCaptureDevice); }
     67    static bool isCapturing(MediaStateFlags state) { return (state & ActiveCaptureMask) || (state & MutedCaptureMask); }
    6768
    6869    virtual MediaStateFlags mediaState() const = 0;
  • trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp

    r246436 r249574  
    283283
    284284    ALWAYS_LOG(LOGIDENTIFIER, track.logIdentifier(), " ", track.muted());
    285     scheduleDeferredTask([this] {
    286         characteristicsChanged();
    287     });
     285    characteristicsChanged();
    288286}
    289287
     
    302300    updateActiveVideoTrack();
    303301
    304     scheduleDeferredTask([this] {
    305         characteristicsChanged();
    306     });
     302    characteristicsChanged();
    307303}
    308304
     
    314310
    315311    ALWAYS_LOG(LOGIDENTIFIER, track.logIdentifier());
    316     scheduleDeferredTask([this] {
    317         characteristicsChanged();
    318     });
     312    characteristicsChanged();
    319313}
    320314
     
    326320
    327321    ALWAYS_LOG(LOGIDENTIFIER, track.logIdentifier());
    328     scheduleDeferredTask([this] {
    329         updateActiveState(NotifyClientOption::Notify);
    330         characteristicsChanged();
    331     });
    332 }
    333 
    334 void MediaStreamPrivate::scheduleDeferredTask(Function<void ()>&& function)
    335 {
    336     ASSERT(function);
    337     callOnMainThread([weakThis = makeWeakPtr(*this), function = WTFMove(function)] {
    338         if (!weakThis)
    339             return;
    340 
    341         function();
    342     });
     322    updateActiveState(NotifyClientOption::Notify);
     323    characteristicsChanged();
    343324}
    344325
  • trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.h

    r246436 r249574  
    4848#include <wtf/UUID.h>
    4949#include <wtf/Vector.h>
    50 #include <wtf/WeakPtr.h>
    5150
    5251namespace WebCore {
     
    5857    : public MediaStreamTrackPrivate::Observer
    5958    , public RefCounted<MediaStreamPrivate>
    60     , public CanMakeWeakPtr<MediaStreamPrivate>
    6159#if !RELEASE_LOG_DISABLED
    6260    , private LoggerHelper
     
    129127    void updateActiveVideoTrack();
    130128
    131     void scheduleDeferredTask(Function<void ()>&&);
    132129    void forEachObserver(const WTF::Function<void(Observer&)>&) const;
    133130
Note: See TracChangeset for help on using the changeset viewer.