Title: [164519] trunk/Source/WebCore
Revision
164519
Author
[email protected]
Date
2014-02-21 18:45:01 -0800 (Fri, 21 Feb 2014)

Log Message

[iOS Media] Wireless target UI
https://bugs.webkit.org/show_bug.cgi?id=129189
<rdar://problem/15349928>
<rdar://problem/16100060>

Reviewed by Eric Carlson.

Implement a prototype UI for wireless playback targets. The UI
doesn't currently work, but can be simulated via a class variable
in ControllerIOS.

* Modules/mediacontrols/mediaControlsiOS.css:
(audio::-webkit-media-controls-panel button): Reset the default style of
button elements, to avoid getting a border.
(audio::-webkit-media-controls-wireless-playback-status): Holds the UI showing
the user that the media is playing on another target.
(audio::-webkit-media-controls-wireless-playback-status.hidden):
(audio::-webkit-media-controls-wireless-playback-picker-button): The button to
trigger selection of targets.
(audio::-webkit-media-controls-wireless-playback-picker-button.active):
(audio::-webkit-media-controls-panel): This needs to be position absolute for
the wireless playback status to fill the viewport.
* Modules/mediacontrols/mediaControlsiOS.js:
(ControllerIOS): Check for targets.
(ControllerIOS.prototype.addVideoListeners):
(ControllerIOS.prototype.removeVideoListeners):
(ControllerIOS.prototype.UIString): New method to return localized strings (with
a FIXME).
(ControllerIOS.prototype.shouldHaveAnyUI): Needs to display if there is a wireless
target.
(ControllerIOS.prototype.currentPlaybackTargetIsWireless):
(ControllerIOS.prototype.updateWirelessPlaybackStatus): Create the status content,
replacing the device name if it is available.
(ControllerIOS.prototype.updateWirelessTargetAvailable):
(ControllerIOS.prototype.createControls):
(ControllerIOS.prototype.configureInlineControls):
(ControllerIOS.prototype.handleWirelessPlaybackChange):
(ControllerIOS.prototype.handleWirelessTargetAvailableChange):
(ControllerIOS.prototype.handleWirelessPickerButtonClicked):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (164518 => 164519)


--- trunk/Source/WebCore/ChangeLog	2014-02-22 01:58:54 UTC (rev 164518)
+++ trunk/Source/WebCore/ChangeLog	2014-02-22 02:45:01 UTC (rev 164519)
@@ -1,3 +1,45 @@
+2014-02-21  Dean Jackson  <[email protected]>
+
+        [iOS Media] Wireless target UI
+        https://bugs.webkit.org/show_bug.cgi?id=129189
+        <rdar://problem/15349928>
+        <rdar://problem/16100060>
+
+        Reviewed by Eric Carlson.
+
+        Implement a prototype UI for wireless playback targets. The UI
+        doesn't currently work, but can be simulated via a class variable
+        in ControllerIOS.
+
+        * Modules/mediacontrols/mediaControlsiOS.css:
+        (audio::-webkit-media-controls-panel button): Reset the default style of
+        button elements, to avoid getting a border.
+        (audio::-webkit-media-controls-wireless-playback-status): Holds the UI showing
+        the user that the media is playing on another target.
+        (audio::-webkit-media-controls-wireless-playback-status.hidden):
+        (audio::-webkit-media-controls-wireless-playback-picker-button): The button to
+        trigger selection of targets.
+        (audio::-webkit-media-controls-wireless-playback-picker-button.active):
+        (audio::-webkit-media-controls-panel): This needs to be position absolute for
+        the wireless playback status to fill the viewport.
+        * Modules/mediacontrols/mediaControlsiOS.js:
+        (ControllerIOS): Check for targets.
+        (ControllerIOS.prototype.addVideoListeners):
+        (ControllerIOS.prototype.removeVideoListeners):
+        (ControllerIOS.prototype.UIString): New method to return localized strings (with
+        a FIXME).
+        (ControllerIOS.prototype.shouldHaveAnyUI): Needs to display if there is a wireless
+        target.
+        (ControllerIOS.prototype.currentPlaybackTargetIsWireless):
+        (ControllerIOS.prototype.updateWirelessPlaybackStatus): Create the status content,
+        replacing the device name if it is available.
+        (ControllerIOS.prototype.updateWirelessTargetAvailable):
+        (ControllerIOS.prototype.createControls):
+        (ControllerIOS.prototype.configureInlineControls):
+        (ControllerIOS.prototype.handleWirelessPlaybackChange):
+        (ControllerIOS.prototype.handleWirelessTargetAvailableChange):
+        (ControllerIOS.prototype.handleWirelessPickerButtonClicked):
+
 2014-02-21  Jer Noble  <[email protected]>
 
         Make a generic CDMPrivateMediaPlayer and move its CDMSession into platform/.

Modified: trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.css (164518 => 164519)


--- trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.css	2014-02-22 01:58:54 UTC (rev 164518)
+++ trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.css	2014-02-22 02:45:01 UTC (rev 164519)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc.  All rights reserved.
+ * Copyright (C) 2012, 2013, 2014 Apple Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -55,6 +55,47 @@
     font-family: -apple-system-font;
 }
 
+video::-webkit-media-controls-panel input[type="button"],
+audio::-webkit-media-controls-panel input[type="button"],
+video::-webkit-media-controls-panel button,
+audio::-webkit-media-controls-panel button {
+    padding: 0;
+    border: none;
+    -webkit-appearance: none;
+}
+
+video::-webkit-media-controls-wireless-playback-status,
+audio::-webkit-media-controls-wireless-playback-status {
+    display: block;
+    width: 100%;
+    height: 100%;
+    background-color: black;
+    background-repeat: no-repeat;
+    background-position: 50% 50%;
+    background-size: 100% 50%;
+}
+
+video::-webkit-media-controls-wireless-playback-status.hidden,
+audio::-webkit-media-controls-wireless-playback-status.hidden {
+    display: none;
+}
+
+video::-webkit-media-controls-wireless-playback-picker-button,
+audio::-webkit-media-controls-wireless-playback-picker-button {
+    display: block;
+    width: 21px;
+    height: 21px;
+    background-color: rgb(92, 92, 92);
+    -webkit-mask-repeat: no-repeat;
+    -webkit-mask-position: 0 1px;
+    -webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 350 305"><g fill="white"><polygon points="50.699,293 175,146 299.302,293"/><polygon points="9,9 9,213 97.392,213 110.921,197 25,197 25,25 325,25 325,197 239.079,197 252.608,213 341,213 341,9"/></g></svg>');
+}
+
+video::-webkit-media-controls-wireless-playback-picker-button.active,
+audio::-webkit-media-controls-wireless-playback-picker-button.active {
+    background-color: #1060FE;
+}
+
 video::-webkit-media-text-track-container,
 audio::-webkit-media-text-track-container {
     position: relative;
@@ -64,7 +105,7 @@
 video::-webkit-media-controls-panel,
 audio::-webkit-media-controls-panel {
     box-sizing: border-box;
-    position: relative;
+    position: absolute;
     bottom: 0;
     width: 100%;
     padding-bottom: 1px;
@@ -91,7 +132,6 @@
     opacity: 1;
 }
 
-
 video::-webkit-media-controls-rewind-button,
 audio::-webkit-media-controls-rewind-button,
 video::-webkit-media-controls-panel .mute-box,

Modified: trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.js (164518 => 164519)


--- trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.js	2014-02-22 01:58:54 UTC (rev 164518)
+++ trunk/Source/WebCore/Modules/mediacontrols/mediaControlsiOS.js	2014-02-22 02:45:01 UTC (rev 164519)
@@ -5,18 +5,31 @@
 
 function ControllerIOS(root, video, host)
 {
+    this.hasWirelessPlaybackTargets = false;
     Controller.call(this, root, video, host);
+
+    this.updateWirelessTargetAvailable();
+    this.updateWirelessPlaybackStatus();
 };
 
 /* Enums */
 ControllerIOS.StartPlaybackControls = 2;
 
+/* Globals */
+ControllerIOS.gWirelessImage = 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 245"><g fill="#1060FE"><path d="M193.6,6.3v121.6H6.4V6.3H193.6 M199.1,0.7H0.9v132.7h198.2V0.7L199.1,0.7z"/><path d="M43.5,139.3c15.8,8,35.3,12.7,56.5,12.7s40.7-4.7,56.5-12.7H43.5z"/></g><g text-anchor="middle" font-family="Helvetica Neue"><text x="100" y="204" fill="white" font-size="24">##DEVICE_TYPE##</text><text x="100" y="234" fill="#5C5C5C" font-size="21">##DEVICE_NAME##</text></g></svg>';
+ControllerIOS.gSimulateWirelessPlaybackTarget = false; // Used for testing when there are no wireless targets.
+
 ControllerIOS.prototype = {
     addVideoListeners: function() {
         Controller.prototype.addVideoListeners.call(this);
 
         this.listenFor(this.video, 'webkitbeginfullscreen', this.handleFullscreenChange);
         this.listenFor(this.video, 'webkitendfullscreen', this.handleFullscreenChange);
+
+        if (window.WebKitPlaybackTargetAvailabilityEvent) {
+            this.listenFor(this.video, 'webkitcurrentplaybacktargetiswirelesschanged', this.handleWirelessPlaybackChange);
+            this.listenFor(this.video, 'webkitplaybacktargetavailabilitychanged', this.handleWirelessTargetAvailableChange);
+        }
     },
 
     removeVideoListeners: function() {
@@ -24,9 +37,13 @@
 
         this.stopListeningFor(this.video, 'webkitbeginfullscreen', this.handleFullscreenChange);
         this.stopListeningFor(this.video, 'webkitendfullscreen', this.handleFullscreenChange);
+
+        if (window.WebKitPlaybackTargetAvailabilityEvent) {
+            this.stopListeningFor(this.video, 'webkitcurrentplaybacktargetiswirelesschanged', this.handleWirelessPlaybackChange);
+            this.stopListeningFor(this.video, 'webkitplaybacktargetavailabilitychanged', this.handleWirelessTargetAvailableChange);
+        }
     },
 
-
     createBase: function() {
         Controller.prototype.createBase.call(this);
 
@@ -39,6 +56,22 @@
         this.stopListeningFor(this.base, 'mouseout', this.handleWrapperMouseOut);
     },
 
+    UIString: function(s){
+        var string = Controller.prototype.UIString.call(this, s);
+        if (string)
+            return string;
+
+        if (this.localizedStrings[s])
+            return this.localizedStrings[s];
+        else
+            return s; // FIXME: LOG something if string not localized.
+    },
+    localizedStrings: {
+        // FIXME: Move localization to ext strings file <http://webkit.org/b/120956>
+        '##DEVICE_TYPE##': 'AirPlay',
+        '##DEVICE_NAME##': 'This video is playing on "##DEVICE_NAME##".',
+    },
+
     shouldHaveStartPlaybackButton: function() {
         var allowsInline = this.host.mediaPlaybackAllowsInline;
 
@@ -68,12 +101,60 @@
     },
 
     shouldHaveAnyUI: function() {
-        return this.shouldHaveStartPlaybackButton() || Controller.prototype.shouldHaveAnyUI.call(this);
+        return this.shouldHaveStartPlaybackButton() || Controller.prototype.shouldHaveAnyUI.call(this) || this.currentPlaybackTargetIsWireless();
     },
 
+    currentPlaybackTargetIsWireless: function()
+    {
+        return ControllerIOS.gSimulateWirelessPlaybackTarget || ((typeof this.video.webkitCurrentPlaybackTargetIsWireless === "function") && this.video.webkitCurrentPlaybackTargetIsWireless());
+    },
+
+    updateWirelessPlaybackStatus: function()
+    {
+        if (this.currentPlaybackTargetIsWireless()) {
+            var backgroundImageSVG = "url('" + ControllerIOS.gWirelessImage + "')";
+
+            var deviceType = this.UIString('##DEVICE_TYPE##');
+            backgroundImageSVG = backgroundImageSVG.replace('##DEVICE_TYPE##', deviceType);
+
+            // FIXME: Get the device type and name from the host.
+            var deviceName = "unknown";
+            var deviceName = this.UIString('##DEVICE_NAME##').replace('##DEVICE_NAME##', deviceName);;
+            backgroundImageSVG = backgroundImageSVG.replace('##DEVICE_NAME##', deviceName);
+
+            this.controls.wirelessPlaybackStatus.style.backgroundImage = backgroundImageSVG;
+            this.controls.wirelessPlaybackStatus.setAttribute('aria-label', deviceType + ", " + deviceName);
+
+            this.controls.wirelessPlaybackStatus.classList.remove(this.ClassNames.hidden);
+            this.controls.wirelessTargetPicker.classList.add(this.ClassNames.active);
+        } else {
+            this.controls.wirelessPlaybackStatus.classList.add(this.ClassNames.hidden);
+            this.controls.wirelessTargetPicker.classList.remove(this.ClassNames.active);
+        }
+    },
+
+    updateWirelessTargetAvailable: function()
+    {
+        if (ControllerIOS.gSimulateWirelessPlaybackTarget || this.hasWirelessPlaybackTargets)
+            this.controls.wirelessTargetPicker.classList.remove(this.ClassNames.hidden);
+        else
+            this.controls.wirelessTargetPicker.classList.add(this.ClassNames.hidden);
+    },
+
     createControls: function() {
         Controller.prototype.createControls.call(this);
 
+        var wirelessPlaybackStatus = this.controls.wirelessPlaybackStatus = document.createElement('div');
+        wirelessPlaybackStatus.setAttribute('pseudo', '-webkit-media-controls-wireless-playback-status');
+        wirelessPlaybackStatus.classList.add(this.ClassNames.hidden);
+
+        var wirelessTargetPicker = this.controls.wirelessTargetPicker = document.createElement('button');
+        wirelessTargetPicker.setAttribute('pseudo', '-webkit-media-controls-wireless-playback-picker-button');
+        wirelessTargetPicker.setAttribute('aria-label', this.UIString('Choose Wireless Display'));
+        this.listenFor(wirelessTargetPicker, 'click', this.handleWirelessPickerButtonClicked);
+        if (!ControllerIOS.gSimulateWirelessPlaybackTarget)
+            wirelessTargetPicker.classList.add(this.ClassNames.hidden);
+
         this.listenFor(this.controls.startPlaybackButton, 'touchstart', this.handleStartPlaybackButtonTouchStart);
         this.listenFor(this.controls.startPlaybackButton, 'touchend', this.handleStartPlaybackButtonTouchEnd);
         this.listenFor(this.controls.startPlaybackButton, 'touchcancel', this.handleStartPlaybackButtonTouchCancel);
@@ -111,8 +192,11 @@
     },
 
     configureInlineControls: function() {
+        this.base.appendChild(this.controls.wirelessPlaybackStatus);
+
         this.controls.panel.appendChild(this.controls.playButton);
         this.controls.panel.appendChild(this.controls.timelineBox);
+        this.controls.panel.appendChild(this.controls.wirelessTargetPicker);
         this.controls.timelineBox.appendChild(this.controls.currentTime);
         this.controls.timelineBox.appendChild(this.controls.timeline);
         this.controls.timelineBox.appendChild(this.controls.remainingTime);
@@ -274,6 +358,21 @@
         this.updateControls();
     },
 
+    handleWirelessPlaybackChange: function(event)
+    {
+        updateWirelessPlaybackStatus();
+    },
+
+    handleWirelessTargetAvailableChange: function(event)
+    {
+        this.hasWirelessPlaybackTargets = event.availability == "available";
+        updateWirelessTargetAvailable();
+    },
+
+    handleWirelessPickerButtonClicked: function(event)
+    {
+        video.webkitShowPlaybackTargetPicker();
+    },
 };
 
 Object.create(Controller.prototype).extend(ControllerIOS.prototype);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to