[modern-media-controls] AirPlaySupport should be disabled by default
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 May 2018 15:34:38 +0000 (15:34 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 May 2018 15:34:38 +0000 (15:34 +0000)
https://bugs.webkit.org/show_bug.cgi?id=185658
<rdar://problem/40272213>

Patch by Antoine Quint <graouts@apple.com> on 2018-05-17
Reviewed by Simon Fraser.

Source/WebCore:

We now only enable AirplaySupport if the controls are visible to the user _and_ media has played.

Test: media/modern-media-controls/airplay-support/airplay-support-disable-event-listeners-until-play.html

* Modules/modern-media-controls/media/airplay-support.js:
(AirplaySupport.prototype.enable):
(AirplaySupport.prototype.controlsUserVisibilityDidChange):
(AirplaySupport.prototype._shouldBeEnabled):
(AirplaySupport):

LayoutTests:

Add a new test that checks that we create an AirplaySupport object only after media has started playing.

* media/modern-media-controls/airplay-support/airplay-support-disable-event-listeners-until-play-expected.txt: Added.
* media/modern-media-controls/airplay-support/airplay-support-disable-event-listeners-until-play.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/media/modern-media-controls/airplay-support/airplay-support-disable-event-listeners-until-play-expected.txt [new file with mode: 0644]
LayoutTests/media/modern-media-controls/airplay-support/airplay-support-disable-event-listeners-until-play.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/modern-media-controls/media/airplay-support.js

index 720cdfc..26bfb85 100644 (file)
@@ -1,3 +1,16 @@
+2018-05-17  Antoine Quint  <graouts@apple.com>
+
+        [modern-media-controls] AirPlaySupport should be disabled by default
+        https://bugs.webkit.org/show_bug.cgi?id=185658
+        <rdar://problem/40272213>
+
+        Reviewed by Simon Fraser.
+
+        Add a new test that checks that we create an AirplaySupport object only after media has started playing.
+
+        * media/modern-media-controls/airplay-support/airplay-support-disable-event-listeners-until-play-expected.txt: Added.
+        * media/modern-media-controls/airplay-support/airplay-support-disable-event-listeners-until-play.html: Added.
+
 2018-05-17  Rob Buis  <rbuis@igalia.com>
 
         Remove cssom-remove-shorthand-property.html test
diff --git a/LayoutTests/media/modern-media-controls/airplay-support/airplay-support-disable-event-listeners-until-play-expected.txt b/LayoutTests/media/modern-media-controls/airplay-support/airplay-support-disable-event-listeners-until-play-expected.txt
new file mode 100644 (file)
index 0000000..1fc8c57
--- /dev/null
@@ -0,0 +1,23 @@
+Testing AirPlaySupport is only enabled once media has started playing.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Starting test, the media can be played but hasn't started playing.
+
+Making AirPlay routes available.
+
+Airplay routes are available and controls are visible on the screen, but since the media hasn't played yet, AirplaySupport should be disabled.
+PASS controls.airplayButton.uiDelegate is undefined.
+PASS controls.visible is true
+PASS controls.faded is false
+
+We play the media so that the Airplay button can be enabled.
+
+Media played, AirplaySupport should become enabled now.
+PASS !!controls.airplayButton.uiDelegate became true
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/media/modern-media-controls/airplay-support/airplay-support-disable-event-listeners-until-play.html b/LayoutTests/media/modern-media-controls/airplay-support/airplay-support-disable-event-listeners-until-play.html
new file mode 100644 (file)
index 0000000..58b2c3a
--- /dev/null
@@ -0,0 +1,83 @@
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../resources/media-controls-loader.js" type="text/javascript"></script>
+<body>
+<video src="../../content/test.mp4" style="width: 320px; height: 240px;" preload controls></video>
+<div id="host"></div>
+<script type="text/javascript">
+
+window.jsTestIsAsync = true;
+
+description("Testing <code>AirPlaySupport</code> is only enabled once media has started playing.");
+
+const container = document.querySelector("div#host");
+const media = document.querySelector("video");
+const mediaController = createControls(container, media, null);
+const controls = mediaController.controls;
+
+controls.autoHideController.autoHideDelay = 100;
+
+media.addEventListener("canplay", startTest);
+
+function startTest()
+{
+    debug("Starting test, the media can be played but hasn't started playing.");
+
+    makeAirPlayAvailable();
+}
+
+function makeAirPlayAvailable()
+{
+    debug("");
+    debug("Making AirPlay routes available.");
+    media.addEventListener("webkitplaybacktargetavailabilitychanged", playbackTargetAvailabilityChangedOnce, true);
+    window.internals.setMockMediaPlaybackTargetPickerEnabled(true);
+}
+
+function playbackTargetAvailabilityChangedOnce(event)
+{
+    media.removeEventListener('webkitplaybacktargetavailabilitychanged', playbackTargetAvailabilityChangedOnce, true);
+    media.addEventListener('webkitplaybacktargetavailabilitychanged', playbackTargetAvailabilityChangedAgain, true);
+
+    window.internals.setMockMediaPlaybackTargetPickerState('Sleepy TV', 'DeviceAvailable');
+}
+
+function playbackTargetAvailabilityChangedAgain(event)
+{
+    // setMockMediaPlaybackTargetPickerState happens asynchronously in WK2 and a
+    // "webkitplaybacktargetavailabilitychanged" is always sent when an event listener
+    // is added, so we may get a "not available" event first.
+    if (event.availability == 'not-available')
+        return;
+
+    media.removeEventListener('webkitplaybacktargetavailabilitychanged', playbackTargetAvailabilityChangedAgain, true);
+
+    debug("");
+    debug("Airplay routes are available and controls are visible on the screen, but since the media hasn't played yet, AirplaySupport should be disabled.");
+    shouldBeUndefined("controls.airplayButton.uiDelegate");
+    shouldBeTrue("controls.visible");
+    shouldBeFalse("controls.faded");
+
+    debug("");
+    debug("We play the media so that the Airplay button can be enabled.");
+    media.addEventListener("play", mediaDidPlay);
+    media.play();
+}
+
+function mediaDidPlay()
+{
+    debug("");
+    debug("Media played, AirplaySupport should become enabled now.");
+    shouldBecomeEqual("!!controls.airplayButton.uiDelegate", "true", finishTest);
+}
+
+function finishTest()
+{
+    debug("");
+    container.remove();
+    media.remove();
+    finishJSTest();
+}
+
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
index 23d6a87..d472ea5 100644 (file)
@@ -1,3 +1,21 @@
+2018-05-17  Antoine Quint  <graouts@apple.com>
+
+        [modern-media-controls] AirPlaySupport should be disabled by default
+        https://bugs.webkit.org/show_bug.cgi?id=185658
+        <rdar://problem/40272213>
+
+        Reviewed by Simon Fraser.
+
+        We now only enable AirplaySupport if the controls are visible to the user _and_ media has played.
+
+        Test: media/modern-media-controls/airplay-support/airplay-support-disable-event-listeners-until-play.html
+
+        * Modules/modern-media-controls/media/airplay-support.js:
+        (AirplaySupport.prototype.enable):
+        (AirplaySupport.prototype.controlsUserVisibilityDidChange):
+        (AirplaySupport.prototype._shouldBeEnabled):
+        (AirplaySupport):
+
 2018-05-17  Zalan Bujtas  <zalan@apple.com>
 
         [LFC] Replace ASSERT_NOT_REACHED with ASSERT_NOT_IMPLEMENTED_YET where applicable.
index 248e576..473e73d 100644 (file)
@@ -38,6 +38,12 @@ class AirplaySupport extends MediaControllerSupport
         return ["webkitplaybacktargetavailabilitychanged", "webkitcurrentplaybacktargetiswirelesschanged"];
     }
 
+    enable()
+    {
+        if (this._shouldBeEnabled())
+            super.enable();
+    }
+
     buttonWasPressed(control)
     {
         this.mediaController.media.webkitShowPlaybackTargetPicker();
@@ -45,8 +51,7 @@ class AirplaySupport extends MediaControllerSupport
 
     controlsUserVisibilityDidChange()
     {
-        const controls = this.mediaController.controls;
-        if (controls.visible && !controls.faded)
+        if (this._shouldBeEnabled())
             this.enable();
         else
             this.disable();
@@ -67,4 +72,15 @@ class AirplaySupport extends MediaControllerSupport
         this.mediaController.controls.muteButton.enabled = !this.control.on;
     }
 
+    // Private
+
+    _shouldBeEnabled()
+    {
+        if (!this.mediaController.hasPlayed)
+            return false;
+
+        const controls = this.mediaController.controls;
+        return controls.visible && !controls.faded;
+    }
+
 }