Add experimental setting to allow document gesture interaction to fulfill media playb...
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 May 2017 22:46:13 +0000 (22:46 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 May 2017 22:46:13 +0000 (22:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=172131

Reviewed by Eric Carlson.

Source/WebCore:

Test: media/restricted-audio-playback-with-document-gesture.html

Move all calls to ScriptController::processingUserGestureForMedia() to the new Document equivalent. In Document,
if the new setting is enabled, return true from processingUserGestureForMedia() if the top-level document has had
a user gesture interaction.

* Modules/mediastream/MediaStream.cpp:
(WebCore::MediaStream::processingUserGestureForMedia):
* Modules/mediastream/MediaStream.h:
* Modules/webaudio/AudioContext.cpp:
(WebCore::AudioContext::processingUserGestureForMedia):
(WebCore::AudioContext::willBeginPlayback):
(WebCore::AudioContext::willPausePlayback):
* Modules/webaudio/AudioContext.h:
* dom/Document.cpp:
(WebCore::Document::processingUserGestureForMedia):
* dom/Document.h:
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::load):
(WebCore::HTMLMediaElement::audioTrackEnabledChanged):
(WebCore::HTMLMediaElement::seekWithTolerance):
(WebCore::HTMLMediaElement::play):
(WebCore::HTMLMediaElement::playInternal):
(WebCore::HTMLMediaElement::pause):
(WebCore::HTMLMediaElement::pauseInternal):
(WebCore::HTMLMediaElement::setMuted):
(WebCore::HTMLMediaElement::webkitShowPlaybackTargetPicker):
(WebCore::HTMLMediaElement::processingUserGestureForMedia):
* html/HTMLMediaElement.h:
* html/MediaElementSession.cpp:
(WebCore::MediaElementSession::playbackPermitted):
(WebCore::MediaElementSession::dataLoadingPermitted):
(WebCore::MediaElementSession::fullscreenPermitted):
(WebCore::MediaElementSession::canShowControlsManager):
(WebCore::MediaElementSession::showPlaybackTargetPicker):
* page/Settings.in:
* platform/audio/PlatformMediaSession.h:

Source/WebKit/mac:

* WebView/WebPreferenceKeysPrivate.h:
* WebView/WebPreferences.mm:
(+[WebPreferences initialize]):
(-[WebPreferences mediaUserGestureInheritsFromDocument]):
(-[WebPreferences setMediaUserGestureInheritsFromDocument:]):
* WebView/WebPreferencesPrivate.h:

Source/WebKit2:

* Shared/WebPreferencesDefinitions.h:
* UIProcess/API/C/WKPreferences.cpp:
(WKPreferencesSetMediaUserGestureInheritsFromDocument):
(WKPreferencesGetMediaUserGestureInheritsFromDocument):
* UIProcess/API/C/WKPreferencesRefPrivate.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::updatePreferences):

LayoutTests:

* media/restricted-audio-playback-with-document-gesture-expected.txt: Added.
* media/restricted-audio-playback-with-document-gesture.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@216886 268f45cc-cd09-0410-ab3c-d52691b4dbfc

24 files changed:
LayoutTests/ChangeLog
LayoutTests/media/restricted-audio-playback-with-document-gesture-expected.txt [new file with mode: 0644]
LayoutTests/media/restricted-audio-playback-with-document-gesture.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/MediaStream.cpp
Source/WebCore/Modules/mediastream/MediaStream.h
Source/WebCore/Modules/webaudio/AudioContext.cpp
Source/WebCore/Modules/webaudio/AudioContext.h
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/MediaElementSession.cpp
Source/WebCore/page/Settings.in
Source/WebCore/platform/audio/PlatformMediaSession.h
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebPreferenceKeysPrivate.h
Source/WebKit/mac/WebView/WebPreferences.mm
Source/WebKit/mac/WebView/WebPreferencesPrivate.h
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/WebPreferencesDefinitions.h
Source/WebKit2/UIProcess/API/C/WKPreferences.cpp
Source/WebKit2/UIProcess/API/C/WKPreferencesRefPrivate.h
Source/WebKit2/WebProcess/WebPage/WebPage.cpp

index 18289d3..2bdb114 100644 (file)
@@ -1,3 +1,13 @@
+2017-05-15  Jer Noble  <jer.noble@apple.com>
+
+        Add experimental setting to allow document gesture interaction to fulfill media playback gesture requirement
+        https://bugs.webkit.org/show_bug.cgi?id=172131
+
+        Reviewed by Eric Carlson.
+
+        * media/restricted-audio-playback-with-document-gesture-expected.txt: Added.
+        * media/restricted-audio-playback-with-document-gesture.html: Added.
+
 2017-05-15  Per Arne Vollan  <pvollan@apple.com>
 
         LayoutTest http/tests/media/track-in-band-hls-metadata-crash.html is a flaky timeout
diff --git a/LayoutTests/media/restricted-audio-playback-with-document-gesture-expected.txt b/LayoutTests/media/restricted-audio-playback-with-document-gesture-expected.txt
new file mode 100644 (file)
index 0000000..c1c12d8
--- /dev/null
@@ -0,0 +1,12 @@
+Test that, when RequireUserGestureForAudioRateChange is set along with MediaUserGestureInheritsForDocument, a user gesture in the document will allow future media playback requests to succeed.
+
+
+RUN(internals.setMediaElementRestrictions(mediaElement, "RequireUserGestureForAudioRateChange"))
+RUN(internals.settings.setMediaUserGestureInheritsFromDocument(true))
+Running with keyDown.
+RUN(mediaElement.src = findMediaFile('audio', 'content/test'))
+EVENT(canplaythrough)
+RUN(mediaElement.play())
+EXPECTED (mediaElement.paused == 'false') OK
+END OF TEST
+
diff --git a/LayoutTests/media/restricted-audio-playback-with-document-gesture.html b/LayoutTests/media/restricted-audio-playback-with-document-gesture.html
new file mode 100644 (file)
index 0000000..7478f80
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>restricted-audio-playback-with-document-gesture</title>
+    <script src=media-file.js></script>
+    <script src=video-test.js></script>
+
+    <script>
+    function runTest()
+    {
+        mediaElement = document.getElementsByTagName('audio')[0];
+
+        if (window.internals) {
+            run('internals.setMediaElementRestrictions(mediaElement, "RequireUserGestureForAudioRateChange")');
+            run('internals.settings.setMediaUserGestureInheritsFromDocument(true)');
+        }
+
+        consoleWrite('Running with keyDown.');
+        runWithKeyDown(() => {
+            run("mediaElement.src = findMediaFile('audio', 'content/test')");
+            waitForEvent('canplaythrough', canplaythrough);
+            waitForEventAndFail('error');
+        });
+    }
+
+    function canplaythrough()
+    {
+        run("mediaElement.play()");
+        testExpected('mediaElement.paused', false);
+        endTest();
+    }
+    </script>
+</head>
+
+<body onload="runTest()">
+    <p>Test that, when RequireUserGestureForAudioRateChange is set along with MediaUserGestureInheritsForDocument, a user gesture in the document will allow future media playback requests to succeed.</p>
+    <audio controls autoplay></audio>
+</body>
+</html>
+
index 5531d89..c9c28e0 100644 (file)
@@ -1,5 +1,50 @@
 2017-05-15  Jer Noble  <jer.noble@apple.com>
 
+        Add experimental setting to allow document gesture interaction to fulfill media playback gesture requirement
+        https://bugs.webkit.org/show_bug.cgi?id=172131
+
+        Reviewed by Eric Carlson.
+
+        Test: media/restricted-audio-playback-with-document-gesture.html
+
+        Move all calls to ScriptController::processingUserGestureForMedia() to the new Document equivalent. In Document,
+        if the new setting is enabled, return true from processingUserGestureForMedia() if the top-level document has had
+        a user gesture interaction.
+
+        * Modules/mediastream/MediaStream.cpp:
+        (WebCore::MediaStream::processingUserGestureForMedia):
+        * Modules/mediastream/MediaStream.h:
+        * Modules/webaudio/AudioContext.cpp:
+        (WebCore::AudioContext::processingUserGestureForMedia):
+        (WebCore::AudioContext::willBeginPlayback):
+        (WebCore::AudioContext::willPausePlayback):
+        * Modules/webaudio/AudioContext.h:
+        * dom/Document.cpp:
+        (WebCore::Document::processingUserGestureForMedia):
+        * dom/Document.h:
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::load):
+        (WebCore::HTMLMediaElement::audioTrackEnabledChanged):
+        (WebCore::HTMLMediaElement::seekWithTolerance):
+        (WebCore::HTMLMediaElement::play):
+        (WebCore::HTMLMediaElement::playInternal):
+        (WebCore::HTMLMediaElement::pause):
+        (WebCore::HTMLMediaElement::pauseInternal):
+        (WebCore::HTMLMediaElement::setMuted):
+        (WebCore::HTMLMediaElement::webkitShowPlaybackTargetPicker):
+        (WebCore::HTMLMediaElement::processingUserGestureForMedia):
+        * html/HTMLMediaElement.h:
+        * html/MediaElementSession.cpp:
+        (WebCore::MediaElementSession::playbackPermitted):
+        (WebCore::MediaElementSession::dataLoadingPermitted):
+        (WebCore::MediaElementSession::fullscreenPermitted):
+        (WebCore::MediaElementSession::canShowControlsManager):
+        (WebCore::MediaElementSession::showPlaybackTargetPicker):
+        * page/Settings.in:
+        * platform/audio/PlatformMediaSession.h:
+
+2017-05-15  Jer Noble  <jer.noble@apple.com>
+
         Only ever initialize LibWebRTCProvider's staticFactoryAndThreads() factories once.
         https://bugs.webkit.org/show_bug.cgi?id=172047
 
index 26f54e0..80be5ff 100644 (file)
@@ -506,6 +506,11 @@ bool MediaStream::canProduceAudio() const
     return !muted() && active() && m_private->hasAudio() && m_isProducingData;
 }
 
+bool MediaStream::processingUserGestureForMedia() const
+{
+    return document() ? document()->processingUserGestureForMedia() : false;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(MEDIA_STREAM)
index d22a915..ea64277 100644 (file)
@@ -153,6 +153,7 @@ private:
     String sourceApplicationIdentifier() const final;
     bool canProduceAudio() const final;
     const Document* hostingDocument() const final { return document(); }
+    bool processingUserGestureForMedia() const final;
 
     bool internalAddTrack(Ref<MediaStreamTrack>&&, StreamModifier);
     bool internalRemoveTrack(const String&, StreamModifier);
index 235299c..884d62c 100644 (file)
@@ -368,6 +368,11 @@ String AudioContext::sourceApplicationIdentifier() const
     return emptyString();
 }
 
+bool AudioContext::processingUserGestureForMedia() const
+{
+    return document() ? document()->processingUserGestureForMedia() : false;
+}
+
 void AudioContext::visibilityStateChanged()
 {
     // Do not suspend if audio is audible.
@@ -933,7 +938,7 @@ void AudioContext::nodeWillBeginPlayback()
 bool AudioContext::willBeginPlayback()
 {
     if (userGestureRequiredForAudioStart()) {
-        if (!ScriptController::processingUserGestureForMedia())
+        if (!processingUserGestureForMedia())
             return false;
         removeBehaviorRestriction(AudioContext::RequireUserGestureForAudioStartRestriction);
     }
@@ -953,7 +958,7 @@ bool AudioContext::willBeginPlayback()
 bool AudioContext::willPausePlayback()
 {
     if (userGestureRequiredForAudioStart()) {
-        if (!ScriptController::processingUserGestureForMedia())
+        if (!processingUserGestureForMedia())
             return false;
         removeBehaviorRestriction(AudioContext::RequireUserGestureForAudioStartRestriction);
     }
index 49bb137..77fa877 100644 (file)
@@ -319,6 +319,7 @@ private:
     bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const override { return false; }
     String sourceApplicationIdentifier() const override;
     bool canProduceAudio() const final { return true; }
+    bool processingUserGestureForMedia() const final;
 
     void visibilityStateChanged() final;
 
index 1fdd203..ec40924 100644 (file)
@@ -6364,6 +6364,17 @@ void Document::updateLastHandledUserGestureTimestamp(MonotonicTime time)
         element->document().updateLastHandledUserGestureTimestamp(time);
 }
 
+bool Document::processingUserGestureForMedia() const
+{
+    if (ScriptController::processingUserGestureForMedia())
+        return true;
+
+    if (!settings().mediaUserGestureInheritsFromDocument())
+        return false;
+
+    return topDocument().hasHadUserInteraction();
+}
+
 void Document::startTrackingStyleRecalcs()
 {
     m_styleRecalcCount = 0;
index 994a9a5..afef033 100644 (file)
@@ -1149,6 +1149,7 @@ public:
     MonotonicTime lastHandledUserGestureTimestamp() const { return m_lastHandledUserGestureTimestamp; }
     bool hasHadUserInteraction() const { return static_cast<bool>(m_lastHandledUserGestureTimestamp); }
     void updateLastHandledUserGestureTimestamp(MonotonicTime);
+    bool processingUserGestureForMedia() const;
 
     void setUserDidInteractWithPage(bool userDidInteractWithPage) { ASSERT(&topDocument() == this); m_userDidInteractWithPage = userDidInteractWithPage; }
     bool userDidInteractWithPage() const { ASSERT(&topDocument() == this); return m_userDidInteractWithPage; }
index 0d18c6a..1d863c5 100644 (file)
@@ -1162,7 +1162,7 @@ void HTMLMediaElement::load()
     
     if (!m_mediaSession->dataLoadingPermitted(*this))
         return;
-    if (ScriptController::processingUserGestureForMedia())
+    if (processingUserGestureForMedia())
         removeBehaviorsRestrictionsAfterFirstUserGesture();
 
     prepareForLoad();
@@ -1878,7 +1878,7 @@ void HTMLMediaElement::audioTrackEnabledChanged(AudioTrack& track)
 {
     if (m_audioTracks && m_audioTracks->contains(track))
         m_audioTracks->scheduleChangeEvent();
-    if (ScriptController::processingUserGestureForMedia())
+    if (processingUserGestureForMedia())
         removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::AllRestrictions & ~MediaElementSession::RequireUserGestureToControlControlsManager);
 }
 
@@ -2689,7 +2689,7 @@ void HTMLMediaElement::seekWithTolerance(const MediaTime& inTime, const MediaTim
     } else
         seekTask();
 
-    if (ScriptController::processingUserGestureForMedia())
+    if (processingUserGestureForMedia())
         m_mediaSession->removeBehaviorRestriction(MediaElementSession::RequireUserGestureToControlControlsManager);
 }
 
@@ -3154,7 +3154,7 @@ void HTMLMediaElement::play(DOMPromiseDeferred<void>&& promise)
         return;
     }
 
-    if (ScriptController::processingUserGestureForMedia())
+    if (processingUserGestureForMedia())
         removeBehaviorsRestrictionsAfterFirstUserGesture();
 
     if (!playInternal()) {
@@ -3175,7 +3175,7 @@ void HTMLMediaElement::play()
             setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::Prevented);
         return;
     }
-    if (ScriptController::processingUserGestureForMedia())
+    if (processingUserGestureForMedia())
         removeBehaviorsRestrictionsAfterFirstUserGesture();
 
     playInternal();
@@ -3239,7 +3239,7 @@ bool HTMLMediaElement::playInternal()
     } else if (m_readyState >= HAVE_FUTURE_DATA)
         scheduleResolvePendingPlayPromises();
 
-    if (ScriptController::processingUserGestureForMedia()) {
+    if (processingUserGestureForMedia()) {
         if (m_playbackWithoutUserGesture == PlaybackWithoutUserGesture::Prevented) {
             handleAutoplayEvent(AutoplayEvent::DidPlayMediaPreventedFromPlaying);
             setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::None);
@@ -3260,7 +3260,7 @@ void HTMLMediaElement::pause()
     if (!m_mediaSession->playbackPermitted(*this))
         return;
 
-    if (ScriptController::processingUserGestureForMedia())
+    if (processingUserGestureForMedia())
         removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::RequireUserGestureToControlControlsManager);
 
     pauseInternal();
@@ -3287,7 +3287,7 @@ void HTMLMediaElement::pauseInternal()
 
     m_autoplaying = false;
 
-    if (ScriptController::processingUserGestureForMedia())
+    if (processingUserGestureForMedia())
         userDidInterfereWithAutoplay();
 
     setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::None);
@@ -3382,7 +3382,7 @@ void HTMLMediaElement::setMuted(bool muted)
 
     bool mutedStateChanged = m_muted != muted;
     if (mutedStateChanged || !m_explicitlyMuted) {
-        if (ScriptController::processingUserGestureForMedia()) {
+        if (processingUserGestureForMedia()) {
             removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::AllRestrictions & ~MediaElementSession::RequireUserGestureToControlControlsManager);
 
             if (hasAudio() && muted)
@@ -5394,7 +5394,7 @@ void HTMLMediaElement::syncTextTrackBounds()
 void HTMLMediaElement::webkitShowPlaybackTargetPicker()
 {
     LOG(Media, "HTMLMediaElement::webkitShowPlaybackTargetPicker(%p)", this);
-    if (ScriptController::processingUserGestureForMedia())
+    if (processingUserGestureForMedia())
         removeBehaviorsRestrictionsAfterFirstUserGesture();
     m_mediaSession->showPlaybackTargetPicker(*this);
 }
@@ -7128,6 +7128,11 @@ bool HTMLMediaElement::shouldOverrideBackgroundPlaybackRestriction(PlatformMedia
     return false;
 }
 
+bool HTMLMediaElement::processingUserGestureForMedia() const
+{
+    return document().processingUserGestureForMedia();
+}
+
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
 void HTMLMediaElement::updateMediaState(UpdateState updateState)
 {
index 2d01375..5f085d3 100644 (file)
@@ -815,6 +815,7 @@ private:
     bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const override;
     bool shouldOverrideBackgroundLoadingRestriction() const override;
     bool canProduceAudio() const final;
+    bool processingUserGestureForMedia() const final;
 
     void pageMutedStateDidChange() override;
 
index ca7be74..09ce77a 100644 (file)
@@ -173,17 +173,17 @@ SuccessOr<MediaPlaybackDenialReason> MediaElementSession::playbackPermitted(cons
     }
 #endif
 
-    if (m_restrictions & RequireUserGestureForVideoRateChange && element.isVideo() && !ScriptController::processingUserGestureForMedia()) {
+    if (m_restrictions & RequireUserGestureForVideoRateChange && element.isVideo() && !element.document().processingUserGestureForMedia()) {
         LOG(Media, "MediaElementSession::playbackPermitted - returning FALSE because of video rate change restriction");
         return MediaPlaybackDenialReason::UserGestureRequired;
     }
 
-    if (m_restrictions & RequireUserGestureForAudioRateChange && (!element.isVideo() || element.hasAudio()) && !element.muted() && element.volume() && !ScriptController::processingUserGestureForMedia()) {
+    if (m_restrictions & RequireUserGestureForAudioRateChange && (!element.isVideo() || element.hasAudio()) && !element.muted() && element.volume() && !element.document().processingUserGestureForMedia()) {
         LOG(Media, "MediaElementSession::playbackPermitted - returning FALSE because of audio rate change restriction");
         return MediaPlaybackDenialReason::UserGestureRequired;
     }
 
-    if (m_restrictions & RequireUserGestureForVideoDueToLowPowerMode && element.isVideo() && !ScriptController::processingUserGestureForMedia()) {
+    if (m_restrictions & RequireUserGestureForVideoDueToLowPowerMode && element.isVideo() && !element.document().processingUserGestureForMedia()) {
         LOG(Media, "MediaElementSession::playbackPermitted - returning FALSE because of video low power mode restriction");
         return MediaPlaybackDenialReason::UserGestureRequired;
     }
@@ -218,12 +218,12 @@ bool MediaElementSession::autoplayPermitted() const
     return true;
 }
 
-bool MediaElementSession::dataLoadingPermitted(const HTMLMediaElement&) const
+bool MediaElementSession::dataLoadingPermitted(const HTMLMediaElement& element) const
 {
     if (m_restrictions & OverrideUserGestureRequirementForMainContent && updateIsMainContent())
         return true;
 
-    if (m_restrictions & RequireUserGestureForLoad && !ScriptController::processingUserGestureForMedia()) {
+    if (m_restrictions & RequireUserGestureForLoad && !element.document().processingUserGestureForMedia()) {
         LOG(Media, "MediaElementSession::dataLoadingPermitted - returning FALSE");
         return false;
     }
@@ -231,9 +231,9 @@ bool MediaElementSession::dataLoadingPermitted(const HTMLMediaElement&) const
     return true;
 }
 
-bool MediaElementSession::fullscreenPermitted(const HTMLMediaElement&) const
+bool MediaElementSession::fullscreenPermitted(const HTMLMediaElement& element) const
 {
-    if (m_restrictions & RequireUserGestureForFullscreen && !ScriptController::processingUserGestureForMedia()) {
+    if (m_restrictions & RequireUserGestureForFullscreen && !element.document().processingUserGestureForMedia()) {
         LOG(Media, "MediaElementSession::fullscreenPermitted - returning FALSE");
         return false;
     }
@@ -281,7 +281,7 @@ bool MediaElementSession::canShowControlsManager(PlaybackControlsPurpose purpose
     }
 
     if (client().presentationType() == Audio) {
-        if (!hasBehaviorRestriction(RequireUserGestureToControlControlsManager) || ScriptController::processingUserGestureForMedia()) {
+        if (!hasBehaviorRestriction(RequireUserGestureToControlControlsManager) || m_element.document().processingUserGestureForMedia()) {
             LOG(Media, "MediaElementSession::canShowControlsManager - returning TRUE: Audio element with user gesture");
             return true;
         }
@@ -315,7 +315,7 @@ bool MediaElementSession::canShowControlsManager(PlaybackControlsPurpose purpose
         return false;
     }
 
-    if (!hasBehaviorRestriction(RequireUserGestureToControlControlsManager) || ScriptController::processingUserGestureForMedia()) {
+    if (!hasBehaviorRestriction(RequireUserGestureToControlControlsManager) || m_element.document().processingUserGestureForMedia()) {
         LOG(Media, "MediaElementSession::canShowControlsManager - returning TRUE: No user gesture required");
         return true;
     }
@@ -384,7 +384,7 @@ void MediaElementSession::showPlaybackTargetPicker(const HTMLMediaElement& eleme
 {
     LOG(Media, "MediaElementSession::showPlaybackTargetPicker");
 
-    if (m_restrictions & RequireUserGestureToShowPlaybackTargetPicker && !ScriptController::processingUserGestureForMedia()) {
+    if (m_restrictions & RequireUserGestureToShowPlaybackTargetPicker && !element.document().processingUserGestureForMedia()) {
         LOG(Media, "MediaElementSession::showPlaybackTargetPicker - returning early because of permissions");
         return;
     }
index cf513e4..e40caa8 100644 (file)
@@ -131,6 +131,7 @@ requiresUserGestureToLoadVideo initial=defaultRequiresUserGestureToLoadVideo
 videoPlaybackRequiresUserGesture initial=defaultVideoPlaybackRequiresUserGesture
 audioPlaybackRequiresUserGesture initial=defaultAudioPlaybackRequiresUserGesture
 mainContentUserGestureOverrideEnabled initial=false
+mediaUserGestureInheritsFromDocument initial=false
 allowsInlineMediaPlayback initial=defaultAllowsInlineMediaPlayback
 allowsInlineMediaPlaybackAfterFullscreen initial=true
 inlineMediaPlaybackRequiresPlaysInlineAttribute initial=defaultInlineMediaPlaybackRequiresPlaysInlineAttribute
index 5b9bd83..a63b9c4 100644 (file)
@@ -231,6 +231,8 @@ public:
     virtual const Document* hostingDocument() const = 0;
     virtual String sourceApplicationIdentifier() const = 0;
 
+    virtual bool processingUserGestureForMedia() const = 0;
+
 protected:
     virtual ~PlatformMediaSessionClient() { }
 };
index c01f25d..c16b46a 100644 (file)
@@ -1,3 +1,17 @@
+2017-05-15  Jer Noble  <jer.noble@apple.com>
+
+        Add experimental setting to allow document gesture interaction to fulfill media playback gesture requirement
+        https://bugs.webkit.org/show_bug.cgi?id=172131
+
+        Reviewed by Eric Carlson.
+
+        * WebView/WebPreferenceKeysPrivate.h:
+        * WebView/WebPreferences.mm:
+        (+[WebPreferences initialize]):
+        (-[WebPreferences mediaUserGestureInheritsFromDocument]):
+        (-[WebPreferences setMediaUserGestureInheritsFromDocument:]):
+        * WebView/WebPreferencesPrivate.h:
+
 2017-05-12  Chris Dumez  <cdumez@apple.com>
 
         Drop uses of PassRefPtr in WebKit/mac
index a1aa2de..7d6de1f 100644 (file)
 #define WebKitWebRTCLegacyAPIEnabledPreferenceKey @"WebKitWebRTCLegacyAPIEnabled"
 #define WebKitLinkPreloadEnabledPreferenceKey @"WebKitLinkPreloadEnabled"
 #define WebKitCredentialManagementEnabledPreferenceKey @"WebKitCredentialManagementEnabled"
+#define WebKitMediaUserGestureInheritsFromDocument @"WebKitMediaUserGestureInheritsFromDocument"
 
 #if !TARGET_OS_IPHONE
 // These are private both because callers should be using the cover methods and because the
index 7749ac6..f8c57c8 100644 (file)
@@ -669,6 +669,7 @@ public:
         @NO, WebKitUserTimingEnabledPreferenceKey,
         @NO, WebKitResourceTimingEnabledPreferenceKey,
         @NO, WebKitCredentialManagementEnabledPreferenceKey,
+        @NO, WebKitMediaUserGestureInheritsFromDocument,
         nil];
 
 #if !PLATFORM(IOS)
@@ -3062,6 +3063,16 @@ static NSString *classIBCreatorID = nil;
     [self _setBoolValue:flag forKey:WebKitCredentialManagementEnabledPreferenceKey];
 }
 
+- (BOOL)mediaUserGestureInheritsFromDocument
+{
+    return [self _boolValueForKey:WebKitMediaUserGestureInheritsFromDocument];
+}
+
+- (void)setMediaUserGestureInheritsFromDocument:(BOOL)flag
+{
+    [self _setBoolValue:flag forKey:WebKitMediaUserGestureInheritsFromDocument];
+}
+
 #if PLATFORM(IOS)
 - (BOOL)quickLookDocumentSavingEnabled
 {
index ef5efc9..823fc36 100644 (file)
@@ -559,6 +559,7 @@ extern NSString *WebPreferencesCacheModelChangedInternalNotification;
 @property (nonatomic) BOOL resourceTimingEnabled;
 @property (nonatomic) BOOL linkPreloadEnabled;
 @property (nonatomic) BOOL credentialManagementEnabled;
+@property (nonatomic) BOOL mediaUserGestureInheritsFromDocument;
 
 #if TARGET_OS_IPHONE
 @property (nonatomic) BOOL quickLookDocumentSavingEnabled;
index 6236811..4d9247d 100644 (file)
@@ -1,3 +1,18 @@
+2017-05-15  Jer Noble  <jer.noble@apple.com>
+
+        Add experimental setting to allow document gesture interaction to fulfill media playback gesture requirement
+        https://bugs.webkit.org/show_bug.cgi?id=172131
+
+        Reviewed by Eric Carlson.
+
+        * Shared/WebPreferencesDefinitions.h:
+        * UIProcess/API/C/WKPreferences.cpp:
+        (WKPreferencesSetMediaUserGestureInheritsFromDocument):
+        (WKPreferencesGetMediaUserGestureInheritsFromDocument):
+        * UIProcess/API/C/WKPreferencesRefPrivate.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::updatePreferences):
+
 2017-05-15  Brent Fulgham  <bfulgham@apple.com>
 
         [WK2][macOS][iOS] Allow Network process to access nsurlstoraged's top level domain data cache 
index f5226af..6d876e7 100644 (file)
     macro(RequiresUserGestureForAudioPlayback, requiresUserGestureForAudioPlayback, Bool, bool, DEFAULT_REQUIRES_USER_GESTURE_FOR_AUDIO_PLAYBACK, "", "") \
     macro(RequiresUserGestureToLoadVideo, requiresUserGestureToLoadVideo, Bool, bool, false, "", "") \
     macro(MainContentUserGestureOverrideEnabled, mainContentUserGestureOverrideEnabled, Bool, bool, false, "", "") \
+    macro(MediaUserGestureInheritsFromDocument, mediaUserGestureInheritsFromDocument, Bool, bool, false, "", "") \
     macro(AllowsInlineMediaPlayback, allowsInlineMediaPlayback, Bool, bool, DEFAULT_ALLOWS_INLINE_MEDIA_PLAYBACK, "", "") \
     macro(AllowsInlineMediaPlaybackAfterFullscreen, allowsInlineMediaPlaybackAfterFullscreen, Bool, bool, DEFAULT_ALLOWS_INLINE_MEDIA_PLAYBACK_AFTER_FULLSCREEN, "", "") \
     macro(InlineMediaPlaybackRequiresPlaysInlineAttribute, inlineMediaPlaybackRequiresPlaysInlineAttribute, Bool, bool, DEFAULT_INLINE_MEDIA_PLAYBACK_REQUIRES_PLAYS_INLINE_ATTRIBUTE, "", "") \
index 9542e0f..ead76ba 100644 (file)
@@ -1760,3 +1760,13 @@ bool WKPreferencesGetShouldSuppressKeyboardInputDuringProvisionalNavigation(WKPr
 {
     return toImpl(preferencesRef)->shouldSuppressKeyboardInputDuringProvisionalNavigation();
 }
+
+void WKPreferencesSetMediaUserGestureInheritsFromDocument(WKPreferencesRef preferencesRef, bool flag)
+{
+    toImpl(preferencesRef)->setMediaUserGestureInheritsFromDocument(flag);
+}
+
+bool WKPreferencesGetMediaUserGestureInheritsFromDocument(WKPreferencesRef preferencesRef)
+{
+    return toImpl(preferencesRef)->mediaUserGestureInheritsFromDocument();
+}
index 2b9c60e..cd232b9 100644 (file)
@@ -493,6 +493,10 @@ WK_EXPORT bool WKPreferencesGetCredentialManagementEnabled(WKPreferencesRef);
 WK_EXPORT void WKPreferencesSetInvisibleMediaAutoplayPermitted(WKPreferencesRef, bool flag);
 WK_EXPORT bool WKPreferencesGetInvisibleMediaAutoplayPermitted(WKPreferencesRef);
 
+// Defaults to false.
+WK_EXPORT void WKPreferencesSetMediaUserGestureInheritsFromDocument(WKPreferencesRef, bool flag);
+WK_EXPORT bool WKPreferencesGetMediaUserGestureInheritsFromDocument(WKPreferencesRef);
+
 #ifdef __cplusplus
 }
 #endif
index 8a182ec..b002fcd 100644 (file)
@@ -3120,6 +3120,7 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
     settings.setAudioPlaybackRequiresUserGesture(requiresUserGestureForMedia || store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureForAudioPlaybackKey()));
     settings.setRequiresUserGestureToLoadVideo(store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureToLoadVideoKey()));
     settings.setMainContentUserGestureOverrideEnabled(store.getBoolValueForKey(WebPreferencesKey::mainContentUserGestureOverrideEnabledKey()));
+    settings.setMediaUserGestureInheritsFromDocument(store.getBoolValueForKey(WebPreferencesKey::mediaUserGestureInheritsFromDocumentKey()));
     settings.setAllowsInlineMediaPlayback(store.getBoolValueForKey(WebPreferencesKey::allowsInlineMediaPlaybackKey()));
     settings.setAllowsInlineMediaPlaybackAfterFullscreen(store.getBoolValueForKey(WebPreferencesKey::allowsInlineMediaPlaybackAfterFullscreenKey()));
     settings.setInlineMediaPlaybackRequiresPlaysInlineAttribute(store.getBoolValueForKey(WebPreferencesKey::inlineMediaPlaybackRequiresPlaysInlineAttributeKey()));