Changeset 215771 in webkit


Ignore:
Timestamp:
Apr 25, 2017 5:02:59 PM (7 years ago)
Author:
mrajca@apple.com
Message:

Indicate presence of audio when handling autoplay events.
https://bugs.webkit.org/show_bug.cgi?id=171227

Reviewed by Alex Christensen.

Source/WebCore:

Added API tests.

  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::handleAutoplayEvent):
(WebCore::HTMLMediaElement::playInternal):
(WebCore::HTMLMediaElement::mediaPlayerTimeChanged):
(WebCore::HTMLMediaElement::stopWithoutDestroyingMediaPlayer):
(WebCore::HTMLMediaElement::userDidInterfereWithAutoplay):
(WebCore::HTMLMediaElement::setPlaybackWithoutUserGesture):

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

Source/WebKit2:

  • UIProcess/API/APIUIClient.h:

(API::UIClient::handleAutoplayEvent):

  • UIProcess/API/C/WKPage.cpp:

(WKPageSetPageUIClient):

  • UIProcess/API/C/WKPageUIClient.h:
  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::handleAutoplayEvent):

  • UIProcess/WebPageProxy.h:
  • UIProcess/WebPageProxy.messages.in:
  • WebProcess/WebCoreSupport/WebChromeClient.cpp:

(WebKit::WebChromeClient::handleAutoplayEvent):

  • WebProcess/WebCoreSupport/WebChromeClient.h:
Location:
trunk
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r215769 r215771  
     12017-04-24  Matt Rajca  <mrajca@apple.com>
     2
     3        Indicate presence of audio when handling autoplay events.
     4        https://bugs.webkit.org/show_bug.cgi?id=171227
     5
     6        Reviewed by Alex Christensen.
     7
     8        Added API tests.
     9
     10        * html/HTMLMediaElement.cpp:
     11        (WebCore::HTMLMediaElement::handleAutoplayEvent):
     12        (WebCore::HTMLMediaElement::playInternal):
     13        (WebCore::HTMLMediaElement::mediaPlayerTimeChanged):
     14        (WebCore::HTMLMediaElement::stopWithoutDestroyingMediaPlayer):
     15        (WebCore::HTMLMediaElement::userDidInterfereWithAutoplay):
     16        (WebCore::HTMLMediaElement::setPlaybackWithoutUserGesture):
     17        * html/HTMLMediaElement.h:
     18        * page/AutoplayEvent.h:
     19        * page/ChromeClient.h:
     20
    1212017-04-25  Aakash Jain  <aakash_jain@apple.com>
    222
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r215649 r215771  
    32433243    if (ScriptController::processingUserGestureForMedia()) {
    32443244        if (m_playbackWithoutUserGesture == PlaybackWithoutUserGesture::Prevented) {
    3245             if (Page* page = document().page())
    3246                 page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidPlayMediaPreventedFromPlaying);
     3245            handleAutoplayEvent(AutoplayEvent::DidPlayMediaPreventedFromPlaying);
    32473246            setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::None);
    32483247        }
     
    33843383    bool mutedStateChanged = m_muted != muted;
    33853384    if (mutedStateChanged || !m_explicitlyMuted) {
     3385        if (ScriptController::processingUserGestureForMedia()) {
     3386            removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::AllRestrictions & ~MediaElementSession::RequireUserGestureToControlControlsManager);
     3387
     3388            if (hasAudio() && muted)
     3389                userDidInterfereWithAutoplay();
     3390        }
     3391
    33863392        m_muted = muted;
    33873393        m_explicitlyMuted = true;
    3388 
    3389         if (ScriptController::processingUserGestureForMedia()) {
    3390             removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::AllRestrictions & ~MediaElementSession::RequireUserGestureToControlControlsManager);
    3391 
    3392             if (hasAudio() && m_muted)
    3393                 userDidInterfereWithAutoplay();
    3394         }
    33953394
    33963395        // Avoid recursion when the player reports volume changes.
     
    44684467                    addBehaviorRestrictionsOnEndIfNecessary();
    44694468
    4470                 if (m_playbackWithoutUserGesture == PlaybackWithoutUserGesture::Started) {
    4471                     if (Page* page = document().page())
    4472                         page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidEndMediaPlaybackWithoutUserInterference);
    4473                 }
     4469                if (m_playbackWithoutUserGesture == PlaybackWithoutUserGesture::Started)
     4470                    handleAutoplayEvent(AutoplayEvent::DidEndMediaPlaybackWithoutUserInterference);
     4471
    44744472                setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::None);
    44754473            }
     
    52315229    m_mediaSession->clientWillPausePlayback();
    52325230
    5233     if (Page* page = document().page()) {
    5234         switch (m_playbackWithoutUserGesture) {
    5235         case PlaybackWithoutUserGesture::Started:
    5236             page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidEndMediaPlaybackWithoutUserInterference);
    5237             break;
    5238         case PlaybackWithoutUserGesture::Prevented:
    5239             page->chrome().client().handleAutoplayEvent(AutoplayEvent::UserNeverPlayedMediaPreventedFromPlaying);
    5240             break;
    5241         case PlaybackWithoutUserGesture::None:
    5242             break;
    5243         }
    5244     }
     5231    switch (m_playbackWithoutUserGesture) {
     5232    case PlaybackWithoutUserGesture::Started:
     5233        handleAutoplayEvent(AutoplayEvent::DidEndMediaPlaybackWithoutUserInterference);
     5234        break;
     5235    case PlaybackWithoutUserGesture::Prevented:
     5236        handleAutoplayEvent(AutoplayEvent::UserNeverPlayedMediaPreventedFromPlaying);
     5237        break;
     5238    case PlaybackWithoutUserGesture::None:
     5239        break;
     5240    }
     5241
    52455242    setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::None);
    52465243
     
    71857182}
    71867183
     7184void HTMLMediaElement::handleAutoplayEvent(AutoplayEvent event)
     7185{
     7186    if (Page* page = document().page()) {
     7187        bool hasAudio = this->hasAudio() && !muted() && volume();
     7188        page->chrome().client().handleAutoplayEvent(event, hasAudio ? AutoplayEventFlags::HasAudio : OptionSet<AutoplayEventFlags>());
     7189    }
     7190}
     7191
    71877192void HTMLMediaElement::userDidInterfereWithAutoplay()
    71887193{
     
    71947199        return;
    71957200
    7196     if (Page* page = document().page())
    7197         page->chrome().client().handleAutoplayEvent(AutoplayEvent::UserDidInterfereWithPlayback);
    7198 
     7201    handleAutoplayEvent(AutoplayEvent::UserDidInterfereWithPlayback);
    71997202    setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::None);
    72007203}
     
    72157218
    72167219        dispatchPlayPauseEventsIfNeedsQuirks();
    7217 
    7218         if (Page* page = document().page())
    7219             page->chrome().client().handleAutoplayEvent(AutoplayEvent::DidPreventMediaFromPlaying);
     7220        handleAutoplayEvent(AutoplayEvent::DidPreventMediaFromPlaying);
    72207221
    72217222        break;
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r215649 r215771  
    2929
    3030#include "ActiveDOMObject.h"
     31#include "AutoplayEvent.h"
    3132#include "GenericEventQueue.h"
    3233#include "GenericTaskQueue.h"
     
    756757    void setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture);
    757758    void userDidInterfereWithAutoplay();
     759    void handleAutoplayEvent(AutoplayEvent);
    758760
    759761    MediaTime minTimeSeekable() const;
  • trunk/Source/WebCore/page/AutoplayEvent.h

    r213471 r215771  
    3636};
    3737
     38enum class AutoplayEventFlags {
     39    HasAudio = 1 << 0,
     40};
     41
    3842} // namespace WebCore
  • trunk/Source/WebCore/page/ChromeClient.h

    r215425 r215771  
    423423
    424424    virtual void isPlayingMediaDidChange(MediaProducer::MediaStateFlags, uint64_t) { }
    425     virtual void handleAutoplayEvent(AutoplayEvent) { }
     425    virtual void handleAutoplayEvent(AutoplayEvent, OptionSet<AutoplayEventFlags>) { }
    426426
    427427#if ENABLE(MEDIA_SESSION)
  • trunk/Source/WebKit2/ChangeLog

    r215753 r215771  
     12017-04-24  Matt Rajca  <mrajca@apple.com>
     2
     3        Indicate presence of audio when handling autoplay events.
     4        https://bugs.webkit.org/show_bug.cgi?id=171227
     5
     6        Reviewed by Alex Christensen.
     7
     8        * UIProcess/API/APIUIClient.h:
     9        (API::UIClient::handleAutoplayEvent):
     10        * UIProcess/API/C/WKPage.cpp:
     11        (WKPageSetPageUIClient):
     12        * UIProcess/API/C/WKPageUIClient.h:
     13        * UIProcess/WebPageProxy.cpp:
     14        (WebKit::WebPageProxy::handleAutoplayEvent):
     15        * UIProcess/WebPageProxy.h:
     16        * UIProcess/WebPageProxy.messages.in:
     17        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     18        (WebKit::WebChromeClient::handleAutoplayEvent):
     19        * WebProcess/WebCoreSupport/WebChromeClient.h:
     20
    1212017-04-25  Daniel Bates  <dabates@apple.com>
    222
  • trunk/Source/WebKit2/Scripts/webkit/messages.py

    r215663 r215771  
    349349    special_cases = {
    350350        'String': ['<wtf/text/WTFString.h>'],
     351        'WebCore::AutoplayEventFlags': ['<WebCore/AutoplayEvent.h>'],
    351352        'WebCore::CompositionUnderline': ['<WebCore/Editor.h>'],
    352353        'WebCore::ExceptionDetails': ['<WebCore/JSDOMExceptionHandling.h>'],
  • trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h

    r215672 r215771  
    2727
    2828#include "ArgumentCoders.h"
     29#include <WebCore/AutoplayEvent.h>
    2930#include <WebCore/CaptureDevice.h>
    3031#include <WebCore/ColorSpace.h>
     
    687688};
    688689
     690template<> struct EnumTraits<WebCore::AutoplayEvent> {
     691    using values = EnumValues<
     692        WebCore::AutoplayEvent,
     693        WebCore::AutoplayEvent::DidPreventMediaFromPlaying,
     694        WebCore::AutoplayEvent::DidPlayMediaPreventedFromPlaying,
     695        WebCore::AutoplayEvent::DidEndMediaPlaybackWithoutUserInterference,
     696        WebCore::AutoplayEvent::UserDidInterfereWithPlayback,
     697        WebCore::AutoplayEvent::UserNeverPlayedMediaPreventedFromPlaying
     698    >;
     699};
     700
    689701template<> struct EnumTraits<WebCore::ShouldSample> {
    690702    using values = EnumValues<
  • trunk/Source/WebKit2/UIProcess/API/APIUIClient.h

    r215545 r215771  
    151151    virtual void isPlayingAudioDidChange(WebKit::WebPageProxy&) { }
    152152    virtual void mediaCaptureStateDidChange(WebCore::MediaProducer::MediaStateFlags) { }
    153     virtual void handleAutoplayEvent(WebKit::WebPageProxy&, WebCore::AutoplayEvent) { }
     153    virtual void handleAutoplayEvent(WebKit::WebPageProxy&, WebCore::AutoplayEvent, OptionSet<WebCore::AutoplayEventFlags>) { }
    154154
    155155#if ENABLE(MEDIA_SESSION)
  • trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp

    r215730 r215771  
    22522252#endif
    22532253
    2254         void handleAutoplayEvent(WebPageProxy& page, WebCore::AutoplayEvent event) override
     2254        static WKAutoplayEventFlags toWKAutoplayEventFlags(OptionSet<WebCore::AutoplayEventFlags> flags)
     2255        {
     2256            WKAutoplayEventFlags wkFlags = kWKAutoplayEventFlagsNone;
     2257            if (flags.contains(WebCore::AutoplayEventFlags::HasAudio))
     2258                wkFlags |= kWKAutoplayEventFlagsHasAudio;
     2259
     2260            return wkFlags;
     2261        }
     2262
     2263        static WKAutoplayEvent toWKAutoplayEvent(WebCore::AutoplayEvent event)
     2264        {
     2265            switch (event) {
     2266            case WebCore::AutoplayEvent::DidEndMediaPlaybackWithoutUserInterference:
     2267                return kWKAutoplayEventDidEndMediaPlaybackWithoutUserInterference;
     2268            case WebCore::AutoplayEvent::DidPlayMediaPreventedFromPlaying:
     2269                return kWKAutoplayEventDidPlayMediaPreventedFromAutoplaying;
     2270            case WebCore::AutoplayEvent::DidPreventMediaFromPlaying:
     2271                return kWKAutoplayEventDidPreventFromAutoplaying;
     2272            case WebCore::AutoplayEvent::UserDidInterfereWithPlayback:
     2273                return kWKAutoplayEventUserDidInterfereWithPlayback;
     2274            case WebCore::AutoplayEvent::UserNeverPlayedMediaPreventedFromPlaying:
     2275                return kWKAutoplayEventUserNeverPlayedMediaPreventedFromPlaying;
     2276            }
     2277        }
     2278
     2279        void handleAutoplayEvent(WebPageProxy& page, WebCore::AutoplayEvent event, OptionSet<WebCore::AutoplayEventFlags> flags) override
    22552280        {
    22562281            if (!m_client.handleAutoplayEvent)
    22572282                return;
    22582283
    2259             m_client.handleAutoplayEvent(toAPI(&page), static_cast<WKAutoplayEvent>(event), m_client.base.clientInfo);
     2284            m_client.handleAutoplayEvent(toAPI(&page), toWKAutoplayEvent(event), toWKAutoplayEventFlags(flags), m_client.base.clientInfo);
    22602285        }
    22612286    };
  • trunk/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h

    r213471 r215771  
    5757};
    5858typedef uint32_t WKAutoplayEvent;
     59
     60enum {
     61    kWKAutoplayEventFlagsNone = 0,
     62    kWKAutoplayEventFlagsHasAudio = 1 << 0,
     63};
     64typedef uint32_t WKAutoplayEventFlags;
    5965
    6066WK_EXPORT WKTypeID WKPageRunBeforeUnloadConfirmPanelResultListenerGetTypeID();
     
    112118typedef void (*WKPageDidClickAutoFillButtonCallback)(WKPageRef page, WKTypeRef userData, const void *clientInfo);
    113119typedef void (*WKPageMediaSessionMetadataDidChangeCallback)(WKPageRef page, WKMediaSessionMetadataRef metadata, const void* clientInfo);
    114 typedef void (*WKHandleAutoplayEventCallback)(WKPageRef page, WKAutoplayEvent event, const void* clientInfo);
     120typedef void (*WKHandleAutoplayEventCallback)(WKPageRef page, WKAutoplayEvent event, WKAutoplayEventFlags flags, const void* clientInfo);
    115121typedef void (*WKFullscreenMayReturnToInlineCallback)(WKPageRef page, const void* clientInfo);
    116122
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp

    r215668 r215771  
    65686568#endif
    65696569
    6570 void WebPageProxy::handleAutoplayEvent(uint32_t event)
    6571 {
    6572     m_uiClient->handleAutoplayEvent(*this, static_cast<AutoplayEvent>(event));
     6570void WebPageProxy::handleAutoplayEvent(WebCore::AutoplayEvent event, OptionSet<AutoplayEventFlags> flags)
     6571{
     6572    m_uiClient->handleAutoplayEvent(*this, event, flags);
    65736573}
    65746574
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.h

    r215653 r215771  
    169169struct WindowFeatures;
    170170
     171enum class AutoplayEvent;
    171172enum class HasInsecureContent;
    172173enum class ShouldSample;
     
    10711072    bool hasActiveVideoStream() const { return m_mediaState & WebCore::MediaProducer::HasActiveVideoCaptureDevice; }
    10721073    WebCore::MediaProducer::MediaStateFlags mediaStateFlags() const { return m_mediaState; }
    1073     void handleAutoplayEvent(uint32_t);
     1074    void handleAutoplayEvent(WebCore::AutoplayEvent, OptionSet<WebCore::AutoplayEventFlags>);
    10741075
    10751076#if PLATFORM(MAC)
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in

    r215653 r215771  
    439439
    440440    IsPlayingMediaDidChange(unsigned state, uint64_t sourceElementID)
    441     HandleAutoplayEvent(uint32_t event)
     441    HandleAutoplayEvent(enum WebCore::AutoplayEvent event, OptionSet<WebCore::AutoplayEventFlags> flags)
    442442
    443443#if ENABLE(MEDIA_SESSION)
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp

    r215425 r215771  
    10891089}
    10901090
    1091 void WebChromeClient::handleAutoplayEvent(AutoplayEvent event)
    1092 {
    1093     m_page.send(Messages::WebPageProxy::HandleAutoplayEvent(static_cast<uint32_t>(event)));
     1091void WebChromeClient::handleAutoplayEvent(AutoplayEvent event, OptionSet<AutoplayEventFlags> flags)
     1092{
     1093    m_page.send(Messages::WebPageProxy::HandleAutoplayEvent(event, flags));
    10941094}
    10951095
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h

    r215425 r215771  
    298298
    299299    void isPlayingMediaDidChange(WebCore::MediaProducer::MediaStateFlags, uint64_t) final;
    300     void handleAutoplayEvent(WebCore::AutoplayEvent) final;
     300    void handleAutoplayEvent(WebCore::AutoplayEvent, OptionSet<WebCore::AutoplayEventFlags>) final;
    301301
    302302#if ENABLE(MEDIA_SESSION)
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WebsitePolicies.mm

    r215249 r215771  
    5252#if PLATFORM(MAC)
    5353static std::optional<WKAutoplayEvent> receivedAutoplayEvent;
     54static std::optional<WKAutoplayEventFlags> receivedAutoplayEventFlags;
    5455#endif
    5556
     
    281282
    282283#if PLATFORM(MAC)
    283 static void handleAutoplayEvent(WKPageRef page, WKAutoplayEvent event, const void* clientInfo)
    284 {
     284static void handleAutoplayEvent(WKPageRef page, WKAutoplayEvent event, WKAutoplayEventFlags flags, const void* clientInfo)
     285{
     286    receivedAutoplayEventFlags = flags;
    285287    receivedAutoplayEvent = event;
    286288}
     
    321323    [webView mouseUpAtPoint:playButtonClickPoint];
    322324    runUntilReceivesAutoplayEvent(kWKAutoplayEventDidPlayMediaPreventedFromAutoplaying);
     325    ASSERT_TRUE(*receivedAutoplayEventFlags & kWKAutoplayEventFlagsHasAudio);
    323326
    324327    receivedAutoplayEvent = std::nullopt;
     
    329332    [webView waitForMessage:@"loaded"];
    330333    runUntilReceivesAutoplayEvent(kWKAutoplayEventDidPreventFromAutoplaying);
     334    ASSERT_TRUE(*receivedAutoplayEventFlags & kWKAutoplayEventFlagsHasAudio);
    331335
    332336    [webView mouseDownAtPoint:playButtonClickPoint simulatePressure:NO];
    333337    [webView mouseUpAtPoint:playButtonClickPoint];
    334338    runUntilReceivesAutoplayEvent(kWKAutoplayEventDidPlayMediaPreventedFromAutoplaying);
     339    ASSERT_TRUE(*receivedAutoplayEventFlags & kWKAutoplayEventFlagsHasAudio);
    335340
    336341    receivedAutoplayEvent = std::nullopt;
     
    360365    [webView mouseUpAtPoint:playButtonClickPoint];
    361366    runUntilReceivesAutoplayEvent(kWKAutoplayEventDidPlayMediaPreventedFromAutoplaying);
     367    ASSERT_TRUE(*receivedAutoplayEventFlags & kWKAutoplayEventFlagsHasAudio);
    362368}
    363369
     
    390396    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
    391397    runUntilReceivesAutoplayEvent(kWKAutoplayEventDidEndMediaPlaybackWithoutUserInterference);
     398    ASSERT_TRUE(*receivedAutoplayEventFlags & kWKAutoplayEventFlagsHasAudio);
    392399
    393400    receivedAutoplayEvent = std::nullopt;
     
    395402    [webView waitForMessage:@"ended"];
    396403    runUntilReceivesAutoplayEvent(kWKAutoplayEventDidEndMediaPlaybackWithoutUserInterference);
     404    ASSERT_TRUE(*receivedAutoplayEventFlags & kWKAutoplayEventFlagsHasAudio);
    397405}
    398406
     
    424432    WKPageSetMuted([webView _pageForTesting], kWKMediaAudioMuted);
    425433    runUntilReceivesAutoplayEvent(kWKAutoplayEventUserDidInterfereWithPlayback);
     434    ASSERT_TRUE(*receivedAutoplayEventFlags & kWKAutoplayEventFlagsHasAudio);
    426435
    427436    receivedAutoplayEvent = std::nullopt;
     
    434443    [webView mouseUpAtPoint:muteButtonClickPoint];
    435444    runUntilReceivesAutoplayEvent(kWKAutoplayEventUserDidInterfereWithPlayback);
     445    ASSERT_TRUE(*receivedAutoplayEventFlags & kWKAutoplayEventFlagsHasAudio);
    436446
    437447    receivedAutoplayEvent = std::nullopt;
     
    444454    [webView mouseUpAtPoint:playButtonClickPoint];
    445455    runUntilReceivesAutoplayEvent(kWKAutoplayEventUserDidInterfereWithPlayback);
     456    ASSERT_TRUE(*receivedAutoplayEventFlags & kWKAutoplayEventFlagsHasAudio);
    446457}
    447458
     
    473484    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
    474485    runUntilReceivesAutoplayEvent(kWKAutoplayEventUserNeverPlayedMediaPreventedFromPlaying);
     486    ASSERT_TRUE(*receivedAutoplayEventFlags & kWKAutoplayEventFlagsHasAudio);
    475487}
    476488
Note: See TracChangeset for help on using the changeset viewer.