Changeset 216197 in webkit


Ignore:
Timestamp:
May 4, 2017 11:32:29 AM (7 years ago)
Author:
eric.carlson@apple.com
Message:

[MediaStream] Allow host application to enable/disable media capture
https://bugs.webkit.org/show_bug.cgi?id=171292
<rdar://problem/31821492>

Reviewed by Jer Noble.

Source/WebCore:

No new layout tests, added an API test instead.

  • Modules/mediastream/MediaStream.cpp:

(WebCore::MediaStream::endStream): New, stop all tracks.

  • Modules/mediastream/MediaStream.h:
  • Modules/mediastream/MediaStreamRegistry.cpp:

(WebCore::MediaStreamRegistry::unregisterStream): Minor cleanup.
(WebCore::MediaStreamRegistry::forEach): New, call the lambda with each stream.
(WebCore::MediaStreamRegistry::MediaStreamRegistry): Deleted, unused.

  • Modules/mediastream/MediaStreamRegistry.h:
  • Modules/mediastream/MediaStreamTrack.cpp:

(WebCore::MediaStreamTrack::stopTrack): Add parameter so caller can specify if an 'ended'
event should be sent or not.
(WebCore::MediaStreamTrack::trackMutedChanged): Don't post an event if the track has ended.

  • Modules/mediastream/MediaStreamTrack.h:
  • dom/Document.cpp:

(WebCore::Document::stopMediaCapture): Stop all streams in the document.

  • dom/Document.h:
  • page/Page.cpp:

(WebCore::Page::stopMediaCapture): Stop all streams.

  • page/Page.h:
  • platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:

(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::currentDisplayMode): Display a black frame
when the stream ends.
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::activeStatusChanged): Signal a characteristics
change to HTMLMediaElement refresh state.

  • platform/mediastream/MediaStreamPrivate.h:
  • platform/mediastream/mac/AVMediaCaptureSource.mm:

(WebCore::AVMediaCaptureSource::stopProducingData): Don't return early if the session isn't
running, we always need to clear m_session on iOS.

Source/WebKit2:

  • UIProcess/API/C/WKPage.cpp:

(WKPageSetMediaCaptureEnabled): New.
(WKPageGetMediaCaptureEnabled): New.

  • UIProcess/API/C/WKPagePrivate.h:
  • UIProcess/API/Cocoa/WKWebView.mm:

(-[WKWebView _setMediaCaptureEnabled:]): New.
(-[WKWebView _mediaCaptureEnabled]): New.

  • UIProcess/API/Cocoa/WKWebViewPrivate.h:
  • UIProcess/Cocoa/UIDelegate.mm:

(WebKit::UIDelegate::setDelegate): Initialize webViewRequestUserMediaAuthorizationForDevicesURLMainFrameURLDecisionHandler
and webViewCheckUserMediaPermissionForURLMainFrameURLFrameIdentifierDecisionHandler on macOS
and iOS.

  • UIProcess/UserMediaPermissionRequestManagerProxy.cpp:

(WebKit::UserMediaPermissionRequestManagerProxy::UserMediaPermissionRequestManagerProxy):
Initialize the rejection timer.
(WebKit::UserMediaPermissionRequestManagerProxy::~UserMediaPermissionRequestManagerProxy):
Call invalidatePendingRequests.
(WebKit::UserMediaPermissionRequestManagerProxy::invalidatePendingRequests): Invalidate all
pending requests.
(WebKit::UserMediaPermissionRequestManagerProxy::stopCapture): New.
(WebKit::UserMediaPermissionRequestManagerProxy::rejectionTimerFired): Reject a promise and
schedule the timer if there are any others pending.
(WebKit::UserMediaPermissionRequestManagerProxy::scheduleNextRejection):
(WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame): Don't
prompt the user if capture is disabled.
(WebKit::UserMediaPermissionRequestManagerProxy::invalidateRequests): Deleted.
(WebKit::UserMediaPermissionRequestManagerProxy::clearCachedState): Deleted.

  • UIProcess/UserMediaPermissionRequestManagerProxy.h:
  • UIProcess/UserMediaProcessManager.cpp:

(WebKit::UserMediaProcessManager::willEnableMediaStreamInPage): Stop capture in the current
page on iOS.
(WebKit::UserMediaProcessManager::setCaptureEnabled):

  • UIProcess/UserMediaProcessManager.h:
  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::setMediaCaptureEnabled):

  • UIProcess/WebPageProxy.h:

(WebKit::WebPageProxy::mediaCaptureEnabled):

  • WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:

(WebKit::UserMediaPermissionRequestManager::cancelPendingRequests): New, cancel all pending
requests.
(WebKit::UserMediaPermissionRequestManager::cancelUserMediaRequest): Deny the request.
(WebKit::UserMediaPermissionRequestManager::cancelMediaDevicesEnumeration):

  • WebProcess/MediaStream/UserMediaPermissionRequestManager.h:
  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::stopMediaCapture):

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/WebPage.messages.in:

Tools:

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WebKit2Cocoa/UserMediaDisabled.mm: Added.

(-[UserMediaMessageHandler userContentController:didReceiveScriptMessage:]):
(-[UserMediaUIDelegate _webView:requestUserMediaAuthorizationForDevices:url:mainFrameURL:decisionHandler:]):
(-[UserMediaUIDelegate _webView:checkUserMediaPermissionForURL:mainFrameURL:frameIdentifier:decisionHandler:]):
(MediaCaptureDisabledTest::SetUp):
(MediaCaptureDisabledTest::loadTestAndWaitForMessage):
(TEST_F):

  • TestWebKitAPI/Tests/WebKit2Cocoa/disableGetUserMedia.html: Added.
Location:
trunk
Files:
2 added
33 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r216196 r216197  
     12017-05-04  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [MediaStream] Allow host application to enable/disable media capture
     4        https://bugs.webkit.org/show_bug.cgi?id=171292
     5        <rdar://problem/31821492>
     6
     7        Reviewed by Jer Noble.
     8
     9        No new layout tests, added an API test instead.
     10
     11        * Modules/mediastream/MediaStream.cpp:
     12        (WebCore::MediaStream::endStream): New, stop all tracks.
     13        * Modules/mediastream/MediaStream.h:
     14
     15        * Modules/mediastream/MediaStreamRegistry.cpp:
     16        (WebCore::MediaStreamRegistry::unregisterStream): Minor cleanup.
     17        (WebCore::MediaStreamRegistry::forEach): New, call the lambda with each stream.
     18        (WebCore::MediaStreamRegistry::MediaStreamRegistry): Deleted, unused.
     19        * Modules/mediastream/MediaStreamRegistry.h:
     20
     21        * Modules/mediastream/MediaStreamTrack.cpp:
     22        (WebCore::MediaStreamTrack::stopTrack): Add parameter so caller can specify if an 'ended'
     23        event should be sent or not.
     24        (WebCore::MediaStreamTrack::trackMutedChanged): Don't post an event if the track has ended.
     25        * Modules/mediastream/MediaStreamTrack.h:
     26
     27        * dom/Document.cpp:
     28        (WebCore::Document::stopMediaCapture): Stop all streams in the document.
     29        * dom/Document.h:
     30
     31        * page/Page.cpp:
     32        (WebCore::Page::stopMediaCapture): Stop all streams.
     33        * page/Page.h:
     34
     35        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
     36        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::currentDisplayMode): Display a black frame
     37        when the stream ends.
     38        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::activeStatusChanged): Signal a characteristics
     39        change to HTMLMediaElement refresh state.
     40        * platform/mediastream/MediaStreamPrivate.h:
     41
     42        * platform/mediastream/mac/AVMediaCaptureSource.mm:
     43        (WebCore::AVMediaCaptureSource::stopProducingData): Don't return early if the session isn't
     44        running, we always need to clear m_session on iOS.
     45
    1462017-05-04  Zalan Bujtas  <zalan@apple.com>
    247
  • trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp

    r216183 r216197  
    315315}
    316316
     317void MediaStream::endStream()
     318{
     319    for (auto& track : m_trackSet.values())
     320        track->stopTrack(MediaStreamTrack::StopMode::PostEvent);
     321}
     322
    317323void MediaStream::pageMutedStateDidChange()
    318324{
  • trunk/Source/WebCore/Modules/mediastream/MediaStream.h

    r216183 r216197  
    9292    void stopProducingData();
    9393
     94    void endStream();
     95
    9496    // EventTarget
    9597    EventTargetInterface eventTargetInterface() const final { return MediaStreamEventTargetInterfaceType; }
     
    106108
    107109    void addTrackFromPlatform(Ref<MediaStreamTrack>&&);
     110
     111    Document* document() const;
    108112
    109113protected:
     
    159163    void statusDidChange();
    160164
    161     Document* document() const;
    162 
    163165    MediaStreamTrackVector trackVectorForType(RealtimeMediaSource::Type) const;
    164166
  • trunk/Source/WebCore/Modules/mediastream/MediaStreamRegistry.cpp

    r216183 r216197  
    6363}
    6464
    65 MediaStreamRegistry::MediaStreamRegistry()
    66 {
    67 }
    68 
    6965MediaStream* MediaStreamRegistry::lookUp(const URL& url) const
    7066{
     
    8581void MediaStreamRegistry::unregisterStream(MediaStream& stream)
    8682{
    87     Vector<MediaStream*>& allStreams = mediaStreams();
     83    auto& allStreams = mediaStreams();
    8884    size_t pos = allStreams.find(&stream);
    8985    if (pos != notFound)
     
    9187}
    9288
    93 MediaStream* MediaStreamRegistry::lookUp(const MediaStreamPrivate& privateStream) const
     89void MediaStreamRegistry::forEach(std::function<void(MediaStream&)> callback) const
    9490{
    95     Vector<MediaStream*>& allStreams = mediaStreams();
    96     for (auto& stream : allStreams) {
    97         if (&stream->privateStream() == &privateStream)
    98             return stream;
    99     }
    100 
    101     return nullptr;
     91    for (auto& stream : mediaStreams())
     92        callback(*stream);
    10293}
    10394
  • trunk/Source/WebCore/Modules/mediastream/MediaStreamRegistry.h

    r216183 r216197  
    5555
    5656    MediaStream* lookUp(const URL&) const;
    57     MediaStream* lookUp(const MediaStreamPrivate&) const;
     57
     58    void forEach(std::function<void(MediaStream&)>) const;
    5859
    5960private:
    60     MediaStreamRegistry();
     61    MediaStreamRegistry() = default;
    6162    HashMap<String, RefPtr<MediaStream>> m_mediaStreams;
    6263};
  • trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp

    r216183 r216197  
    114114}
    115115
    116 void MediaStreamTrack::stopTrack()
     116void MediaStreamTrack::stopTrack(StopMode mode)
    117117{
    118118    // NOTE: this method is called when the "stop" method is called from JS, using the "ImplementedAs" IDL attribute.
     
    122122        return;
    123123
     124    // An 'ended' event is not posted if m_ended is true when trackEnded is called, so set it now if we are
     125    // not supposed to post the event.
     126    if (mode == StopMode::Silently)
     127        m_ended = true;
     128
     129    m_private->endTrack();
    124130    m_ended = true;
    125     m_private->endTrack();
    126131}
    127132
     
    304309void MediaStreamTrack::trackMutedChanged(MediaStreamTrackPrivate&)
    305310{
    306     if (scriptExecutionContext()->activeDOMObjectsAreSuspended() || scriptExecutionContext()->activeDOMObjectsAreStopped())
     311    if (scriptExecutionContext()->activeDOMObjectsAreSuspended() || scriptExecutionContext()->activeDOMObjectsAreStopped() || m_ended)
    307312        return;
    308313
  • trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h

    r216183 r216197  
    7272
    7373    Ref<MediaStreamTrack> clone();
    74     void stopTrack();
     74
     75    enum class StopMode { Silently, PostEvent };
     76    void stopTrack(StopMode = StopMode::Silently);
    7577
    7678    bool isCaptureTrack() const;
  • trunk/Source/WebCore/dom/Document.cpp

    r216183 r216197  
    272272#endif
    273273
     274#if ENABLE(MEDIA_STREAM)
     275#include "MediaStream.h"
     276#include "MediaStreamRegistry.h"
     277#endif
     278
    274279using namespace WTF;
    275280using namespace Unicode;
     
    69736978}
    69746979
     6980#if ENABLE(MEDIA_STREAM)
     6981void Document::stopMediaCapture()
     6982{
     6983    MediaStreamRegistry::shared().forEach([this](MediaStream& stream) {
     6984        if (stream.document() == this)
     6985            stream.endStream();
     6986    });
     6987}
     6988#endif
     6989
    69756990} // namespace WebCore
  • trunk/Source/WebCore/dom/Document.h

    r216183 r216197  
    12781278    void setDeviceIDHashSalt(const String& salt) { m_idHashSalt = salt; }
    12791279    String deviceIDHashSalt() const { return m_idHashSalt; }
     1280    void stopMediaCapture();
    12801281#endif
    12811282
  • trunk/Source/WebCore/page/Page.cpp

    r216183 r216197  
    15331533}
    15341534
     1535void Page::stopMediaCapture()
     1536{
     1537#if ENABLE(MEDIA_STREAM)
     1538    for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
     1539        if (!frame->document())
     1540            continue;
     1541
     1542        frame->document()->stopMediaCapture();
     1543    }
     1544#endif
     1545}
     1546
    15351547#if ENABLE(MEDIA_SESSION)
    15361548void Page::handleMediaEvent(MediaEventType eventType)
  • trunk/Source/WebCore/page/Page.h

    r216183 r216197  
    531531    bool isMediaCaptureMuted() const { return m_mutedState & MediaProducer::CaptureDevicesAreMuted; };
    532532    WEBCORE_EXPORT void setMuted(MediaProducer::MutedStateFlags);
     533    WEBCORE_EXPORT void stopMediaCapture();
    533534
    534535#if ENABLE(MEDIA_SESSION)
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm

    r216183 r216197  
    581581MediaPlayerPrivateMediaStreamAVFObjC::DisplayMode MediaPlayerPrivateMediaStreamAVFObjC::currentDisplayMode() const
    582582{
    583     if (m_ended || m_intrinsicSize.isEmpty() || !metaDataAvailable() || !m_sampleBufferDisplayLayer)
     583    if (m_intrinsicSize.isEmpty() || !metaDataAvailable() || !m_sampleBufferDisplayLayer)
    584584        return None;
    585585
    586586    if (auto* track = m_mediaStreamPrivate->activeVideoTrack()) {
    587         if (!track->enabled() || track->muted())
     587        if (!track->enabled() || track->muted() || track->ended())
    588588            return PaintItBlack;
    589589    }
    590590
    591     if (playing()) {
     591    if (playing() && !m_ended) {
    592592        if (!m_mediaStreamPrivate->isProducingData())
    593593            return PausedImage;
     
    595595    }
    596596
    597     if (m_playbackState == PlaybackState::None)
     597    if (m_playbackState == PlaybackState::None || m_ended)
    598598        return PaintItBlack;
    599599
     
    769769        if (ended != m_ended) {
    770770            m_ended = ended;
    771             if (m_player)
     771            if (m_player) {
    772772                m_player->timeChanged();
     773                m_player->characteristicChanged();
     774            }
    773775        }
    774776    });
  • trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.h

    r216183 r216197  
    9696    bool isProducingData() const;
    9797
     98    void endStream();
     99
    98100    bool hasVideo() const;
    99101    bool hasAudio() const;
  • trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm

    r216183 r216197  
    182182void AVMediaCaptureSource::stopProducingData()
    183183{
    184     if (!m_session || ![m_session isRunning])
     184    if (!m_session)
    185185        return;
    186186
    187187    [m_objcObserver removeNotificationObservers];
    188     [m_session stopRunning];
     188
     189    if ([m_session isRunning])
     190        [m_session stopRunning];
     191
    189192#if PLATFORM(IOS)
    190193    m_session = nullptr;
  • trunk/Source/WebKit2/ChangeLog

    r216187 r216197  
     12017-05-04  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [MediaStream] Allow host application to enable/disable media capture
     4        https://bugs.webkit.org/show_bug.cgi?id=171292
     5        <rdar://problem/31821492>
     6
     7        Reviewed by Jer Noble.
     8
     9        * UIProcess/API/C/WKPage.cpp:
     10        (WKPageSetMediaCaptureEnabled): New.
     11        (WKPageGetMediaCaptureEnabled): New.
     12        * UIProcess/API/C/WKPagePrivate.h:
     13
     14        * UIProcess/API/Cocoa/WKWebView.mm:
     15        (-[WKWebView _setMediaCaptureEnabled:]): New.
     16        (-[WKWebView _mediaCaptureEnabled]): New.
     17        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
     18
     19        * UIProcess/Cocoa/UIDelegate.mm:
     20        (WebKit::UIDelegate::setDelegate): Initialize webViewRequestUserMediaAuthorizationForDevicesURLMainFrameURLDecisionHandler
     21        and webViewCheckUserMediaPermissionForURLMainFrameURLFrameIdentifierDecisionHandler on macOS
     22        and iOS.
     23
     24        * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
     25        (WebKit::UserMediaPermissionRequestManagerProxy::UserMediaPermissionRequestManagerProxy):
     26        Initialize the rejection timer.
     27        (WebKit::UserMediaPermissionRequestManagerProxy::~UserMediaPermissionRequestManagerProxy):
     28        Call invalidatePendingRequests.
     29        (WebKit::UserMediaPermissionRequestManagerProxy::invalidatePendingRequests): Invalidate all
     30        pending requests.
     31        (WebKit::UserMediaPermissionRequestManagerProxy::stopCapture): New.
     32        (WebKit::UserMediaPermissionRequestManagerProxy::rejectionTimerFired): Reject a promise and
     33        schedule the timer if there are any others pending.
     34        (WebKit::UserMediaPermissionRequestManagerProxy::scheduleNextRejection):
     35        (WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame): Don't
     36        prompt the user if capture is disabled.
     37        (WebKit::UserMediaPermissionRequestManagerProxy::invalidateRequests): Deleted.
     38        (WebKit::UserMediaPermissionRequestManagerProxy::clearCachedState): Deleted.
     39        * UIProcess/UserMediaPermissionRequestManagerProxy.h:
     40
     41        * UIProcess/UserMediaProcessManager.cpp:
     42        (WebKit::UserMediaProcessManager::willEnableMediaStreamInPage): Stop capture in the current
     43        page on iOS.
     44        (WebKit::UserMediaProcessManager::setCaptureEnabled):
     45        * UIProcess/UserMediaProcessManager.h:
     46
     47        * UIProcess/WebPageProxy.cpp:
     48        (WebKit::WebPageProxy::setMediaCaptureEnabled):
     49
     50        * UIProcess/WebPageProxy.h:
     51        (WebKit::WebPageProxy::mediaCaptureEnabled):
     52
     53        * WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:
     54        (WebKit::UserMediaPermissionRequestManager::cancelPendingRequests): New, cancel all pending
     55        requests.
     56        (WebKit::UserMediaPermissionRequestManager::cancelUserMediaRequest): Deny the request.
     57        (WebKit::UserMediaPermissionRequestManager::cancelMediaDevicesEnumeration):
     58        * WebProcess/MediaStream/UserMediaPermissionRequestManager.h:
     59
     60        * WebProcess/WebPage/WebPage.cpp:
     61        (WebKit::WebPage::stopMediaCapture):
     62        * WebProcess/WebPage/WebPage.h:
     63        * WebProcess/WebPage/WebPage.messages.in:
     64
    1652017-05-04  Konstantin Tokarev  <annulen@yandex.ru>
    266
  • trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp

    r216183 r216197  
    26782678}
    26792679
     2680void WKPageSetMediaCaptureEnabled(WKPageRef page, bool enabled)
     2681{
     2682    toImpl(page)->setMediaCaptureEnabled(enabled);
     2683}
     2684
     2685bool WKPageGetMediaCaptureEnabled(WKPageRef page)
     2686{
     2687    return toImpl(page)->mediaCaptureEnabled();
     2688}
     2689
    26802690void WKPageDidAllowPointerLock(WKPageRef page)
    26812691{
  • trunk/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h

    r216183 r216197  
    128128
    129129WK_EXPORT void WKPageClearUserMediaState(WKPageRef page);
     130WK_EXPORT void WKPageSetMediaCaptureEnabled(WKPageRef page, bool enabled);
     131WK_EXPORT bool WKPageGetMediaCaptureEnabled(WKPageRef page);
    130132
    131133WK_EXPORT void WKPageDidAllowPointerLock(WKPageRef page);
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm

    r216183 r216197  
    44744474}
    44754475
     4476- (void)_setMediaCaptureEnabled:(BOOL)enabled
     4477{
     4478    _page->setMediaCaptureEnabled(enabled);
     4479}
     4480
     4481- (BOOL)_mediaCaptureEnabled
     4482{
     4483    return _page->mediaCaptureEnabled();
     4484}
     4485
    44764486- (void)_setPageMuted:(_WKMediaMutedState)mutedState
    44774487{
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h

    r216183 r216197  
    293293@property (nonatomic, readonly) BOOL _isInFullscreen WK_API_AVAILABLE(macosx(WK_MAC_TBA));
    294294
    295 - (void)_muteMediaCapture;
     295- (void)_muteMediaCapture WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
    296296- (void)_setPageMuted:(_WKMediaMutedState)mutedState WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
     297
     298@property (nonatomic, setter=_setMediaCaptureEnabled:) BOOL _mediaCaptureEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
    297299
    298300@end
  • trunk/Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm

    r216183 r216197  
    116116    m_delegateMethods.webViewActionsForElementDefaultActions = [delegate respondsToSelector:@selector(_webView:actionsForElement:defaultActions:)];
    117117    m_delegateMethods.webViewDidNotHandleTapAsClickAtPoint = [delegate respondsToSelector:@selector(_webView:didNotHandleTapAsClickAtPoint:)];
     118    m_delegateMethods.presentingViewControllerForWebView = [delegate respondsToSelector:@selector(_presentingViewControllerForWebView:)];
     119#endif
    118120    m_delegateMethods.webViewRequestUserMediaAuthorizationForDevicesURLMainFrameURLDecisionHandler = [delegate respondsToSelector:@selector(_webView:requestUserMediaAuthorizationForDevices:url:mainFrameURL:decisionHandler:)];
    119121    m_delegateMethods.webViewCheckUserMediaPermissionForURLMainFrameURLFrameIdentifierDecisionHandler = [delegate respondsToSelector:@selector(_webView:checkUserMediaPermissionForURL:mainFrameURL:frameIdentifier:decisionHandler:)];
    120122    m_delegateMethods.webViewMediaCaptureStateDidChange = [delegate respondsToSelector:@selector(_webView:mediaCaptureStateDidChange:)];
    121     m_delegateMethods.presentingViewControllerForWebView = [delegate respondsToSelector:@selector(_presentingViewControllerForWebView:)];
    122 #endif
    123123    m_delegateMethods.dataDetectionContextForWebView = [delegate respondsToSelector:@selector(_dataDetectionContextForWebView:)];
    124124    m_delegateMethods.webViewImageOrMediaDocumentSizeChanged = [delegate respondsToSelector:@selector(_webView:imageOrMediaDocumentSizeChanged:)];
  • trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp

    r216183 r216197  
    9797UserMediaPermissionRequestManagerProxy::UserMediaPermissionRequestManagerProxy(WebPageProxy& page)
    9898    : m_page(page)
     99    , m_rejectionTimer(*this, &UserMediaPermissionRequestManagerProxy::rejectionTimerFired)
    99100{
    100101#if ENABLE(MEDIA_STREAM)
     
    108109    UserMediaProcessManager::singleton().removeUserMediaPermissionRequestManagerProxy(*this);
    109110#endif
    110     invalidateRequests();
    111 }
    112 
    113 void UserMediaPermissionRequestManagerProxy::invalidateRequests()
     111    invalidatePendingRequests();
     112}
     113
     114void UserMediaPermissionRequestManagerProxy::invalidatePendingRequests()
    114115{
    115116    for (auto& request : m_pendingUserMediaRequests.values())
     
    124125}
    125126
     127void UserMediaPermissionRequestManagerProxy::stopCapture()
     128{
     129    invalidatePendingRequests();
     130    m_page.stopMediaCapture();
     131}
     132
    126133void UserMediaPermissionRequestManagerProxy::clearCachedState()
    127134{
    128     invalidateRequests();
     135    invalidatePendingRequests();
    129136}
    130137
     
    222229    UNUSED_PARAM(videoDeviceUID);
    223230#endif
     231}
     232
     233void UserMediaPermissionRequestManagerProxy::rejectionTimerFired()
     234{
     235    uint64_t userMediaID = m_pendingRejections[0];
     236    m_pendingRejections.remove(0);
     237
     238    denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied, emptyString());
     239    if (!m_pendingRejections.isEmpty())
     240        scheduleNextRejection();
     241}
     242
     243void UserMediaPermissionRequestManagerProxy::scheduleNextRejection()
     244{
     245    const double mimimumDelayBeforeReplying = .25;
     246    if (!m_rejectionTimer.isActive())
     247        m_rejectionTimer.startOneShot(Seconds(mimimumDelayBeforeReplying + randomNumber()));
    224248}
    225249
     
    273297    };
    274298
     299    if (!UserMediaProcessManager::singleton().captureEnabled()) {
     300        m_pendingRejections.append(userMediaID);
     301        scheduleNextRejection();
     302        return;
     303    }
     304
    275305    auto audioConstraints = MediaConstraintsImpl::create(MediaConstraintsData(audioConstraintsData));
    276306    auto videoConstraints = MediaConstraintsImpl::create(MediaConstraintsData(videoConstraintsData));
  • trunk/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h

    r216183 r216197  
    1818 */
    1919
    20 #ifndef UserMediaPermissionRequestManagerProxy_h
    21 #define UserMediaPermissionRequestManagerProxy_h
     20#pragma once
    2221
    2322#include "UserMediaPermissionCheckProxy.h"
    2423#include "UserMediaPermissionRequestProxy.h"
    2524#include <WebCore/SecurityOrigin.h>
     25#include <WebCore/Timer.h>
    2626#include <WebCore/UserMediaRequest.h>
    2727#include <wtf/HashMap.h>
     28#include <wtf/Seconds.h>
    2829
    2930namespace WebCore {
     
    5859    WebPageProxy& page() const { return m_page; }
    5960
    60     void invalidateRequests();
     61    void invalidatePendingRequests();
    6162
    6263    void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, const WebCore::MediaConstraintsData& audioConstraintsData, const WebCore::MediaConstraintsData& videoConstraintsData);
     
    7071    void didCompleteUserMediaPermissionCheck(uint64_t, const String&, bool allow);
    7172
     73    void stopCapture();
     74    void scheduleNextRejection();
     75    void rejectionTimerFired();
    7276    void clearCachedState();
    7377
     
    8690
    8791    WebPageProxy& m_page;
     92
     93    WebCore::Timer m_rejectionTimer;
     94    Vector<uint64_t> m_pendingRejections;
    8895};
    8996
    9097} // namespace WebKit
    9198
    92 #endif // UserMediaPermissionRequestManagerProxy_h
  • trunk/Source/WebKit2/UIProcess/UserMediaProcessManager.cpp

    r216183 r216197  
    116116        for (auto& manager : state.value->managers()) {
    117117
    118             if (&manager->page() == &pageStartingCapture)
     118            if (&manager->page() == &pageStartingCapture) {
     119#if PLATFORM(IOS)
     120                manager->page().stopMediaCapture();
     121#endif
    119122                continue;
     123            }
    120124
    121125            manager->page().setMuted(WebCore::MediaProducer::CaptureDevicesAreMuted);
     
    231235}
    232236
     237void UserMediaProcessManager::setCaptureEnabled(bool enabled)
     238{
     239    if (enabled == m_captureEnabled)
     240        return;
     241
     242    m_captureEnabled = enabled;
     243
     244    if (enabled)
     245        return;
     246
     247    for (auto& state : stateMap()) {
     248        for (auto& manager : state.value->managers())
     249            manager->stopCapture();
     250    }
     251}
     252
    233253} // namespace WebKit
    234254
  • trunk/Source/WebKit2/UIProcess/UserMediaProcessManager.h

    r216183 r216197  
    4040    void startedCaptureSession(UserMediaPermissionRequestManagerProxy&);
    4141    void endedCaptureSession(UserMediaPermissionRequestManagerProxy&);
     42
     43    void setCaptureEnabled(bool);
     44    bool captureEnabled() const { return m_captureEnabled; }
     45
     46private:
     47    bool m_captureEnabled { true };
    4248};
    4349
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp

    r216183 r216197  
    42074207}
    42084208
     4209void WebPageProxy::setMediaCaptureEnabled(bool enabled)
     4210{
     4211    m_mediaCaptureEnabled = enabled;
     4212
     4213    if (!isValid())
     4214        return;
     4215
     4216#if ENABLE(MEDIA_STREAM)
     4217    UserMediaProcessManager::singleton().setCaptureEnabled(enabled);
     4218#endif
     4219}
     4220
     4221void WebPageProxy::stopMediaCapture()
     4222{
     4223    if (!isValid())
     4224        return;
     4225
     4226#if ENABLE(MEDIA_STREAM)
     4227    m_process->send(Messages::WebPage::StopMediaCapture(), m_pageID);
     4228#endif
     4229}
     4230
    42094231#if ENABLE(MEDIA_SESSION)
    42104232void WebPageProxy::handleMediaEvent(MediaEventType eventType)
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.h

    r216183 r216197  
    980980    void setMayStartMediaWhenInWindow(bool);
    981981    bool mayStartMediaWhenInWindow() const { return m_mayStartMediaWhenInWindow; }
    982        
     982    void setMediaCaptureEnabled(bool);
     983    bool mediaCaptureEnabled() const { return m_mediaCaptureEnabled; }
     984    void stopMediaCapture();
     985
    983986#if ENABLE(MEDIA_SESSION)
    984987    bool hasMediaSessionWithActiveMediaElements() const { return m_hasMediaSessionWithActiveMediaElements; }
     
    19361939    WebCore::MediaProducer::MutedStateFlags m_mutedState { WebCore::MediaProducer::NoneMuted };
    19371940    bool m_mayStartMediaWhenInWindow;
     1941    bool m_mediaCaptureEnabled { true };
    19381942
    19391943    bool m_waitingForDidUpdateActivityState;
  • trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp

    r216183 r216197  
    5757}
    5858
     59void UserMediaPermissionRequestManager::cancelPendingRequests()
     60{
     61    for (auto& request : m_idToUserMediaRequestMap.values())
     62        cancelUserMediaRequest(*request);
     63
     64    for (auto& request : m_idToMediaDevicesEnumerationRequestMap.values())
     65        cancelMediaDevicesEnumeration(*request);
     66}
     67
    5968void UserMediaPermissionRequestManager::startUserMediaRequest(UserMediaRequest& request)
    6069{
     
    105114    if (!requestID)
    106115        return;
     116
     117    request.deny(UserMediaRequest::OtherFailure, emptyString());
    107118    m_idToUserMediaRequestMap.remove(requestID);
    108119    removeMediaRequestFromMaps(request);
     
    191202    if (!requestID)
    192203        return;
     204    request.setDeviceInfo(Vector<CaptureDevice>(), emptyString(), false);
    193205    m_idToMediaDevicesEnumerationRequestMap.remove(requestID);
    194206}
  • trunk/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.h

    r216183 r216197  
    5656    void revokeUserMediaDeviceSandboxExtensions(const Vector<String>&);
    5757
     58    void cancelPendingRequests();
     59
    5860private:
    5961    void sendUserMediaRequest(WebCore::UserMediaRequest&);
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r216183 r216197  
    45574557}
    45584558
     4559void WebPage::stopMediaCapture()
     4560{
     4561#if ENABLE(MEDIA_STREAM)
     4562    m_page->stopMediaCapture();
     4563#endif
     4564}
     4565
    45594566#if ENABLE(MEDIA_SESSION)
    45604567void WebPage::handleMediaEvent(uint32_t eventType)
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h

    r216183 r216197  
    766766    void setMuted(WebCore::MediaProducer::MutedStateFlags);
    767767    void setMayStartMediaWhenInWindow(bool);
     768    void stopMediaCapture();
    768769
    769770#if ENABLE(MEDIA_SESSION)
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in

    r216183 r216197  
    339339    SetMuted(WebCore::MediaProducer::MutedStateFlags muted)
    340340    SetMayStartMediaWhenInWindow(bool mayStartMedia)
     341    StopMediaCapture()
    341342
    342343#if ENABLE(MEDIA_SESSION)
  • trunk/Tools/ChangeLog

    r216193 r216197  
     12017-05-04  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [MediaStream] Allow host application to enable/disable media capture
     4        https://bugs.webkit.org/show_bug.cgi?id=171292
     5        <rdar://problem/31821492>
     6
     7        Reviewed by Jer Noble.
     8
     9        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     10        * TestWebKitAPI/Tests/WebKit2Cocoa/UserMediaDisabled.mm: Added.
     11        (-[UserMediaMessageHandler userContentController:didReceiveScriptMessage:]):
     12        (-[UserMediaUIDelegate _webView:requestUserMediaAuthorizationForDevices:url:mainFrameURL:decisionHandler:]):
     13        (-[UserMediaUIDelegate _webView:checkUserMediaPermissionForURL:mainFrameURL:frameIdentifier:decisionHandler:]):
     14        (MediaCaptureDisabledTest::SetUp):
     15        (MediaCaptureDisabledTest::loadTestAndWaitForMessage):
     16        (TEST_F):
     17        * TestWebKitAPI/Tests/WebKit2Cocoa/disableGetUserMedia.html: Added.
     18
    1192017-05-04  Caio Lima  <ticaiolima@gmail.com>
    220
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r216183 r216197  
    2626                07492B3C1DF8B86600633DE1 /* enumerateMediaDevices.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 07492B391DF8ADA400633DE1 /* enumerateMediaDevices.html */; };
    2727                074994421EA5034B000DA44E /* getUserMedia.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 4A410F4D19AF7BEF002EBAB5 /* getUserMedia.html */; };
     28                0799C3491EBA2D7B003B7532 /* UserMediaDisabled.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07EDEFAC1EB9400C00D43292 /* UserMediaDisabled.mm */; };
     29                0799C34B1EBA3301003B7532 /* disableGetUserMedia.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 0799C34A1EBA32F4003B7532 /* disableGetUserMedia.html */; };
    2830                07C046CA1E4262A8007201E7 /* CARingBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07C046C91E42573E007201E7 /* CARingBuffer.cpp */; };
    2931                0F139E771A423A5B00F590F5 /* WeakObjCPtr.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F139E751A423A5300F590F5 /* WeakObjCPtr.mm */; };
     
    688690                                55226A2F1EBA44B900C36AD0 /* large-red-square-image.html in Copy Resources */,
    689691                                5797FE331EB15AB100B2F4A0 /* navigation-client-default-crypto.html in Copy Resources */,
     692                                0799C34B1EBA3301003B7532 /* disableGetUserMedia.html in Copy Resources */,
    690693                                074994421EA5034B000DA44E /* getUserMedia.html in Copy Resources */,
    691694                                C9BF06EF1E9C132500595E3E /* autoplay-muted-with-controls.html in Copy Resources */,
     
    880883                07492B3A1DF8AE2D00633DE1 /* EnumerateMediaDevices.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EnumerateMediaDevices.cpp; sourceTree = "<group>"; };
    881884                0766DD1F1A5AD5200023E3BB /* PendingAPIRequestURL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PendingAPIRequestURL.cpp; sourceTree = "<group>"; };
     885                0799C34A1EBA32F4003B7532 /* disableGetUserMedia.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = disableGetUserMedia.html; sourceTree = "<group>"; };
    882886                07C046C91E42573E007201E7 /* CARingBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CARingBuffer.cpp; sourceTree = "<group>"; };
     887                07EDEFAC1EB9400C00D43292 /* UserMediaDisabled.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UserMediaDisabled.mm; sourceTree = "<group>"; };
    883888                0BCD833414857CE400EA2003 /* HashMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HashMap.cpp; sourceTree = "<group>"; };
    884889                0BCD85691485C98B00EA2003 /* SetForScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SetForScope.cpp; sourceTree = "<group>"; };
     
    16721677                                A16F66B81C40E9E100BD4D24 /* Resources */,
    16731678                                7CEFA9641AC0B9E200B910FD /* _WKUserContentExtensionStore.mm */,
     1679                                07EDEFAC1EB9400C00D43292 /* UserMediaDisabled.mm */,
    16741680                                37E7DD631EA06FF2009B396D /* AdditionalReadAccessAllowedURLs.mm */,
    16751681                                37E7DD661EA071F3009B396D /* AdditionalReadAccessAllowedURLsPlugin.mm */,
     
    18971903                                A16F66B91C40EA2000BD4D24 /* ContentFiltering.html */,
    18981904                                5C2936941D5BFD1900DEAB1E /* CookieMessage.html */,
     1905                                0799C34A1EBA32F4003B7532 /* disableGetUserMedia.html */,
    18991906                                837A35F01D9A1E6400663C57 /* DownloadRequestBlobURL.html */,
    19001907                                5714ECB81CA8B58800051AC8 /* DownloadRequestOriginalURL.html */,
     
    30803087                                315231CA1EB3B3C700A22A16 /* GPUCommandQueue.mm in Sources */,
    30813088                                F4FA91811E61849B007B8C1D /* WKWebViewSelectionTests.mm in Sources */,
     3089                                0799C3491EBA2D7B003B7532 /* UserMediaDisabled.mm in Sources */,
    30823090                                93F56DA91E5F919D003EDE84 /* WKWebViewSnapshot.mm in Sources */,
    30833091                                9984FACC1CFFAF60008D198C /* WKWebViewTextInput.mm in Sources */,
Note: See TracChangeset for help on using the changeset viewer.