Title: [202100] trunk
Revision
202100
Author
[email protected]
Date
2016-06-15 12:32:50 -0700 (Wed, 15 Jun 2016)

Log Message

[iOS] Make HTMLMediaElement.muted mutable
https://bugs.webkit.org/show_bug.cgi?id=158787
<rdar://problem/24452567>

Reviewed by Dean Jackson.

Source/WebCore:

Tests: media/audio-playback-restriction-removed-muted.html
       media/audio-playback-restriction-removed-track-enabled.html

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::audioTrackEnabledChanged): Remove most behavior restrictions if
  the track state was changed as a result of a user gesture.
(WebCore::HTMLMediaElement::setMuted): Ditto.
(WebCore::HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture): Add mask
  parameter so caller can choose which restrictions are removed.
* html/HTMLMediaElement.h:

* html/MediaElementSession.cpp:
(WebCore::restrictionName): Drive-by fix: remove duplicate label.
* html/MediaElementSession.h:

* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayer): Set muted on AVPlayer if setMuted
  was called before the player was created.
(WebCore::MediaPlayerPrivateAVFoundationObjC::setVolume): Drive-by fix: return early if there
  is no AVPlayer, not if we won't have metadata yet.
(WebCore::MediaPlayerPrivateAVFoundationObjC::setMuted): New.

LayoutTests:

* media/audio-playback-restriction-removed-muted-expected.txt: Added.
* media/audio-playback-restriction-removed-muted.html: Added.
* media/audio-playback-restriction-removed-track-enabled-expected.txt: Added.
* media/audio-playback-restriction-removed-track-enabled.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (202099 => 202100)


--- trunk/LayoutTests/ChangeLog	2016-06-15 19:30:23 UTC (rev 202099)
+++ trunk/LayoutTests/ChangeLog	2016-06-15 19:32:50 UTC (rev 202100)
@@ -1,3 +1,16 @@
+2016-06-15  Eric Carlson  <[email protected]>
+
+        [iOS] Make HTMLMediaElement.muted mutable
+        https://bugs.webkit.org/show_bug.cgi?id=158787
+        <rdar://problem/24452567>
+
+        Reviewed by Dean Jackson.
+
+        * media/audio-playback-restriction-removed-muted-expected.txt: Added.
+        * media/audio-playback-restriction-removed-muted.html: Added.
+        * media/audio-playback-restriction-removed-track-enabled-expected.txt: Added.
+        * media/audio-playback-restriction-removed-track-enabled.html: Added.
+
 2016-06-15  Simon Fraser  <[email protected]>
 
         fast/events/ios tests are marked as flakey, but really just fail in OpenSource and WK1

Added: trunk/LayoutTests/media/audio-playback-restriction-removed-muted-expected.txt (0 => 202100)


--- trunk/LayoutTests/media/audio-playback-restriction-removed-muted-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/media/audio-playback-restriction-removed-muted-expected.txt	2016-06-15 19:32:50 UTC (rev 202100)
@@ -0,0 +1,11 @@
+Test that when RequireUserGestureForAudioRateChange is set, setting muted with a user gesture clears the restriction.
+
+
+RUN(internals.setMediaElementRestrictions(video, "RequireUserGestureForAudioRateChange"))
+RUN(video.src = "" "content/test"))
+EVENT(canplaythrough)
+RUN(video.play())
+EVENT(playing)
+RUN(video.muted = false)
+END OF TEST
+

Added: trunk/LayoutTests/media/audio-playback-restriction-removed-muted.html (0 => 202100)


--- trunk/LayoutTests/media/audio-playback-restriction-removed-muted.html	                        (rev 0)
+++ trunk/LayoutTests/media/audio-playback-restriction-removed-muted.html	2016-06-15 19:32:50 UTC (rev 202100)
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>audio-playback-restriction</title>
+    <script src=""
+    <script src=""
+
+    <script>
+    function runTest()
+    {
+        video = document.getElementsByTagName('audio')[0];
+
+        if (window.internals)
+            run('internals.setMediaElementRestrictions(video, "RequireUserGestureForAudioRateChange")');
+
+        waitForEventAndFail('error');
+        waitForEvent('canplaythrough', canplaythrough);
+        run('video.src = "" "content/test")');
+    }    
+
+    function canplaythrough()
+    {
+        waitForEvent('playing', playing);
+        run('video.play()');
+    }
+
+    function playing()
+    {
+        waitForEventAndFail('pause');
+        runWithKeyDown('video.muted = false');
+        setTimeout(endTest, 250);
+    }
+    </script>
+</head>
+
+<body _onload_="runTest()">
+    <p>Test that when RequireUserGestureForAudioRateChange is set, setting muted with a user gesture clears the restriction.</p>
+    <audio muted controls></audio>
+</body>
+</html>
+

Added: trunk/LayoutTests/media/audio-playback-restriction-removed-track-enabled-expected.txt (0 => 202100)


--- trunk/LayoutTests/media/audio-playback-restriction-removed-track-enabled-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/media/audio-playback-restriction-removed-track-enabled-expected.txt	2016-06-15 19:32:50 UTC (rev 202100)
@@ -0,0 +1,12 @@
+Test that when RequireUserGestureForAudioRateChange is set, enabling an audio track with a user gesture clears the restriction.
+
+
+RUN(internals.setMediaElementRestrictions(video, 'RequireUserGestureForAudioRateChange'))
+RUN(video.src = "" 'content/audio-tracks'))
+EVENT(canplaythrough)
+RUN(video.play())
+EVENT(playing)
+RUN(audioTrack.enabled = true)
+RUN(video.muted = false)
+END OF TEST
+

Added: trunk/LayoutTests/media/audio-playback-restriction-removed-track-enabled.html (0 => 202100)


--- trunk/LayoutTests/media/audio-playback-restriction-removed-track-enabled.html	                        (rev 0)
+++ trunk/LayoutTests/media/audio-playback-restriction-removed-track-enabled.html	2016-06-15 19:32:50 UTC (rev 202100)
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>audio-playback-restriction</title>
+    <script src=""
+    <script src=""
+
+    <script>
+
+    let audioTrack = null;
+    function runTest()
+    {
+        video = document.getElementsByTagName('audio')[0];
+
+        if (window.internals)
+            run(`internals.setMediaElementRestrictions(video, 'RequireUserGestureForAudioRateChange')`);
+
+        waitForEventAndFail('error');
+        waitForEvent('canplaythrough', canplaythrough);
+        run(`video.src = "" 'content/audio-tracks')`);
+    }    
+
+    function canplaythrough()
+    {
+        waitForEvent('playing', playing);
+        video.audioTracks.addEventListener('change', setMuted, true);
+        run('video.play()');
+    }
+
+    function playing()
+    {
+        for (let i = 0; i < video.audioTracks.length; i++) {
+            if (video.audioTracks[i].enabled)
+                continue;
+
+            audioTrack = video.audioTracks[i];
+            break;
+        }
+        if (audioTrack === null)
+            failTest('Failed to find disabled audio track!');
+
+        runWithKeyDown('audioTrack.enabled = true');
+    }
+    
+    function setMuted()
+    {
+        waitForEventAndFail('pause');
+        video.audioTracks.removeEventListener('change', setMuted, true);
+        run('video.muted = false');
+        setTimeout(endTest, 250);
+    }
+
+    </script>
+</head>
+
+<body _onload_='runTest()'>
+    <p>Test that when RequireUserGestureForAudioRateChange is set, enabling an audio track with a user gesture clears the restriction.</p>
+    <audio muted controls></audio>
+</body>
+</html>
+

Modified: trunk/Source/WebCore/ChangeLog (202099 => 202100)


--- trunk/Source/WebCore/ChangeLog	2016-06-15 19:30:23 UTC (rev 202099)
+++ trunk/Source/WebCore/ChangeLog	2016-06-15 19:32:50 UTC (rev 202100)
@@ -1,3 +1,34 @@
+2016-06-15  Eric Carlson  <[email protected]>
+
+        [iOS] Make HTMLMediaElement.muted mutable
+        https://bugs.webkit.org/show_bug.cgi?id=158787
+        <rdar://problem/24452567>
+
+        Reviewed by Dean Jackson.
+
+        Tests: media/audio-playback-restriction-removed-muted.html
+               media/audio-playback-restriction-removed-track-enabled.html
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::audioTrackEnabledChanged): Remove most behavior restrictions if
+          the track state was changed as a result of a user gesture.
+        (WebCore::HTMLMediaElement::setMuted): Ditto.
+        (WebCore::HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture): Add mask 
+          parameter so caller can choose which restrictions are removed.
+        * html/HTMLMediaElement.h:
+
+        * html/MediaElementSession.cpp:
+        (WebCore::restrictionName): Drive-by fix: remove duplicate label.
+        * html/MediaElementSession.h:
+
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayer): Set muted on AVPlayer if setMuted
+          was called before the player was created.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setVolume): Drive-by fix: return early if there
+          is no AVPlayer, not if we won't have metadata yet.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setMuted): New.
+
 2016-06-15  Romain Bellessort  <[email protected]>
 
         Enabling Shadow DOM for all platforms

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (202099 => 202100)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2016-06-15 19:30:23 UTC (rev 202099)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2016-06-15 19:32:50 UTC (rev 202100)
@@ -1757,6 +1757,8 @@
     ASSERT(track);
     if (m_audioTracks && m_audioTracks->contains(*track))
         m_audioTracks->scheduleChangeEvent();
+    if (ScriptController::processingUserGestureForMedia())
+        removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::AllRestrictions & ~MediaElementSession::RequireUserGestureToControlControlsManager);
 }
 
 void HTMLMediaElement::textTrackModeChanged(TextTrack* track)
@@ -3332,12 +3334,13 @@
 {
     LOG(Media, "HTMLMediaElement::setMuted(%p) - %s", this, boolString(muted));
 
-#if PLATFORM(IOS)
-    UNUSED_PARAM(muted);
-#else
     if (m_muted != muted || !m_explicitlyMuted) {
         m_muted = muted;
         m_explicitlyMuted = true;
+
+        if (ScriptController::processingUserGestureForMedia())
+            removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::AllRestrictions & ~MediaElementSession::RequireUserGestureToControlControlsManager);
+
         // Avoid recursion when the player reports volume changes.
         if (!processingMediaPlayerCallback()) {
             if (m_player) {
@@ -3360,7 +3363,6 @@
         updateMediaState(UpdateMediaState::Asynchronously);
 #endif
     }
-#endif
 
     updatePlaybackControlsManager();
 }
@@ -6401,9 +6403,10 @@
 }
 #endif
 
-void HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture()
+void HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::BehaviorRestrictions mask)
 {
-    MediaElementSession::BehaviorRestrictions restrictionsToRemove = MediaElementSession::RequireUserGestureForLoad
+    MediaElementSession::BehaviorRestrictions restrictionsToRemove = mask &
+        (MediaElementSession::RequireUserGestureForLoad
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
         | MediaElementSession::RequireUserGestureToShowPlaybackTargetPicker
         | MediaElementSession::RequireUserGestureToAutoplayToExternalDevice
@@ -6413,7 +6416,8 @@
         | MediaElementSession::RequireUserGestureForAudioRateChange
         | MediaElementSession::RequireUserGestureForFullscreen
         | MediaElementSession::InvisibleAutoplayNotPermitted
-        | MediaElementSession::RequireUserGestureToControlControlsManager;
+        | MediaElementSession::RequireUserGestureToControlControlsManager);
+
     m_mediaSession->removeBehaviorRestriction(restrictionsToRemove);
 }
 

Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (202099 => 202100)


--- trunk/Source/WebCore/html/HTMLMediaElement.h	2016-06-15 19:30:23 UTC (rev 202099)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h	2016-06-15 19:32:50 UTC (rev 202100)
@@ -721,7 +721,7 @@
 
     void changeNetworkStateFromLoadingToIdle();
 
-    void removeBehaviorsRestrictionsAfterFirstUserGesture();
+    void removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::BehaviorRestrictions mask = MediaElementSession::AllRestrictions);
 
     void updateMediaController();
     bool isBlocked() const;

Modified: trunk/Source/WebCore/html/MediaElementSession.cpp (202099 => 202100)


--- trunk/Source/WebCore/html/MediaElementSession.cpp	2016-06-15 19:30:23 UTC (rev 202099)
+++ trunk/Source/WebCore/html/MediaElementSession.cpp	2016-06-15 19:32:50 UTC (rev 202100)
@@ -82,7 +82,6 @@
     CASE(RequireUserGestureToShowPlaybackTargetPicker);
     CASE(WirelessVideoPlaybackDisabled);
 #endif
-    CASE(RequireUserGestureForAudioRateChange);
     CASE(InvisibleAutoplayNotPermitted);
     CASE(OverrideUserGestureRequirementForMainContent);
 

Modified: trunk/Source/WebCore/html/MediaElementSession.h (202099 => 202100)


--- trunk/Source/WebCore/html/MediaElementSession.h	2016-06-15 19:30:23 UTC (rev 202099)
+++ trunk/Source/WebCore/html/MediaElementSession.h	2016-06-15 19:32:50 UTC (rev 202100)
@@ -86,16 +86,15 @@
         RequirePageConsentToLoadMedia = 1 << 3,
         RequirePageConsentToResumeMedia = 1 << 4,
         RequireUserGestureForAudioRateChange = 1 << 5,
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
         RequireUserGestureToShowPlaybackTargetPicker = 1 << 6,
         WirelessVideoPlaybackDisabled =  1 << 7,
         RequireUserGestureToAutoplayToExternalDevice = 1 << 8,
-#endif
         MetadataPreloadingNotPermitted = 1 << 9,
         AutoPreloadingNotPermitted = 1 << 10,
         InvisibleAutoplayNotPermitted = 1 << 11,
         OverrideUserGestureRequirementForMainContent = 1 << 12,
         RequireUserGestureToControlControlsManager = 1 << 13,
+        AllRestrictions = ~NoRestrictions,
     };
     typedef unsigned BehaviorRestrictions;
 

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h (202099 => 202100)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h	2016-06-15 19:30:23 UTC (rev 202099)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h	2016-06-15 19:32:50 UTC (rev 202100)
@@ -176,6 +176,8 @@
     void platformPause() override;
     MediaTime currentMediaTime() const override;
     void setVolume(float) override;
+    bool supportsMuting() const override { return true; }
+    void setMuted(bool) override;
     void setClosedCaptionsVisible(bool) override;
     void paint(GraphicsContext&, const FloatRect&) override;
     void paintCurrentFrameInContext(GraphicsContext&, const FloatRect&) override;
@@ -424,6 +426,7 @@
     bool m_haveBeenAskedToCreateLayer;
     bool m_cachedCanPlayFastForward;
     bool m_cachedCanPlayFastReverse;
+    bool m_muted { false };
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     mutable bool m_allowsWirelessVideoPlayback;
     bool m_shouldPlayToPlaybackTarget { false };

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm (202099 => 202100)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2016-06-15 19:30:23 UTC (rev 202099)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2016-06-15 19:32:50 UTC (rev 202100)
@@ -1058,6 +1058,12 @@
     }
 #endif
 
+    if (m_muted) {
+        // Clear m_muted so setMuted doesn't return without doing anything.
+        m_muted = false;
+        [m_avPlayer.get() setMuted:m_muted];
+    }
+
     if (player()->client().mediaPlayerIsVideo())
         createAVPlayerLayer();
 
@@ -1395,13 +1401,28 @@
     UNUSED_PARAM(volume);
     return;
 #else
-    if (!metaDataAvailable())
+    if (!m_avPlayer)
         return;
 
     [m_avPlayer.get() setVolume:volume];
 #endif
 }
 
+void MediaPlayerPrivateAVFoundationObjC::setMuted(bool muted)
+{
+    if (m_muted == muted)
+        return;
+
+    LOG(Media, "MediaPlayerPrivateAVFoundationObjC::setMuted(%p) - set to %s", this, boolString(muted));
+
+    m_muted = muted;
+
+    if (!m_avPlayer)
+        return;
+
+    [m_avPlayer.get() setMuted:m_muted];
+}
+
 void MediaPlayerPrivateAVFoundationObjC::setClosedCaptionsVisible(bool closedCaptionsVisible)
 {
     UNUSED_PARAM(closedCaptionsVisible);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to