Diff
Modified: trunk/LayoutTests/ChangeLog (214975 => 214976)
--- trunk/LayoutTests/ChangeLog 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/LayoutTests/ChangeLog 2017-04-05 23:22:20 UTC (rev 214976)
@@ -1,3 +1,14 @@
+2017-04-05 Eric Carlson <[email protected]>
+
+ [MediaStream] Host application should be able to mute and unmute media streams
+ https://bugs.webkit.org/show_bug.cgi?id=170519
+ <rdar://problem/31174326>
+
+ Reviewed by Youenn Fablet.
+
+ * fast/mediastream/MediaStream-page-muted-expected.txt:
+ * fast/mediastream/MediaStream-page-muted.html:
+
2017-04-05 Javier Fernandez <[email protected]>
[css-align] Implement the place-items shorthand
Modified: trunk/LayoutTests/fast/mediastream/MediaStream-page-muted-expected.txt (214975 => 214976)
--- trunk/LayoutTests/fast/mediastream/MediaStream-page-muted-expected.txt 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/LayoutTests/fast/mediastream/MediaStream-page-muted-expected.txt 2017-04-05 23:22:20 UTC (rev 214976)
@@ -15,7 +15,10 @@
EVENT: mute
PASS muteChangedEvent.target.muted is true
-PASS window.internals.pageMediaState().includes('HasActiveAudioCaptureDevice') && window.internals.pageMediaState().includes('HasActiveVideoCaptureDevice') became false
+PASS window.internals.pageMediaState().includes(HasMutedAudioCaptureDevice) became true
+PASS window.internals.pageMediaState().includes(HasMutedVideoCaptureDevice) became true
+PASS window.internals.pageMediaState().includes(HasActiveAudioCaptureDevice) became false
+PASS window.internals.pageMediaState().includes(HasActiveVideoCaptureDevice) became false
*** Unmuting capture devices
EVENT: unmute
@@ -23,7 +26,10 @@
EVENT: unmute
PASS muteChangedEvent.target.muted is false
-PASS window.internals.pageMediaState().includes('HasActiveAudioCaptureDevice') && window.internals.pageMediaState().includes('HasActiveVideoCaptureDevice') became true
+PASS window.internals.pageMediaState().includes(HasActiveAudioCaptureDevice) became true
+PASS window.internals.pageMediaState().includes(HasActiveVideoCaptureDevice) became true
+PASS window.internals.pageMediaState().includes(HasMutedAudioCaptureDevice) became false
+PASS window.internals.pageMediaState().includes(HasMutedVideoCaptureDevice) became false
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/fast/mediastream/MediaStream-page-muted.html (214975 => 214976)
--- trunk/LayoutTests/fast/mediastream/MediaStream-page-muted.html 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/LayoutTests/fast/mediastream/MediaStream-page-muted.html 2017-04-05 23:22:20 UTC (rev 214976)
@@ -27,8 +27,37 @@
if (++eventCount == 2) {
debug("");
- let shouldBeActive = muteChangedEvent.type == "mute" ? "false" : "true";
- shouldBecomeEqual("window.internals.pageMediaState().includes('HasActiveAudioCaptureDevice') && window.internals.pageMediaState().includes('HasActiveVideoCaptureDevice')", shouldBeActive, nextStep);
+
+ let activeState = muteChangedEvent.type == "mute" ? "Muted" : "Active";
+ let inactiveState = muteChangedEvent.type == "mute" ? "Active" : "Muted";
+ let retryCount = 0;
+ let retryInterval = 100;
+ let maximumRetryCount = 20 * 1000 / retryInterval;
+ let test = () => {
+
+ if (window.internals.pageMediaState().includes(`Has${activeState}AudioCaptureDevice`)
+ && window.internals.pageMediaState().includes(`Has${activeState}VideoCaptureDevice`)
+ && !window.internals.pageMediaState().includes(`Has${inactiveState}VideoCaptureDevice`)
+ && !window.internals.pageMediaState().includes(`Has${inactiveState}VideoCaptureDevice`)) {
+
+ testPassed(`window.internals.pageMediaState().includes(Has${activeState}AudioCaptureDevice) became true`);
+ testPassed(`window.internals.pageMediaState().includes(Has${activeState}VideoCaptureDevice) became true`);
+ testPassed(`window.internals.pageMediaState().includes(Has${inactiveState}AudioCaptureDevice) became false`);
+ testPassed(`window.internals.pageMediaState().includes(Has${inactiveState}VideoCaptureDevice) became false`);
+
+ nextStep()
+ return;
+ }
+
+ if (++retryCount > maximumRetryCount) {
+ testFailed(`Page muted state failed to change after ${maximumRetryCount / 1000} seconds`);
+ return;
+ }
+
+ setTimeout(test, retryInterval);
+ }
+
+ setTimeout(test, 0);
}
}
Modified: trunk/Source/WebCore/ChangeLog (214975 => 214976)
--- trunk/Source/WebCore/ChangeLog 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/ChangeLog 2017-04-05 23:22:20 UTC (rev 214976)
@@ -1,3 +1,41 @@
+2017-04-05 Eric Carlson <[email protected]>
+
+ [MediaStream] Host application should be able to mute and unmute media streams
+ https://bugs.webkit.org/show_bug.cgi?id=170519
+ <rdar://problem/31174326>
+
+ Reviewed by Youenn Fablet.
+
+ No new tests, fast/mediastream/MediaStream-page-muted.html was updated.
+
+ * Modules/mediastream/MediaStream.cpp:
+ (WebCore::MediaStream::~MediaStream): Fix a typo.
+ (WebCore::MediaStream::pageMutedStateDidChange): Don't store muted state, let the private
+ stream store it.
+ (WebCore::MediaStream::mediaState): Deal with new muted state flags.
+ * Modules/mediastream/MediaStream.h:
+
+ * dom/Document.cpp:
+ (WebCore::Document::prepareForDestruction): Clear media state before the frame is cleared.
+
+ * page/MediaProducer.h: Add muted flags.
+
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
+ (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::checkSelectedVideoTrack): The display layer
+ should not be visible when the video track is muted.
+
+ * platform/mediastream/MediaStreamPrivate.cpp:
+ (WebCore::MediaStreamPrivate::addTrack): Mute the new track if necessary.
+ (WebCore::MediaStreamPrivate::startProducingData): Do nothing when muted.
+ (WebCore::MediaStreamPrivate::setExternallyMuted): New, mute/unmute tracks.
+ * platform/mediastream/MediaStreamPrivate.h:
+
+ * platform/mediastream/RealtimeMediaSource.cpp:
+ (WebCore::RealtimeMediaSource::setMuted): Start/stop producing data.
+
+ * testing/Internals.cpp:
+ (WebCore::Internals::pageMediaState): Support new media stream muted flags.
+
2017-04-05 Andreas Kling <[email protected]>
Make inactive web processes behave as though under memory pressure.
Modified: trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp (214975 => 214976)
--- trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp 2017-04-05 23:22:20 UTC (rev 214976)
@@ -104,7 +104,7 @@
MediaStream::~MediaStream()
{
- // Set isActive to false immediately so an callbacks triggered by shutting down, e.g.
+ // Set isActive to false immediately so any callbacks triggered by shutting down, e.g.
// mediaState(), are short circuited.
m_isActive = false;
MediaStreamRegistry::shared().unregisterStream(*this);
@@ -300,15 +300,7 @@
if (!document)
return;
- bool pageMuted = document->page()->isMediaCaptureMuted();
- if (m_externallyMuted == pageMuted)
- return;
-
- m_externallyMuted = pageMuted;
- if (pageMuted)
- stopProducingData();
- else
- startProducingData();
+ m_private->setMuted(document->page()->isMediaCaptureMuted());
}
MediaProducer::MediaStateFlags MediaStream::mediaState() const
@@ -320,14 +312,22 @@
if (m_private->hasAudio()) {
state |= HasAudioOrVideo;
- if (m_private->hasCaptureAudioSource() && m_private->isProducingData())
- state |= HasActiveAudioCaptureDevice;
+ if (m_private->hasCaptureAudioSource()) {
+ if (m_private->isProducingData())
+ state |= HasActiveAudioCaptureDevice;
+ else if (m_private->muted())
+ state |= HasMutedAudioCaptureDevice;
+ }
}
if (m_private->hasVideo()) {
state |= HasAudioOrVideo;
- if (m_private->hasCaptureVideoSource() && m_private->isProducingData())
- state |= HasActiveVideoCaptureDevice;
+ if (m_private->hasCaptureVideoSource()) {
+ if (m_private->isProducingData())
+ state |= HasActiveVideoCaptureDevice;
+ else if (m_private->muted())
+ state |= HasMutedVideoCaptureDevice;
+ }
}
return state;
Modified: trunk/Source/WebCore/Modules/mediastream/MediaStream.h (214975 => 214976)
--- trunk/Source/WebCore/Modules/mediastream/MediaStream.h 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStream.h 2017-04-05 23:22:20 UTC (rev 214976)
@@ -157,7 +157,6 @@
bool m_isActive { false };
bool m_isMuted { true };
- bool m_externallyMuted { false };
bool m_isWaitingUntilMediaCanStart { false };
};
Modified: trunk/Source/WebCore/dom/Document.cpp (214975 => 214976)
--- trunk/Source/WebCore/dom/Document.cpp 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/dom/Document.cpp 2017-04-05 23:22:20 UTC (rev 214976)
@@ -2267,6 +2267,11 @@
m_cachedResourceLoader->stopUnusedPreloadsTimer();
+ if (page() && m_mediaState != MediaProducer::IsNotPlaying) {
+ m_mediaState = MediaProducer::IsNotPlaying;
+ page()->updateIsPlayingMedia(HTMLMediaElementInvalidID);
+ }
+
detachFromFrame();
m_hasPreparedForDestruction = true;
Modified: trunk/Source/WebCore/page/MediaProducer.h (214975 => 214976)
--- trunk/Source/WebCore/page/MediaProducer.h 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/page/MediaProducer.h 2017-04-05 23:22:20 UTC (rev 214976)
@@ -44,6 +44,8 @@
HasAudioOrVideo = 1 << 10,
HasActiveAudioCaptureDevice = 1 << 11,
HasActiveVideoCaptureDevice = 1 << 12,
+ HasMutedAudioCaptureDevice = 1 << 13,
+ HasMutedVideoCaptureDevice = 1 << 14,
};
typedef unsigned MediaStateFlags;
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm (214975 => 214976)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm 2017-04-05 23:22:20 UTC (rev 214976)
@@ -950,7 +950,7 @@
if (oldVideoTrack != m_activeVideoTrack)
m_imagePainter.reset();
ensureLayers();
- m_sampleBufferDisplayLayer.get().hidden = hideVideoLayer;
+ m_sampleBufferDisplayLayer.get().hidden = hideVideoLayer || m_displayMode < PausedImage;
m_pendingSelectedTrackCheck = false;
updateDisplayMode();
});
Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp (214975 => 214976)
--- trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp 2017-04-05 23:22:20 UTC (rev 214976)
@@ -134,6 +134,9 @@
if (m_trackSet.contains(track->id()))
return;
+ if (m_muted)
+ track->stopProducingData();
+
track->addObserver(*this);
m_trackSet.add(track->id(), track);
@@ -162,6 +165,9 @@
void MediaStreamPrivate::startProducingData()
{
+ if (m_muted)
+ return;
+
for (auto& track : m_trackSet.values())
track->startProducingData();
}
@@ -181,6 +187,18 @@
return false;
}
+void MediaStreamPrivate::setMuted(bool muted)
+{
+ if (m_muted == muted)
+ return;
+
+ m_muted = muted;
+ for (auto& track : m_trackSet.values()) {
+ if (track->isCaptureTrack())
+ track->setMuted(muted);
+ }
+}
+
bool MediaStreamPrivate::hasVideo() const
{
for (auto& track : m_trackSet.values()) {
Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.h (214975 => 214976)
--- trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.h 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.h 2017-04-05 23:22:20 UTC (rev 214976)
@@ -95,6 +95,8 @@
bool hasVideo() const;
bool hasAudio() const;
+
+ void setMuted(bool);
bool muted() const;
bool hasCaptureVideoSource() const;
@@ -134,6 +136,7 @@
MediaStreamTrackPrivate* m_activeVideoTrack { nullptr };
HashMap<String, RefPtr<MediaStreamTrackPrivate>> m_trackSet;
bool m_isActive { false };
+ bool m_muted { false };
};
typedef Vector<RefPtr<MediaStreamPrivate>> MediaStreamPrivateVector;
Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp (214975 => 214976)
--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp 2017-04-05 23:22:20 UTC (rev 214976)
@@ -91,6 +91,13 @@
if (stopped())
return;
+ if (muted) {
+ // FIXME: We need to figure out how to guarantee that at least one black video frame is
+ // emitted after being muted.
+ stopProducingData();
+ } else
+ startProducingData();
+
for (auto& observer : m_observers)
observer->sourceMutedChanged();
}
Modified: trunk/Source/WebCore/testing/Internals.cpp (214975 => 214976)
--- trunk/Source/WebCore/testing/Internals.cpp 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/testing/Internals.cpp 2017-04-05 23:22:20 UTC (rev 214976)
@@ -3523,6 +3523,10 @@
string.append("HasActiveAudioCaptureDevice,");
if (state & MediaProducer::HasActiveVideoCaptureDevice)
string.append("HasActiveVideoCaptureDevice,");
+ if (state & MediaProducer::HasMutedAudioCaptureDevice)
+ string.append("HasMutedAudioCaptureDevice,");
+ if (state & MediaProducer::HasMutedVideoCaptureDevice)
+ string.append("HasMutedVideoCaptureDevice,");
if (string.isEmpty())
string.append("IsNotPlaying");
Modified: trunk/Source/WebKit2/ChangeLog (214975 => 214976)
--- trunk/Source/WebKit2/ChangeLog 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebKit2/ChangeLog 2017-04-05 23:22:20 UTC (rev 214976)
@@ -1,3 +1,17 @@
+2017-04-05 Eric Carlson <[email protected]>
+
+ [MediaStream] Host application should be able to mute and unmute media streams
+ https://bugs.webkit.org/show_bug.cgi?id=170519
+ <rdar://problem/31174326>
+
+ Reviewed by Youenn Fablet.
+
+ * UIProcess/API/C/WKPage.cpp:
+ (WKPageGetMediaState): Support new media stream state flags.
+ * UIProcess/API/C/WKPagePrivate.h:
+ * UIProcess/API/Cocoa/WKWebViewPrivate.h: Ditto.
+ * UIProcess/Cocoa/UIDelegate.mm: Ditto.
+
2017-04-05 Brady Eidson <[email protected]>
Refactor so WebsiteDataStores always have a StorageManager.
Modified: trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp (214975 => 214976)
--- trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp 2017-04-05 23:22:20 UTC (rev 214976)
@@ -2813,6 +2813,10 @@
state |= kWKMediaHasActiveAudioCaptureDevice;
if (coreState & WebCore::MediaProducer::HasActiveVideoCaptureDevice)
state |= kWKMediaHasActiveVideoCaptureDevice;
+ if (coreState & WebCore::MediaProducer::HasMutedAudioCaptureDevice)
+ state |= kWKMediaHasMutedAudioCaptureDevice;
+ if (coreState & WebCore::MediaProducer::HasMutedVideoCaptureDevice)
+ state |= kWKMediaHasMutedVideoCaptureDevice;
return state;
}
Modified: trunk/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h (214975 => 214976)
--- trunk/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h 2017-04-05 23:22:20 UTC (rev 214976)
@@ -137,6 +137,8 @@
kWKMediaIsPlayingVideo = 1 << 1,
kWKMediaHasActiveAudioCaptureDevice = 1 << 2,
kWKMediaHasActiveVideoCaptureDevice = 1 << 3,
+ kWKMediaHasMutedAudioCaptureDevice = 1 << 4,
+ kWKMediaHasMutedVideoCaptureDevice = 1 << 5,
};
typedef uint32_t WKMediaState;
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h (214975 => 214976)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h 2017-04-05 23:22:20 UTC (rev 214976)
@@ -41,8 +41,10 @@
typedef NS_OPTIONS(NSInteger, _WKMediaCaptureState) {
_WKMediaCaptureStateNone = 0,
- _WKMediaCaptureStateMicrophone = 1 << 0,
- _WKMediaCaptureStateCamera = 1 << 1,
+ _WKMediaCaptureStateActiveMicrophone = 1 << 0,
+ _WKMediaCaptureStateActiveCamera = 1 << 1,
+ _WKMediaCaptureStateMutedMicrophone = 1 << 2,
+ _WKMediaCaptureStateMutedCamera = 1 << 3,
} WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
#if !TARGET_OS_IPHONE
Modified: trunk/Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm (214975 => 214976)
--- trunk/Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm 2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm 2017-04-05 23:22:20 UTC (rev 214976)
@@ -443,9 +443,13 @@
_WKMediaCaptureState mediaCaptureState = _WKMediaCaptureStateNone;
if (state & WebCore::MediaProducer::HasActiveAudioCaptureDevice)
- mediaCaptureState |= _WKMediaCaptureStateMicrophone;
+ mediaCaptureState |= _WKMediaCaptureStateActiveMicrophone;
if (state & WebCore::MediaProducer::HasActiveVideoCaptureDevice)
- mediaCaptureState |= _WKMediaCaptureStateCamera;
+ mediaCaptureState |= _WKMediaCaptureStateActiveCamera;
+ if (state & WebCore::MediaProducer::HasActiveAudioCaptureDevice)
+ mediaCaptureState |= _WKMediaCaptureStateMutedMicrophone;
+ if (state & WebCore::MediaProducer::HasMutedVideoCaptureDevice)
+ mediaCaptureState |= _WKMediaCaptureStateMutedCamera;
[(id <WKUIDelegatePrivate>)delegate _webView:webView mediaCaptureStateDidChange:mediaCaptureState];
}