Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.
This specification defines an API to enable web content to access external presentation-type displays and use them for presenting web content.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document was published by the Second Screen Presentation Working Group as an Editor's Draft. If you wish to make comments regarding this document, please send them to public-secondscreen@w3.org (subscribe, archives). All comments are welcome.
This document is a work in progress and is subject to change. It builds on the final report (dated 18 November 2014) produced by the Second Screen Presentation Community Group. Algorithms have been drafted in particular. Most sections are still incomplete or underspecified. Privacy and security considerations are missing. A few open issues are noted inline. Please check the group's issue tracker on GitHub for an accurate list. Feedback from early experimentations is encouraged to allow the Second Screen Presentation Working Group to evolve the specification based on implementation issues.
Publication as a First Public Working Draft does not imply endorsement by the W3C Membership. This draft document may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent that the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This document is governed by the 1 August 2014 W3C Process Document.
PresentationSession
NavigatorPresentation
AvailableChangeEvent
DefaultSessionStart
This specification aims to make secondary displays such as a projector or a connected TV available to the web and takes into account displays that are attached using wired (HDMI, DVI or similar) and wireless technologies (MiraCast, Chromecast, DLNA, AirPlay or similar).
Devices with limited screen size lack the ability to show content to a larger audience, for example, a group of colleagues in a conference room, or friends and family at home. Showing content on an external large display helps to improve the perceived quality and impact of the presented content.
At its core, this specification enables an exchange of messages between a requesting page and a presentation page shown in the secondary display. How those messages are transmitted is left to the UA in order to allow for the use of display devices that can be attached to a wide variety of ways. For example, when a display device is attached using HDMI or MiraCast, the UA on the requesting device can render the requested presentation page in that same UA. Instead of displaying in a window on that same device, however, it can use whatever means the operating system provides for using those external displays. In that case, both the requesting page and the presentation page run on the requesting device and the operating system is used to route the presentation display output to the other display device. The second display device doesn't need to know anything about this spec or that the content involves HTML5.
Alternately, some types of external displays may be able to render HTML5 themselves and may have defined their way to send messages to that content. In that case, the UA on the requesting device would not need to render the presentation page itself. Instead, the UA could act as a proxy translating the request to show a page and the messages into the form understood by the display device.
This way of attaching to displays could be enhanced in the future by defining a standard protocol for delivering these types of messages that display devices could choose to implement.
The API defined here is intended to be used with UAs that attach to display devices through any of the above means.
ISSUE 40: Screen availability mechanism for multiple sessions
The requirements enumerated in this section are derived from the use cases.
Multi-screen enumeration and named identification requirement was removed after discussion on the mailing list.
All diagrams, examples, and notes in this specification are non-normative, as are all sections explicitly marked non-normative. Everything else in this specification is normative.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. For readability, these words do not appear in all uppercase letters in this specification. [RFC2119]
Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and terminate these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc.) used in introducing the algorithm.
Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)
The terms browsing context, event handlers, event handler event types, firing an event, navigate, queing a task are defined in [HTML5].
The term DOMException is defined in [DOM].
The term Promise is defined in [ES6]. The terms resolving a Promise, and rejecting a Promise are used as explained in [PROMGUIDE].
The term URL is defined in the WHATWG URL standard: [URL].
The terms ArrayBuffer, ArrayBufferView are defined in the Typed Array specification: [TYPEDARRAY].
The term Blob is defined in the File API specification: [FILEAPI].
This document provides interface definitions using the [WEBIDL] standard.
ISSUE 42: Make the Example section more concise
This section shows example codes that highlight the usage of main
features of the Presentation API. In these examples,
controller.html
represents the controlling page that runs
in the opener UA and presentation.html
represents the
presenting page that runs in the presenting UA. Both pages are served
from the domain http://example.org
(http://example.org/controller.html
and
http://example.org/presentation.html
). Please refer to the
comments in the code examples for further details.
<!-- controller.html --> <button id="castBtn" style="display: none;">Cast</button> <script> // the cast button is visible if at least one presentation display is available var castBtn = document.getElementById("castBtn"); // availablechange event is fired when the presentation display availability changes navigator.presentation.onavailablechange = function (evt) { // show or hide cast button depending on display availability castBtn.style.display = evt.available ? "inline" : "none"; }; </script>
<!-- controller.html --> <script> // it is also possible to use relative presentation URL e.g. "presentation.html" var presUrl = "http://example.com/presentation.html"; // create random presId var presId = Math.random().toFixed(6).substr(2); // Start new session. presId is optional. navigator.presentation.startSession(presUrl, presId) // the new started session will be passed to setSession on success .then(setSession) // user cancels the selection dialog or an error is occurred .catch(endSession); </script>
<!-- controller.html --> <script> // read presId from localStorage if exists var presId = localStorage && localStorage["presId"] || null; // presId is mandatory for joinSession. presId && navigator.presentation.joinSession(presUrl, presId) // The joined session will be passed to setSession on success .then(setSession) // no session found for presUrl and presId or an error is occurred .catch(endSession); </script>
<!-- controller.html --> <head> <!-- the link element with rel='default-presentation' allows the page to specify --> <!-- the presentation URL and id for when the UA initiates a presentation session --> <link href="http://example.com/presentation.html" rel="default-presentation" id="ABCD1234" > </head> <script> navigator.presentation.ondefaultsessionstart = function (evt) { setSession(evt.session); }; </script>
<!-- controller.html --> <script> var session; var setSession = function (theSession) { // end existing session, if any endSession(); // set the new session session = theSession; if (session) { // save presId in localStorage localStorage && (localStorage["presId"] = session.id); // monitor session's state session.onstatechange = function () { if (this == session && this.state == "disconnected") endSession(); }; // register message handler session.onmessage = function (evt) { console.log("receive message", evt.data); }; // send message to presentation page session.send("say hello"); } }; var endSession = function () { // close old session if exists session && session.close(); // remove old presId from localStorage if exists localStorage && delete localStorage["presId"]; }; </script>
<!-- presentation.html --> <script> var session = navigator.presentation.session; session.onstatechange = function () { // session.state is either 'connected' or 'disconnected' console.log("session's state is now", session.state); }; session.onmessage = function (evt) { if (evt.data == "say hello") session.send("hello"); }; </script>
A presentation display refers to an external screen available to the user agent via an implementation specific connection technology.
A presentation is an active connection between a user agent and a presentation display for displaying web content on the latter at the request of the former.
A presentation session is an object relating an opening browsing context to its presentation display and enabling two-way-messaging between them. Each such object has a presentation session state and a presentation session identifier to distinguish it from other presentation sessions.
An opening browsing context is a browsing context that has initiated or resumed a
presentation session by calling
startSession()
or
joinSession()
or received a
presentation session via
ondefaultsessionstart
event.
The presenting browsing context is the browsing context responsible for rendering to a presentation display. A presenting browsing context can reside in the same user agent as the opening browsing context or a different one.
Let D be the set of presentations that are currently known
to the user agent (regardles of their state). D is
represented as a set of tuples (U, I, S) where U is
the URL that is being presented;
I is an alphanumeric identifier for the presentation; and
S is the user agent's PresentationSession
for
the presentation. U and I together uniquely
identify the PresentationSession
of the corresponding
presentation.
PresentationSession
Each presentation
session is represented by a PresentationSession
object.
enum PresentationSessionState { "connected", "disconnected" /*, "resumed" */ }; enum BinaryType { "blob", "arraybuffer" }; interface PresentationSession : EventTarget { readonly DOMString? id; readonly attribute PresentationSessionState state; void close(); attribute EventHandler onstatechange; // Communication attribute BinaryType binaryType; EventHandler onmessage; void send (DOMString message); void send (Blob data); void send (ArrayBuffer data); void send (ArrayBufferView data); };
The id
attribute holds the alphanumeric
presentation session identifier.
The state
attribute represents the
presentation session's current state. It can take one of
the values of PresentationSessionState
depending on connection state.
When the send()
method is called on a
PresentationSession
object with a message
,
the user agent must run the algorithm to send a message through a
PresentationSession
.
When the close()
method is called on a
PresentationSession
, the user agent must run the
algorithm to close a presentation
session.
ISSUE 34: Specify the presentation initialization algorithm
ISSUE 46: Define send behavior
PresentationSession
Presentation API does not mandate a specific protocol for the
connection between the opening browsing context and
the presenting browsing context except that for
multiple calls to send
it has to be ensured that
messages are delivered to the other end in sequence.
Let presentation message data be the payload data to be
transmitted between two browsing contexts. Let presentation
message type be the type of that data, one of
text
and binary
.
When the user agent is to send a
message through a PresentationSession
S, it must
run the following steps:
state
property of
PresentationSession
is "disconnected"
,
throw an InvalidStateError
exception.
binary
if data
is one of
ArrayBuffer
or Blob
. Let
messageType be text
if data
is
of type DOMString
)
data
argument as presentation
message data and presentation message type
messageType to the destination browsing context
side.
PresentationSession
When the user agent has received a transmission from the remote side consisting of presentation message data and presentation message type, it must run the following steps:
state
property of
PresentationSession
is "disconnected"
,
abort these steps.
MessageEvent
interface, with the event type
message
, which does not bubble, is not cancelable, and
has no default action.
text
, then initialize event's
data
attribute to the contents of
presentation message data of type
DOMString
.
binary
, and binaryType
is set to
blob
, then initialise event's
data
attribute to a new Blob
object
that represents presentation message data as its
raw data.
binary
, and binaryType
is set to
arraybuffer
, then initialise event's
data
attribute to a new ArrayBuffer
object whose contents are presentation message
data.
PresentationSession
.
ISSUE 63: Define (cross) origin relationship between opener and presenting page
PresentationSession
When the user agent is to close a presentation session S, it must run the following steps:
connected
, then:
disconnected
.
statechange
at s.onstatechange.
ISSUE 35: Refine how to do session teardown/disconnect/closing
The following are the event handlers (and their corresponding event
handler event types) that must be supported, as event handler IDL
attributes, by objects implementing the
PresentationSession
interface:
Event handler | Event handler event type |
---|---|
onmessage
|
message
|
onstatechange
|
statechange
|
NavigatorPresentation
partial interface Navigator { readonly attribute NavigatorPresentation presentation; };
The presentation
attribute is used to
retrieve an instance of the NavigatorPresentation
interface, the main interface of Presentation API.
interface NavigatorPresentation : EventTarget { readonly attribute PresentationSession? session; Promise<PresentationSession> startSession(DOMString url, DOMString? presentationId); Promise<PresentationSession> joinSession(DOMString url, DOMString? presentationId); attribute EventHandler onavailablechange; attribute EventHandler ondefaultsessionstart; };
ISSUE 52: Specify the NavigatorPresentation.session attribute and its related algorithms
When the startSession(presentationUrl,
presentationId)
method is called, the user agent must run
the following steps:
presentationUrl
, the URL of the document to be presented
presentationId
, an optional identifier for the
presentation
"NotFoundError"
.
presentationId
is not
undefined, assign I to that that
presentationId
.
presentationId
is
undefined
, let I be a random
alphanumeric value of at least 16 characters drawn from the
characters [A-Za-z0-9]
.
PresentationSession
S.
S.url
to presentationUrl
,
set S.id
to I, and set
S.state
to disconnected
.
presentationUrl
in it.
"OperationError"
.
"AbortError"
.
The details of implementing the permission request and display selection are left to the user agent; for example it may show the user a dialog and allow the user to select an available screen (granting permission), or cancel the selection (denying permission).
ISSUE: Do we want to distinguish the permission-denied outcome from
the no-screens-available outcome? Developers would be able to infer
it anyway from onavailablechange
.
When the joinSession(presentationUrl,
presentationId)
method is called, the user agent must run
the following steps:
presentationUrl
, the URL of the document being presented
presentationId
, the identifier for the presentation
presentationUrl
and i is equal to presentationId
, run
the following steps:
"NotFoundError"
.
ISSUE: If no matching presentation is found, we could leave the Promise pending in case a matching presentation is started in the future.
When the user agent is to establish a presentation connection using a presentation session S, it must run the following steps:
connected
, then:
connected.
statechange
at
s.onstatechange.
The mechanism that is used to present on the remote display and
connect the opening browsing context with the
presented document is an implementation choice of the user agent.
The connection must provide a two-way messaging abstraction capable
of carrying DOMString
payloads in a reliable and
in-order fashion as described in the Send Message and
Receive Message steps below.
If T does not complete successfully, the user agent may choose to re-execute the Presentation Connection algorithm at a later time.
ISSUE: Do we want to notify the caller of a failure to connect, i.e. with an "error" onstatechange?
ISSUE: Do we want to pass the new state as a property of the statechange event?
onavailablechange
EventHandler
The following are the event handlers (and their corresponding
event handler event types) that must be supported, as event handler
IDL attributes, by objects implementing the
NavigatorPresentation
interface:
Event handler | Event handler event type |
---|---|
onavailablechange
|
availablechange
|
In order to satisfy the power saving non-functionional
requirements the user agent must keep track of the number of
EventHandler
s registered to the
onavailablechange
event. Using this information,
implementation specific discovery of presentation displays can be resumed
or suspended, in order to save power.
onavailablechange
, the user agent must also keep the
list up to date by running the algorithm for monitoring the list of available
presentation displays.
EventHandler
to
onavailablechange
When an event handler is added to the list of event handlers
registered for the onavailablechange
event, the user
agent must run the algorithm to monitor the list of
available presentation displays.
EventHandler
When an event handler is removed from the list of event handlers
registered to the onavailablechange
event, the user
agent must run the following steps:
When the user agent is to monitor the list of available presentation displays, it must run the following steps:
While there are event handlers added to NavigatorPresentation.onavailablechange, the user agent must continuously keep track the list of available presentation displays and repeat the following steps:
availablechange
at with the event's
available
property set to true
.
availablechange
with the event's
available
property set to false
.
The mechanism used to monitor presention displays availability is
left to the user agent. The user agent may choose search for
screens at any time, not just when event handlers are added to
NavigatorPresentation.onavailablechange
.
When the user agent is to cancel monitoring the list of available presentation displays, it must run the following steps:
availablechange
at E (and only
E) with the event's available
property
set to false
.
AvailableChangeEvent
[Constructor(DOMString type, optional AvailableChangeEventInit eventInitDict)]
interface AvailableChangeEvent : Event {
readonly attribute boolean available;
};
dictionary AvailableChangeEventInit : EventInit {
boolean available;
};
An event named availablechange
is fired during the
execution of the monitoring presentation display
availability algorithm when the presentation display
availability changes. It is fired at the
NavigatorPresentation
object, using the
AvailableChangeEvent
interface, with the
available
attribute set to the boolean value that the
algorithm determined.
DefaultSessionStart
[Constructor(DOMString type, optional DefaultSessionStartEventInit eventInitDict)]
interface DefaultSessionStartEvent : Event {
readonly attribute PresentationSession session;
};
dictionary DefaultSessionStartEventInit : EventInit {
PresentationSession session;
};
An event named defaultsessionstart
is fired when the UA
initiates a presentation on behalf of the page. It is fired at the
NavigatorPresentation
object, using the
DefaultSessionStartEvent
interface, with the
session
attribute set to the
PresentationSession
object provided by the
UA.
Thanks to Wayne Carr, Louay Bassbouss, Anssi Kostiainen, 闵洪波 (Hongbo Min), Anton Vayvod, and Mark Foltz for help with editing, reviews and feedback to this draft.