Changeset 213161 in webkit


Ignore:
Timestamp:
Feb 28, 2017 11:42:20 AM (7 years ago)
Author:
mrajca@apple.com
Message:

Media: notify clients when autoplayed media ends without being paused
https://bugs.webkit.org/show_bug.cgi?id=168852

Reviewed by Alex Christensen.

Source/WebCore:

Added API tests.

  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::setReadyState):

Set state accordingly if we autoplayed or if playback was prevented.

(WebCore::HTMLMediaElement::play):

Update state if playback was prevented.

(WebCore::HTMLMediaElement::playInternal):

Update state if playback began without user interaction.

(WebCore::HTMLMediaElement::pauseInternal):

Update state.

(WebCore::HTMLMediaElement::mediaPlayerTimeChanged):

If playback ends and it began without user interaction, send a DidPlayMediaWithoutInterference event.

(WebCore::HTMLMediaElement::stopWithoutDestroyingMediaPlayer): Ditto.

  • html/HTMLMediaElement.h:
  • page/AutoplayEvent.h:

Source/WebKit2:

  • UIProcess/API/C/WKPageUIClient.h:

Tools:

  • TestWebKitAPI/Tests/WebKit2/js-play-with-controls.html:
  • TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm:

(TEST): Added.

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r213149 r213161  
     12017-02-24  Matt Rajca  <mrajca@apple.com>
     2
     3        Media: notify clients when autoplayed media ends without being paused
     4        https://bugs.webkit.org/show_bug.cgi?id=168852
     5
     6        Reviewed by Alex Christensen.
     7
     8        Added API tests.
     9
     10        * html/HTMLMediaElement.cpp:
     11        (WebCore::HTMLMediaElement::setReadyState):
     12         Set state accordingly if we autoplayed or if playback was prevented.
     13        (WebCore::HTMLMediaElement::play):
     14         Update state if playback was prevented.
     15        (WebCore::HTMLMediaElement::playInternal):
     16         Update state if playback began without user interaction.
     17        (WebCore::HTMLMediaElement::pauseInternal):
     18         Update state.
     19        (WebCore::HTMLMediaElement::mediaPlayerTimeChanged):
     20         If playback ends and it began without user interaction, send a DidPlayMediaWithoutInterference event.
     21        (WebCore::HTMLMediaElement::stopWithoutDestroyingMediaPlayer): Ditto.
     22        * html/HTMLMediaElement.h:
     23        * page/AutoplayEvent.h:
     24
    1252017-02-27  Dave Hyatt  <hyatt@apple.com>
    226
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r212994 r213161  
    24172417            m_paused = false;
    24182418            invalidateCachedTime();
     2419            m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::Started;
    24192420            m_playbackStartedTime = currentMediaTime().toDouble();
    24202421            scheduleEvent(eventNames().playEvent);
    24212422            scheduleNotifyAboutPlaying();
    24222423        } else if (success.value() == MediaPlaybackDenialReason::UserGestureRequired) {
    2423             m_preventedFromPlayingWithoutUserGesture = true;
     2424            m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::Prevented;
    24242425
    24252426            if (Page* page = document().page())
     
    31053106    if (!success) {
    31063107        if (success.value() == MediaPlaybackDenialReason::UserGestureRequired) {
    3107             m_preventedFromPlayingWithoutUserGesture = true;
     3108            m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::Prevented;
    31083109
    31093110            if (Page* page = document().page())
     
    31373138    if (!success) {
    31383139        if (success.value() == MediaPlaybackDenialReason::UserGestureRequired) {
    3139             m_preventedFromPlayingWithoutUserGesture = true;
     3140            m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::Prevented;
    31403141
    31413142            if (Page* page = document().page())
     
    32083209        scheduleResolvePendingPlayPromises();
    32093210
    3210     if (ScriptController::processingUserGestureForMedia() && m_preventedFromPlayingWithoutUserGesture) {
    3211         if (Page* page = document().page())
    3212             page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidPlayMediaPreventedFromPlaying);
    3213         m_preventedFromPlayingWithoutUserGesture = false;
    3214     }
     3211    if (ScriptController::processingUserGestureForMedia()) {
     3212        if (m_playbackWithoutUserGesture == PlaybackWithoutUserGesture::Prevented) {
     3213            if (Page* page = document().page())
     3214                page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidPlayMediaPreventedFromPlaying);
     3215            m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::None;
     3216        }
     3217    } else
     3218        m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::Started;
    32153219
    32163220    m_autoplaying = false;
     
    32533257
    32543258    m_autoplaying = false;
     3259    m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::None;
    32553260
    32563261    if (!m_paused) {
     
    44024407                if (!wasSeeking)
    44034408                    addBehaviorRestrictionsOnEndIfNecessary();
     4409
     4410                if (m_playbackWithoutUserGesture == PlaybackWithoutUserGesture::Started) {
     4411                    if (Page* page = document().page())
     4412                        page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidEndMediaPlaybackWithoutUserInterference);
     4413                }
     4414                m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::None;
    44044415            }
    44054416            // If the media element has a current media controller, then report the controller state
     
    51575168    setPausedInternal(true);
    51585169    m_mediaSession->clientWillPausePlayback();
     5170
     5171    if (m_playbackWithoutUserGesture == PlaybackWithoutUserGesture::Started) {
     5172        if (Page* page = document().page())
     5173            page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidEndMediaPlaybackWithoutUserInterference);
     5174    }
     5175    m_playbackWithoutUserGesture = PlaybackWithoutUserGesture::None;
    51595176
    51605177    userCancelledLoad();
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r212314 r213161  
    975975    bool m_receivedLayoutSizeChanged : 1;
    976976    bool m_hasEverNotifiedAboutPlaying : 1;
    977     bool m_preventedFromPlayingWithoutUserGesture : 1;
    978977
    979978    bool m_hasEverHadAudio : 1;
     
    991990    bool m_haveVisibleTextTrack : 1;
    992991    bool m_processingPreferenceChange : 1;
     992
     993    enum class PlaybackWithoutUserGesture { None, Started, Prevented };
     994    PlaybackWithoutUserGesture m_playbackWithoutUserGesture;
    993995
    994996    String m_subtitleTrackLanguage;
  • trunk/Source/WebCore/page/AutoplayEvent.h

    r212982 r213161  
    3131    DidPreventMediaFromPlaying,
    3232    DidPlayMediaPreventedFromPlaying,
     33    DidEndMediaPlaybackWithoutUserInterference,
    3334};
    3435
  • trunk/Source/WebKit2/ChangeLog

    r213127 r213161  
     12017-02-24  Matt Rajca  <mrajca@apple.com>
     2
     3        Media: notify clients when autoplayed media ends without being paused
     4        https://bugs.webkit.org/show_bug.cgi?id=168852
     5
     6        Reviewed by Alex Christensen.
     7
     8        * UIProcess/API/C/WKPageUIClient.h:
     9
    1102017-02-28  Csaba Osztrogonác  <ossy@webkit.org>
    211
  • trunk/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h

    r212982 r213161  
    5252    kWKAutoplayEventDidPreventFromAutoplaying,
    5353    kWKAutoplayEventDidPlayMediaPreventedFromAutoplaying,
     54    kWKAutoplayEventDidEndMediaPlaybackWithoutUserInterference,
    5455};
    5556typedef uint32_t WKAutoplayEvent;
  • trunk/Tools/ChangeLog

    r213150 r213161  
     12017-02-24  Matt Rajca  <mrajca@apple.com>
     2
     3        Media: notify clients when autoplayed media ends without being paused
     4        https://bugs.webkit.org/show_bug.cgi?id=168852
     5
     6        Reviewed by Alex Christensen.
     7
     8        * TestWebKitAPI/Tests/WebKit2/js-play-with-controls.html:
     9        * TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm:
     10        (TEST): Added.
     11
    1122017-02-28  Jonathan Bedard  <jbedard@apple.com>
    213
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2/js-play-with-controls.html

    r211226 r213161  
    1212                document.getElementById("video").play();
    1313            }
     14
     15            function beganPlaying() {
     16                try {
     17                    window.webkit.messageHandlers.testHandler.postMessage("playing");
     18                } catch(e) { }
     19            }
     20
     21            function endedPlaying() {
     22                try {
     23                    window.webkit.messageHandlers.testHandler.postMessage("ended");
     24                } catch(e) { }
     25            }
    1426        </script>
    1527    </head>
    1628    <body onload="pageLoaded()">
    1729        <button onclick="play()">Play</button>
    18         <video id="video" src="test.mp4" />
     30        <video id="video" onplaying=beganPlaying() onended=endedPlaying() src="test.mp4" />
    1931    </body>
    2032</html>
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm

    r212982 r213161  
    317317    ASSERT_TRUE(receivedAutoplayEvent == std::nullopt);
    318318}
    319 #endif
    320 
    321 #endif
     319
     320TEST(WebKit2, WebsitePoliciesPlayingWithoutInterference)
     321{
     322    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     323    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 336, 276) configuration:configuration.get()]);
     324
     325    auto delegate = adoptNS([[AutoplayPoliciesDelegate alloc] init]);
     326    [delegate setAutoplayPolicyForURL:^(NSURL *) {
     327        return _WKWebsiteAutoplayPolicyAllow;
     328    }];
     329    [webView setNavigationDelegate:delegate.get()];
     330
     331    WKPageUIClientV9 uiClient;
     332    memset(&uiClient, 0, sizeof(uiClient));
     333
     334    uiClient.base.version = 9;
     335    uiClient.handleAutoplayEvent = handleAutoplayEvent;
     336
     337    WKPageSetPageUIClient([webView _pageForTesting], &uiClient.base);
     338
     339    receivedAutoplayEvent = std::nullopt;
     340    NSURLRequest *jsPlayRequest = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"js-play-with-controls" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
     341    [webView loadRequest:jsPlayRequest];
     342    [webView waitForMessage:@"playing"];
     343
     344    ASSERT_TRUE(receivedAutoplayEvent == std::nullopt);
     345
     346    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
     347    runUntilReceivesAutoplayEvent(kWKAutoplayEventDidEndMediaPlaybackWithoutUserInterference);
     348
     349    receivedAutoplayEvent = std::nullopt;
     350    [webView loadRequest:jsPlayRequest];
     351    [webView waitForMessage:@"ended"];
     352    runUntilReceivesAutoplayEvent(kWKAutoplayEventDidEndMediaPlaybackWithoutUserInterference);
     353}
     354#endif
     355
     356#endif
Note: See TracChangeset for help on using the changeset viewer.