Apple.com keynote does not display media controls
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 10 Sep 2016 08:19:10 +0000 (08:19 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 10 Sep 2016 08:19:10 +0000 (08:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=161833
<rdar://problem/28230123>

Reviewed by Tim Horton.

Source/WebCore:

Tweaks the main content check so that we can distinguish between main content for the purposes of determining
autoplay policy vs. main content for the purposes of showing media controls. Namely, we make the latter less
restrictive than the former in terms of the maximum aspect ratio a video can have to be considered the right
size for main content.

New unit test in TestWebKitAPI.

* html/HTMLMediaElement.cpp:
(WebCore::mediaElementSessionInfoForSession):
* html/MediaElementSession.cpp:
(WebCore::MediaElementSession::canShowControlsManager):
(WebCore::MediaElementSession::isLargeEnoughForMainContent):
(WebCore::MediaElementSession::wantsToObserveViewportVisibilityForMediaControls):
(WebCore::isMainContentForPurposesOfAutoplay):
(WebCore::isElementLargeEnoughForMainContent):
(WebCore::MediaElementSession::updateIsMainContent):
(WebCore::isMainContent): Deleted.
* html/MediaElementSession.h:

Tools:

New unit test verifying that wide videos (~2 aspect ratio) still get media controls.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit2Cocoa/VideoControlsManager.mm:
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebKit2Cocoa/wide-autoplaying-video-with-audio.html: Added.

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

Source/WebCore/ChangeLog
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/MediaElementSession.cpp
Source/WebCore/html/MediaElementSession.h
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/VideoControlsManager.mm
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/wide-autoplaying-video-with-audio.html [new file with mode: 0644]

index 2db5a87..0100a79 100644 (file)
@@ -1,3 +1,30 @@
+2016-09-10  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Apple.com keynote does not display media controls
+        https://bugs.webkit.org/show_bug.cgi?id=161833
+        <rdar://problem/28230123>
+
+        Reviewed by Tim Horton.
+
+        Tweaks the main content check so that we can distinguish between main content for the purposes of determining
+        autoplay policy vs. main content for the purposes of showing media controls. Namely, we make the latter less
+        restrictive than the former in terms of the maximum aspect ratio a video can have to be considered the right
+        size for main content.
+
+        New unit test in TestWebKitAPI.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::mediaElementSessionInfoForSession):
+        * html/MediaElementSession.cpp:
+        (WebCore::MediaElementSession::canShowControlsManager):
+        (WebCore::MediaElementSession::isLargeEnoughForMainContent):
+        (WebCore::MediaElementSession::wantsToObserveViewportVisibilityForMediaControls):
+        (WebCore::isMainContentForPurposesOfAutoplay):
+        (WebCore::isElementLargeEnoughForMainContent):
+        (WebCore::MediaElementSession::updateIsMainContent):
+        (WebCore::isMainContent): Deleted.
+        * html/MediaElementSession.h:
+
 2016-09-09  Alex Christensen  <achristensen@webkit.org>
 
         URLParser: Keep track of cannot-be-a-base-url according to spec
index 93ca4a4..17fb88b 100644 (file)
@@ -364,7 +364,7 @@ static MediaElementSessionInfo mediaElementSessionInfoForSession(const MediaElem
         session.mostRecentUserInteractionTime(),
         session.canShowControlsManager(),
         element.isFullscreen() || element.isVisibleInViewport(),
-        session.isLargeEnoughForMainContent(),
+        session.isLargeEnoughForMainContent(MediaSessionMainContentPurpose::MediaControls),
         element.isPlaying() && element.hasAudio() && !element.muted()
     };
 }
index 846e56f..9d8ca2d 100644 (file)
@@ -59,8 +59,7 @@ namespace WebCore {
 
 static const double elementMainContentCheckInterval = .250;
 
-static bool isMainContent(const HTMLMediaElement&);
-static bool isElementLargeEnoughForMainContent(const HTMLMediaElement&);
+static bool isElementLargeEnoughForMainContent(const HTMLMediaElement&, MediaSessionMainContentPurpose);
 
 #if !LOG_DISABLED
 static String restrictionName(MediaElementSession::BehaviorRestrictions restriction)
@@ -274,7 +273,7 @@ bool MediaElementSession::canShowControlsManager() const
             return false;
         }
 
-        if (isLargeEnoughForMainContent()) {
+        if (isLargeEnoughForMainContent(MediaSessionMainContentPurpose::MediaControls)) {
             LOG(Media, "MediaElementSession::canShowControlsManager - returning TRUE: Is main content");
             return true;
         }
@@ -284,9 +283,9 @@ bool MediaElementSession::canShowControlsManager() const
     return false;
 }
 
-bool MediaElementSession::isLargeEnoughForMainContent() const
+bool MediaElementSession::isLargeEnoughForMainContent(MediaSessionMainContentPurpose purpose) const
 {
-    return isElementLargeEnoughForMainContent(m_element);
+    return isElementLargeEnoughForMainContent(m_element, purpose);
 }
 
 double MediaElementSession::mostRecentUserInteractionTime() const
@@ -296,7 +295,7 @@ double MediaElementSession::mostRecentUserInteractionTime() const
 
 bool MediaElementSession::wantsToObserveViewportVisibilityForMediaControls() const
 {
-    return isLargeEnoughForMainContent();
+    return isLargeEnoughForMainContent(MediaSessionMainContentPurpose::MediaControls);
 }
 
 bool MediaElementSession::wantsToObserveViewportVisibilityForAutoplay() const
@@ -582,7 +581,7 @@ size_t MediaElementSession::maximumMediaSourceBufferSize(const SourceBuffer& buf
 }
 #endif
 
-static bool isMainContent(const HTMLMediaElement& element)
+static bool isMainContentForPurposesOfAutoplay(const HTMLMediaElement& element)
 {
     if (!element.hasAudio() || !element.hasVideo())
         return false;
@@ -592,7 +591,7 @@ static bool isMainContent(const HTMLMediaElement& element)
     if (!renderer)
         return false;
 
-    if (!isElementLargeEnoughForMainContent(element))
+    if (!isElementLargeEnoughForMainContent(element, MediaSessionMainContentPurpose::Autoplay))
         return false;
 
     // Elements which are hidden by style, or have been scrolled out of view, cannot be main content.
@@ -652,10 +651,10 @@ static bool isElementLargeRelativeToMainFrame(const HTMLMediaElement& element)
     return maxVisibleClientWidth * maxVisibleClientHeight > minimumPercentageOfMainFrameAreaForMainContent * mainFrameView.visibleWidth() * mainFrameView.visibleHeight();
 }
 
-static bool isElementLargeEnoughForMainContent(const HTMLMediaElement& element)
+static bool isElementLargeEnoughForMainContent(const HTMLMediaElement& element, MediaSessionMainContentPurpose purpose)
 {
     static const double elementMainContentAreaMinimum = 400 * 300;
-    static const double maximumAspectRatio = 1.8; // Slightly larger than 16:9.
+    static const double maximumAspectRatio = purpose == MediaSessionMainContentPurpose::MediaControls ? 3 : 1.8;
     static const double minimumAspectRatio = .5; // Slightly smaller than 9:16.
 
     // Elements which have not yet been laid out, or which are not yet in the DOM, cannot be main content.
@@ -688,7 +687,7 @@ void MediaElementSession::mainContentCheckTimerFired()
 bool MediaElementSession::updateIsMainContent() const
 {
     bool wasMainContent = m_isMainContent;
-    m_isMainContent = isMainContent(m_element);
+    m_isMainContent = isMainContentForPurposesOfAutoplay(m_element);
 
     if (m_isMainContent != wasMainContent)
         m_element.updateShouldPlay();
index 5b5c5c6..833fe6a 100644 (file)
 
 namespace WebCore {
 
+enum class MediaSessionMainContentPurpose {
+    MediaControls,
+    Autoplay
+};
+
 class Document;
 class HTMLMediaElement;
 class SourceBuffer;
@@ -114,7 +119,7 @@ public:
     bool wantsToObserveViewportVisibilityForMediaControls() const;
     bool wantsToObserveViewportVisibilityForAutoplay() const;
     bool canShowControlsManager() const;
-    bool isLargeEnoughForMainContent() const;
+    bool isLargeEnoughForMainContent(MediaSessionMainContentPurpose) const;
     double mostRecentUserInteractionTime() const;
 
 private:
index 3706b16..5744a4b 100644 (file)
@@ -1,3 +1,18 @@
+2016-09-10  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Apple.com keynote does not display media controls
+        https://bugs.webkit.org/show_bug.cgi?id=161833
+        <rdar://problem/28230123>
+
+        Reviewed by Tim Horton.
+
+        New unit test verifying that wide videos (~2 aspect ratio) still get media controls.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit2Cocoa/VideoControlsManager.mm:
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WebKit2Cocoa/wide-autoplaying-video-with-audio.html: Added.
+
 2016-09-09  Tim Horton  <timothy_horton@apple.com>
 
         WKThumbnailView should expose a mode where it can be reparented without resnapshotting
index b38017d..a87d4dc 100644 (file)
@@ -59,6 +59,7 @@
                2DD7D3AF178227B30026E1E3 /* lots-of-text-vertical-lr.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2DD7D3AE178227AC0026E1E3 /* lots-of-text-vertical-lr.html */; };
                2DE71AFE1D49C0BD00904094 /* AnimatedResize.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2DE71AFD1D49C0BD00904094 /* AnimatedResize.mm */; };
                2DE71B001D49C3ED00904094 /* blinking-div.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2DE71AFF1D49C2F000904094 /* blinking-div.html */; };
+               2E131C181D83A98A001BA36C /* wide-autoplaying-video-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E131C171D83A97E001BA36C /* wide-autoplaying-video-with-audio.html */; };
                2E14A5291D3FE96B0010F35B /* autoplaying-video-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E14A5281D3FE8B80010F35B /* autoplaying-video-with-audio.html */; };
                2E1B7B001D41ABA7007558B4 /* large-video-seek-after-ending.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1B7AFF1D41A95F007558B4 /* large-video-seek-after-ending.html */; };
                2E1B7B021D41B1B9007558B4 /* large-video-hides-controls-after-seek-to-end.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1B7B011D41B1B3007558B4 /* large-video-hides-controls-after-seek-to-end.html */; };
                        dstPath = TestWebKitAPI.resources;
                        dstSubfolderSpec = 7;
                        files = (
+                               2E131C181D83A98A001BA36C /* wide-autoplaying-video-with-audio.html in Copy Resources */,
                                2E54F40D1D7BC84200921ADF /* large-video-mutes-onplaying.html in Copy Resources */,
                                2E691AF31D79E75E00129407 /* large-video-playing-scroll-away.html in Copy Resources */,
                                2E691AF11D79E51A00129407 /* large-videos-autoplaying-scroll-to-video.html in Copy Resources */,
                2DD7D3AE178227AC0026E1E3 /* lots-of-text-vertical-lr.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "lots-of-text-vertical-lr.html"; sourceTree = "<group>"; };
                2DE71AFD1D49C0BD00904094 /* AnimatedResize.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AnimatedResize.mm; sourceTree = "<group>"; };
                2DE71AFF1D49C2F000904094 /* blinking-div.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "blinking-div.html"; sourceTree = "<group>"; };
+               2E131C171D83A97E001BA36C /* wide-autoplaying-video-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "wide-autoplaying-video-with-audio.html"; sourceTree = "<group>"; };
                2E14A5281D3FE8B80010F35B /* autoplaying-video-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "autoplaying-video-with-audio.html"; sourceTree = "<group>"; };
                2E1B7AFF1D41A95F007558B4 /* large-video-seek-after-ending.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-seek-after-ending.html"; sourceTree = "<group>"; };
                2E1B7B011D41B1B3007558B4 /* large-video-hides-controls-after-seek-to-end.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-hides-controls-after-seek-to-end.html"; sourceTree = "<group>"; };
                A16F66B81C40E9E100BD4D24 /* Resources */ = {
                        isa = PBXGroup;
                        children = (
+                               2E131C171D83A97E001BA36C /* wide-autoplaying-video-with-audio.html */,
                                2E54F40C1D7BC83900921ADF /* large-video-mutes-onplaying.html */,
                                2E691AF21D79E75400129407 /* large-video-playing-scroll-away.html */,
                                2E691AF01D79E51400129407 /* large-videos-autoplaying-scroll-to-video.html */,
index b9e32c7..d07d2e4 100644 (file)
@@ -411,6 +411,14 @@ TEST(VideoControlsManager, VideoControlsManagerLongSkinnyVideoInWideMainFrame)
     [webView expectControlsManager:NO afterReceivingMessage:@"playing"];
 }
 
+TEST(VideoControlsManager, VideoControlsManagerWideMediumSizedVideoInWideMainFrame)
+{
+    RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 1600, 800));
+
+    [webView loadTestPageNamed:@"wide-autoplaying-video-with-audio"];
+    [webView expectControlsManager:YES afterReceivingMessage:@"playing"];
+}
+
 TEST(VideoControlsManager, VideoControlsManagerFullSizeVideoInWideMainFrame)
 {
     RetainPtr<VideoControlsManagerTestWebView*> webView = setUpWebViewForTestingVideoControlsManager(NSMakeRect(0, 0, 1600, 800));
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/wide-autoplaying-video-with-audio.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/wide-autoplaying-video-with-audio.html
new file mode 100644 (file)
index 0000000..0eb9af6
--- /dev/null
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        video {
+            width: 800px;
+            height: 400px;
+        }
+    </style>
+    <script>
+    function finishTest() {
+        setTimeout(function() {
+            try {
+                window.webkit.messageHandlers.playingHandler.postMessage("playing");
+            } catch(e) { }
+        }, 0);
+    }
+   </script>
+</head>
+<body>
+    <video autoplay src="video-with-audio.mp4" webkit-playsinline onplaying=finishTest()></video>
+</body>
+</html>