├── .github └── workflows │ └── auto-publish.yml ├── .pr-preview.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── Makefile ├── README.md ├── build └── tidyconfig.txt ├── images ├── interoperability-1ua.png ├── interoperability-2ua.png ├── uc-multiplayer-game-player-alice.png ├── uc-multiplayer-game-player-bob.png └── uc-multiplayer-game-poker-table.png ├── index.html ├── interoperability.md ├── releases ├── FPWD.html └── WD.html ├── uc-req.md └── w3c.json /.github/workflows/auto-publish.yml: -------------------------------------------------------------------------------- 1 | name: Build, Validate, Deploy and Publish 2 | on: 3 | pull_request: {} 4 | push: 5 | branches: [main] 6 | jobs: 7 | main: 8 | name: Build and validate spec, then deploy and publish (only if push to main branch) 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: w3c/spec-prod@v2 13 | with: 14 | GH_PAGES_BRANCH: gh-pages 15 | W3C_ECHIDNA_TOKEN: ${{ secrets.ECHIDNA_TOKEN }} 16 | W3C_WG_DECISION_URL: https://lists.w3.org/Archives/Public/public-secondscreen/2022Apr/0007.html 17 | W3C_BUILD_OVERRIDE: | 18 | specStatus: CRD -------------------------------------------------------------------------------- /.pr-preview.json: -------------------------------------------------------------------------------- 1 | { 2 | "src_file": "index.html", 3 | "type": "respec" 4 | } 5 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | All documentation, code and communication under this repository are covered by the [W3C Code of Ethics and Professional Conduct](https://www.w3.org/Consortium/cepc/). 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | Please refer to the group's [Work Mode](https://www.w3.org/wiki/Second_Screen/Work_Mode). 4 | 5 | Contributions to this repository are intended to become part of Recommendation-track documents governed by the 6 | [W3C Patent Policy](http://www.w3.org/Consortium/Patent-Policy-20040205/) and 7 | [Software and Document License](http://www.w3.org/Consortium/Legal/copyright-software). 8 | To make substantive contributions to specifications, you must either participate 9 | in the relevant W3C Working Group or make a non-member patent licensing commitment. 10 | 11 | If you are not the sole contributor to a contribution (pull request), please identify all 12 | contributors in the pull request comment. 13 | 14 | To add a contributor (other than yourself, that's automatic), mark them one per line as follows: 15 | 16 | ``` 17 | +@github_username 18 | ``` 19 | 20 | If you added a contributor by mistake, you can remove them in a comment with: 21 | 22 | ``` 23 | -@github_username 24 | ``` 25 | 26 | If you are making a pull request on behalf of someone else but you had no part in designing the 27 | feature, you can remove yourself with the above syntax. 28 | 29 | # Tests 30 | 31 | For normative changes, a corresponding 32 | [web-platform-tests](https://github.com/web-platform-tests/wpt) PR is highly appreciated. Typically, 33 | both PRs will be merged at the same time. Note that a test change that contradicts the spec should 34 | not be merged before the corresponding spec change. If testing is not practical, please explain why 35 | and if appropriate [file a web-platform-tests issue](https://github.com/web-platform-tests/wpt/issues/new) 36 | to follow up later. Add the `type:untestable` or `type:missing-coverage` label as appropriate. 37 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | All documents in this Repository are licensed by contributors 2 | under the 3 | [W3C Software and Document License](http://www.w3.org/Consortium/Legal/copyright-software). 4 | 5 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TIDY ?= tidy-html5 2 | 3 | tidy: index.html build/tidyconfig.txt 4 | $(TIDY) -ashtml -config build/tidyconfig.txt -o $< $< 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Presentation API 2 | 3 | This repository contains the 4 | [Presentation API](https://w3c.github.io/presentation-api/) 5 | specification that is being worked on in the 6 | [W3C Second Screen Working Group](http://www.w3.org/2014/secondscreen/). 7 | 8 | Please refer to the group's [Work Mode](https://www.w3.org/wiki/Second_Screen/Work_Mode) 9 | for instructions on how to contribute. 10 | 11 | ### Useful Resources 12 | 13 | * [Specification](https://w3c.github.io/presentation-api/) 14 | * [Issue Tracker](https://github.com/w3c/presentation-api/issues) 15 | * [Mailing List](http://lists.w3.org/Archives/Public/public-secondscreen/) -------------------------------------------------------------------------------- /build/tidyconfig.txt: -------------------------------------------------------------------------------- 1 | char-encoding: utf8 2 | doctype: html5 3 | drop-proprietary-attributes: no 4 | warn-proprietary-attributes: no 5 | indent: yes 6 | indent-spaces: 2 7 | preserve-entities: yes 8 | wrap: 80 9 | tidy-mark: no 10 | quiet: yes 11 | -------------------------------------------------------------------------------- /images/interoperability-1ua.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w3c/presentation-api/7c6c9f7cdddd24653d25cfb62ea36f0748884f84/images/interoperability-1ua.png -------------------------------------------------------------------------------- /images/interoperability-2ua.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w3c/presentation-api/7c6c9f7cdddd24653d25cfb62ea36f0748884f84/images/interoperability-2ua.png -------------------------------------------------------------------------------- /images/uc-multiplayer-game-player-alice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w3c/presentation-api/7c6c9f7cdddd24653d25cfb62ea36f0748884f84/images/uc-multiplayer-game-player-alice.png -------------------------------------------------------------------------------- /images/uc-multiplayer-game-player-bob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w3c/presentation-api/7c6c9f7cdddd24653d25cfb62ea36f0748884f84/images/uc-multiplayer-game-player-bob.png -------------------------------------------------------------------------------- /images/uc-multiplayer-game-poker-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w3c/presentation-api/7c6c9f7cdddd24653d25cfb62ea36f0748884f84/images/uc-multiplayer-game-poker-table.png -------------------------------------------------------------------------------- /interoperability.md: -------------------------------------------------------------------------------- 1 | # Assess interoperability of Presentation API implementations 2 | 3 | This document discusses the interoperability of potential Presentation API 4 | implementations; in particular, interoperability between user agents in case of 5 | [2-UA implementations][2ua] and between user agents and presentation displays in 6 | case of [1-UA implementations][1ua]. For this, state of the art technologies 7 | and standards that may be useful to implement the Presentation API will be 8 | considered. 9 | 10 | ## Interoperability between user agents (2-UA) 11 | 12 | The following diagram shows an overview of the main components for the 2-UA 13 | implementation. Each of the user agents implements part of the Presentation API 14 | (for controlling browsing context or presenting browsing context). 15 | 16 | 17 | ![2-UA implementation][2ua-img] 18 | 19 | To ensure interoperability between user agents running on controller devices and 20 | user agents running on presentation devices the following aspects should be 21 | considered: 22 | 23 | - **Discovery**: To discover presentation devices, the controlling user agent 24 | should use the same technology as the presenting user agent uses to advertise 25 | itself. 26 | - **Potential technologies**: [SSDP](http://upnp.org/sdcps-and-certification/standards/device-architecture-documents/), [mDNS/DNS-SD](http://www.dns-sd.org/) or [Bluetooth Low Energy](http://www.bluetooth.com/Pages/low-energy-tech-info.aspx). 27 | - **Launch**: after discovery, the controlling user agent should know how to 28 | launch a new presentation or join an existing one. Common message formats 29 | should be also used. 30 | - **Potential technologies**: [DIAL](http://www.dial-multiscreen.org/dial-protocol-specification) (uses SSDP for discovery), [Google Cast](https://developers.google.com/cast/?hl=en) (part of it), HBBTv 2.0 (see https://github.com/w3c/presentation-api/issues/67). 31 | - **Communication**: also for communication both user agents should use same 32 | technologies/protocols to ensure interoperability. 33 | - **Potential technologies**: [WebSockets](https://tools.ietf.org/html/rfc6455), [WebRTC](http://www.webrtc.org/), Raw Socket, Google Cast (part of it). 34 | - **Signaling**: Common language and message formats (e.g. using JSON or XML) 35 | should be used to exchange signaling information between the two user agents. 36 | - **Security**: Means of authenticatating the presenting user agent to the 37 | controlling user agent (and vice versa), and ensuring privacy of communication. 38 | - **Potential technologies**: [TLS](https://tools.ietf.org/html/rfc5246), [DTLS-SRTP](https://tools.ietf.org/html/rfc5764), [X.509 Certificates](https://tools.ietf.org/html/rfc5280). 39 | 40 | 41 | ## Interoperability between user agents and presentation displays (1-UA) 42 | 43 | The following diagram shows an overview of the main components for the 1-UA 44 | implementation. There are fewer requirements than the 2-UA case for 45 | interoperability between controlling user agents and presentation displays. The 46 | controlling user agent implements the Presentation API for both controlling and 47 | presenting browsing contexts and the presentation page is rendered in silent 48 | mode (not visible for the user). The controlling user agent captures the UI 49 | output of the presentation page and sends the frames to a presentation device 50 | like a projector or wireless display. 51 | 52 | ![1-UA implementation][1ua-img] 53 | 54 | The controlling user agent and the presentation device must implement a common 55 | streaming technology to interoperate. More than likely, the user agent will use 56 | system APIs offered by the OS to show content on the presentation device. But 57 | other technologies not offered directly by the OS are also possible; for 58 | example, the Google Cast extension for Chrome supports mirroring tabs to 59 | Chromecast using WebRTC. 60 | 61 | **Potential Technologies**: [HDMI](http://www.hdmi.org/), [Intel WiDi](http://www.intel.com/content/www/us/en/architecture-and-technology/intel-wireless-display.html), [Miracast](http://www.wi-fi.org/discover-wi-fi/wi-fi-certified-miracast), [Airplay](http://www.apple.com/airplay/), [MHL](http://www.mhlconsortium.org/), WebRTC. 62 | 63 | [1ua]: http://w3c.github.io/presentation-api/#1-ua 64 | [2ua]: http://w3c.github.io/presentation-api/#2-ua 65 | [1ua-img]: ./images/interoperability-1ua.png 66 | [2ua-img]: ./images/interoperability-2ua.png 67 | -------------------------------------------------------------------------------- /releases/FPWD.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 9 | 10 | Presentation API 11 | 12 | 13 | 14 |

15 | This document has been published as a W3C First 17 | Public Working Draft 17 February 2015. 18 |

19 | 20 | 21 | -------------------------------------------------------------------------------- /releases/WD.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Presentation API 5 | 6 | 7 | 65 | 66 | 67 |
68 | 69 | 70 |

W3C

71 | 72 |

73 | Presentation API 74 |

75 |

76 | W3C Working Draft 1 July 2015 77 |

78 |
79 |
80 | This version: 81 |
82 |
83 | http://www.w3.org/TR/2015/WD-presentation-api-20150701/ 84 |
85 |
86 | Latest published version: 87 |
88 |
89 | http://www.w3.org/TR/presentation-api/ 90 |
Previous version:
http://www.w3.org/TR/2015/WD-presentation-api-20150217/
91 |
92 | Latest editor's draft: 93 |
94 |
95 | http://w3c.github.io/presentation-api/ 96 |
97 |
98 | Version history: 99 |
100 |
101 | GitHub 102 | w3c/presentation-api/commits 103 |
104 |
105 | Participate: 106 |
107 |
108 | GitHub 109 | w3c/presentation-api (file an 110 | issue, open issues) 111 |
112 |
113 | Send feedback to public-secondscreen@w3.org 114 | (archives) 115 |
116 |
117 | Editors: 118 |
119 |
120 | Mark Foltz, Google 121 |
122 |
123 | Dominik Röttsches, Intel (until April 2015) 124 |
125 |
126 | 134 |
135 |
136 |
137 |

138 | Abstract 139 |

140 |

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

145 |
146 |
147 |

148 | Status of This Document 149 |

150 |

151 | This section describes the status of this document at the time of 152 | its publication. Other documents may supersede this document. A list of 153 | current W3C publications and the latest revision of this technical 154 | report can be found in the W3C 155 | technical reports index at http://www.w3.org/TR/. 156 |

157 |

158 | This document was published by the Second Screen Presentation 159 | Working Group as a Working Draft. If you wish to make comments 160 | regarding this document, please send them to public-secondscreen@w3.org 161 | (subscribe, 162 | archives). 163 | All comments are welcome. 164 |

165 |

166 | This document is a work in progress and is subject to change. 167 | Some sections are still incomplete or underspecified. Security and privacy 168 | considerations need to be adjusted based on feedback and 169 | experience. Some open issues are noted inline; please check the group's 170 | issue 171 | tracker on GitHub for all open issues. Feedback from early 172 | experimentations is encouraged to allow the Second Screen Presentation 173 | Working Group to evolve the specification based on implementation 174 | issues. 175 |

176 |

177 | Publication as a Working Draft does not imply endorsement by the W3C 178 | Membership. This is a draft document and may be updated, replaced or 179 | obsoleted by other documents at any time. It is inappropriate to cite 180 | this document as other than work in progress. 181 |

182 |

183 | This document was produced by a group operating under the 5 February 2004 184 | W3C Patent Policy. W3C maintains a public list of any patent disclosures made in 185 | connection with the deliverables of the group; that page also includes 186 | instructions for disclosing a patent. An individual who has actual 187 | knowledge of a patent which the individual believes contains Essential 188 | Claim(s) must disclose the information in accordance with section 189 | 6 of the W3C Patent Policy. 190 |

191 |

192 | This document is governed by the 1 August 2014 W3C Process Document. 193 |

194 |
195 |
196 |

197 | Table of Contents 198 |

199 | 200 |
    201 |
  1. 1 202 | Introduction 203 |
  2. 204 |
  3. 2 205 | Use cases and requirements 206 |
  4. 207 |
  5. 3 208 | Conformance 209 |
  6. 210 |
  7. 4 211 | Terminology 212 |
  8. 213 |
  9. 5 214 | Examples 215 | 216 |
      217 |
    1. 5.1 218 | Monitor availability of presentation displays example 219 |
    2. 220 |
    3. 5.2 221 | Starting a new presentation session example 222 |
    4. 223 |
    5. 5.3 224 | Joining a presentation session example 225 |
    6. 226 |
    7. 5.4 227 | Handling an event for a UA initiated presentation session example 228 |
    8. 229 |
    9. 5.5 230 | Monitor session's state and exchange data example 231 |
  10. 232 |
  11. 6 233 | API 234 | 235 |
      236 |
    1. 6.1 237 | Common idioms 238 |
    2. 239 |
    3. 6.2 240 | Interface PresentationSession 241 | 242 |
        243 |
      1. 6.2.1 244 | Sending a message through PresentationSession 245 |
      2. 246 |
      3. 6.2.2 247 | Receiving a message through PresentationSession 248 |
      4. 249 |
      5. 6.2.3 250 | Closing a PresentationSession 251 |
      6. 252 |
      7. 6.2.4 253 | Event Handlers 254 |
    4. 255 |
    5. 6.3 256 | Interface Availability 257 | 258 |
        259 |
      1. 6.3.1 260 | The set of availability objects 261 |
      2. 262 |
      3. 6.3.2 263 | The list of available presentation displays 264 |
      4. 265 |
      5. 6.3.3 266 | Monitor the list of available presentation displays 267 |
    6. 268 |
    7. 6.4 269 | Interface NavigatorPresentation 270 | 271 |
        272 |
      1. 6.4.1 273 | Starting a presentation session 274 |
      2. 275 |
      3. 6.4.2 276 | Joining a presentation session 277 |
      4. 278 |
      5. 6.4.3 279 | Establishing a presentation connection in a controlling browsing 280 | context 281 |
      6. 282 |
      7. 6.4.4 283 | Getting the presentation displays availability 284 | information 285 |
      8. 286 |
      9. 6.4.5 287 | Establishing a presentation connection in a presenting browsing 288 | context 289 |
      10. 290 |
      11. 6.4.6 291 | Monitoring incoming presentation sessions in a presenting browsing 292 | context 293 |
      12. 294 |
      13. 6.4.7 295 | Getting the first connected presentation session on the startup of 296 | a presenting browsing context 297 |
      14. 298 |
      15. 6.4.8 299 | Getting all connected presentation sessions in a presenting 300 | browsing context 301 |
      16. 302 |
      17. 6.4.9 303 | Event Handlers 304 |
    8. 305 |
    9. 6.5 306 | Interface DefaultSessionStart 307 |
  12. 308 |
  13. 7 309 | Security and privacy considerations 310 | 311 |
      312 |
    1. 7.1 313 | Personally identifiable information 314 |
    2. 315 |
    3. 7.2 316 | Cross-origin access 317 |
    4. 318 |
    5. 7.3 319 | Device Access 320 |
    6. 321 |
    7. 7.4 322 | Temporary identifiers and browser state 323 |
    8. 324 |
    9. 7.5 325 | Incognito mode and clearing of browsing data 326 |
    10. 327 |
    11. 7.6 328 | Messaging between presentation sessions 329 |
  14. 330 |
  15. 8 331 | References 332 |
  16. 333 |
  17. 9 334 | Acknowledgments 335 |
336 | 337 |
338 |
339 |

1 340 | Introduction 341 |

This section is non-normative. 342 |

343 | This specification aims to make presentation displays such 344 | as projectors or connected TVs, available to the Web and takes into 345 | account displays that are attached using wired (HDMI, DVI, or similar) 346 | and wireless technologies (Miracast, Chromecast, DLNA, AirPlay, or 347 | similar). 348 |

349 |

350 | Devices with limited screen size lack the ability to show content to a 351 | larger audience, for example, a group of colleagues in a conference 352 | room, or friends and family at home. Showing content on an external 353 | large presentation display helps to improve the perceived 354 | quality and impact of the presented content. 355 |

356 |

357 | At its core, this specification enables an exchange of messages between 358 | a page that acts as the controller and another page that 359 | represents the presentation shown in the 360 | presentation display. How the messages are transmitted is 361 | left to the UA in order to allow the use of presentation 362 | display devices that can be attached in a wide variety of ways. 363 | For example, when a presentation display device is 364 | attached using HDMI or Miracast, the same UA that acts as the 365 | controller renders the presentation. Instead 366 | of displaying the presentation in another window on the 367 | same device, however, it can use whatever means the operating system 368 | provides for using the external presentation displays. In 369 | such a case, both the controller and 370 | presentation run on the same UA and the operating system 371 | is used to route the presentation display output to the 372 | presentation display. This specification imposes no 373 | requirements on the presentation display devices connected 374 | in such a manner. 375 |

376 |

377 | If the presentation display is able to render HTML 378 | documents and communicate with the controller, the 379 | controller does not need to render the 380 | presentation. In this case, the UA acts as a proxy that 381 | requests the presentation display to show and render the 382 | presentation itself. This way of attaching to displays 383 | could be enhanced in the future by defining a standard protocol for 384 | delivering these types of messages that display devices could choose to 385 | implement. 386 |

387 |

388 | The API defined here is intended to be used with UAs that attach to 389 | presentation display devices through any of the above 390 | means. 391 |

392 |
393 |
394 |

2 395 | Use cases and requirements 396 |

Use cases and requirements are captured in a separate Presentation 397 | API Use Cases and Requirements document. 398 |
399 |
400 |

3 401 | Conformance 402 |

403 |

404 | All diagrams, examples, and notes in this specification are 405 | non-normative, as are all sections explicitly marked non-normative. 406 | Everything else in this specification is normative. 407 |

408 |

409 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 410 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 411 | "OPTIONAL" in this document are to be interpreted as described in RFC 412 | 2119. For readability, these words do not appear in all uppercase 413 | letters in this specification. [RFC2119] 414 |

415 |

416 | Requirements phrased in the imperative as part of algorithms (such as 417 | "strip any leading space characters" or "return false and terminate 418 | these steps") are to be interpreted with the meaning of the key word 419 | ("must", "should", "may", etc.) used in introducing the algorithm. 420 |

421 |

422 | Conformance requirements phrased as algorithms or specific steps may be 423 | implemented in any manner, so long as the result is equivalent. (In 424 | particular, the algorithms defined in this specification are intended 425 | to be easy to follow, and not intended to be performant.) 426 |

427 |
428 |
429 |

4 430 | Terminology 431 |

432 |

433 | The terms browsing context, 434 | event handlers, event handler 435 | event types, firing an event, navigate, queuing a task are defined in 436 | [HTML5]. 437 |

438 |

439 | The term DOMException is defined 440 | in [WEBIDL]. 441 |

442 |

443 | This document provides interface definitions using the 444 | [WEBIDL] standard. The terms 445 | Promise, ArrayBuffer, and ArrayBufferView are defined in [WEBIDL]. 446 |

447 |

448 | The terms resolving a Promise, and rejecting a Promise 449 | are used as explained in [PROMGUIDE]. 450 |

451 |

452 | The term URL is defined in the 453 | WHATWG URL standard [URL]. 454 |

455 |

456 | The term Blob is defined in the 457 | File API specification [FILEAPI]. 458 |

459 |

460 | The term RTCDataChannel is 461 | defined in the WebRTC API specification [WEBRTC]. 462 |

463 |
464 |
465 |

5 466 | Examples 467 |

468 |

469 | This section shows example codes that highlight the usage of main 470 | features of the Presentation API. In these examples, 471 | controller.html implements the controller and 472 | presentation.html implements the presentation. Both pages 473 | are served from the domain http://example.org 474 | (http://example.org/controller.html and 475 | http://example.org/presentation.html). Please refer to the 476 | comments in the code examples for further details. 477 |

478 |
479 |

5.1 480 | Monitor availability of presentation displays example 481 |

482 |
<!-- controller.html -->
 483 | <button id="castBtn" style="display: none;">Cast</button>
 484 | <script>
 485 |   // it is also possible to use relative presentation URL e.g. "presentation.html"
 486 |   var presUrl = "http://example.com/presentation.html";
 487 |   // the cast button is visible if at least one presentation display is available
 488 |   var castBtn = document.getElementById("castBtn");
 489 |   // show or hide cast button depending on display availability
 490 |   var handleAvailabilityChange = function(available) {
 491 |     castBtn.style.display = available ? "inline" : "none";
 492 |   };
 493 |   // Promise is resolved as soon as the presentation display availability is known.
 494 |   navigator.presentation.getAvailability(presUrl).then(function(availability) {
 495 |     // availability.value may be kept up-to-date by the UA as long as the availability
 496 |     // object is alive. It is advised for the web developers to discard the object
 497 |     // as soon as it's not needed.
 498 |     handleAvailabilityChange(availability.value);
 499 |     availability.onchange = function() { handleAvailabilityChange(this.value); };
 500 |   }.catch(function() {
 501 |     // Availability monitoring is not supported by the platform, discovery of presentation
 502 |     // displays will happen only after startSession() call. Pretend the devices are
 503 |     // available for simplicity (one could implement the third state for the button).
 504 |     handleAvailabilityChange(true);
 505 |   });
 506 | </script>
 507 | 
508 |
509 |
510 |

5.2 511 | Starting a new presentation session example 512 |

513 |
<!-- controller.html -->
 514 | <script>
 515 |   // it is also possible to use relative presentation URL e.g. "presentation.html"
 516 |   var presUrl = "http://example.com/presentation.html";
 517 |   // Start new session.
 518 |   navigator.presentation.startSession(presUrl)
 519 |     // the new started session will be passed to setSession on success
 520 |     .then(setSession)
 521 |     // user cancels the selection dialog or an error is occurred
 522 |     .catch(endSession);
 523 | </script>
 524 | 
525 |
526 |
527 |

5.3 528 | Joining a presentation session example 529 |

530 |
<!-- controller.html -->
 531 | <script>
 532 |   // read presId from localStorage if exists
 533 |   var presId = localStorage && localStorage["presId"] || null;
 534 |   // presId is mandatory for joinSession.
 535 |   presId && navigator.presentation.joinSession(presUrl, presId)
 536 |     // The joined session will be passed to setSession on success
 537 |     .then(setSession)
 538 |     // no session found for presUrl and presId or an error is occurred
 539 |     .catch(endSession);
 540 | </script>
 541 | 
542 |
543 |
544 |

5.4 545 | Handling an event for a UA initiated presentation session example 546 |

547 |
<!-- controller.html -->
 548 | <head>
 549 |   <!-- the link element with rel='default-presentation' allows the page to specify -->
 550 |   <!-- the presentation URL and id for when the UA initiates a presentation session -->
 551 |   <link href="http://example.com/presentation.html" rel="default-presentation" >
 552 | </head>
 553 | <script>
 554 |   navigator.presentation.ondefaultsessionstart = function (evt) {
 555 |     setSession(evt.session);
 556 |   };
 557 | </script>
 558 | 
 559 | 
560 |
561 |
562 |

5.5 563 | Monitor session's state and exchange data example 564 |

565 |
<!-- controller.html -->
 566 | <script>
 567 |   var session;
 568 |   var setSession = function (theSession) {
 569 |     // end existing session, if any
 570 |     endSession();
 571 |     // set the new session
 572 |     session = theSession;
 573 |     if (session) {
 574 |       // save presId in localStorage
 575 |       localStorage && (localStorage["presId"] = session.id);
 576 |       // monitor session's state
 577 |       session.onstatechange = function () {
 578 |         if (this == session && this.state == "disconnected")
 579 |           endSession();
 580 |       };
 581 |       // register message handler
 582 |       session.onmessage = function (evt) {
 583 |         console.log("receive message", evt.data);
 584 |       };
 585 |       // send message to presentation page
 586 |       session.send("say hello");
 587 |     }
 588 |   };
 589 |   var endSession = function () {
 590 |     // close old session if exists
 591 |     session && session.close();
 592 |     // remove old presId from localStorage if exists
 593 |     localStorage && delete localStorage["presId"];
 594 |   };
 595 | </script>
 596 | 
 597 | 
598 |
<!-- presentation.html -->
 599 | <script>
 600 |   var addSession = function(session) {
 601 |     session.onstatechange = function () {
 602 |       // session.state is either 'connected' or 'disconnected'
 603 |       console.log("session's state is now", session.state);
 604 |     };
 605 |     session.onmessage = function (evt) {
 606 |       if (evt.data == "say hello")
 607 |         session.send("hello");
 608 |     }
 609 |   });
 610 |   navigator.presentation.getSession().then(addSession);
 611 |   navigator.presentation.onsessionavailable = function(evt) {
 612 |     navigator.presentation.getSessions().then(function(sessions) {
 613 |       addSession(sessions[sessions.length-1]);
 614 |     });
 615 |   };
 616 | </script>
 617 | 
 618 | 
619 |
620 |
621 |
622 |

6 623 | API 624 |

625 |
626 |

6.1 627 | Common idioms 628 |

629 |

630 | A presentation display refers to an external screen 631 | available to the user agent via an implementation specific connection 632 | technology. 633 |

634 |

635 | A presentation session is an object relating a 636 | controlling browsing context to its presenting 637 | browsing context and enables two-way-messaging between them. 638 | Each presentation session has a presentation 639 | session state, a presentation session identifier to 640 | distinguish it from other presentation sessions, and a 641 | presentation session URL that is a URL used to create or resume the presentation 642 | session. A valid presentation session identifier 643 | consists of alphanumeric ASCII characters only, is at least 16 644 | characters long, and is unique within the set of 645 | presentations. 646 |

647 |

648 | A controlling browsing context (or controller 649 | for short) is a browsing 650 | context that has initiated or resumed a presentation 651 | session by calling startSession() or 652 | joinSession() or received a 653 | presentation session via 654 | ondefaultsessionstart event. 655 |

656 |

657 | The presenting browsing context (or 658 | presentation for short) is the browsing context 659 | responsible for rendering to a presentation display. A 660 | presenting browsing context can reside in the same user 661 | agent as the controlling browsing context or a different 662 | one. 663 |

664 |

665 | The set of presentations, initially empty, contains the 666 | presentation sessions created by the controlling 667 | browsing contexts for the user agent (or a specific user 668 | profile within the user agent). The set of presentations 669 | is represented by a list of tuples, where each tuple consists of a 670 | presentation session URL, a presentation session 671 | identifier, and the presentation session itself. 672 | The presentation session URL and presentation 673 | session identifier uniquely identify the presentation 674 | session. 675 |

676 |
677 |
678 |

6.2 679 | Interface PresentationSession 680 |

681 |

682 | Each presentation session is represented by a 683 | PresentationSession object. 684 |

685 |
enum PresentationSessionState { "connected", "disconnected" /*, "resumed" */ };
 686 | enum BinaryType { "blob", "arraybuffer" };
 687 | 
 688 | interface PresentationSession : EventTarget {
 689 |   readonly DOMString? id;
 690 |   readonly attribute PresentationSessionState state;
 691 |   void close();
 692 |   attribute EventHandler onstatechange;
 693 | 
 694 |   // Communication
 695 |   attribute BinaryType binaryType;
 696 |   EventHandler onmessage;
 697 |   void send (DOMString message);
 698 |   void send (Blob data);
 699 |   void send (ArrayBuffer data);
 700 |   void send (ArrayBufferView data);
 701 | };
 702 | 
703 |

704 | The id attribute specifies the 705 | presentation session's presentation session 706 | identifier. 707 |

708 |

709 | The state attribute represents the 710 | presentation session's current state. It can take one of 711 | the values of PresentationSessionState 712 | depending on connection state. 713 |

714 |

715 | When the send() method is called on a 716 | PresentationSession object with a message, 717 | the user agent must run the algorithm to send a message through a 718 | PresentationSession. 719 |

720 |

721 | When the close() method is called on a 722 | PresentationSession, the user agent must run the 723 | algorithm to close a presentation 724 | session with PresentationSession. 725 |

726 |
727 |

6.2.1 728 | Sending a message through PresentationSession 729 |

730 |

731 | No specific transport for the connection between the 732 | controlling browsing context and the presenting 733 | browsing context is mandated, except that for multiple calls 734 | to send() it has to be ensured that 735 | messages are delivered to the other end reliably and in sequence. 736 | The transport should function equivalently to an 737 | RTCDataChannel 738 | in reliable mode. 739 |

740 |

741 | Let presentation message data be the payload data to be 742 | transmitted between two browsing contexts. Let presentation 743 | message type be the type of that data, one of 744 | text and binary. 745 |

746 |

747 | When the user agent is to send a 748 | message through a PresentationSession S, it must 749 | run the following steps: 750 |

751 |
    752 |
  1. If the state property of 753 | PresentationSession is "disconnected", 754 | throw an InvalidStateError exception. 755 |
  2. 756 |
  3. Let presentation message type messageType 757 | be binary if data is one of 758 | ArrayBuffer, ArrayBufferView, or 759 | Blob. Let messageType be text if 760 | data is of type DOMString) 761 |
  4. 762 |
  5. Assign the destination browsing context as follows: 763 |
      764 |
    1. Let the destination browsing context be the 765 | controlling browsing context if send() is called in the presenting browsing 766 | context. 767 |
    2. 768 |
    3. Let destination browsing context be the 769 | presenting browsing context if send() is called from the controlling 770 | browsing context. 771 |
    4. 772 |
    773 |
  6. 774 |
  7. Using an implementation specific mechanism, transmit the 775 | contents of the data argument as presentation 776 | message data and presentation message type 777 | messageType to the destination browsing context 778 | side. 779 |
  8. 780 |
781 |
782 |
783 |

6.2.2 784 | Receiving a message through PresentationSession 785 |

786 |

787 | When the user agent has received a transmission from the remote 788 | side consisting of presentation message data and 789 | presentation message type, it must run the following 790 | steps: 791 |

792 |
    793 |
  1. If the state property of 794 | PresentationSession is "disconnected", 795 | abort these steps. 796 |
  2. 797 |
  3. Let event be a newly created trusted event that 798 | uses the MessageEvent interface, with the event type 799 | message, which does not bubble, is not cancelable, and 800 | has no default action. 801 |
  4. 802 |
  5. Initialize the event's data attribute as follows: 803 |
      804 |
    1. If the presentation message type is 805 | text, then initialize event's 806 | data attribute to the contents of 807 | presentation message data of type 808 | DOMString. 809 |
    2. 810 |
    3. If the presentation message type is 811 | binary, and binaryType is set to 812 | blob, then initialise event's 813 | data attribute to a new Blob object 814 | that represents presentation message data as its 815 | raw data. 816 |
    4. 817 |
    5. If the presentation message type is 818 | binary, and binaryType is set to 819 | arraybuffer, then initialise event's 820 | data attribute to a new ArrayBuffer 821 | object whose contents are presentation message 822 | data. 823 |
    6. 824 |
    825 |
  6. 826 |
  7. 827 | Queue a task to 828 | fire 829 | event at 830 | PresentationSession. 831 |
  8. 832 |
833 |
834 |
835 |

6.2.3 836 | Closing a PresentationSession 837 |

838 |

839 | When the user agent is to close a 840 | presentation session using session, it must run the 841 | following steps: 842 |

843 |
    844 |
  1. If presentation session state of session 845 | is not connected, then abort these steps. 846 |
  2. 847 |
  3. Set presentation session state of session 848 | to disconnected. 849 |
  4. 850 |
  5. 851 | Queue a task to run the 852 | following steps in order: 853 |
      854 |
    1. For each known session in the set of 855 | presentations: 856 |
        857 |
      1. If the presentation session identifier of 858 | known session and session are equal, run 859 | the following steps: 860 |
          861 |
        1. 862 | Queue a task 863 | to fire an event named 864 | statechange at session. 865 |
        2. 866 |
        867 |
      2. 868 |
      869 |
    2. 870 |
    871 |
  6. 872 |
873 |

874 | ISSUE 875 | 35: Refine how to do session teardown/disconnect/closing 876 |

877 |
878 |
879 |

6.2.4 880 | Event Handlers 881 |

882 |

883 | The following are the event handlers (and their corresponding event 884 | handler event types) that must be supported, as event handler IDL 885 | attributes, by objects implementing the 886 | PresentationSession interface: 887 |

888 | 889 | 890 | 891 | 894 | 897 | 898 | 899 | 900 | 901 | 904 | 907 | 908 | 909 | 912 | 915 | 916 | 917 |
892 | Event handler 893 | 895 | Event handler event type 896 |
902 | onmessage 903 | 905 | message 906 |
910 | onstatechange 911 | 913 | statechange 914 |
918 |
919 |
920 |
921 |

6.3 922 | Interface Availability 923 |

924 |
interface Availability : EventTarget {
 925 |   readonly attribute boolean value;
 926 |   attribute EventHandler onchange;
 927 | };
 928 | 
 929 | 
930 |

931 | An Availability object is associated with a 932 | presentation display and represents its 933 | presentation display availability. 934 |

935 |

936 | The value attribute must return the last value it was 937 | set to. The value is updated by the monitor the list of 938 | available presentation displays algorithm. 939 |

940 |

941 | The onchange attribute is an event handler whose 942 | corresponding event handler event 943 | type is change. 944 |

945 |

946 | When the user agent is to signal a presentation display 947 | availability change using availability object, the 948 | user agent must run the following steps: 949 |

950 |
    951 |
  1. 952 | Queue a task to 953 | fire 954 | an event named change at availability 955 | object. 956 |
  2. 957 |
958 |
959 |

6.3.1 960 | The set of availability objects 961 |

962 |

963 | The user agent must keep track of the set of availability 964 | objects requested through the getAvailability() 965 | method. The set of availability objects is represented 966 | as a set of tuples (A, availabilityUrl, P), initially 967 | empty, where: 968 |

969 |
    970 |
  1. 971 | A is a live Availability object; 972 |
  2. 973 |
  3. 974 | availabilityUrl is the availabilityUrl 975 | passed to getAvailability() to create A. 976 |
  4. 977 |
  5. 978 | P is the Promise 979 | that was returned by getAvailability() when 980 | A was created. 981 |
  6. 982 |
983 |
984 |
985 |

6.3.2 986 | The list of available presentation displays 987 |

988 |

989 | The user agent must keep a list of available presentation 990 | displays. This current list of presentation 991 | displays that may be used for starting new presentations, 992 | and is populated based on an implementation specific discovery 993 | mechanism. It is set to the most recent result of the algorithm to 994 | monitor the list of available presentation displays. 995 |

996 |

997 | While there are live Availability objects, the user 998 | agent may monitor the list of available presentation 999 | displays continuously, so that pages can use the 1000 | value property of an Availability object 1001 | to offer presentation only when there are available displays. 1002 | However, the user agent may not support continuous availability 1003 | monitoring; for example, because of platform or power consumption 1004 | restrictions. In this case the Promise returned by 1005 | getAvailability() is rejected and the 1006 | algorithm to monitor the list of available presentation 1007 | displays will only run as part of the session start algorithm. 1008 |

1009 |

1010 | When there are no live Availability objects (that is, 1011 | the set of availability objects is empty), user agents 1012 | should not monitor the list of available presentation 1013 | displays to satisfy the 1014 | power saving non-functional requirement. To further save power, 1015 | the UA may also keep track of whether the page holding an 1016 | Availability object is in the foreground. Using this 1017 | information, implementation specific discovery of presentation displays can be resumed 1018 | or suspended. 1019 |

1020 |

1021 | Some presentation displays may only be able to display 1022 | a subset of Web content because of functional, security or hardware 1023 | limitations. Examples are set-top boxes, smart TVs or networked 1024 | speakers capable of rendering only audio. We say that such a 1025 | display is a compatible presentation display for a 1026 | display availability URL if the user agent can 1027 | reasonably guarantee that the presentation of the URL on that 1028 | display will succeed. 1029 |

1030 |
1031 |
1032 |

6.3.3 1033 | Monitor the list of available presentation displays 1034 |

1035 |

1036 | If set of availability objects is non-empty, or there 1037 | is a pending request to start a 1038 | session, the user agent must monitor the list of 1039 | available presentation displays by running the following 1040 | steps. 1041 |

1042 |
    1043 |
  1. 1044 | Queue a task to retrieve 1045 | available presentation displays (using an implementation specific 1046 | mechanism) and let newDisplays 1047 | be this list. 1048 |
  2. 1049 |
  3. Wait for the completion of that task. 1050 |
  4. 1051 |
  5. For each member (A, availabilityUrl, P) of the 1052 | set of availability objects: 1053 |
      1054 |
    1. Set previousAvailability to the value of 1055 | A's value property. 1056 |
    2. 1057 |
    3. Let newAvailability be true if 1058 | newDisplays is not empty and at least one display in 1059 | newDisplays is a compatible presentation 1060 | display for availabilityUrl. Otherwise, set 1061 | newAvailability to false. 1062 |
    4. 1063 |
    5. Set A's value property to 1064 | newAvailability. 1065 |
    6. 1066 |
    7. If P is not settled, then 1067 | resolve P with A. 1068 |
    8. 1069 |
    9. If previousAvailability is not equal to 1070 | newAvailability, signal a presentation display 1071 | availability change with A. 1072 |
    10. 1073 |
    1074 |
  6. 1075 |
  7. Set the list of available presentation displays to 1076 | the value of newDisplays. 1077 |
  8. 1078 |
1079 |

1080 | When an Availability object is no longer alive (i.e., 1081 | is eligible for garbage collection), the user agent should run the 1082 | following steps: 1083 |

1084 |
    1085 |
  1. Find and remove any entry (A, availabilityUrl, P) in 1086 | the set of availability objects for the newly deceased 1087 | A. 1088 |
  2. 1089 |
  3. If the set of availability objects is now empty 1090 | and there is no pending request to start 1091 | a session, cancel any pending task to monitor the set 1092 | of presentation displays for power saving purposes. 1093 |
  4. 1094 |
1095 |

1096 | The mechanism used to monitor presention displays 1097 | availability and determine the compatibility of a 1098 | presentation display with a given URL is left to the 1099 | user agent. 1100 |

1101 |
1102 |
1103 |
1104 |

6.4 1105 | Interface NavigatorPresentation 1106 |

1107 |
partial interface Navigator {
1108 |   readonly attribute NavigatorPresentation presentation;
1109 | };
1110 | 
1111 |

1112 | The presentation attribute is 1113 | used to retrieve an instance of the 1114 | NavigatorPresentation interface. 1115 |

1116 |
interface NavigatorPresentation : EventTarget {
1117 |   // This API used by controlling browsing context.
1118 |   Promise<PresentationSession> startSession(DOMString url);
1119 |   Promise<PresentationSession> joinSession(DOMString url, DOMString presentationId);
1120 |   Promise<Availability> getAvailability(DOMString url);
1121 |   attribute EventHandler ondefaultsessionstart;
1122 | 
1123 |   // This API used by presenting browsing context.
1124 |   Promise<PresentationSession> getSession();
1125 |   Promise<PresentationSession[]> getSessions();
1126 |   attribute EventHandler onsessionavailable;
1127 | };
1128 | 
1129 |
1130 |

6.4.1 1131 | Starting a presentation session 1132 |

1133 |

1134 | When the startSession(presentationUrl) 1135 | method is called, the user agent must run the following steps: 1136 |

1137 |
1138 |
1139 | Input 1140 |
1141 |
1142 | presentationUrl, the presentation session 1143 | URL 1144 |
1145 |
1146 | Output 1147 |
1148 |
1149 | P, a Promise 1150 |
1151 |
1152 |
    1153 |
  1. Let P be a new Promise. 1154 |
  2. 1155 |
  3. Return P. 1156 |
  4. 1157 |
  5. Run the following steps: 1158 |
      1159 |
    1. 1160 | Monitor the list of available presentation 1161 | displays. 1162 |
    2. 1163 |
    3. Wait until the algorithm completes. 1164 |
    4. 1165 |
    1166 |
  6. 1167 |
  7. If either of the following is true: 1168 |
      1169 |
    1. The list of available presentation displays is 1170 | empty; 1171 |
    2. 1172 |
    3. No member if the list of available presentation displays is 1173 | a compatible presentation display for 1174 | presentationUrl; 1175 |
    4. 1176 |
    1177 |
  8. 1178 |
  9. Then run the following steps: 1179 |
      1180 |
    1. 1181 | Reject P with a 1182 | DOMException named 1183 | "NotFoundError". 1184 |
    2. 1185 |
    3. Abort all remaining steps. 1186 |
    4. 1187 |
    1188 |
  10. 1189 |
  11. 1190 | Queue a task T 1191 | to request user permission for the use of a 1192 | presentation display 1193 | and selection of one presentation display. 1194 |
      1195 |
    1. If T completes with the user granting 1196 | permission to use a display, run the following steps: 1197 |
        1198 |
      1. Let I be a new valid presentation 1199 | session identifier unique among all 1200 | presentation session identifiers for known 1201 | sessions in the set of presentations. 1202 |
      2. 1203 |
      3. Create a new PresentationSession 1204 | S. 1205 |
      4. 1206 |
      5. Set the presentation session identifier of 1207 | S to I, and set the 1208 | presentation session state of S to 1209 | disconnected. 1210 |
      6. 1211 |
      7. 1212 | Queue a task 1213 | C to create a new browsing context on the user-selected 1214 | presentation display and 1215 | navigate to 1216 | presentationUrl in it. 1217 |
          1218 |
        1. If C completes successfully, run the 1219 | following steps: 1220 |
            1221 |
          1. Add the tuple {presentationUrl, 1222 | S.id, S} to the set of 1223 | presentations. 1224 |
          2. 1225 |
          3. 1226 | Resolve P with 1227 | S. 1228 |
          4. 1229 |
          5. 1230 | Establish a presentation connection 1231 | with S. 1232 |
          6. 1233 |
          1234 |
        2. 1235 |
        3. If C fails, run the following steps: 1236 |
            1237 |
          1. 1238 | Reject P with a 1239 | DOMException named 1240 | "OperationError". 1241 |
          2. 1242 |
          1243 |
        4. 1244 |
        1245 |
      8. 1246 |
      1247 |
    2. 1248 |
    3. If T completes with the user denying 1249 | permission, run the following steps: 1250 |
        1251 |
      1. 1252 | Reject P with a 1253 | DOMException named 1254 | "AbortError". 1255 |
      2. 1256 |
      1257 |
    4. 1258 |
    1259 |
  12. 1260 |
1261 |

1262 | The details of implementing the permission request and display 1263 | selection are left to the user agent; for example it may show the 1264 | user a dialog and allow the user to select an available display 1265 | (granting permission), or cancel the selection (denying 1266 | permission). 1267 |

1268 |

1269 | The presentationUrl should name a resource accessible 1270 | to the local or a remote user agent. This specification defines 1271 | behavior for presentationUrl using the 1272 | http or https schemes; behavior for other 1273 | schemes is not defined by this specification. 1274 |

1275 |

1276 | ISSUE: Do we want to distinguish the permission-denied outcome from 1277 | the no-screens-available outcome? Developers would be able to infer 1278 | it anyway from getAvailability(). 1279 |

1280 |
1281 |
1282 |

6.4.2 1283 | Joining a presentation session 1284 |

1285 |

1286 | When the joinSession(presentationUrl, 1287 | presentationId) method is called, the user agent must run 1288 | the following steps: 1289 |

1290 |
1291 |
1292 | Input 1293 |
1294 |
1295 | presentationUrl, the presentation session 1296 | URL 1297 |
1298 |
1299 | presentationId, the presentation session 1300 | identifier 1301 |
1302 |
1303 | Output 1304 |
1305 |
1306 | P, a Promise 1307 |
1308 |
1309 |
    1310 |
  1. Let P be a new Promise. 1311 |
  2. 1312 |
  3. Return P. 1313 |
  4. 1314 |
  5. 1315 | Queue a task T 1316 | to run the following steps in order: 1317 |
      1318 |
    1. For each known session in the set of 1319 | presentations, 1320 |
      1321 | If the presentation session URL of known 1322 | session is equal to presentationUrl, and 1323 | the presentation session identifier of 1324 | known session is equal to 1325 | presentationId, run the following steps: 1326 |
        1327 |
      1. Let S be the presentation 1328 | session of known session. 1329 |
      2. 1330 |
      3. 1331 | Resolve P with 1332 | S. 1333 |
      4. 1334 |
      5. 1335 | Establish a presentation connection with 1336 | S. 1337 |
      6. 1338 |
      7. Abort the remaining steps of T. 1339 |
      8. 1340 |
      1341 |
      1342 |
    2. 1343 |
    3. 1344 | Reject P with a 1345 | DOMException named 1346 | "NotFoundError". 1347 |
    4. 1348 |
    1349 |
  6. 1350 |
1351 |

1352 | ISSUE: If no matching presentation is found, we could leave the 1353 | Promise pending in case a matching presentation is started in the 1354 | future. 1355 |

1356 |
1357 |
1358 |

6.4.3 1359 | Establishing a presentation connection in a controlling browsing 1360 | context 1361 |

1362 |

1363 | When the user agent is to establish a presentation 1364 | connection using a presentation session 1365 | S, it must run the following steps: 1366 |

1367 |
    1368 |
  1. If the presentation session state of S 1369 | is connected, then: 1370 |
      1371 |
    1. Abort all remaining steps. 1372 |
    2. 1373 |
    1374 |
  2. 1375 |
  3. 1376 | Queue a task T 1377 | to connect the presentation session S to 1378 | the presenting browsing context. 1379 |
  4. 1380 |
  5. If T completes successfully, run the following steps: 1381 |
      1382 |
    1. Set the presentation session state of 1383 | S to connected. 1384 |
    2. 1385 |
    3. 1386 | Queue a task 1387 | T to run the following steps in order: 1388 |
        1389 |
      1. For each known session in the set of 1390 | presentations: 1391 |
          1392 |
        1. If the presentation session identifier 1393 | of known session and S are equal, 1394 | then run the following steps: 1395 |
            1396 |
          1. 1397 | Queue a 1398 | task to fire an event 1399 | named statechange at s. 1400 |
          2. 1401 |
          1402 |
        2. 1403 |
        1404 |
      2. 1405 |
      1406 |
    4. 1407 |
    1408 |
  6. 1409 |
1410 |

1411 | The mechanism that is used to present on the remote display and 1412 | connect the controlling browsing context with the 1413 | presented document is an implementation choice of the user agent. 1414 | The connection must provide a two-way messaging abstraction capable 1415 | of carrying DOMString payloads in a reliable and 1416 | in-order fashion as described in the Send Message and 1417 | Receive Message steps below. 1418 |

1419 |

1420 | If T does not complete successfully, the user agent may 1421 | choose to re-execute the Presentation Connection algorithm at a 1422 | later time. 1423 |

1424 |

1425 | ISSUE: Do we want to notify the caller of a failure to connect, 1426 | i.e. with an "error" onstatechange? 1427 |

1428 |

1429 | ISSUE: Do we want to pass the new state as a property of the 1430 | statechange event? 1431 |

1432 |
1433 |
1434 |

6.4.4 1435 | Getting the presentation displays availability 1436 | information 1437 |

1438 |

1439 | When the getAvailability(availabilityUrl) 1440 | method is called, the user agent must run the following steps: 1441 |

1442 |
1443 |
1444 | Input 1445 |
1446 |
1447 | availabilityUrl, a display availability 1448 | URL 1449 |
1450 |
1451 | Output 1452 |
1453 |
1454 | P, a Promise 1455 |
1456 |
1457 |
    1458 |
  1. Let P be a new Promise. 1459 |
  2. 1460 |
  3. Return P. 1461 |
  4. 1462 |
  5. If the user agent is unable to continuously monitor the 1463 | list of available presentation displays, then: 1464 |
      1465 |
    1. 1466 | Reject P. 1467 |
    2. 1468 |
    3. Abort all the remaining steps. 1469 |
    4. 1470 |
    1471 |
  6. 1472 |
  7. Otherwise, let A be a new Availability 1473 | object with its value property set to 1474 | false. 1475 |
  8. 1476 |
  9. Create a tuple (A, availabilityUrl, P) and add it to 1477 | the set of availability objects. 1478 |
  10. 1479 |
  11. Run the algorithm to monitor the list of available 1480 | presentation displays. 1481 |
  12. 1482 |
1483 |
1484 |
1485 |

6.4.5 1486 | Establishing a presentation connection in a presenting browsing 1487 | context 1488 |

1489 |

1490 | ISSUE 1491 | 19: Specify behavior when multiple controlling pages are connected 1492 | to the session 1493 |

1494 |

1495 | When a new presenting browsing context has been 1496 | created and navigated to the presentationUrl on a 1497 | user-selected presentation display, the user agent 1498 | must run the following steps: 1499 |

1500 |
    1501 |
  1. 1502 | Queue a 1503 | task to start monitoring incoming presentation 1504 | sessions from controlling browsing 1505 | contexts. 1506 |
  2. 1507 |
1508 |
1509 |
1510 |

6.4.6 1511 | Monitoring incoming presentation sessions in a presenting browsing 1512 | context 1513 |

1514 |

1515 | When the user agent is to start monitoring incoming 1516 | presentation sessions in a presenting browsing 1517 | context from controlling browsing 1518 | contexts, it must run the following steps: 1519 |

1520 |
    1521 |
  1. 1522 | Queue a 1523 | task T to wait for and accept an incoming 1524 | connection request from a controlling browsing 1525 | context using an implementation specific mechanism. 1526 |
  2. 1527 |
  3. When a new connection request is received from a 1528 | controlling browsing context, run the following steps: 1529 |
      1530 |
    1. Create new PresentationSession S. 1531 |
    2. 1532 |
    3. Let I be a new valid presentation session 1533 | identifier unique among all presentation session 1534 | identifiers for known sessions in the set of 1535 | presentations. 1536 |
    4. 1537 |
    5. Set the presentation session identifier of 1538 | S to I. 1539 |
    6. 1540 |
    7. Establish the connection between the controlling and 1541 | presenting browsing contexts using an implementation specific 1542 | mechanism. 1543 |
    8. 1544 |
    9. Set the presentation session state of 1545 | S to connected. 1546 |
    10. 1547 |
    11. Add a tuple (undefined, presentation 1548 | session identifier of S, S) to the 1549 | set of presentations. 1550 |
    12. 1551 |
    13. 1552 | Queue 1553 | a task to fire an event named 1554 | sessionavailable at 1555 | NavigatorPresentation. 1556 |
    14. 1557 |
    1558 |
  4. 1559 |
1560 |
1561 |
1562 |

6.4.7 1563 | Getting the first connected presentation session on the startup of 1564 | a presenting browsing context 1565 |

1566 |

1567 | When the getSession() method is called, the user agent 1568 | must run the following steps: 1569 |

1570 |
    1571 |
  1. Let P be a new Promise. 1572 |
  2. 1573 |
  3. Return P. 1574 |
  4. 1575 |
  5. 1576 | Queue a 1577 | task T to run the following steps in order: 1578 |
      1579 |
    1. If the set of presentations is empty, then 1580 | wait until at least one element is added to the set of 1581 | presentations. 1582 |
    2. 1583 |
    3. Let S be the first presentation 1584 | session added to the set of presentations. 1585 |
    4. 1586 |
    5. 1587 | Resolve P with 1588 | S. 1589 |
    6. 1590 |
    1591 |
  6. 1592 |
1593 |

1594 | If the set of presentations is empty, we leave the 1595 | Promise pending until 1596 | connecting request arrives from the controlling browsing 1597 | context. If the first controlling browsing 1598 | context disconnects after initial connection, then the 1599 | Promise returned to 1600 | subsequent calls to getSession() will resolve with a 1601 | presentation session that has its presentation 1602 | session state set to disconnected. 1603 |

1604 |
1605 |
1606 |

6.4.8 1607 | Getting all connected presentation sessions in a presenting 1608 | browsing context 1609 |

1610 |

1611 | When the getSessions() method is called, the user 1612 | agent must run the following steps: 1613 |

1614 |
    1615 |
  1. Let P be a new Promise. 1616 |
  2. 1617 |
  3. Return P. 1618 |
  4. 1619 |
  5. 1620 | Queue a 1621 | task to run the following steps in order: 1622 |
      1623 |
    1. Let array be an empty array. 1624 |
    2. 1625 |
    3. For each known session in the set of 1626 | presentations 1627 |
        1628 |
      1. Add known session to array. 1629 |
      2. 1630 |
      1631 |
    4. 1632 |
    5. 1633 | Resolve P with 1634 | array. 1635 |
    6. 1636 |
    1637 |
  6. 1638 |
1639 |
1640 |
1641 |

6.4.9 1642 | Event Handlers 1643 |

1644 |

1645 | The following are the event handlers (and their corresponding 1646 | event handler event types) that must be supported, as event handler 1647 | IDL attributes, by objects implementing the 1648 | NavigatorPresentation interface: 1649 |

1650 | 1651 | 1652 | 1653 | 1656 | 1659 | 1660 | 1661 | 1662 | 1663 | 1666 | 1669 | 1670 | 1671 | 1674 | 1677 | 1678 | 1679 |
1654 | Event handler 1655 | 1657 | Event handler event type 1658 |
1664 | ondefaultsessionstart 1665 | 1667 | defaultsessionstart 1668 |
1672 | onsessionavailable 1673 | 1675 | sessionavailable 1676 |
1680 |
1681 |
1682 |
1683 |

6.5 1684 | Interface DefaultSessionStart 1685 |

1686 |
[Constructor(DOMString type, optional DefaultSessionStartEventInit eventInitDict)]
1687 | interface DefaultSessionStartEvent : Event {
1688 |   readonly attribute PresentationSession session;
1689 | };
1690 | 
1691 | dictionary DefaultSessionStartEventInit : EventInit {
1692 |   PresentationSession session;
1693 | };
1694 | 
1695 | 
1696 |

1697 | An event named defaultsessionstart is fired when the UA 1698 | initiates a presentation on behalf of the page. It is fired at the 1699 | NavigatorPresentation object, using the 1700 | DefaultSessionStartEvent interface, with the 1701 | session attribute set to the 1702 | PresentationSession object provided by the 1703 | UA. 1704 |

1705 |
1706 |
1707 |
1708 |

7 1709 | Security and privacy considerations 1710 |

1711 |

1712 | ISSUE 45: 1713 | Security and privacy considerations section 1714 |

1715 |

7.1 1716 | Personally identifiable information 1717 |

1718 |

1719 | The change event fired on the Availability 1720 | object reveals one bit of information about the presence (or 1721 | non-presence) of a presentation screen typically 1722 | discovered through the local area network. This could be used in 1723 | conjunction with other information for fingerprinting the user. 1724 | However, this information is also dependent on the user's local network 1725 | context, so the risk is minimized. 1726 |

1727 |

1728 | If we allow the page to filter the set of presentation screens based on 1729 | capabilities, then more bits of more information would be revealed. 1730 | This feature, if implemented, should take privacy into consideration. 1731 | See ISSUE 9: 1732 | How to filter available screens according to the content being 1733 | presented? 1734 |

1735 |

1736 | We do not want to require user permission before disclosing the 1737 | presence of a presentation display, as it is counter to the initial 1738 | purpose of improving the user experience. See ISSUE 10: Is user 1739 | permission required to prompt for screen availability information? 1740 |

1741 |

7.2 1742 | Cross-origin access 1743 |

1744 |

1745 | A presentation session is allowed to be accessed across 1746 | origins; the presentation URL and presentation ID used to create the 1747 | presentation are the only information needed to join a session from any 1748 | origin in that user agent. In other words, a presentation is not tied 1749 | to a particular opening origin. 1750 |

1751 |

1752 | This design allows controlling contexts from different domains to 1753 | connect to a shared presentation resource. The security of the 1754 | presentation ID prevents arbitrary pages from connecting to an existing 1755 | presentation. 1756 |

1757 |

1758 | This specification does not prohibit a user agent from publishing 1759 | information about its set of presentations. The group 1760 | envisions a user agent on a another device (distinct from the 1761 | controller or presentation) becoming authorized to join the 1762 | presentation, either by user action or by discovering the 1763 | presentation's URL and id. 1764 |

1765 |

1766 | This section should provide informative guidance as to what constitutes 1767 | a reasonable context for a Web page to become authorized to control a 1768 | presentation session. 1769 |

1770 |

7.3 1771 | Device Access 1772 |

1773 |

1774 | The presentation API abstracts away what "local" means for displays, 1775 | meaning that it exposes network-accessible displays as though they were 1776 | local displays. The Presentation API requires user permission for a 1777 | page to access any display to mitigate issues that could arise, such as 1778 | showing unwanted content on a display viewable by others. 1779 |

1780 |

7.4 1781 | Temporary identifiers and browser state 1782 |

1783 |

1784 | The presentation URL and presentation ID can be used to connect to a 1785 | presentation session from another browsing context. They can be 1786 | intercepted if an attacker can inject content into the controlling 1787 | page. 1788 |

1789 |

1790 | Should we restrict the API to some extent in non secure contexts? 1791 |

1792 |

7.5 1793 | Incognito mode and clearing of browsing data 1794 |

1795 |

1796 | The content displayed on the presentation is different from the 1797 | controller. In particular, if the user is logged in in both contexts, 1798 | then logs out of the controlling browsing context, she will not be 1799 | automatically logged out from the presenting browsing context. 1800 | Applications that use authentication should pay extra care when 1801 | communicating between devices. 1802 |

1803 |

1804 | The set of presentations known to the user agent should be cleared when 1805 | the user requests to "clear browsing data." 1806 |

1807 |

1808 | The spec should specify any restrictions on the presenting browsing 1809 | context when the opening browsing context is in "incognito" mode. See 1810 | ISSUE 14: 1811 | Define user agent context for rendering the presentation 1812 |

1813 |

1814 | The spec should clarify what is to happen to the set of known 1815 | presentations in "incognito" (private browsing context) mode. 1816 |

1817 |

7.6 1818 | Messaging between presentation sessions 1819 |

1820 |

1821 | This spec will not mandate communication protocols, but it should set 1822 | some guarantees of message confidentiality and authenticity. 1823 |

1824 |

1825 | ISSUE 80: 1826 | Define security requirements for messaging channel between secure 1827 | origins 1828 |

1829 |
1830 |
1831 |

8 1832 | References 1833 |

1834 |
[FILEAPI] 1835 |
File API, Arun Ranganathan and Jonas Sicking. W3C. 1836 | 1837 |
[HTML5] 1838 |
HTML5, Robin Berjon, Steve Faulkner, Travis Leithead et al.. W3C. 1839 | 1840 |
[PROMGUIDE] 1841 |
Writing Promise-Using Specifications, Domenic Denicola. W3C. 1842 | 1843 |
[RFC2119] 1844 |
Key words for use in RFCs to Indicate Requirement Levels, Scott Bradner. IETF. 1845 | 1846 |
[URL] 1847 |
URL, Anne van Kesteren. WHATWG. 1848 | 1849 |
[WEBIDL] 1850 |
Web IDL, Cameron McCormack. W3C. 1851 | 1852 |
[WEBRTC] 1853 |
(Non-normative) WebRTC, Ian Hickson, Adam Bergkvist, Daniel C. Burnett et al.. W3C. 1854 | 1855 |
1856 |
1857 |
1858 |

9 1859 | Acknowledgments 1860 |

1861 |

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

1866 |
1867 | 1868 | 1869 | -------------------------------------------------------------------------------- /uc-req.md: -------------------------------------------------------------------------------- 1 | # Use cases and requirements for Presentation API 2 | 3 | This document captures the [use cases](#use-cases) and 4 | [requirements](#requirements) to consider in the specification of the 5 | [W3C Presentation API][pres-api]. 6 | 7 | ## Use Cases 8 | 9 | This section collects relevant use cases for the [Presentation API][pres-api]. 10 | 11 | > Each use case is defined in its own subsection. To define a new use case just 12 | > copy/paste an existing one and update the use case identifier (UCxx), title, 13 | > description and requirements. 14 | 15 | ### UC01: Presentation 16 | 17 | A user is preparing a set of slides for a talk. Using a Web-based service, she 18 | edits her slides and speaker notes on the primary screen while the secondary 19 | larger screen shows a preview of the current slide. When the slides are done, 20 | her mobile phone allows her to access them from an online service while on the 21 | go. At the conference, using wireless display technology, she presents her 22 | slides on the stage screen from her mobile phone. The phone's touch screen 23 | helps her to navigate slides and presents a slide preview while the stage screen 24 | shows her slides to the audience. At the end of the presentaton, she clicks a 25 | button to stop presentation, which stops showing slides on the stage screen and 26 | reverts to a local view of the presentation on her mobile phone. 27 | 28 | **Requirements**: [REQ01](#req01), [REQ02](#req02), [REQ05](#req05), [REQ06](#req06), [REQ09](#req09) 29 | 30 | ### UC02: Video and image sharing 31 | 32 | Using an online video or image sharing service, a user would like to show 33 | memorable moments to her friends. However, she cannot show the content to a 34 | large group of people using her smartphone with its small screen. She connects 35 | an external TV screen to her mobile device (wired or wirelessly); the online 36 | sharing service now makes use of the connected display, allowing a wider 37 | audience to enjoy the content. After the connection is made, the Web page adds 38 | a button (e.g., "send to second screen") that allows her to send content to 39 | the TV screen. 40 | 41 | She clicks the "send to second screen" button to start display on her 42 | TV screen, then selects a set of videos and images to show there. The playback 43 | starts on the TV screen and continues even after she navigates to another Web 44 | page on her mobile device. She navigates back to the online sharing service and 45 | the site reconnects automatically to the content shown on the TV screen. 46 | 47 | **Requirements**: [REQ01](#req01), [REQ02](#req02), [REQ03](#req03), [REQ05](#req05), [REQ06](#req06) 48 | 49 | ### UC03: Multiplayer gaming - Poker 50 | 51 | Bob enters an online poker site on his smartphone to play poker with friends. He 52 | selects the option "create new game" to start a game session for two 53 | players. The poker site detects that there is display available and asks Bob to 54 | extend the game UI by keeping his personal cards and control UI on the 55 | smartphone and displaying the poker table on the large display. Bob confirms and 56 | waits for other players to join. 57 | 58 | Alice is visiting Bob and decides to join the game. She opens the same poker 59 | site in the browser on her smartphone and selects the option "join game". The 60 | browser shows a dialog with a list of running poker sessions. She selects the 61 | session started by Bob and joins the game. The game starts immediately after two 62 | players are joined. Now Alice and Bob can see their personal cards on their 63 | smartphones and the large screen displays the poker table with shared cards, 64 | current bets, and remaining money of each player. 65 | 66 | **Requirements**: [REQ01](#req01), [REQ02](#req02), [REQ04](#req04), [REQ05](#req05), [REQ06](#req06), [REQ07](#req07) 67 | 68 | **Images** 69 | 70 | * Poker Table 71 | 72 | ![Poker Table][uc03-img1] 73 | 74 | * Poker Player: Alice 75 | 76 | ![Poker Client: Alice][uc03-img2] 77 | 78 | * Poker Player: Bob 79 | 80 | ![Poker Client: Bob][uc03-img3] 81 | 82 | ### UC04: Media flinging to multiple screens 83 | 84 | Alice enters a video sharing site using a browser on her tablet. Next, Alice 85 | picks her favorite video from the site, and the video starts to play on her 86 | tablet. While the video is playing Alice clicks a button "Share on different 87 | screen". The browser provides a user interface that lists all the screens Alice 88 | has at her home, asking her to select one. The screens are identified by names 89 | that are familiar to Alice. Alice picks one screen from the list, "Alice's big 90 | TV", and the video playback continues seamlessly on the selected screen. Next 91 | she decides to switch the playback to a different screen. She clicks the same 92 | button "Share on different screen" provided by the site, and the browser 93 | presents the user interface that lists all the screens. Alice picks another 94 | screen from the list, "Alice's kitchen TV", and the playback resumes on that 95 | screen. Video site also provides a feature to see the action (Alice is watching 96 | a soccer game) from a different angle. Alice clicks a button "Select screen for 97 | additional angle", and the browser asks Alice similarly to select the screen for 98 | playback. Alice picks "Alice's Projector" and the soccer game is shown on the 99 | projector from a different angle, in parallel to the content being played back 100 | on "Alice's kitchen TV". 101 | 102 | **Requirements**: [REQ01](#req01), [REQ02](#req02), [REQ05](#req05), [REQ06](#req06), [REQ08](#req08) 103 | 104 | > ISSUE #40: [Screen availability mechanism for multiple 105 | > sessions](https://github.com/w3c/presentation-api/issues/40) 106 | 107 | ### UC05: Multiplayer gaming - Pictionary 108 | 109 | Bob visits a Pictionary game [[PICTIONARYGAME]](#ref-PICTIONARYGAME) site on his 110 | smartphone. He clicks the "Start on TV" button and selects his TV’s name from 111 | the list of presentation displays that pops up on the phone's screen. The 112 | Pictionary site opens on the TV screen. 113 | 114 | Bob now waits for Ann and Joe to join the game from their smartphones by opening 115 | the same site and connecting to the TV. After all the players have joined, Bob 116 | presses the "start game" button on his smartphone and receives the first word to 117 | draw: "blanket." 118 | 119 | Bob draws a picture of a blanket on the touch screen of his smartphone. The 120 | picture is mirrored on the TV screen as he draws. At the same time, Ann 121 | and Joe are trying to guess what Bob is drawing by typing answers on their own 122 | smartphones and sending them to the TV screen. The TV shows the answers coming 123 | from all users and the game continues until Ann provides the correct answer. 124 | Ann gets points for the correct answer. The next round of the game starts with 125 | Ann drawing a new word. 126 | 127 | Joe then decides to exit the game by pressing the "exit game" button. That 128 | information is passed to the TV and Joe's name disappears from the list of the 129 | players on the TV screen. Bob and Ann play one more round of the game with Ann 130 | drawing and Bob guessing the correct word. After that round is over, they decide 131 | to stop playing and both press the "exit game" button on their smartphones. The 132 | site on the TV is notified that all the players have left the game, and it 133 | presents a list of the top players. No one decides to start a new game, and 134 | after a period of time the the game on the TV exits itself. 135 | 136 | **Requirements**: [REQ01](#req01), [REQ02](#req02), [REQ04](#req04), [REQ05](#req05), [REQ06](#req06), [REQ07](#req07), [REQ09](#req09) 137 | 138 | ### UC06: Presenting to local and remote screens 139 | 140 | Alice enters a conference room with two flat screen TVs. She opens a slide 141 | presentation site and initiates presentation of a deck of slides on the first 142 | TV. The presentation connects automatically to the second TV to show a video 143 | accompanying her slides. 144 | 145 | Alice wishes to present simultaneously to Bob, who at a remote site. She 146 | initiates a connection via the presentation site to Bob's conference room, which 147 | causes the presentation running in Alice's room to start showing on the TVs in 148 | Bob's room. As Alice moves through the slides in her room, the content in Bob's 149 | room remains in sync. 150 | 151 | When Alice is done presenting, she stops presentation locally, which also 152 | terminates presentation on Bob's TVs. 153 | 154 | **Requirements**: [REQ01](#req01), [REQ02](#req02), [REQ04](#req04), [REQ05](#req05), [REQ06](#req06), [REQ07](#req08) 155 | 156 | ## Requirements 157 | 158 | This section collects all requirements derived from the [use cases](#use-cases) 159 | listed in the previews section. 160 | 161 | > Each requirement is defined in its own subsection. To define a new requirement 162 | > just copy/paste an existing one and update the identifier (REQxx), title and 163 | > description. 164 | 165 | ### REQ01: Discovery & availability 166 | 167 | The UA must provide a way to find out whether at least one 168 | [presentation display](https://w3c.github.io/presentation-api/#presentation-display) 169 | is available. 170 | 171 | ### REQ02: Launching presentation 172 | 173 | The UA must provide a way to start sending content to a presentation display or 174 | displays from a 175 | [controlling browsing context](https://w3c.github.io/presentation-api/#controlling-browsing-context) 176 | (or controller), which creates a new 177 | [receiving browsing context](https://w3c.github.io/presentation-api/#dfn-receiving-browsing-context) 178 | (or presentation). This may occur at the request of the controller or 179 | at the request of the UA. A single controller may be able to send content to 180 | multiple displays at once, and a single display may be able to host multiple 181 | presentations at once. 182 | 183 | ### REQ03: Resuming connection to presentation 184 | 185 | If a controller becomes disconnected from its presentation, the UA must provide 186 | a way for it to resume its connection to the presentation. It must also provide 187 | a way for a new browsing context on the same UA to request connection to one or 188 | more presentations (thus becoming their controller). 189 | 190 | ### REQ04: Joining presentation 191 | 192 | The UA on the controller device must provide a way for controlling browsing context 193 | to join running presentations. These are started in general either manually 194 | by the user or from another controller as described in [REQ02](#req02). 195 | 196 | ### REQ05: Communication 197 | 198 | The UA must enable exchange of data between a presentation and its controller or 199 | controllers. This data exchange can be used to determine what content is shown 200 | in the presentation. The UAs that host the controllers must not make an 201 | assumption about the execution locality of the UA that hosts the presentation; 202 | they may be rendered on one or more remote UAs, and thus the communication 203 | channels between a presentation and its controllers 204 | is loosely coupled. 205 | 206 | ### REQ06: Signaling disconnection 207 | 208 | The UA must signal disconnection between a controller and a presentation to both 209 | the controller and the presentation. The controller or the presentation may 210 | choose to initiate disconnection; in that case, the UA must signal disconnection 211 | to the other side. 212 | 213 | ### REQ07: Multiple controllers per presentation 214 | 215 | A presentation should be able to accept control (via data exchange) from 216 | multiple controllers simultaneously. Not all presentations will support this; 217 | for example, when the presentation browsing context is not accessible to other 218 | devices. 219 | 220 | ### REQ08: Multiple presentations per controller 221 | 222 | A single controller should be able to launch multiple presentations and exchange 223 | data with them. Each connection between a controller and a presentation is 224 | handled independently by the UA; controlling the same content on multiple 225 | presentations simultaneously in a synchronized fashion is out of scope for this 226 | specification. 227 | 228 | ### REQ09: Terminating presentation 229 | 230 | A connected controller should be able to request termination of a presentation, 231 | which closes the browsing context and disconnects all connected controllers. In 232 | addition, a presentation should be able to terminate itself. 233 | 234 | ## Non-functional Requirements 235 | 236 | ### NF-REQ01: Power saving friendly 237 | 238 | All API design decisions must be analyzed from a power efficiency point of 239 | view. Especially when using wireless display technologies or querying 240 | availability over a radio channel, care needs to be taken to design the API in a 241 | way that does not pose obstacles to using radio resources in an efficient 242 | way. For example, powering up the wireless display detection only when 243 | needed. 244 | 245 | 246 | [pres-api]: http://w3c.github.io/presentation-api/ 247 | [uc03-img1]: ./images/uc-multiplayer-game-poker-table.png 248 | [uc03-img2]: ./images/uc-multiplayer-game-player-alice.png 249 | [uc03-img3]: ./images/uc-multiplayer-game-player-bob.png 250 | 251 | ## References 252 | 253 | [PICTIONARYGAME] https://en.wikipedia.org/wiki/Pictionary 254 | -------------------------------------------------------------------------------- /w3c.json: -------------------------------------------------------------------------------- 1 | { 2 | "group": [ 3 | "74168" 4 | ], 5 | "contacts": [ 6 | "tidoust" 7 | ], 8 | "shortName": "presentation-api", 9 | "repo-type": "rec-track" 10 | } --------------------------------------------------------------------------------