W3C

Presentation API

Draft Report - 22 September 2014

This Version:
http://webscreens.github.io/presentation-api/
Latest Published Version
http://webscreens.github.io/presentation-api/
Previous Version:
http://webscreens.github.io/presentation-api/20131112/
Participate:
Send feedback to the community group's mailing list public-webscreens@w3.org, or create or browse open issues on GitHub. Also, you may join on the CG's IRC channel.
Version History:
https://github.com/webscreens/presentation-api/commits/
Editors:
Dominik Röttsches, Intel

Abstract

This specification defines an API to enable web content to access external presentation-type displays and use them for presenting web content.

Status of this Document

This specification was published by the Second Screen Presentation Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Final Specification Agreement (FSA) other conditions apply. Learn more about W3C Community and Business Groups.

This report documents the use cases, requirements, examples and interfaces needed to enable web pages to display web content on secondary screens. It is an evolved version of the initial Presentation API that represents the result of discussions within the Second Screen Presentation Community Group so far. API semantics still need to be specified. The report may serve as starting point for a possible Working Group chartered to work on the same topic.

Table of Contents

  1. 1 Introduction
    1. 1.1 Use Cases
      1. 1.1.1 Presentations
      2. 1.1.2 Video and Image Sharing
      3. 1.1.3 Gaming
      4. 1.1.4 Media Flinging to Multiple Screens
  2. 2 Requirements
    1. 2.1 Functional Requirements
    2. 2.2 Non-Functional Requirements
  3. 3 Conformance
  4. 4 Terminology
  5. 5 Example
    1. 5.1 Starting New Presentations
    2. 5.2 Reconnecting to Existing Presentations
    3. 5.3 Open Questions
    4. 5.4 Usage on Remote Screen
  6. 6 Interfaces
    1. 6.1 NavigatorPresentation
    2. 6.2 AvailableChangeEvent
    3. 6.3 PresentationSession
  7. 7 Algorithms
    1. 7.1 The Screen Availability algorithm
    2. 7.2 The Start Session algorithm
    3. 7.3 The Join Session algorithm
    4. 7.4 The Close Session algorithm
    5. 7.5 The Presentation Initialization algorithm
  8. References
  9. Acknowledgments

1 Introduction

This section is non-normative.

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 use of display devices that can be attached in 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, but instead of displaying in a window on that same device, 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 own 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 through definition of a standard protocol for delivering these types of messages that display devices could choose to implement.

The API defined here is intended be used with UAs that attach to display devices through any of the above means.

1.1 Use Cases

1.1.1 Presentations

A user is preparing a set of slides for a talk. Using a web based service, she is editing her slides and speaker notes on the primary screen, while the secondary larger screen shows a preview of the current slide. When the slides are done, her mobile phone allows her to access them from an online service while on the go. Coming to the conference, using wireless display technology, she would like to present her slides on the stage screen from her mobile phone. The phone's touch screen helps her to navigate slides and presents a slide preview, while the projector shows her slides to the audience.

Requirements: R1, R3, R4, R5, R7

1.1.2 Video and Image Sharing

Using an online video or image sharing service, a user would like to show memorable moments to her friends. Using a device with a small screen, it is impossible to show the content to a large group of people. Connecting an external TV screen or projector to her device - with a cable or wirelessly - the online sharing service now makes use of the connected display, allowing a wider audience to enjoy the content.

The web page shows UI elements that allow the user to trigger displaying content on the secondary display (e.g a "send to second screen" ) only if there is at least one secondary screen available.

Requirements: R1, R3, R4, R5, R7

1.1.3 Gaming

Splitting the gaming experience into a near screen controller and a large screen visual experience, new gaming experiences can be created. Accessing the local display on the small screen device and an external larger display allows for richer web-based gaming experiences.

Requirements: R1, R3, R4, R5, R7

1.1.4 Media Flinging to Multiple Screens

Alice enters a video sharing site using a browser on her tablet. Next, Alice picks her favorite video from the site, and the video starts to play on her tablet. While the video is playing Alice clicks a button "Share on different screen". The browser provides a user interface that lists all the screens Alice has around her home, asking her to select one. The screens are identified by names that are familiar to Alice. Alice picks one screen from the list, "Alice's big TV", and the video playback continues seamlessly on the selected screen. Next she decides to switch the playback to a different screen. She clicks the same button "Share on different screen" provided by the site, and the browser presents the user interface that lists all the screens. Alice picks another screen from the list, "Alice's kitchen TV", and the playback resumes on that screen. Video site also provides a feature to see the action (Alice is watching a soccer game) from different angle. Alice clicks a button "Select screen for additional angle", and the browser asks Alice similarly to select the screen to be used for playback. Alice picks "Alice's Projector" and the soccer game is shown on the projector from a different angle, in parallel to the content being played back on "Alice's kitchen TV".

Requirements: R1, R3, R4, R5, R6, R7

2 Requirements

2.1 Functional Requirements

Multi-Screen enumeration and named identification removed, after discussion on the mailing list, cmp. http://lists.w3.org/Archives/Public/public-webscreens/2014Feb/0021.html :

2.2 Non-Functional Requirements

3 Conformance

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 end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)

4 Terminology

The term presentation display refers to an external screen connected to the device that the user agent runs on.

The terms event handlers and event handler event types are defined in [HTML5].

This document provides interface definitions using the [WEBIDL] standard.

5 Example

Running in a compliant user agent, code for presenting a page http://example.org/presentation.html on the presentation display looks as follows:

/* controller.html */

<button disabled id=show>Show</button>
<button disabled id=stop>Stop</button>

<script>

var presentation = navigator.presentation,
    showButton = document.getElementById('show'),
    stopButton = document.getElementById('stop');

var session = null,
    screenAvailable = false,
    presentationUrl = 'http://example.org/presentation.html',
    previousSessionId = localStorage['sessionId'];

presentation.onavailablechange = function (e) {
    screenAvailable = e.available;
    updateButtons();
};

function tryJoin() {
    if (!previousSessionId) return;
    // Join an existing presentation if one exists.
    session = presentation.joinSession(presentationUrl, previousSessionId);
    console.log(session.state); // "unknown"
    session.onstatechange = handleSessionState;
}

function startPresent() {
    session = presentation.startSession(presentationUrl);
    console.log(session.state); // "unknown"
    session.onstatechange = handleSessionState;
}

function handleSessionState() {
    switch (session.state) {
        case 'connected':
            if (previousSessionId == session.id) {
                console.log("Joined existing session.");
            } else {
                console.log("New session opened.");
                localStorage['sessionId'] = session.id;
            }
            session.postMessage( /*...*/ );
            session.onmessage = function () { /*...*/
            };
            break;
        case 'disconnected':
            // Session join/start failed, or session terminated.
            break;
    }
    updateButtons();
}

function updateButtons() {
    var sessionConnected = session && session.state == "connected";
    stopButton.disabled = !sessionConnected;
    stopButton.onClick = sessionConnected ? stopPresent : null;
    var sessionPendingOrConnected = sessionConnected || (session && session.state == "unknown");
    showButton.disabled = !screenAvailable || sessionPendingOrConnected;
    showButton.onclick = screenAvailable && !sessionPendingOrConnected ? startPresent : null;
}

function stopPresent() {
    session.close();
}

tryJoin();
</script>

The availability monitoring for secondary screens begins when the page adds an event listener for the availablechange event on the navigator.presentation object. If there are already available screens when the page adds the first event listener for the event, the UA synthesizes a single availablechange event to signal the availability.

Do we want to fire an event immediately after the page registers for it? What's a best practice method for asynchronous notifications of this kind? See below in the Open Questions section.

It is an open issue whether to provide filter information as part of the request for notification of available screens. This could be useful when a particular application or capability is needed in order to display the contents of a presentation. One possible approach to this could be to provide the URL for the presentation and / or required options as part of the request for notification of available screens. If this was supported, only screens that satisfied the filter would trigger a notification.

5.1 Starting New Presentations

The "Show" button's state (initially disabled) informs the user of the availability of secondary screen(s), and the button's state is updated if the availability changes. (The rationale of putting the actual boolean information into a property of the event e.available is to allow the implementation to optimize power consumption for network discovery of remote wireless screens. If this information was provided in a globally accessible flag, the network discovery could never be suspended for keeping the flag up to date.)

Clicking the "Show" button calls navigator.presentation.startSession(), which causes the user agent to request from the user a screen to show the presentation. The url argument indicates the content to be presented.

If the user selects a screen with an existing presentation showing the same url under the same presentationId, the opener page is connected to that existing presentation.

If the user selects a screen without an existing presentation, or a screen presenting a different url or presentationId, the UA connects to the selected screen, brings up a new presentation window on it, and starts to show the content denoted by the url argument. The UA then connects the opener page to this new presentation and allows the opener page to exchange messages with it.

navigator.presentation.startSession(url, presentationId) returns a PresentationSession object, initially in "unknown" state. Changes of the state property of the PresentationSession object are signalled through the onstatechange event handler. If presentationId is not specified, the UA generates one for the returned object.

Once the UA established the connection to the presentation page, the state changes from "unknown" to "connected". At this point, the opener page can communicate with the presentation page using the session's postMessage() to send messages and its onmessage event handler to receive messages.

The presentation page will also have access to PresentationSession that it can use to send and receive messages with the opener page (see Usage on Remote Screen).

If the user cancels screen selection when the UA brings up the selection dialog, the state property of the PresentationSession object remains at "unknown". If the UA attempts and for technical reasons fails at establishing a link with the presentation page, the state property transitions to "disconnected".

5.2 Reconnecting to Existing Presentations

The opener page may wish to reconnect to an existing presentation without prompting the user to select a screen. For example, the site could allow media items from different pages to be shown on the same presentation page, and does not want to prompt the user on each page to reconnect to that presentation.

To reconnect, the page calls joinSession(url, presentationId), which returns a PresentationSession, initially in "unknown" state.

The presentationId argument in this case is the value of the session.id property of a previously established PresentationSession.

If the UA finds an existing presenting instance that matches the url and presentationId as was passed originally into startSession, the UA then transistions the state of the returned PresentationSession to "connected". The requesting page can then communicate with the presentation as if the user had manually connected to it via startSession.

If no such instance exists, the state of the returned PresentationSession transitions to "disconnected".

5.3 Open Questions

Do we need to insert into the description an additional permission prompt to grant the page access to the "one ore more screens are available" Information?

Do we reload the presentation page after startSession() if the page was previously already shown on this screen?

If there are already connected screens when the page subscribes to the onavailablechange event, we can handle this in two ways: We can synthesize one initial event to notify the page about available screens as soon as the first event handler is installed (as described). Or we can add another message like navigator.presentation.getAvailable(function(available) { } ); to notify the page about available screens using this one-time asynchronous getter. Which way should we go?

Do we need an additional state like resumed in order to identify resumed session? It seems that this could be handled on the page level. The opener page could ask the presentation page whether it is "new" or "resumed".

If more than one presentation session exists with the same url and presentationId (on different screens) then what is the behavior of joinSession(url, presentationId)? This can be resolved by having the UA generate different ids on different screens.

If the page calls startSession(url) and joinSession(url, presentationId) with the same url, and the latter call has not resolved, behavior is not defined.

5.4 Usage on Remote Screen

For addressing the requirement of communication between originating page and presentation page/screen, the presenting page can now use the same session object. It accesses this object through the navigator.presentation.session property, which is only non-null for the page on the presentation screen.

if (navigator.presentation.session) {
  var session = navigator.presentation.session;
  // Communicate with opener page.
  session.postMessage(/*...*/);
  session.onmessage = function() {/*...*/};

  session.onstatechange = function() {
    switch (this.state) {
      case "disconnected":
        // Handle disconnection from opener page.
    }
  };
};

When the content denoted by the url argument in the requestSession() example above is loaded, the page on the presentation screen will have its navigator.presentation.session property set to the session. This session is a similar object as in the first example. Here, its initial state is "connected", which means we can use it to communicate with the opener page using postMessage() and onmessage.

The presentation page can also monitor the connection state by listening for statechange events. When the state changes to "disconnected" the page is made aware of the fact that communication with the opener page was lost, but it can continue to display the current content. The communication can be re-established when a statechange event fires with a new state of "connected".

6 Interfaces

The interfaces described herein address the requirements outlined in the Use Cases section, and specifically, also consider the Media Flinging to Multiple Screens use case unaddressed by the previous version of the Presentation API. This section describes the interfaces to the extend discussed in the Second Screen Presentation Community Group. Readers are encouraged to consult the Example and Algorithms sections together with this section for a more complete understanding of the technical parts of this specification.

Since we permit multiple opener pages to connect the same presentation page, we need to define how connection and disconnection of these pages is communicated to the presentation page (if at all).

interface NavigatorPresentation : EventTarget {
  readonly attribute PresentationSession? session;
  PresentationSession startSession(DOMString url, DOMString? presentationId);
  PresentationSession joinSession(DOMString url, DOMString? presentationId);
  attribute EventHandler onavailablechange;
};

partial interface Navigator {
  readonly attribute NavigatorPresentation presentation;
};

6.2 AvailableChangeEvent

Fired at the primary screen's NavigatorPresentation object, when screen availability changes.

[Constructor(DOMString type, optional AvailableChangeEventInit eventInitDict)]
interface AvailableChangeEvent : Event {
  readonly attribute boolean available;
};

dictionary AvailableChangeEventInit : EventInit {
  boolean available;
};

6.3 PresentationSession

An object representing the established presentation session.

enum PresentationSessionState { "unknown", "connected", "disconnected" };

interface PresentationSession : EventTarget {
  readonly DOMString? id;
  readonly attribute PresentationSessionState state;
  void postMessage(DOMString message);
  void close();
  attribute EventHandler onmessage;
  attribute EventHandler onstatechange;
};

7 Algorithms

These algorithms are intended to define the behavior of the NavigatorPresentation and PresentationSession interfaces declared in the Interfaces section.

7.1 The Screen Availability algorithm

Run when an event handler is added to onavailablechange.

7.2 The Start Session algorithm

Run when startSession(url, presentationId) is called.

7.3 The Join Session algorithm

Run when joinSession(url, presentationId) is called.

7.4 The Close Session algorithm

Run when close() is called on a PresentationSession.

7.5 The Presentation Initialization algorithm

Run when a document opened by startSession() is loaded.

References

[HTML5]
HTML5, Robin Berjon, Steve Faulkner, Travis Leithead et al.. W3C.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, Scott Bradner. IETF.
[WEBIDL]
Web IDL, Cameron McCormack. W3C.

Acknowledgments

Thanks to Wayne Carr, Louay Bassbous, Anssi Kostiainen, 闵洪波 (Hongbo Min), Anton Vayvod, and Mark Foltz for help with editing, reviews and feedback to this draft.