Title: [205412] trunk
Revision
205412
Author
[email protected]
Date
2016-09-03 17:24:14 -0700 (Sat, 03 Sep 2016)

Log Message

Refactor the heuristic for showing media controls to take all media sessions into account
https://bugs.webkit.org/show_bug.cgi?id=161503
<rdar://problem/28033783>

Reviewed by Darin Adler.

Source/WebCore:

Currently, when selecting a media session to show playback controls for, we grab the first media session that
passes our heuristic. Using this method, we are unable to take additional factors into account, such as whether
another media session's element is scrolled in view, or if another media session has been interacted with more
recently. To address this, we make the following changes:

    1.  Consider the list of all MediaElementSessions.

    2.  Select only the MediaElementSessions capable of showing media controls and sort the list by a special
        heuristic that takes visibility and time of last user interaction into account. The first element on
        this list is the strongest candidate for main content.

    3.  If this strongest candidate is visible in the viewport, or it is playing with audio, we return this
        as the chosen candidate. Otherwise, we return this session only if no other non-candidate video could be
        confused as the main content (i.e. the non-candidate video is not only visible in the viewport, but also
        large enough to be considered main content).

Using this new method of determining the video to show controls for, we retain previous behavior for pages with
a single video. On pages with multiple videos, the above logic ensures that if the current controlled video is
paused, scrolled out of view, and then a new video is scrolled into view, we will either hide media controls to
avoid confusion if that video could be confused for main content (using the mechanism in step 3), or we
hook up the media controls to the new video if it satisfies main content (using the mechanism in step 2).

This patch also adds 6 new TestWebKitAPI unit tests.

* html/HTMLMediaElement.cpp:
(WebCore::mediaElementSessionInfoForSession):
(WebCore::preferMediaControlsForCandidateSessionOverOtherCandidateSession):
(WebCore::mediaSessionMayBeConfusedWithMainContent):
(WebCore::bestMediaSessionForShowingPlaybackControlsManager):
(WebCore::HTMLMediaElement::didAttachRenderers):
(WebCore::HTMLMediaElement::layoutSizeChanged):
(WebCore::HTMLMediaElement::isVisibleInViewportChanged):
(WebCore::HTMLMediaElement::resetPlaybackSessionState):
(WebCore::HTMLMediaElement::isVisibleInViewport):
(WebCore::HTMLMediaElement::updatePlaybackControlsManager):
* html/HTMLMediaElement.h:
* html/MediaElementSession.cpp:
(WebCore::MediaElementSession::removeBehaviorRestriction):
(WebCore::MediaElementSession::canShowControlsManager):
(WebCore::MediaElementSession::isLargeEnoughForMainContent):
(WebCore::MediaElementSession::mostRecentUserInteractionTime):
(WebCore::MediaElementSession::wantsToObserveViewportVisibilityForMediaControls):
(WebCore::MediaElementSession::wantsToObserveViewportVisibilityForAutoplay):
(WebCore::MediaElementSession::resetPlaybackSessionState):
(WebCore::MediaElementSession::canControlControlsManager): Deleted.
* html/MediaElementSession.h:
* platform/audio/PlatformMediaSession.h:
(WebCore::PlatformMediaSession::resetPlaybackSessionState):
(WebCore::PlatformMediaSession::canControlControlsManager): Deleted.
* platform/audio/PlatformMediaSessionManager.cpp:
(WebCore::PlatformMediaSessionManager::currentSessionsMatching):
(WebCore::PlatformMediaSessionManager::currentSessionMatching): Deleted.
* platform/audio/PlatformMediaSessionManager.h:
* platform/cocoa/WebPlaybackSessionModelMediaElement.mm:
(WebPlaybackSessionModelMediaElement::setMediaElement):

Source/WebKit2:

Adds an SPI testing hook for sending the element ID of the currently controlled video element from the web
process to the UI process. See VideoControlsManager.mm in Tools/TestWebKitAPI/ for usage.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _requestControlledElementID]):
(-[WKWebView _handleControlledElementIDResponse:]):
(-[WKWebView _hasActiveVideoForControlsManager]): Deleted.
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/Cocoa/WebPlaybackSessionManagerProxy.h:
* UIProcess/Cocoa/WebPlaybackSessionManagerProxy.messages.in:
* UIProcess/Cocoa/WebPlaybackSessionManagerProxy.mm:
(WebKit::WebPlaybackSessionManagerProxy::handleControlledElementIDResponse):
(WebKit::WebPlaybackSessionManagerProxy::requestControlledElementID):
* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::requestControlledElementID):
(WebKit::WebPageProxy::handleControlledElementIDResponse):
* UIProcess/WebPageProxy.h:
* UIProcess/mac/PageClientImpl.h:
* UIProcess/mac/PageClientImpl.mm:
(WebKit::PageClientImpl::handleControlledElementIDResponse):
* WebProcess/cocoa/WebPlaybackSessionManager.h:
* WebProcess/cocoa/WebPlaybackSessionManager.messages.in:
* WebProcess/cocoa/WebPlaybackSessionManager.mm:
(WebKit::WebPlaybackSessionManager::handleControlledElementIDRequest):

Tools:

Adds new unit tests verifying the behavior of media playback controls when scrolling another video into view.
Please see the WebCore ChangeLog for more details about this change. Also refactors existing
VideoControlsManager tests by folding duplicated setup and testing logic into helper methods to make the unit
tests more readable.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit2Cocoa/VideoControlsManager.mm:
(-[MessageHandler initWithMessage:handler:]):
(-[MessageHandler userContentController:didReceiveScriptMessage:]):
(-[VideoControlsManagerTestWebView performAfterLoading:]):
(-[VideoControlsManagerTestWebView loadTestPageNamed:]):
(-[VideoControlsManagerTestWebView loadTestPageNamed:andExpectControlsManager:afterReceivingMessage:]):
(-[VideoControlsManagerTestWebView performAfterReceivingMessage:action:]):
(-[VideoControlsManagerTestWebView controlledElementID]):
(-[VideoControlsManagerTestWebView _handleControlledElementIDResponse:]):
(TestWebKitAPI::setUpWebViewForTestingVideoControlsManager):
(TestWebKitAPI::TEST):
(-[MediaPlaybackMessageHandler initWithWKWebView:finalMessageString:]): Deleted.
(-[MediaPlaybackMessageHandler userContentController:didReceiveScriptMessage:]): Deleted.
(-[OnLoadMessageHandler initWithWKWebView:handler:]): Deleted.
(-[OnLoadMessageHandler userContentController:didReceiveScriptMessage:]): Deleted.
(-[WKWebView performAfterLoading:]): Deleted.
* TestWebKitAPI/Tests/WebKit2Cocoa/large-video-playing-scroll-away.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-autoplaying-click-to-pause.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-autoplaying-scroll-to-video.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-paused-video-hides-controls.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-playing-muted-video-hides-controls.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-playing-video-keeps-controls.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (205411 => 205412)


--- trunk/Source/WebCore/ChangeLog	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebCore/ChangeLog	2016-09-04 00:24:14 UTC (rev 205412)
@@ -1,3 +1,67 @@
+2016-09-03  Wenson Hsieh  <[email protected]>
+
+        Refactor the heuristic for showing media controls to take all media sessions into account
+        https://bugs.webkit.org/show_bug.cgi?id=161503
+        <rdar://problem/28033783>
+
+        Reviewed by Darin Adler.
+
+        Currently, when selecting a media session to show playback controls for, we grab the first media session that
+        passes our heuristic. Using this method, we are unable to take additional factors into account, such as whether
+        another media session's element is scrolled in view, or if another media session has been interacted with more
+        recently. To address this, we make the following changes:
+
+            1.  Consider the list of all MediaElementSessions.
+
+            2.  Select only the MediaElementSessions capable of showing media controls and sort the list by a special
+                heuristic that takes visibility and time of last user interaction into account. The first element on
+                this list is the strongest candidate for main content.
+
+            3.  If this strongest candidate is visible in the viewport, or it is playing with audio, we return this
+                as the chosen candidate. Otherwise, we return this session only if no other non-candidate video could be
+                confused as the main content (i.e. the non-candidate video is not only visible in the viewport, but also
+                large enough to be considered main content).
+
+        Using this new method of determining the video to show controls for, we retain previous behavior for pages with
+        a single video. On pages with multiple videos, the above logic ensures that if the current controlled video is
+        paused, scrolled out of view, and then a new video is scrolled into view, we will either hide media controls to
+        avoid confusion if that video could be confused for main content (using the mechanism in step 3), or we
+        hook up the media controls to the new video if it satisfies main content (using the mechanism in step 2).
+
+        This patch also adds 6 new TestWebKitAPI unit tests.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::mediaElementSessionInfoForSession):
+        (WebCore::preferMediaControlsForCandidateSessionOverOtherCandidateSession):
+        (WebCore::mediaSessionMayBeConfusedWithMainContent):
+        (WebCore::bestMediaSessionForShowingPlaybackControlsManager):
+        (WebCore::HTMLMediaElement::didAttachRenderers):
+        (WebCore::HTMLMediaElement::layoutSizeChanged):
+        (WebCore::HTMLMediaElement::isVisibleInViewportChanged):
+        (WebCore::HTMLMediaElement::resetPlaybackSessionState):
+        (WebCore::HTMLMediaElement::isVisibleInViewport):
+        (WebCore::HTMLMediaElement::updatePlaybackControlsManager):
+        * html/HTMLMediaElement.h:
+        * html/MediaElementSession.cpp:
+        (WebCore::MediaElementSession::removeBehaviorRestriction):
+        (WebCore::MediaElementSession::canShowControlsManager):
+        (WebCore::MediaElementSession::isLargeEnoughForMainContent):
+        (WebCore::MediaElementSession::mostRecentUserInteractionTime):
+        (WebCore::MediaElementSession::wantsToObserveViewportVisibilityForMediaControls):
+        (WebCore::MediaElementSession::wantsToObserveViewportVisibilityForAutoplay):
+        (WebCore::MediaElementSession::resetPlaybackSessionState):
+        (WebCore::MediaElementSession::canControlControlsManager): Deleted.
+        * html/MediaElementSession.h:
+        * platform/audio/PlatformMediaSession.h:
+        (WebCore::PlatformMediaSession::resetPlaybackSessionState):
+        (WebCore::PlatformMediaSession::canControlControlsManager): Deleted.
+        * platform/audio/PlatformMediaSessionManager.cpp:
+        (WebCore::PlatformMediaSessionManager::currentSessionsMatching):
+        (WebCore::PlatformMediaSessionManager::currentSessionMatching): Deleted.
+        * platform/audio/PlatformMediaSessionManager.h:
+        * platform/cocoa/WebPlaybackSessionModelMediaElement.mm:
+        (WebPlaybackSessionModelMediaElement::setMediaElement):
+
 2016-09-03  Darin Adler  <[email protected]>
 
         Streamline DOMImplementation, and move it to our new DOM exception system

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (205411 => 205412)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2016-09-04 00:24:14 UTC (rev 205412)
@@ -346,6 +346,79 @@
 }
 #endif
 
+struct MediaElementSessionInfo {
+    const MediaElementSession* session;
+
+    double timeOfLastUserInteraction;
+    bool canShowControlsManager : 1;
+    bool isVisibleInViewportOrFullscreen : 1;
+    bool isLargeEnoughForMainContent : 1;
+    bool isPlayingAudio : 1;
+};
+
+static MediaElementSessionInfo mediaElementSessionInfoForSession(const MediaElementSession& session)
+{
+    const HTMLMediaElement& element = session.element();
+    return {
+        &session,
+        session.mostRecentUserInteractionTime(),
+        session.canShowControlsManager(),
+        element.isFullscreen() || element.isVisibleInViewport(),
+        session.isLargeEnoughForMainContent(),
+        element.isPlaying() && element.hasAudio() && !element.muted()
+    };
+}
+
+static bool preferMediaControlsForCandidateSessionOverOtherCandidateSession(const MediaElementSessionInfo& session, const MediaElementSessionInfo& otherSession)
+{
+    // Prioritize visible media over offscreen media.
+    if (session.isVisibleInViewportOrFullscreen != otherSession.isVisibleInViewportOrFullscreen)
+        return session.isVisibleInViewportOrFullscreen;
+
+    // As a tiebreaker, prioritize elements that the user recently interacted with.
+    return session.timeOfLastUserInteraction > otherSession.timeOfLastUserInteraction;
+}
+
+static bool mediaSessionMayBeConfusedWithMainContent(const MediaElementSessionInfo& session)
+{
+    if (!session.isVisibleInViewportOrFullscreen)
+        return false;
+
+    if (!session.isLargeEnoughForMainContent)
+        return false;
+
+    // Even if this video is not a candidate, if it is visible to the user and large enough
+    // to be main content, it poses a risk for being confused with main content.
+    return true;
+}
+
+static const MediaElementSession* bestMediaSessionForShowingPlaybackControlsManager()
+{
+    auto allSessions = PlatformMediaSessionManager::sharedManager().currentSessionsMatching([] (const PlatformMediaSession& session) {
+        return is<MediaElementSession>(session);
+    });
+
+    Vector<MediaElementSessionInfo> candidateSessions;
+    bool atLeastOneNonCandidateMayBeConfusedForMainContent = false;
+    for (auto& session : allSessions) {
+        auto mediaElementSessionInfo = mediaElementSessionInfoForSession(downcast<MediaElementSession>(*session));
+        if (mediaElementSessionInfo.canShowControlsManager)
+            candidateSessions.append(mediaElementSessionInfo);
+        else if (mediaSessionMayBeConfusedWithMainContent(mediaElementSessionInfo))
+            atLeastOneNonCandidateMayBeConfusedForMainContent = true;
+    }
+
+    if (!candidateSessions.size())
+        return nullptr;
+
+    std::sort(candidateSessions.begin(), candidateSessions.end(), preferMediaControlsForCandidateSessionOverOtherCandidateSession);
+    auto strongestSessionCandidate = candidateSessions.first();
+    if (!strongestSessionCandidate.isVisibleInViewportOrFullscreen && !strongestSessionCandidate.isPlayingAudio && atLeastOneNonCandidateMayBeConfusedForMainContent)
+        return nullptr;
+
+    return strongestSessionCandidate.session;
+}
+
 HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& document, bool createdByParser)
     : HTMLElement(tagName, document)
     , ActiveDOMObject(&document)
@@ -837,8 +910,7 @@
 {
     if (auto* renderer = this->renderer()) {
         renderer->updateFromElement();
-        if (m_mediaSession->hasBehaviorRestriction(MediaElementSession::InvisibleAutoplayNotPermitted)
-            || m_mediaSession->hasBehaviorRestriction(MediaElementSession::OverrideUserGestureRequirementForMainContent))
+        if (m_mediaSession && m_mediaSession->wantsToObserveViewportVisibilityForAutoplay())
             renderer->registerForVisibleInViewportCallback();
     }
     updateShouldAutoplay();
@@ -4022,6 +4094,11 @@
         m_receivedLayoutSizeChanged = true;
         scheduleUpdatePlaybackControlsManager();
     }
+
+    // If the video is a candidate for main content, we should register it for viewport visibility callbacks
+    // if it hasn't already been registered.
+    if (renderer() && m_mediaSession && !m_mediaSession->wantsToObserveViewportVisibilityForAutoplay() && m_mediaSession->wantsToObserveViewportVisibilityForMediaControls())
+        renderer()->registerForVisibleInViewportCallback();
 }
 
 void HTMLMediaElement::visibilityDidChange()
@@ -7141,6 +7218,7 @@
 void HTMLMediaElement::isVisibleInViewportChanged()
 {
     updateShouldAutoplay();
+    scheduleUpdatePlaybackControlsManager();
 }
 
 void HTMLMediaElement::updateShouldAutoplay()
@@ -7169,6 +7247,18 @@
         play();
 }
 
+void HTMLMediaElement::resetPlaybackSessionState()
+{
+    if (m_mediaSession)
+        m_mediaSession->resetPlaybackSessionState();
+}
+
+bool HTMLMediaElement::isVisibleInViewport() const
+{
+    auto renderer = this->renderer();
+    return renderer && renderer->visibleInViewportState() == RenderElement::VisibleInViewport;
+}
+
 void HTMLMediaElement::updatePlaybackControlsManager()
 {
     Page* page = document().page();
@@ -7175,14 +7265,11 @@
     if (!page)
         return;
 
-    PlatformMediaSession* session = PlatformMediaSessionManager::sharedManager().currentSessionMatching([] (const PlatformMediaSession& session) {
-        return session.canControlControlsManager();
-    });
-
-    if (!is<MediaElementSession>(session))
+    // FIXME: Ensure that the renderer here should be up to date.
+    if (auto bestMediaSession = bestMediaSessionForShowingPlaybackControlsManager())
+        page->chrome().client().setUpPlaybackControlsManager(bestMediaSession->element());
+    else
         page->chrome().client().clearPlaybackControlsManager();
-    else
-        page->chrome().client().setUpPlaybackControlsManager(downcast<MediaElementSession>(session)->element());
 }
 
 void HTMLMediaElement::scheduleUpdatePlaybackControlsManager()

Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (205411 => 205412)


--- trunk/Source/WebCore/html/HTMLMediaElement.h	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h	2016-09-04 00:24:14 UTC (rev 205412)
@@ -468,6 +468,9 @@
 
     RenderMedia* renderer() const;
 
+    void resetPlaybackSessionState();
+    bool isVisibleInViewport() const;
+
 protected:
     HTMLMediaElement(const QualifiedName&, Document&, bool createdByParser);
     virtual ~HTMLMediaElement();

Modified: trunk/Source/WebCore/html/MediaElementSession.cpp (205411 => 205412)


--- trunk/Source/WebCore/html/MediaElementSession.cpp	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebCore/html/MediaElementSession.cpp	2016-09-04 00:24:14 UTC (rev 205412)
@@ -47,6 +47,7 @@
 #include "RenderView.h"
 #include "ScriptController.h"
 #include "SourceBuffer.h"
+#include <wtf/CurrentTime.h>
 
 #if PLATFORM(IOS)
 #include "AudioSession.h"
@@ -137,6 +138,9 @@
 
 void MediaElementSession::removeBehaviorRestriction(BehaviorRestrictions restriction)
 {
+    if (restriction & RequireUserGestureToControlControlsManager)
+        m_mostRecentUserInteractionTime = monotonicallyIncreasingTime();
+
     LOG(Media, "MediaElementSession::removeBehaviorRestriction - removing %s", restrictionName(restriction).utf8().data());
     m_restrictions &= ~restriction;
 }
@@ -212,69 +216,89 @@
     return true;
 }
 
-bool MediaElementSession::canControlControlsManager() const
+bool MediaElementSession::canShowControlsManager() const
 {
     if (m_element.isFullscreen()) {
-        LOG(Media, "MediaElementSession::canControlControlsManager - returning TRUE: Is fullscreen");
+        LOG(Media, "MediaElementSession::canShowControlsManager - returning TRUE: Is fullscreen");
         return true;
     }
 
     if (!m_element.hasAudio()) {
-        LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: No audio");
+        LOG(Media, "MediaElementSession::canShowControlsManager - returning FALSE: No audio");
         return false;
     }
 
     if (m_element.document().activeDOMObjectsAreSuspended()) {
-        LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: activeDOMObjectsAreSuspended()");
+        LOG(Media, "MediaElementSession::canShowControlsManager - returning FALSE: activeDOMObjectsAreSuspended()");
         return false;
     }
 
     if (!playbackPermitted(m_element)) {
-        LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: Playback not permitted");
+        LOG(Media, "MediaElementSession::canShowControlsManager - returning FALSE: Playback not permitted");
         return false;
     }
 
     if (!hasBehaviorRestriction(RequireUserGestureToControlControlsManager) || ScriptController::processingUserGestureForMedia()) {
-        LOG(Media, "MediaElementSession::canControlControlsManager - returning TRUE: No user gesture required");
+        LOG(Media, "MediaElementSession::canShowControlsManager - returning TRUE: No user gesture required");
         return true;
     }
 
     if (hasBehaviorRestriction(RequirePlaybackToControlControlsManager) && !m_element.isPlaying()) {
-        LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: Needs to be playing");
+        LOG(Media, "MediaElementSession::canShowControlsManager - returning FALSE: Needs to be playing");
         return false;
     }
 
     if (m_element.muted()) {
-        LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: Muted");
+        LOG(Media, "MediaElementSession::canShowControlsManager - returning FALSE: Muted");
         return false;
     }
 
     if (m_element.isVideo()) {
         if (!m_element.renderer()) {
-            LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: No renderer");
+            LOG(Media, "MediaElementSession::canShowControlsManager - returning FALSE: No renderer");
             return false;
         }
 
         if (m_element.document().isMediaDocument()) {
-            LOG(Media, "MediaElementSession::canControlControlsManager - returning TRUE: Is media document");
+            LOG(Media, "MediaElementSession::canShowControlsManager - returning TRUE: Is media document");
             return true;
         }
 
         if (!m_element.hasVideo()) {
-            LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: No video");
+            LOG(Media, "MediaElementSession::canShowControlsManager - returning FALSE: No video");
             return false;
         }
 
-        if (isElementLargeEnoughForMainContent(m_element)) {
-            LOG(Media, "MediaElementSession::canControlControlsManager - returning TRUE: Is main content");
+        if (isLargeEnoughForMainContent()) {
+            LOG(Media, "MediaElementSession::canShowControlsManager - returning TRUE: Is main content");
             return true;
         }
     }
 
-    LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: No user gesture");
+    LOG(Media, "MediaElementSession::canShowControlsManager - returning FALSE: No user gesture");
     return false;
 }
 
+bool MediaElementSession::isLargeEnoughForMainContent() const
+{
+    return isElementLargeEnoughForMainContent(m_element);
+}
+
+double MediaElementSession::mostRecentUserInteractionTime() const
+{
+    return m_mostRecentUserInteractionTime;
+}
+
+bool MediaElementSession::wantsToObserveViewportVisibilityForMediaControls() const
+{
+    return isLargeEnoughForMainContent();
+}
+
+bool MediaElementSession::wantsToObserveViewportVisibilityForAutoplay() const
+{
+    return hasBehaviorRestriction(InvisibleAutoplayNotPermitted) || hasBehaviorRestriction(OverrideUserGestureRequirementForMainContent);
+}
+
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
 void MediaElementSession::showPlaybackTargetPicker(const HTMLMediaElement& element)
 {
@@ -502,6 +526,12 @@
     
 }
 
+void MediaElementSession::resetPlaybackSessionState()
+{
+    m_mostRecentUserInteractionTime = 0;
+    addBehaviorRestriction(RequireUserGestureToControlControlsManager | RequirePlaybackToControlControlsManager);
+}
+
 bool MediaElementSession::allowsPictureInPicture(const HTMLMediaElement& element) const
 {
     Settings* settings = element.document().settings();

Modified: trunk/Source/WebCore/html/MediaElementSession.h (205411 => 205412)


--- trunk/Source/WebCore/html/MediaElementSession.h	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebCore/html/MediaElementSession.h	2016-09-04 00:24:14 UTC (rev 205412)
@@ -54,8 +54,6 @@
     bool pageAllowsDataLoading(const HTMLMediaElement&) const;
     bool pageAllowsPlaybackAfterResuming(const HTMLMediaElement&) const;
 
-    bool canControlControlsManager() const override;
-
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     void showPlaybackTargetPicker(const HTMLMediaElement&);
     bool hasWirelessPlaybackTargets(const HTMLMediaElement&) const;
@@ -78,6 +76,8 @@
 
     void mediaEngineUpdated(const HTMLMediaElement&);
 
+    void resetPlaybackSessionState() override;
+
     // Restrictions to modify default behaviors.
     enum BehaviorRestrictionFlags : unsigned {
         NoRestrictions = 0,
@@ -111,6 +111,12 @@
 
     HTMLMediaElement& element() const { return m_element; }
 
+    bool wantsToObserveViewportVisibilityForMediaControls() const;
+    bool wantsToObserveViewportVisibilityForAutoplay() const;
+    bool canShowControlsManager() const;
+    bool isLargeEnoughForMainContent() const;
+    double mostRecentUserInteractionTime() const;
+
 private:
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
@@ -140,6 +146,8 @@
     bool m_hasPlaybackTargetAvailabilityListeners { false };
 #endif
 
+    double m_mostRecentUserInteractionTime { 0 };
+
     mutable bool m_isMainContent { false };
     Timer m_mainContentCheckTimer;
 };

Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSession.h (205411 => 205412)


--- trunk/Source/WebCore/platform/audio/PlatformMediaSession.h	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSession.h	2016-09-04 00:24:14 UTC (rev 205412)
@@ -145,7 +145,6 @@
 
     bool shouldOverrideBackgroundLoadingRestriction() const;
 
-    virtual bool canControlControlsManager() const { return false; }
     virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
     virtual bool isPlayingToWirelessPlaybackTarget() const { return m_isPlayingToWirelessPlaybackTarget; }
     void isPlayingToWirelessPlaybackTargetChanged(bool);
@@ -166,6 +165,7 @@
     void setCanProduceAudio(bool);
 
     void scheduleClientDataBufferingCheck();
+    virtual void resetPlaybackSessionState() { }
 
 protected:
     PlatformMediaSessionClient& client() const { return m_client; }

Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp (205411 => 205412)


--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp	2016-09-04 00:24:14 UTC (rev 205412)
@@ -280,13 +280,14 @@
     return m_sessions[0];
 }
 
-PlatformMediaSession* PlatformMediaSessionManager::currentSessionMatching(std::function<bool(const PlatformMediaSession &)> filter)
+Vector<PlatformMediaSession*> PlatformMediaSessionManager::currentSessionsMatching(std::function<bool(const PlatformMediaSession &)> filter)
 {
+    Vector<PlatformMediaSession*> matchingSessions;
     for (auto& session : m_sessions) {
         if (filter(*session))
-            return session;
+            matchingSessions.append(session);
     }
-    return nullptr;
+    return matchingSessions;
 }
     
 bool PlatformMediaSessionManager::sessionCanLoadMedia(const PlatformMediaSession& session) const

Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h (205411 => 205412)


--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h	2016-09-04 00:24:14 UTC (rev 205412)
@@ -92,7 +92,7 @@
     void setCurrentSession(PlatformMediaSession&);
     PlatformMediaSession* currentSession() const;
 
-    PlatformMediaSession* currentSessionMatching(std::function<bool(const PlatformMediaSession&)>);
+    Vector<PlatformMediaSession*> currentSessionsMatching(std::function<bool(const PlatformMediaSession&)>);
 
     void sessionIsPlayingToWirelessPlaybackTargetChanged(PlatformMediaSession&);
     void sessionCanProduceAudioChanged(PlatformMediaSession&);

Modified: trunk/Source/WebCore/platform/cocoa/WebPlaybackSessionModelMediaElement.mm (205411 => 205412)


--- trunk/Source/WebCore/platform/cocoa/WebPlaybackSessionModelMediaElement.mm	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebCore/platform/cocoa/WebPlaybackSessionModelMediaElement.mm	2016-09-04 00:24:14 UTC (rev 205412)
@@ -67,6 +67,9 @@
     }
     m_isListening = false;
 
+    if (m_mediaElement)
+        m_mediaElement->resetPlaybackSessionState();
+
     m_mediaElement = mediaElement;
 
     if (m_mediaElement) {

Modified: trunk/Source/WebKit2/ChangeLog (205411 => 205412)


--- trunk/Source/WebKit2/ChangeLog	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebKit2/ChangeLog	2016-09-04 00:24:14 UTC (rev 205412)
@@ -1,3 +1,37 @@
+2016-09-03  Wenson Hsieh  <[email protected]>
+
+        Refactor the heuristic for showing media controls to take all media sessions into account
+        https://bugs.webkit.org/show_bug.cgi?id=161503
+        <rdar://problem/28033783>
+
+        Reviewed by Darin Adler.
+
+        Adds an SPI testing hook for sending the element ID of the currently controlled video element from the web
+        process to the UI process. See VideoControlsManager.mm in Tools/TestWebKitAPI/ for usage.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _requestControlledElementID]):
+        (-[WKWebView _handleControlledElementIDResponse:]):
+        (-[WKWebView _hasActiveVideoForControlsManager]): Deleted.
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/Cocoa/WebPlaybackSessionManagerProxy.h:
+        * UIProcess/Cocoa/WebPlaybackSessionManagerProxy.messages.in:
+        * UIProcess/Cocoa/WebPlaybackSessionManagerProxy.mm:
+        (WebKit::WebPlaybackSessionManagerProxy::handleControlledElementIDResponse):
+        (WebKit::WebPlaybackSessionManagerProxy::requestControlledElementID):
+        * UIProcess/PageClient.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::requestControlledElementID):
+        (WebKit::WebPageProxy::handleControlledElementIDResponse):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/mac/PageClientImpl.h:
+        * UIProcess/mac/PageClientImpl.mm:
+        (WebKit::PageClientImpl::handleControlledElementIDResponse):
+        * WebProcess/cocoa/WebPlaybackSessionManager.h:
+        * WebProcess/cocoa/WebPlaybackSessionManager.messages.in:
+        * WebProcess/cocoa/WebPlaybackSessionManager.mm:
+        (WebKit::WebPlaybackSessionManager::handleControlledElementIDRequest):
+
 2016-09-03  Darin Adler  <[email protected]>
 
         Streamline DOMImplementation, and move it to our new DOM exception system

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (205411 => 205412)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2016-09-04 00:24:14 UTC (rev 205412)
@@ -4553,6 +4553,17 @@
 {
     return _page && _page->hasActiveVideoForControlsManager();
 }
+
+- (void)_requestControlledElementID
+{
+    if (_page)
+        _page->requestControlledElementID();
+}
+
+- (void)_handleControlledElementIDResponse:(NSString *)identifier
+{
+    // Overridden by subclasses.
+}
 #endif // PLATFORM(MAC)
 
 // Execute the supplied block after the next transaction from the WebProcess.

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h (205411 => 205412)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h	2016-09-04 00:24:14 UTC (rev 205412)
@@ -271,6 +271,8 @@
 
 #if !TARGET_OS_IPHONE
 @property (nonatomic, readonly) BOOL _hasActiveVideoForControlsManager WK_API_AVAILABLE(macosx(WK_MAC_TBA));
+- (void)_requestControlledElementID WK_API_AVAILABLE(macosx(WK_MAC_TBA));
+- (void)_handleControlledElementIDResponse:(NSString *)identifier WK_API_AVAILABLE(macosx(WK_MAC_TBA));
 #endif
 
 - (void)_doAfterNextPresentationUpdate:(void (^)(void))updateBlock WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.h (205411 => 205412)


--- trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.h	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.h	2016-09-04 00:24:14 UTC (rev 205412)
@@ -146,6 +146,7 @@
     void invalidate();
 
     PlatformWebPlaybackSessionInterface* controlsManagerInterface();
+    void requestControlledElementID();
 
 private:
     friend class WebPlaybackSessionModelContext;
@@ -176,6 +177,7 @@
     void setWirelessVideoPlaybackDisabled(uint64_t contextId, bool);
     void setDuration(uint64_t contextId, double duration);
     void setRate(uint64_t contextId, bool isPlaying, double rate);
+    void handleControlledElementIDResponse(uint64_t, String) const;
 
     // Messages to WebPlaybackSessionManager
     void play(uint64_t contextId);

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.messages.in (205411 => 205412)


--- trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.messages.in	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.messages.in	2016-09-04 00:24:14 UTC (rev 205412)
@@ -35,5 +35,7 @@
     SetRate(uint64_t contextId, bool isPlaying, double rate)
     SetUpPlaybackControlsManagerWithID(uint64_t contextId)
     ClearPlaybackControlsManager()
+
+    HandleControlledElementIDResponse(uint64_t contextId, String id)
 }
 #endif

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.mm (205411 => 205412)


--- trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.mm	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.mm	2016-09-04 00:24:14 UTC (rev 205412)
@@ -394,6 +394,19 @@
     ensureModel(contextId).setRate(isPlaying, rate);
 }
 
+
+void WebPlaybackSessionManagerProxy::handleControlledElementIDResponse(uint64_t contextId, String identifier) const
+{
+#if PLATFORM(MAC)
+    if (contextId == m_controlsManagerContextId)
+        m_page->handleControlledElementIDResponse(identifier);
+#else
+    UNUSED_PARAM(contextId);
+    UNUSED_PARAM(identifier);
+#endif
+}
+
+
 #pragma mark Messages to WebPlaybackSessionManager
 
 void WebPlaybackSessionManagerProxy::play(uint64_t contextId)
@@ -456,6 +469,12 @@
     m_page->send(Messages::WebPlaybackSessionManager::SelectLegibleMediaOption(contextId, index), m_page->pageID());
 }
 
+void WebPlaybackSessionManagerProxy::requestControlledElementID()
+{
+    if (m_controlsManagerContextId)
+        m_page->send(Messages::WebPlaybackSessionManager::HandleControlledElementIDRequest(m_controlsManagerContextId), m_page->pageID());
+}
+
 PlatformWebPlaybackSessionInterface* WebPlaybackSessionManagerProxy::controlsManagerInterface()
 {
     if (!m_controlsManagerContextId)

Modified: trunk/Source/WebKit2/UIProcess/PageClient.h (205411 => 205412)


--- trunk/Source/WebKit2/UIProcess/PageClient.h	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebKit2/UIProcess/PageClient.h	2016-09-04 00:24:14 UTC (rev 205412)
@@ -247,6 +247,7 @@
     virtual void recordAutocorrectionResponse(WebCore::AutocorrectionResponseType, const String& replacedString, const String& replacementString) = 0;
     virtual void recommendedScrollbarStyleDidChange(WebCore::ScrollbarStyle) = 0;
     virtual void removeNavigationGestureSnapshot() = 0;
+    virtual void handleControlledElementIDResponse(const String&) = 0;
 
     virtual CGRect boundsOfLayerInLayerBackedWindowCoordinates(CALayer *) const = 0;
 

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (205411 => 205412)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp	2016-09-04 00:24:14 UTC (rev 205412)
@@ -6298,6 +6298,19 @@
 #endif
 }
 
+void WebPageProxy::requestControlledElementID() const
+{
+#if ENABLE(VIDEO_PRESENTATION_MODE)
+    if (m_playbackSessionManager)
+        m_playbackSessionManager->requestControlledElementID();
+#endif
+}
+
+void WebPageProxy::handleControlledElementIDResponse(const String& identifier) const
+{
+    m_pageClient.handleControlledElementIDResponse(identifier);
+}
+
 bool WebPageProxy::isPlayingVideoInEnhancedFullscreen() const
 {
 #if ENABLE(VIDEO_PRESENTATION_MODE)

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (205411 => 205412)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h	2016-09-04 00:24:14 UTC (rev 205412)
@@ -1031,6 +1031,8 @@
 #if PLATFORM(MAC)
     void videoControlsManagerDidChange();
     bool hasActiveVideoForControlsManager() const;
+    void requestControlledElementID() const;
+    void handleControlledElementIDResponse(const String&) const;
     bool isPlayingVideoInEnhancedFullscreen() const;
 #endif
 

Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h (205411 => 205412)


--- trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h	2016-09-04 00:24:14 UTC (rev 205412)
@@ -206,6 +206,7 @@
     void didFailLoadForMainFrame() override;
     void didSameDocumentNavigationForMainFrame(SameDocumentNavigationType) override;
     void removeNavigationGestureSnapshot() override;
+    void handleControlledElementIDResponse(const String&) override;
 
     void didPerformImmediateActionHitTest(const WebHitTestResultData&, bool contentPreventsDefault, API::Object*) override;
     void* immediateActionAnimationControllerForHitTestResult(RefPtr<API::HitTestResult>, uint64_t, RefPtr<API::Object>) override;

Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm (205411 => 205412)


--- trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm	2016-09-04 00:24:14 UTC (rev 205412)
@@ -752,6 +752,13 @@
         gestureController->removeSwipeSnapshot();
 }
 
+void PageClientImpl::handleControlledElementIDResponse(const String& identifier)
+{
+#if WK_API_ENABLED
+    [m_webView _handleControlledElementIDResponse:nsStringFromWebCoreString(identifier)];
+#endif
+}
+
 void PageClientImpl::didChangeBackgroundColor()
 {
     notImplemented();

Modified: trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.h (205411 => 205412)


--- trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.h	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.h	2016-09-04 00:24:14 UTC (rev 205412)
@@ -143,6 +143,7 @@
     void endScanning(uint64_t contextId);
     void selectAudioMediaOption(uint64_t contextId, uint64_t index);
     void selectLegibleMediaOption(uint64_t contextId, uint64_t index);
+    void handleControlledElementIDRequest(uint64_t contextId);
 
     WebPage* m_page;
     HashMap<WebCore::HTMLMediaElement*, uint64_t> m_mediaElements;

Modified: trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.messages.in (205411 => 205412)


--- trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.messages.in	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.messages.in	2016-09-04 00:24:14 UTC (rev 205412)
@@ -35,5 +35,6 @@
     EndScanning(uint64_t contextId)
     SelectAudioMediaOption(uint64_t contextId, uint64_t index)
     SelectLegibleMediaOption(uint64_t contextId, uint64_t index)
+    HandleControlledElementIDRequest(uint64_t contextId)
 }
 #endif

Modified: trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.mm (205411 => 205412)


--- trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.mm	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.mm	2016-09-04 00:24:14 UTC (rev 205412)
@@ -415,6 +415,13 @@
     ensureModel(contextId).selectLegibleMediaOption(index);
 }
 
+void WebPlaybackSessionManager::handleControlledElementIDRequest(uint64_t contextId)
+{
+    auto element = ensureModel(contextId).mediaElement();
+    if (element)
+        m_page->send(Messages::WebPlaybackSessionManagerProxy::HandleControlledElementIDResponse(contextId, element->getIdAttribute()));
+}
+
 } // namespace WebKit
 
 #endif // PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))

Modified: trunk/Tools/ChangeLog (205411 => 205412)


--- trunk/Tools/ChangeLog	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Tools/ChangeLog	2016-09-04 00:24:14 UTC (rev 205412)
@@ -1,3 +1,40 @@
+2016-09-03  Wenson Hsieh  <[email protected]>
+
+        Refactor the heuristic for showing media controls to take all media sessions into account
+        https://bugs.webkit.org/show_bug.cgi?id=161503
+        <rdar://problem/28033783>
+
+        Reviewed by Darin Adler.
+
+        Adds new unit tests verifying the behavior of media playback controls when scrolling another video into view.
+        Please see the WebCore ChangeLog for more details about this change. Also refactors existing
+        VideoControlsManager tests by folding duplicated setup and testing logic into helper methods to make the unit
+        tests more readable.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit2Cocoa/VideoControlsManager.mm:
+        (-[MessageHandler initWithMessage:handler:]):
+        (-[MessageHandler userContentController:didReceiveScriptMessage:]):
+        (-[VideoControlsManagerTestWebView performAfterLoading:]):
+        (-[VideoControlsManagerTestWebView loadTestPageNamed:]):
+        (-[VideoControlsManagerTestWebView loadTestPageNamed:andExpectControlsManager:afterReceivingMessage:]):
+        (-[VideoControlsManagerTestWebView performAfterReceivingMessage:action:]):
+        (-[VideoControlsManagerTestWebView controlledElementID]):
+        (-[VideoControlsManagerTestWebView _handleControlledElementIDResponse:]):
+        (TestWebKitAPI::setUpWebViewForTestingVideoControlsManager):
+        (TestWebKitAPI::TEST):
+        (-[MediaPlaybackMessageHandler initWithWKWebView:finalMessageString:]): Deleted.
+        (-[MediaPlaybackMessageHandler userContentController:didReceiveScriptMessage:]): Deleted.
+        (-[OnLoadMessageHandler initWithWKWebView:handler:]): Deleted.
+        (-[OnLoadMessageHandler userContentController:didReceiveScriptMessage:]): Deleted.
+        (-[WKWebView performAfterLoading:]): Deleted.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/large-video-playing-scroll-away.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-autoplaying-click-to-pause.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-autoplaying-scroll-to-video.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-paused-video-hides-controls.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-playing-muted-video-hides-controls.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-playing-video-keeps-controls.html: Added.
+
 2016-09-03  Youenn Fablet  <[email protected]>
 
         run-webkit-tests should detect w3c test resource files

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (205411 => 205412)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2016-09-04 00:24:14 UTC (rev 205412)
@@ -64,6 +64,12 @@
 		2E1DFDED1D42A51100714A00 /* large-videos-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDEC1D42A41C00714A00 /* large-videos-with-audio.html */; };
 		2E1DFDEF1D42A6F200714A00 /* large-videos-with-audio-autoplay.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDEE1D42A6EB00714A00 /* large-videos-with-audio-autoplay.html */; };
 		2E1DFDF11D42E1E400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */; };
+		2E691AEA1D78B53600129407 /* large-videos-paused-video-hides-controls.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E691AE81D78B52B00129407 /* large-videos-paused-video-hides-controls.html */; };
+		2E691AEB1D78B53600129407 /* large-videos-playing-video-keeps-controls.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E691AE91D78B52B00129407 /* large-videos-playing-video-keeps-controls.html */; };
+		2E691AED1D78B91000129407 /* large-videos-playing-muted-video-hides-controls.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E691AEC1D78B90200129407 /* large-videos-playing-muted-video-hides-controls.html */; };
+		2E691AEF1D79DE8400129407 /* large-videos-autoplaying-click-to-pause.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E691AEE1D79DE6F00129407 /* large-videos-autoplaying-click-to-pause.html */; };
+		2E691AF11D79E51A00129407 /* large-videos-autoplaying-scroll-to-video.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E691AF01D79E51400129407 /* large-videos-autoplaying-scroll-to-video.html */; };
+		2E691AF31D79E75E00129407 /* large-video-playing-scroll-away.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E691AF21D79E75400129407 /* large-video-playing-scroll-away.html */; };
 		2E7765CD16C4D80A00BA2BB1 /* mainIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E7765CC16C4D80A00BA2BB1 /* mainIOS.mm */; };
 		2E7765CF16C4D81100BA2BB1 /* mainMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E7765CE16C4D81100BA2BB1 /* mainMac.mm */; };
 		33BE5AF9137B5AAE00705813 /* MouseMoveAfterCrash_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BE5AF8137B5AAE00705813 /* MouseMoveAfterCrash_Bundle.cpp */; };
@@ -520,6 +526,12 @@
 			dstPath = TestWebKitAPI.resources;
 			dstSubfolderSpec = 7;
 			files = (
+				2E691AF31D79E75E00129407 /* large-video-playing-scroll-away.html in Copy Resources */,
+				2E691AF11D79E51A00129407 /* large-videos-autoplaying-scroll-to-video.html in Copy Resources */,
+				2E691AEF1D79DE8400129407 /* large-videos-autoplaying-click-to-pause.html in Copy Resources */,
+				2E691AED1D78B91000129407 /* large-videos-playing-muted-video-hides-controls.html in Copy Resources */,
+				2E691AEA1D78B53600129407 /* large-videos-paused-video-hides-controls.html in Copy Resources */,
+				2E691AEB1D78B53600129407 /* large-videos-playing-video-keeps-controls.html in Copy Resources */,
 				1A9E52C913E65EF4006917F5 /* 18-characters.html in Copy Resources */,
 				379028B914FAC24C007E6B43 /* acceptsFirstMouse.html in Copy Resources */,
 				1C2B81871C8925A000A5529F /* Ahem.ttf in Copy Resources */,
@@ -743,6 +755,12 @@
 		2E1DFDEC1D42A41C00714A00 /* large-videos-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-videos-with-audio.html"; sourceTree = "<group>"; };
 		2E1DFDEE1D42A6EB00714A00 /* large-videos-with-audio-autoplay.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-videos-with-audio-autoplay.html"; sourceTree = "<group>"; };
 		2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-seek-to-beginning-and-play-after-ending.html"; sourceTree = "<group>"; };
+		2E691AE81D78B52B00129407 /* large-videos-paused-video-hides-controls.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-videos-paused-video-hides-controls.html"; sourceTree = "<group>"; };
+		2E691AE91D78B52B00129407 /* large-videos-playing-video-keeps-controls.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-videos-playing-video-keeps-controls.html"; sourceTree = "<group>"; };
+		2E691AEC1D78B90200129407 /* large-videos-playing-muted-video-hides-controls.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-videos-playing-muted-video-hides-controls.html"; sourceTree = "<group>"; };
+		2E691AEE1D79DE6F00129407 /* large-videos-autoplaying-click-to-pause.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-videos-autoplaying-click-to-pause.html"; sourceTree = "<group>"; };
+		2E691AF01D79E51400129407 /* large-videos-autoplaying-scroll-to-video.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-videos-autoplaying-scroll-to-video.html"; sourceTree = "<group>"; };
+		2E691AF21D79E75400129407 /* large-video-playing-scroll-away.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-playing-scroll-away.html"; sourceTree = "<group>"; };
 		2E7765CC16C4D80A00BA2BB1 /* mainIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = mainIOS.mm; sourceTree = "<group>"; };
 		2E7765CE16C4D81100BA2BB1 /* mainMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = mainMac.mm; sourceTree = "<group>"; };
 		333B9CE11277F23100FEFCE3 /* PreventEmptyUserAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PreventEmptyUserAgent.cpp; sourceTree = "<group>"; };
@@ -1400,6 +1418,12 @@
 		A16F66B81C40E9E100BD4D24 /* Resources */ = {
 			isa = PBXGroup;
 			children = (
+				2E691AF21D79E75400129407 /* large-video-playing-scroll-away.html */,
+				2E691AF01D79E51400129407 /* large-videos-autoplaying-scroll-to-video.html */,
+				2E691AEE1D79DE6F00129407 /* large-videos-autoplaying-click-to-pause.html */,
+				2E691AEC1D78B90200129407 /* large-videos-playing-muted-video-hides-controls.html */,
+				2E691AE81D78B52B00129407 /* large-videos-paused-video-hides-controls.html */,
+				2E691AE91D78B52B00129407 /* large-videos-playing-video-keeps-controls.html */,
 				5C9E593E1D3EB1DE00E3C62E /* ApplicationCache.db */,
 				5C9E593F1D3EB1DE00E3C62E /* ApplicationCache.db-shm */,
 				5C9E59401D3EB1DE00E3C62E /* ApplicationCache.db-wal */,

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/VideoControlsManager.mm (205411 => 205412)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/VideoControlsManager.mm	2016-09-03 23:34:00 UTC (rev 205411)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/VideoControlsManager.mm	2016-09-04 00:24:14 UTC (rev 205412)
@@ -37,66 +37,30 @@
 
 #if WK_API_ENABLED && PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
 
-static bool testedControlsManagerAfterPlaying;
-static bool receivedScriptMessage;
+@interface WKWebView (WKWebViewAdditions)
 
-@interface MediaPlaybackMessageHandler : NSObject <WKScriptMessageHandler> {
-    RetainPtr<WKWebView> _webView;
-}
+- (void)_interactWithMediaControlsForTesting;
 
-@property (nonatomic) BOOL expectedToHaveControlsManager;
-@property (nonatomic, retain) NSString *finalMessageString;
-
-- (instancetype)initWithWKWebView:(WKWebView*)webView finalMessageString:(NSString *)finalMessageString;
 @end
 
-@implementation MediaPlaybackMessageHandler
-
-- (instancetype)initWithWKWebView:(WKWebView*)webView finalMessageString:(NSString *)finalMessageString
-{
-    if (!(self = [super init]))
-        return nil;
-
-    _webView = webView;
-    _finalMessageString = finalMessageString;
-
-    return self;
+@interface MessageHandler : NSObject <WKScriptMessageHandler> {
+    dispatch_block_t _handler;
+    NSString *_message;
 }
 
-- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
-{
-    receivedScriptMessage = true;
+- (instancetype)initWithMessage:(NSString *)message handler:(dispatch_block_t)handler;
 
-    NSString *bodyString = (NSString *)[message body];
-    if ([bodyString isEqualToString:self.finalMessageString]) {
-        BOOL hasControlsManager = [_webView _hasActiveVideoForControlsManager];
-        if (self.expectedToHaveControlsManager)
-            EXPECT_TRUE(hasControlsManager);
-        else
-            EXPECT_FALSE(hasControlsManager);
-        testedControlsManagerAfterPlaying = true;
-    }
-}
 @end
 
-@interface OnLoadMessageHandler : NSObject <WKScriptMessageHandler> {
-    RetainPtr<WKWebView> _webView;
-}
+@implementation MessageHandler
 
-@property (nonatomic, strong) dispatch_block_t onloadHandler;
-
-- (instancetype)initWithWKWebView:(WKWebView*)webView handler:(dispatch_block_t)handler;
-@end
-
-@implementation OnLoadMessageHandler
-
-- (instancetype)initWithWKWebView:(WKWebView*)webView handler:(dispatch_block_t)handler
+- (instancetype)initWithMessage:(NSString *)message handler:(dispatch_block_t)handler
 {
     if (!(self = [super init]))
         return nil;
 
-    _webView = webView;
-    _onloadHandler = handler;
+    _handler = [handler copy];
+    _message = message;
 
     return self;
 }
@@ -103,30 +67,28 @@
 
 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
 {
-    if (![(NSString *)[message body] isEqualToString:@"loaded"])
-        return;
-
-    if (_onloadHandler)
-        _onloadHandler();
-
-    _onloadHandler = nil;
+    if ([(NSString *)[message body] isEqualToString:_message] && _handler)
+        _handler();
 }
-@end
 
-@interface WKWebView (WKWebViewAdditions)
-
-- (void)_interactWithMediaControlsForTesting;
-
 @end
 
-@interface WKWebView (TestingAdditions)
+@interface VideoControlsManagerTestWebView : WKWebView
 
 - (void)mouseDownAtPoint:(NSPoint)point;
 - (void)performAfterLoading:(dispatch_block_t)actions;
+- (void)loadTestPageNamed:(NSString *)pageName;
+- (void)loadTestPageNamed:(NSString *)pageName andExpectControlsManager:(BOOL)expectControlsManager afterReceivingMessage:(NSString *)message;
+- (void)performAfterReceivingMessage:(NSString *)message action:(dispatch_block_t)action;
 
+@property (nonatomic, readonly) NSString *controlledElementID;
+
 @end
 
-@implementation WKWebView (TestingAdditions)
+@implementation VideoControlsManagerTestWebView {
+    bool _isDoneQueryingControlledElementID;
+    NSString *_controlledElementID;
+}
 
 - (void)mouseDownAtPoint:(NSPoint)point {
     [self mouseDown:[NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:NSMakePoint(point.x, point.y) modifierFlags:0 timestamp:GetCurrentEventTime() windowNumber:0 context:[NSGraphicsContext currentContext] eventNumber:0 clickCount:0 pressure:0]];
@@ -133,78 +95,103 @@
 }
 
 - (void)performAfterLoading:(dispatch_block_t)actions {
-    OnLoadMessageHandler *handler = [[OnLoadMessageHandler alloc] initWithWKWebView:self handler:actions];
+    MessageHandler *handler = [[MessageHandler alloc] initWithMessage:@"loaded" handler:actions];
     NSString *_onloadScript_ = @"window._onload_ = function() { window.webkit.messageHandlers.onloadHandler.postMessage('loaded'); }";
     WKUserScript *script = [[WKUserScript alloc] initWithSource:onloadScript injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
-    [[[self configuration] userContentController] addUserScript:script];
-    [[[self configuration] userContentController] addScriptMessageHandler:handler name:@"onloadHandler"];
+
+    WKUserContentController* contentController = [[self configuration] userContentController];
+    [contentController addUserScript:script];
+    [contentController addScriptMessageHandler:handler name:@"onloadHandler"];
 }
 
+- (void)loadTestPageNamed:(NSString *)pageName
+{
+    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:pageName withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    [self loadRequest:request];
+}
+
+- (void)loadTestPageNamed:(NSString *)pageName andExpectControlsManager:(BOOL)expectControlsManager afterReceivingMessage:(NSString *)message
+{
+    __block bool doneWaiting = false;
+    [self performAfterReceivingMessage:message action:^ {
+        BOOL hasVideoForControlsManager = [self _hasActiveVideoForControlsManager];
+        if (expectControlsManager)
+            EXPECT_TRUE(hasVideoForControlsManager);
+        else
+            EXPECT_FALSE(hasVideoForControlsManager);
+        doneWaiting = true;
+    }];
+
+    [self loadTestPageNamed:pageName];
+    TestWebKitAPI::Util::run(&doneWaiting);
+}
+
+- (void)performAfterReceivingMessage:(NSString *)message action:(dispatch_block_t)action
+{
+    RetainPtr<MessageHandler> handler = adoptNS([[MessageHandler alloc] initWithMessage:message handler:action]);
+    [[[self configuration] userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
+}
+
+- (NSString *)controlledElementID
+{
+    _isDoneQueryingControlledElementID = false;
+    [self _requestControlledElementID];
+    TestWebKitAPI::Util::run(&_isDoneQueryingControlledElementID);
+    return _controlledElementID;
+}
+
+- (void)_handleControlledElementIDResponse:(NSString *)identifier
+{
+    _controlledElementID = [identifier copy];
+    _isDoneQueryingControlledElementID = true;
+}
+
 @end
 
 namespace TestWebKitAPI {
 
-TEST(VideoControlsManager, VideoControlsManagerSingleLargeVideo)
+RetainPtr<VideoControlsManagerTestWebView*> setUpWebViewForTestingVideoControlsManager(NSRect frame)
 {
     RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
-    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"playing"]);
-    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
-
+    RetainPtr<VideoControlsManagerTestWebView> webView = adoptNS([[VideoControlsManagerTestWebView alloc] initWithFrame:frame configuration:configuration.get()]);
     RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
     [[window contentView] addSubview:webView.get()];
 
+    return webView;
+}
+
+TEST(VideoControlsManager, VideoControlsManagerSingleLargeVideo)
+{
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 100, 100));
+
     // A large video with audio should have a controls manager even if it is played via script like this video.
     // So the expectation is YES.
-    [handler setExpectedToHaveControlsManager:YES];
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"large-video-with-audio" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
-    [webView loadRequest:request];
-
-    TestWebKitAPI::Util::run(&testedControlsManagerAfterPlaying);
-    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    [webView loadTestPageNamed:@"large-video-with-audio" andExpectControlsManager:YES afterReceivingMessage:@"playing"];
 }
 
 TEST(VideoControlsManager, VideoControlsManagerSingleSmallVideo)
 {
-    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
-    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"playing"]);
-    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 100, 100));
 
-    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
-    [[window contentView] addSubview:webView.get()];
-
     // A small video will not have a controls manager unless it started playing because of a user gesture. Since this
     // video is started with a script, the expectation is NO.
-    [handler setExpectedToHaveControlsManager:NO];
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"video-with-audio" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
-    [webView loadRequest:request];
-
-    TestWebKitAPI::Util::run(&testedControlsManagerAfterPlaying);
-    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    [webView loadTestPageNamed:@"video-with-audio" andExpectControlsManager:NO afterReceivingMessage:@"playing"];
 }
 
 TEST(VideoControlsManager, VideoControlsManagerMultipleVideosWithAudio)
 {
-    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 100, 100));
 
     __block BOOL didShowMediaControls;
     __block bool isDoneLoading = false;
 
-    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
-    [[window contentView] addSubview:webView.get()];
-    RetainPtr<OnLoadMessageHandler> _onloadHandler_ = adoptNS([[OnLoadMessageHandler alloc] initWithWKWebView:webView.get() handler:^() {
+    [webView performAfterLoading:^ {
         didShowMediaControls = [webView _hasActiveVideoForControlsManager];
         isDoneLoading = true;
-    }]);
-    [[configuration userContentController] addScriptMessageHandler:onloadHandler.get() name:@"onloadHandler"];
+    }];
 
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"large-videos-with-audio" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
-    [webView loadRequest:request];
+    [webView loadTestPageNamed:@"large-videos-with-audio"];
 
     TestWebKitAPI::Util::run(&isDoneLoading);
     EXPECT_FALSE(didShowMediaControls);
@@ -212,175 +199,157 @@
 
 TEST(VideoControlsManager, VideoControlsManagerMultipleVideosWithAudioAndAutoplay)
 {
-    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 100, 100));
 
     __block BOOL didShowMediaControls;
     __block bool isDoneLoading = false;
 
-    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
-    [[window contentView] addSubview:webView.get()];
-    RetainPtr<OnLoadMessageHandler> _onloadHandler_ = adoptNS([[OnLoadMessageHandler alloc] initWithWKWebView:webView.get() handler:^() {
+    [webView performAfterLoading:^ {
         didShowMediaControls = [webView _hasActiveVideoForControlsManager];
         isDoneLoading = true;
-    }]);
-    [[configuration userContentController] addScriptMessageHandler:onloadHandler.get() name:@"onloadHandler"];
+    }];
 
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"large-videos-with-audio-autoplay" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
-    [webView loadRequest:request];
+    [webView loadTestPageNamed:@"large-videos-with-audio-autoplay"];
 
     TestWebKitAPI::Util::run(&isDoneLoading);
     EXPECT_TRUE(didShowMediaControls);
 }
 
-TEST(VideoControlsManager, VideoControlsManagerSingleSmallAutoplayingVideo)
+TEST(VideoControlsManager, VideoControlsManagerMultipleVideosScrollPausedVideoOutOfView)
 {
-    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
-    RetainPtr<MediaPlaybackMessageHandler> playbackHandler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"paused"]);
-    [[configuration userContentController] addScriptMessageHandler:playbackHandler.get() name:@"playingHandler"];
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 500, 500));
 
-    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
-    [[window contentView] addSubview:webView.get()];
+    [webView loadTestPageNamed:@"large-videos-paused-video-hides-controls" andExpectControlsManager:NO afterReceivingMessage:@"paused"];
+}
 
-    RetainPtr<OnLoadMessageHandler> _onloadHandler_ = adoptNS([[OnLoadMessageHandler alloc] initWithWKWebView:webView.get() handler:^() {
-        [webView mouseDownAtPoint:NSMakePoint(50, 50)];
-    }]);
-    [[configuration userContentController] addScriptMessageHandler:onloadHandler.get() name:@"onloadHandler"];
+TEST(VideoControlsManager, VideoControlsManagerMultipleVideosScrollPlayingVideoWithSoundOutOfView)
+{
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 500, 500));
 
-    // A small video should have a controls manager after the first user gesture, which includes pausing the video. The expectation is YES.
-    [playbackHandler setExpectedToHaveControlsManager:YES];
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"autoplaying-video-with-audio" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
-    [webView loadRequest:request];
+    [webView loadTestPageNamed:@"large-videos-playing-video-keeps-controls" andExpectControlsManager:YES afterReceivingMessage:@"playing"];
+}
 
-    TestWebKitAPI::Util::run(&testedControlsManagerAfterPlaying);
-    TestWebKitAPI::Util::run(&receivedScriptMessage);
+TEST(VideoControlsManager, VideoControlsManagerMultipleVideosScrollPlayingMutedVideoOutOfView)
+{
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 500, 500));
+
+    [webView loadTestPageNamed:@"large-videos-playing-muted-video-hides-controls" andExpectControlsManager:NO afterReceivingMessage:@"playing"];
 }
 
-TEST(VideoControlsManager, VideoControlsManagerLargeAutoplayingVideoSeeksAfterEnding)
+TEST(VideoControlsManager, VideoControlsManagerMultipleVideosShowControlsForLastInteractedVideo)
 {
-    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
-    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"ended"]);
-    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 800, 600));
+    NSPoint clickPoint = NSMakePoint(400, 300);
 
-    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
-    [[window contentView] addSubview:webView.get()];
+    [webView performAfterLoading:^ {
+        [webView mouseDownAtPoint:clickPoint];
+    }];
 
-    // Since the video has ended, the expectation is NO even if the page programmatically seeks to the beginning.
-    [handler setExpectedToHaveControlsManager:NO];
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"large-video-seek-after-ending" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
-    [webView loadRequest:request];
+    __block bool firstVideoPaused = false;
+    __block bool secondVideoPaused = false;
+    [webView performAfterReceivingMessage:@"paused" action:^ {
+        NSString *controlledElementID = [webView controlledElementID];
+        if (firstVideoPaused) {
+            secondVideoPaused = true;
+            EXPECT_TRUE([controlledElementID isEqualToString:@"second"]);
+        } else {
+            [webView mouseDownAtPoint:clickPoint];
+            EXPECT_TRUE([controlledElementID isEqualToString:@"first"]);
+        }
+        firstVideoPaused = true;
+    }];
 
-    TestWebKitAPI::Util::run(&testedControlsManagerAfterPlaying);
-    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    [webView loadTestPageNamed:@"large-videos-autoplaying-click-to-pause"];
+    TestWebKitAPI::Util::run(&secondVideoPaused);
 }
 
-TEST(VideoControlsManager, VideoControlsManagerLargeAutoplayingVideoSeeksAndPlaysAfterEnding)
+TEST(VideoControlsManager, VideoControlsManagerMultipleVideosSwitchControlledVideoWhenScrolling)
 {
-    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
-    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"replaying"]);
-    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 800, 600));
 
-    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
-    [[window contentView] addSubview:webView.get()];
+    __block bool scrolledSecondVideoIntoView = false;
+    [webView loadTestPageNamed:@"large-videos-autoplaying-scroll-to-video"];
+    [webView performAfterReceivingMessage:@"scrolled" action:^ {
+        scrolledSecondVideoIntoView = true;
+    }];
 
-    // Since the video is still playing, the expectation is YES even if the video has ended once.
-    [handler setExpectedToHaveControlsManager:YES];
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"large-video-seek-to-beginning-and-play-after-ending" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
-    [webView loadRequest:request];
+    TestWebKitAPI::Util::run(&scrolledSecondVideoIntoView);
+    EXPECT_TRUE([[webView controlledElementID] isEqualToString:@"second"]);
+}
 
-    TestWebKitAPI::Util::run(&testedControlsManagerAfterPlaying);
-    TestWebKitAPI::Util::run(&receivedScriptMessage);
+TEST(VideoControlsManager, VideoControlsManagerMultipleVideosScrollOnlyLargeVideoOutOfView)
+{
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 500, 500));
+
+    [webView loadTestPageNamed:@"large-video-playing-scroll-away" andExpectControlsManager:YES afterReceivingMessage:@"scrolled"];
 }
 
+TEST(VideoControlsManager, VideoControlsManagerSingleSmallAutoplayingVideo)
+{
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 100, 100));
+
+    [webView performAfterLoading:^ {
+        [webView mouseDownAtPoint:NSMakePoint(50, 50)];
+    }];
+
+    [webView loadTestPageNamed:@"autoplaying-video-with-audio" andExpectControlsManager:YES afterReceivingMessage:@"paused"];
+}
+
+TEST(VideoControlsManager, VideoControlsManagerLargeAutoplayingVideoSeeksAfterEnding)
+{
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 100, 100));
+
+    // Since the video has ended, the expectation is NO even if the page programmatically seeks to the beginning.
+    [webView loadTestPageNamed:@"large-video-seek-after-ending" andExpectControlsManager:NO afterReceivingMessage:@"ended"];
+}
+
+TEST(VideoControlsManager, VideoControlsManagerLargeAutoplayingVideoSeeksAndPlaysAfterEnding)
+{
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 100, 100));
+
+    // Since the video is still playing, the expectation is YES even if the video has ended once.
+    [webView loadTestPageNamed:@"large-video-seek-to-beginning-and-play-after-ending" andExpectControlsManager:YES afterReceivingMessage:@"replaying"];
+}
+
 TEST(VideoControlsManager, VideoControlsManagerLargeAutoplayingVideoAfterSeekingToEnd)
 {
-    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
-    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"ended"]);
-    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 100, 100));
 
-    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
-    [[window contentView] addSubview:webView.get()];
-
-    RetainPtr<OnLoadMessageHandler> _onloadHandler_ = adoptNS([[OnLoadMessageHandler alloc] initWithWKWebView:webView.get() handler:^() {
+    [webView performAfterLoading:^ {
         [webView mouseDownAtPoint:NSMakePoint(50, 50)];
-    }]);
-    [[configuration userContentController] addScriptMessageHandler:onloadHandler.get() name:@"onloadHandler"];
+    }];
 
     // We expect there to be media controls, since this is a user gestured seek to the end.
     // This is akin to seeking to the end by scrubbing in the controls.
-    [handler setExpectedToHaveControlsManager:YES];
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"large-video-hides-controls-after-seek-to-end" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
-    [webView loadRequest:request];
-
-    TestWebKitAPI::Util::run(&testedControlsManagerAfterPlaying);
-    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    [webView loadTestPageNamed:@"large-video-hides-controls-after-seek-to-end" andExpectControlsManager:YES afterReceivingMessage:@"ended"];
 }
 
 TEST(VideoControlsManager, VideoControlsManagerSingleLargeVideoWithoutAudio)
 {
-    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
-    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"playing"]);
-    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 100, 100));
 
-    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
-    [[window contentView] addSubview:webView.get()];
-
     // A large video with no audio will not have a controls manager unless it started playing because of a user gesture. Since this
     // video is started with a script, the expectation is NO.
-    [handler setExpectedToHaveControlsManager:NO];
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"large-video-without-audio" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
-    [webView loadRequest:request];
-
-    TestWebKitAPI::Util::run(&testedControlsManagerAfterPlaying);
-    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    [webView loadTestPageNamed:@"large-video-without-audio" andExpectControlsManager:NO afterReceivingMessage:@"playing"];
 }
 
 TEST(VideoControlsManager, VideoControlsManagerAudioElementStartedWithScript)
 {
-    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
-    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"playing"]);
-    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 100, 100));
 
-    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
-    [[window contentView] addSubview:webView.get()];
-
     // An audio element MUST be started with a user gesture in order to have a controls manager, so the expectation is NO.
-    [handler setExpectedToHaveControlsManager:NO];
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"audio-only" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
-    [webView loadRequest:request];
-
-    TestWebKitAPI::Util::run(&testedControlsManagerAfterPlaying);
-    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    [webView loadTestPageNamed:@"audio-only" andExpectControlsManager:NO afterReceivingMessage:@"playing"];
 }
 
 TEST(VideoControlsManager, VideoControlsManagerTearsDownMediaControlsOnDealloc)
 {
-    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 100, 100));
 
-    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
-    [[window contentView] addSubview:webView.get()];
-
     NSURL *urlOfVideo = [[NSBundle mainBundle] URLForResource:@"video-with-audio" withExtension:@"mp4" subdirectory:@"TestWebKitAPI.resources"];
     [webView loadFileURL:urlOfVideo allowingReadAccessToURL:[urlOfVideo URLByDeletingLastPathComponent]];
 
     __block bool finishedTest = false;
-    [webView performAfterLoading:^()
-    {
+    [webView performAfterLoading:^ {
         // Verify that we tear down the media controls properly, such that we don't crash when the web view is released.
         if ([webView respondsToSelector:@selector(_interactWithMediaControlsForTesting)])
             [webView _interactWithMediaControlsForTesting];
@@ -394,16 +363,10 @@
 
 TEST(VideoControlsManager, VideoControlsManagerSmallVideoInMediaDocument)
 {
-    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
-    
-    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
-    [[window contentView] addSubview:webView.get()];
-    
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 100, 100));
+
     __block bool finishedLoad = false;
-    [webView performAfterLoading:^()
-    {
+    [webView performAfterLoading:^ {
         finishedLoad = true;
     }];
     
@@ -418,40 +381,16 @@
 
 TEST(VideoControlsManager, VideoControlsManagerLongSkinnyVideoInWideMainFrame)
 {
-    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 1600, 800) configuration:configuration.get()]);
-    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
-    [[window contentView] addSubview:webView.get()];
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 1600, 800));
 
-    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"playing"]);
-    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
-    [handler setExpectedToHaveControlsManager:NO];
-
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"skinny-autoplaying-video-with-audio" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
-    [webView loadRequest:request];
-
-    TestWebKitAPI::Util::run(&testedControlsManagerAfterPlaying);
-    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    [webView loadTestPageNamed:@"skinny-autoplaying-video-with-audio" andExpectControlsManager:NO afterReceivingMessage:@"playing"];
 }
 
 TEST(VideoControlsManager, VideoControlsManagerFullSizeVideoInWideMainFrame)
 {
-    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
-    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 1600, 800) configuration:configuration.get()]);
-    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
-    [[window contentView] addSubview:webView.get()];
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 1600, 800));
 
-    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"playing"]);
-    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
-    [handler setExpectedToHaveControlsManager:YES];
-
-    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"full-size-autoplaying-video-with-audio" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
-    [webView loadRequest:request];
-
-    TestWebKitAPI::Util::run(&testedControlsManagerAfterPlaying);
-    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    [webView loadTestPageNamed:@"full-size-autoplaying-video-with-audio" andExpectControlsManager:YES afterReceivingMessage:@"playing"];
 }
 
 } // namespace TestWebKitAPI

Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-video-playing-scroll-away.html (0 => 205412)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-video-playing-scroll-away.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-video-playing-scroll-away.html	2016-09-04 00:24:14 UTC (rev 205412)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <style>
+            video {
+                width: 480px;
+                height: 320px;
+            }
+            div {
+                margin-top: 5000px;
+            }
+        </style>
+        <script>
+            function handleLoaded() {
+                document.querySelector("div").scrollIntoView();
+                setTimeout(function() {
+                    window.webkit.messageHandlers.playingHandler.postMessage("scrolled");
+                }, 0);
+            }
+        </script>
+    </head>
+    <body _onload_=handleLoaded()>
+        <video autoplay loop id="first" src=""
+        <br>
+        <div>hello world!</div>
+    </body>
+<html>

Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-autoplaying-click-to-pause.html (0 => 205412)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-autoplaying-click-to-pause.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-autoplaying-click-to-pause.html	2016-09-04 00:24:14 UTC (rev 205412)
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <style>
+            video {
+                width: 480px;
+                height: 320px;
+            }
+        </style>
+        <script>
+            var isFirstClick = true;
+            function handleMouseDown() {
+                document.querySelector(isFirstClick ? "#first" : "#second").pause();
+                isFirstClick = false;
+            }
+
+            function handleFirstPause() {
+                setTimeout(function() {
+                    try {
+                        window.webkit.messageHandlers.playingHandler.postMessage("paused");
+                    } catch(e) { }
+                }, 0);
+            }
+
+            function handleSecondPause() {
+                setTimeout(function() {
+                    try {
+                        window.webkit.messageHandlers.playingHandler.postMessage("paused");
+                    } catch(e) { }
+                }, 0);
+            }
+        </script>
+    </head>
+    <body _onmousedown_=handleMouseDown()>
+        <video autoplay loop id="first" src="" _onpause_=handleFirstPause()></video>
+        <video autoplay loop id="second" src="" _onpause_=handleSecondPause()></video>
+    </body>
+<html>

Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-autoplaying-scroll-to-video.html (0 => 205412)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-autoplaying-scroll-to-video.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-autoplaying-scroll-to-video.html	2016-09-04 00:24:14 UTC (rev 205412)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <style>
+            video {
+                width: 480px;
+                height: 320px;
+            }
+            #second {
+                margin-top: 5000px;
+            }
+        </style>
+        <script>
+            function handleLoaded() {
+                document.querySelector("#second").scrollIntoView();
+                setTimeout(function() {
+                    window.webkit.messageHandlers.playingHandler.postMessage("scrolled");
+                }, 0);
+            }
+        </script>
+    </head>
+    <body _onload_=handleLoaded()>
+        <video autoplay loop id="first" src=""
+        <br>
+        <video autoplay loop id="second" src=""
+    </body>
+<html>

Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-paused-video-hides-controls.html (0 => 205412)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-paused-video-hides-controls.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-paused-video-hides-controls.html	2016-09-04 00:24:14 UTC (rev 205412)
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<style>
+    video {
+        width: 480px;
+        height: 320px;
+    }
+    #bar {
+        margin-top: 5000px;
+    }
+</style>
+<script>
+    function handleLoaded() {
+        document.querySelector("#bar").scrollIntoView();
+        document.querySelector("#foo").pause();
+    }
+    function handlePaused() {
+        setTimeout(function() {
+            try {
+                window.webkit.messageHandlers.playingHandler.postMessage("paused");
+            } catch(e) { }
+        }, 0);
+    }
+</script>
+<body _onload_=handleLoaded()>
+    <video autoplay loop id="foo" _onpause_=handlePaused()><source src=""
+    <br>
+    <video id="bar"><source src=""
+</body>
+<html>
\ No newline at end of file

Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-playing-muted-video-hides-controls.html (0 => 205412)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-playing-muted-video-hides-controls.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-playing-muted-video-hides-controls.html	2016-09-04 00:24:14 UTC (rev 205412)
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<style>
+    video {
+        width: 480px;
+        height: 320px;
+    }
+    #bar {
+        margin-top: 5000px;
+    }
+</style>
+<script>
+    function handleLoaded() {
+        document.querySelector("#foo").muted = true;
+        document.querySelector("#bar").scrollIntoView();
+        setTimeout(function() {
+            try {
+                window.webkit.messageHandlers.playingHandler.postMessage("playing");
+            } catch(e) { }
+        }, 0);
+    }
+</script>
+<body _onload_=handleLoaded()>
+    <video autoplay loop id="foo"><source src=""
+    <br>
+    <video id="bar"><source src=""
+</body>
+<html>
\ No newline at end of file

Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-playing-video-keeps-controls.html (0 => 205412)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-playing-video-keeps-controls.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-videos-playing-video-keeps-controls.html	2016-09-04 00:24:14 UTC (rev 205412)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<style>
+    video {
+        width: 480px;
+        height: 320px;
+    }
+    #bar {
+        margin-top: 5000px;
+    }
+</style>
+<script>
+    function handleLoaded() {
+        document.querySelector("#bar").scrollIntoView();
+        setTimeout(function() {
+            try {
+                window.webkit.messageHandlers.playingHandler.postMessage("playing");
+            } catch(e) { }
+        }, 0);
+    }
+</script>
+<body _onload_=handleLoaded()>
+    <video autoplay loop id="foo"><source src=""
+    <br>
+    <video id="bar"><source src=""
+</body>
+<html>
\ No newline at end of file
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to