Diff
Modified: trunk/LayoutTests/ChangeLog (217774 => 217775)
--- trunk/LayoutTests/ChangeLog 2017-06-04 18:19:16 UTC (rev 217774)
+++ trunk/LayoutTests/ChangeLog 2017-06-04 20:56:58 UTC (rev 217775)
@@ -1,3 +1,14 @@
+2017-06-04 Eric Carlson <[email protected]>
+
+ [MediaStream] Page capture state not reported correctly
+ https://bugs.webkit.org/show_bug.cgi?id=172897
+ <rdar://problem/32493318>
+
+ Reviewed by Youenn Fablet.
+
+ * fast/mediastream/media-stream-track-muted-expected.txt: Added.
+ * fast/mediastream/media-stream-track-muted.html: Added.
+
2017-06-03 Sam Weinig <[email protected]>
Can't use Object.defineProperty() to add an item to a DOMStringMap or Storage
Added: trunk/LayoutTests/fast/mediastream/media-stream-track-muted-expected.txt (0 => 217775)
--- trunk/LayoutTests/fast/mediastream/media-stream-track-muted-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/mediastream/media-stream-track-muted-expected.txt 2017-06-04 20:56:58 UTC (rev 217775)
@@ -0,0 +1,5 @@
+
+PASS Create stream
+PASS Mute video track only
+PASS Mute audio track only
+
Added: trunk/LayoutTests/fast/mediastream/media-stream-track-muted.html (0 => 217775)
--- trunk/LayoutTests/fast/mediastream/media-stream-track-muted.html (rev 0)
+++ trunk/LayoutTests/fast/mediastream/media-stream-track-muted.html 2017-06-04 20:56:58 UTC (rev 217775)
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Mute video and audio tracks independently, make sure page state updates correctly.</title>
+ <script src=""
+ <script src=""
+ <script>
+
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+
+ function waitForPageStateChange(numberOfTries, originalState, resolve, reject)
+ {
+ let newState = internals.pageMediaState();
+ if (newState != originalState) {
+ resolve(newState);
+ return;
+ }
+
+ if (numberOfTries <= 0) {
+ reject('Page state did not change in time.');
+ return;
+ }
+
+ setTimeout(() => { waitForPageStateChange(--numberOfTries, originalState, resolve, reject); }, 10);
+ }
+
+ function testTrack(track, title)
+ {
+ promise_test((test) => {
+ return new Promise((resolve, reject) => {
+ let isVideo = track.kind == "video";
+ if (window.internals) {
+ assert_false(internals.pageMediaState().includes('HasMutedVideoCaptureDevice'));
+ assert_false(internals.pageMediaState().includes('HasMutedAudioCaptureDevice'));
+ }
+
+ track._onunmute_ = () => reject("Got 'unmute' event unexpectedly!");
+ track._onmute_ = () => {
+ new Promise((innerResolve, innerReject) => {
+ waitForPageStateChange(10, internals.pageMediaState(), innerResolve, innerReject)
+ }).then((pageMediaState) => {
+
+ track._onunmute_ = (evt) => {
+ waitForPageStateChange(10, internals.pageMediaState(), resolve, reject)
+ }
+
+ if (window.internals) {
+ assert_true(pageMediaState.includes(isVideo ? 'HasMutedVideoCaptureDevice' : 'HasMutedAudioCaptureDevice'));
+ assert_false(pageMediaState.includes(isVideo ? 'HasMutedAudioCaptureDevice' : 'HasMutedVideoCaptureDevice'));
+ assert_true(pageMediaState.includes(isVideo ? 'HasActiveAudioCaptureDevice' : 'HasActiveVideoCaptureDevice'));
+ assert_false(pageMediaState.includes(isVideo ? 'HasActiveVideoCaptureDevice' : 'HasActiveAudioCaptureDevice'));
+ internals.setMediaStreamTrackMuted(track, false)
+ }
+ })
+ }
+
+ if (window.internals)
+ internals.setMediaStreamTrackMuted(track, true);
+ setTimeout(() => reject("Muted state did not change in .5 second"), 500);
+ });
+ }, title);
+ }
+
+ promise_test((test) => {
+ return navigator.mediaDevices.getUserMedia({ video: true, audio: true})
+ .then((stream) => {
+ testTrack(stream.getVideoTracks()[0], "Mute video track only");
+ testTrack(stream.getAudioTracks()[0], "Mute audio track only");
+ });
+ }, "Create stream");
+
+
+ </script>
+</head>
+<body>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (217774 => 217775)
--- trunk/Source/WebCore/ChangeLog 2017-06-04 18:19:16 UTC (rev 217774)
+++ trunk/Source/WebCore/ChangeLog 2017-06-04 20:56:58 UTC (rev 217775)
@@ -1,3 +1,25 @@
+2017-06-04 Eric Carlson <[email protected]>
+
+ [MediaStream] Page capture state not reported correctly
+ https://bugs.webkit.org/show_bug.cgi?id=172897
+ <rdar://problem/32493318>
+
+ Reviewed by Youenn Fablet.
+
+ Test: fast/mediastream/media-stream-track-muted.html
+
+ * Modules/mediastream/MediaStream.cpp:
+ (WebCore::MediaStream::mediaState): Test for audio and video mute on the tracks.
+ (WebCore::MediaStream::characteristicsChanged): Call statusDidChange when m_mediaState
+ changes instead of m_muted, so the page is informed when just audio or video mute state
+ changes.
+ * Modules/mediastream/MediaStream.h:
+
+ * testing/Internals.cpp:
+ (WebCore::Internals::setMediaStreamTrackMuted): New.
+ * testing/Internals.h:
+ * testing/Internals.idl:
+
2017-06-03 Darin Adler <[email protected]>
Streamline handling of attributes, using references as much as possible
Modified: trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp (217774 => 217775)
--- trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp 2017-06-04 18:19:16 UTC (rev 217774)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp 2017-06-04 20:56:58 UTC (rev 217775)
@@ -341,20 +341,17 @@
if (!m_isActive)
return state;
- if (m_private->hasAudio()) {
- state |= HasAudioOrVideo;
- if (m_private->hasCaptureAudioSource()) {
- if (m_private->muted())
+ for (const auto& track : m_trackSet.values()) {
+ if (!track->isCaptureTrack() || track->ended())
+ continue;
+
+ if (track->source().type() == RealtimeMediaSource::Type::Audio) {
+ if (track->muted())
state |= HasMutedAudioCaptureDevice;
else if (m_isProducingData && m_private->isProducingData())
state |= HasActiveAudioCaptureDevice;
- }
- }
-
- if (m_private->hasVideo()) {
- state |= HasAudioOrVideo;
- if (m_private->hasCaptureVideoSource()) {
- if (m_private->muted())
+ } else {
+ if (track->muted())
state |= HasMutedVideoCaptureDevice;
else if (m_isProducingData && m_private->isProducingData())
state |= HasActiveVideoCaptureDevice;
@@ -377,9 +374,9 @@
void MediaStream::characteristicsChanged()
{
- bool muted = m_private->muted();
- if (m_isMuted != muted) {
- m_isMuted = muted;
+ MediaStateFlags state = mediaState();
+ if (m_state != state) {
+ m_state = state;
statusDidChange();
}
}
Modified: trunk/Source/WebCore/Modules/mediastream/MediaStream.h (217774 => 217775)
--- trunk/Source/WebCore/Modules/mediastream/MediaStream.h 2017-06-04 18:19:16 UTC (rev 217774)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStream.h 2017-06-04 20:56:58 UTC (rev 217775)
@@ -84,7 +84,7 @@
RefPtr<MediaStream> clone();
bool active() const { return m_isActive; }
- bool muted() const { return m_isMuted; }
+ bool muted() const { return m_private->muted(); }
MediaStreamPrivate& privateStream() { return m_private.get(); }
@@ -175,8 +175,9 @@
Vector<Observer*> m_observers;
std::unique_ptr<PlatformMediaSession> m_mediaSession;
+ MediaStateFlags m_state { IsNotPlaying };
+
bool m_isActive { false };
- bool m_isMuted { true };
bool m_isProducingData { false };
bool m_isWaitingUntilMediaCanStart { false };
};
Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp (217774 => 217775)
--- trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp 2017-06-04 18:19:16 UTC (rev 217774)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp 2017-06-04 20:56:58 UTC (rev 217775)
@@ -137,6 +137,7 @@
}
updateActiveState(notifyClientOption);
+ characteristicsChanged();
}
void MediaStreamPrivate::removeTrack(MediaStreamTrackPrivate& track, NotifyClientOption notifyClientOption)
@@ -152,6 +153,7 @@
}
updateActiveState(NotifyClientOption::Notify);
+ characteristicsChanged();
}
void MediaStreamPrivate::startProducingData()
Modified: trunk/Source/WebCore/testing/Internals.cpp (217774 => 217775)
--- trunk/Source/WebCore/testing/Internals.cpp 2017-06-04 18:19:16 UTC (rev 217774)
+++ trunk/Source/WebCore/testing/Internals.cpp 2017-06-04 20:56:58 UTC (rev 217775)
@@ -4088,6 +4088,11 @@
track.source().delaySamples(delay);
}
+void Internals::setMediaStreamTrackMuted(MediaStreamTrack& track, bool muted)
+{
+ track.source().setMuted(muted);
+}
+
#endif
} // namespace WebCore
Modified: trunk/Source/WebCore/testing/Internals.h (217774 => 217775)
--- trunk/Source/WebCore/testing/Internals.h 2017-06-04 18:19:16 UTC (rev 217774)
+++ trunk/Source/WebCore/testing/Internals.h 2017-06-04 20:56:58 UTC (rev 217775)
@@ -582,6 +582,7 @@
using TrackFramePromise = DOMPromiseDeferred<IDLInterface<ImageData>>;
void grabNextMediaStreamTrackFrame(TrackFramePromise&&);
void delayMediaStreamTrackSamples(MediaStreamTrack&, float);
+ void setMediaStreamTrackMuted(MediaStreamTrack&, bool);
#endif
private:
Modified: trunk/Source/WebCore/testing/Internals.idl (217774 => 217775)
--- trunk/Source/WebCore/testing/Internals.idl 2017-06-04 18:19:16 UTC (rev 217774)
+++ trunk/Source/WebCore/testing/Internals.idl 2017-06-04 20:56:58 UTC (rev 217775)
@@ -543,4 +543,5 @@
[Conditional=MEDIA_STREAM] readonly attribute unsigned long trackVideoSampleCount;
[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);
};