├── .gitignore ├── .pr-preview.json ├── images └── fingerprint.png ├── w3c.json ├── LICENSE.md ├── CODE_OF_CONDUCT.md ├── .github └── workflows │ └── auto-publish.yml ├── CONTRIBUTING.md ├── README.md ├── screenshare.css ├── screenshare.js ├── explainer.md ├── questionnaire.md └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .DS_Store 3 | build 4 | support 5 | webrtc-respec-ci 6 | -------------------------------------------------------------------------------- /.pr-preview.json: -------------------------------------------------------------------------------- 1 | { 2 | "src_file": "index.html", 3 | "type": "respec" 4 | } 5 | -------------------------------------------------------------------------------- /images/fingerprint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w3c/mediacapture-screen-share/HEAD/images/fingerprint.png -------------------------------------------------------------------------------- /w3c.json: -------------------------------------------------------------------------------- 1 | { 2 | "group": 47318 3 | , "contacts": ["dontcallmedom", "caribouW3"] 4 | , "shortName": "screen-capture" 5 | , "repo-type": "rec-track" 6 | } 7 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | All documents in this Repository are licensed by contributors 2 | under the 3 | [W3C Software and Document License](https://www.w3.org/Consortium/Legal/copyright-software). 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 | -------------------------------------------------------------------------------- /.github/workflows/auto-publish.yml: -------------------------------------------------------------------------------- 1 | name: Validate and Auto Publish 2 | 3 | on: 4 | push: 5 | paths: index.html 6 | branches: 7 | - gh-pages 8 | pull_request: {} 9 | 10 | jobs: 11 | validate-and-publish: 12 | name: Validate and Publish 13 | runs-on: ubuntu-latest # only linux supported at present 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: w3c/spec-prod@v2 # use the action 17 | with: 18 | W3C_ECHIDNA_TOKEN: ${{ secrets.ECHIDNA_TOKEN }} 19 | W3C_WG_DECISION_URL: "https://lists.w3.org/Archives/Public/public-webrtc/2016Mar/0031.html" 20 | W3C_NOTIFICATIONS_CC: "dom@w3.org" 21 | VALIDATE_LINKS: false 22 | W3C_BUILD_OVERRIDE: | 23 | specStatus: WD 24 | shortName: screen-capture 25 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributions to this repository are intended to become part of Recommendation-track documents governed by the 2 | [W3C Patent Policy](https://www.w3.org/Consortium/Patent-Policy/) and 3 | [Software and Document License](https://www.w3.org/Consortium/Legal/copyright-software). To make substantive contributions to specifications, you must either participate 4 | in the relevant W3C Working Group or make a non-member patent licensing commitment. 5 | 6 | If you are not the sole contributor to a contribution (pull request), please identify all 7 | contributors in the pull request comment. 8 | 9 | To add a contributor (other than yourself, that's automatic), mark them one per line as follows: 10 | 11 | ``` 12 | +@github_username 13 | ``` 14 | 15 | If you added a contributor by mistake, you can remove them in a comment with: 16 | 17 | ``` 18 | -@github_username 19 | ``` 20 | 21 | If you are making a pull request on behalf of someone else but you had no part in designing the 22 | feature, you can remove yourself with the above syntax. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Screen Capture 2 | 3 | [](https://wpt.fyi/results/screen-capture) 4 | [](https://wpt.fyi/results/screen-capture) 5 | [](https://wpt.fyi/results/screen-capture) 6 | 7 | This work is currently licensed under a Creative Commons Attribution-NoDerivatives 4.0 8 | International (CC BY-ND 4.0) License. See 9 | http://creativecommons.org/licenses/by-nd/4.0/legalcode 10 | 11 | Copyright Cisco and Mozilla 12 | 13 | ### Published Versions 14 | 15 | While we have taken measures to reduce the frequency of build breakages, the tip-of-tree 16 | of this document may contain work in progress changes and other inconsistencies. 17 | If you want to review something more coherent, review the latest editors' draft; 18 | these are published at intervals on the order of weeks. 19 | 20 | * [Tip of tree as HTML](https://w3c.github.io/mediacapture-screen-share/) 21 | * [Latest published editor's draft at github](https://w3c.github.io/mediacapture-screen-share/) 22 | * [Latest W3C published version](https://www.w3.org/TR/screen-capture/) (automatically updated; should be identical to the latest editors' draft) 23 | 24 | To Reflow the Spec 25 | ------------------ 26 | 27 | To format the draft use something like 28 | 29 | tidy --quiet y -utf8 --vertical-space y --tidy-mark n -indent -wrap 80 30 | -------------------------------------------------------------------------------- /screenshare.css: -------------------------------------------------------------------------------- 1 | 2 | @media screen { 3 | html { background: #eeeeee; } 4 | body { margin-bottom: 30%; border-bottom: thin solid #3c790a; max-width: 720px; } 5 | } 6 | 7 | pre { margin-left: 2em; white-space: pre-wrap; } 8 | dt, dfn { font-weight: bold; font-style: normal; } 9 | i, em, dt dfn { font-style: italic; } 10 | pre, code { font-size: inherit; font-family: monospace, Droid Sans Fallback, sans-serif; font-variant: normal; } 11 | pre strong { color: black; font: inherit; font-weight: bold; background: yellow; } 12 | pre em { font-weight: bolder; font-style: normal; } 13 | @media screen { code { color: orangered; } } 14 | var sub { vertical-align: bottom; font-size: smaller; position: relative; top: 0.1em; } 15 | table { border-collapse: collapse; border-style: hidden hidden none hidden; } 16 | table thead, table tbody { border-bottom: solid; } 17 | table tbody th { text-align: left; } 18 | table tbody th:first-child { border-left: solid; } 19 | table td, table th { border-left: solid; border-right: solid; border-bottom: solid thin; vertical-align: top; padding: 0.2em; } 20 | 21 | ins { background: green; color: white; /* color: green; border: solid thin lime; padding: 0.3em; line-height: 1.6em; */ text-decoration: none; } 22 | del { background: maroon; color: white; /* color: maroon; border: solid thin red; padding: 0.3em; line-height: 1.6em; */ text-decoration: line-through; } 23 | body ins, body del { display: block; } 24 | body * ins, body * del { display: inline; } 25 | 26 | 27 | p > span:not([title=""]):not([class="XXX"]):not([class="impl"]):not([class="note"]), 28 | li > span:not([title=""]):not([class="XXX"]):not([class="impl"]):not([class="note"]) { border-bottom: solid #99CC99; } 29 | 30 | .note { color: green; background: transparent; font-family: sans-serif, Droid Sans Fallback; } 31 | .warning { color: red; background: transparent; } 32 | .note, .warning { font-weight: bolder; font-style: italic; } 33 | .note em, .warning em, .note i, .warning i { font-style: normal; } 34 | p.note, div.note { padding: 0.5em 2em; } 35 | span.note { padding: 0 2em; } 36 | .note p:first-child, .warning p:first-child { margin-top: 0; } 37 | .note p:last-child, .warning p:last-child { margin-bottom: 0; } 38 | .warning:before { font-style: normal; } 39 | p.note:before { content: 'Note: '; } 40 | p.warning:before { content: '\26A0 Warning! '; } 41 | 42 | .bookkeeping:before { display: block; content: 'Bookkeeping details'; font-weight: bolder; font-style: italic; } 43 | .bookkeeping { font-size: 0.8em; margin: 2em 0; } 44 | .bookkeeping p { margin: 0.5em 2em; display: list-item; list-style: square; } 45 | .bookkeeping dt { margin: 0.5em 2em 0; } 46 | .bookkeeping dd { margin: 0 3em 0.5em; } 47 | 48 | .critical { margin: 1em; border: double thick red; padding: 1em; background: #FFFFCC; } 49 | .critical > :first-child { margin-top: 0; } 50 | 51 | .example { display: block; color: #222222; background: #FCFCFC; border-left: double; margin-left: 2em; padding-left: 1em; } 52 | td > .example:only-child { margin: 0 0 0 0.1em; } 53 | a.externalDFN { 54 | color: inherit; 55 | border-bottom: 1px dotted #ccc; 56 | text-decoration: none; 57 | } 58 | -------------------------------------------------------------------------------- /screenshare.js: -------------------------------------------------------------------------------- 1 | var respecConfig = { 2 | // specification status (e.g. WD, LCWD, NOTE, etc.). If in doubt use ED. 3 | specStatus: "ED", // "base", 4 | 5 | // the specification's short name, as in http://www.w3.org/TR/short-name/ 6 | shortName: "screen-capture", 7 | // if your specification has a subtitle that goes below the main 8 | // formal title, define it here 9 | // subtitle : "an excellent document", 10 | 11 | // if you wish the publication date to be other than today, set this 12 | // publishDate: "2009-08-06", 13 | 14 | // new ability to override the copyright completely 15 | // overrideCopyright: "This document is licensed under a Creative Commons Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) License. Copyright 2014 Cisco and Mozilla. ", 16 | 17 | // if the specification's copyright date is a range of years, specify 18 | // the start date here: 19 | copyrightStart: "2015", 20 | 21 | // if there is a previously published draft, uncomment this and set its YYYY-MM-DD 22 | // prevED: "http://dev.w3.org/2011/webrtc/editor/archives/20140321/screenshare.html", 23 | 24 | // if there a publicly available Editor's Draft, this is the link 25 | edDraftURI: "https://w3c.github.io/mediacapture-screen-share/", 26 | 27 | // if this is a LCWD, uncomment and set the end of its review period 28 | // lcEnd: "2009-08-05", 29 | 30 | // if you want to have extra CSS, append them to this list 31 | // it is recommended that the respec.css stylesheet be kept 32 | //extraCSS: ["http://dev.w3.org/2009/dap/ReSpec.js/css/respec.css"], 33 | //extraCSS: ["../../../2009/dap/ReSpec.js/css/respec.css"], 34 | 35 | // editors, add as many as you like 36 | // only "name" is required 37 | editors: [ 38 | // { name: "Your Name", url: "http://example.org/", 39 | // company: "Your Company", companyURL: "http://example.com/" }, 40 | { name: "Jan-Ivar Bruaroey", company: "Mozilla", w3cid: 79152}, 41 | { name: "Elad Alon", company: "Google", w3cid: 118124} 42 | ], 43 | 44 | formerEditors: [ 45 | { name: "Martin Thomson", company: "Mozilla", w3cid: 68503 }, 46 | { name: "Keith Griffin", company: "Cisco", w3cid: 65606 }, 47 | { name: "Suhas Nandakumar", company: "Cisco", w3cid: 48827}, 48 | { name: "Henrik Boström", company: "Google", w3cid: 96936}, 49 | ], 50 | 51 | // authors, add as many as you like. 52 | // This is optional, uncomment if you have authors as well as editors. 53 | // only "name" is required. Same format as editors. 54 | 55 | //authors: [ 56 | // { name: "Your Name", url: "http://example.org/", 57 | // company: "Your Company", companyURL: "http://example.com/" }, 58 | //], 59 | 60 | // name of the WG 61 | group: "webrtc", 62 | xref: ["html", "infra", "permissions", "permissions-policy", "dom", "mediacapture-streams", "webidl", "cssom-view", "css-values", "hr-time"], 63 | // name (without the @w3.org) of the public mailing to which comments are due 64 | wgPublicList: "public-webrtc", 65 | 66 | github: "https://github.com/w3c/mediacapture-screen-share/", 67 | 68 | otherLinks: [ 69 | { 70 | key: "Participate", 71 | data: [ 72 | { 73 | value: "Mailing list", 74 | href: "https://lists.w3.org/Archives/Public/public-webrtc/" 75 | } 76 | ] 77 | } 78 | ] 79 | }; 80 | -------------------------------------------------------------------------------- /explainer.md: -------------------------------------------------------------------------------- 1 | # Screen Capture Explained 2 | 3 | ## What is it? What’s it for? 4 | 5 | It’s an API to get a live video stream of your computer screen or a single window on it, optionally with sound. 6 | 7 | It’s sometimes referred to as screen-sharing, even though only the capturing part is being defined (sharing is just the primary use case). 8 | 9 | Have you ever been a presenter in an online video conference call? You probably shared your screen or the window of a presentation-program to do that. Have you ever presented in an online video conference call without this feature? You likely either had to gesticulate over printouts in front of your camera, or you had to carefully direct your audience to follow along in their own copy of previously-shared online documents, or both. This can lead to confusion as everyone can get a subtly different view. It’s a pretty key feature. This is that feature. 10 | 11 | * Not the networking part—that’s WebRTC’s [RTCPeerConnection](https://w3c.github.io/webrtc-pc/#interface-definition) 12 | * Not the camera and microphone part—that’s MediaCapture’s [getUserMedia](https://w3c.github.io/mediacapture-main/getusermedia.html#idl-def-mediadevices-partial-1) 13 | * **Just** the part that captures your computer's display. It’s called: [getDisplayMedia](https://w3c.github.io/mediacapture-screen-share/#mediadevices-additions) 14 | 15 | Besides formal presentations, being able to spontaneously share what we're looking at on our computers in real-time can complement many online conversations. It's the conversational answer to "What are you looking at?" 16 | 17 | Web sites may capture the screen for other reasons as well, but screen-sharing is the driving use-case. 18 | 19 | ## Non-goals 20 | 21 | Some adjacent goals that are not in scope of this specification: 22 | * Online document sharing 23 | * Remote assistance temporarily "taking over" control of a system 24 | * Co-browsing 25 | 26 | ## Alternatives 27 | 28 | Alternatives to screen-sharing: 29 | * Online document sharing using web technology. 30 | * Browser plug-in (like Chrome's now-abandoned Screen Capture extension) 31 | 32 | Both alternatives have adoption problems and limitations. In contrast, this spec is widely supported, and screen-sharing appears well-understood as a concept. 33 | 34 | ## Approach 35 | 36 | The approach is heavily modeled on our [camera API](https://w3c.github.io/mediacapture-main/getusermedia.html#idl-def-mediadevices-partial-1), hence the name similarity. There’s a reason for that: both require user permission, and return a MediaStream object with a pair of highly privacy sensitive video and audio tracks—It’s just your screen instead of your face. The resulting MediaStream is a drop-in anywhere a MediaStream is accepted in the platform. Having obtained such a MediaStream, a website can trivially: 37 | 38 | * play the live stream of your screen locally in a video element, 39 | * send it over a peer connection to another client, 40 | * send it to a [MediaRecorder](https://w3c.github.io/mediacapture-record/MediaRecorder.html#mediarecorder-api), perhaps for subsequent upload to a server, 41 | * or all of the above (at once even). 42 | 43 | This flexibility is thanks to the MediaCapture-main spec which already did the heavy lifting of: 44 | * defining [MediaStream](https://w3c.github.io/mediacapture-main/getusermedia.html#mediastream) and [MediaStreamTrack](https://w3c.github.io/mediacapture-main/getusermedia.html#dom-mediastreamtrack) 45 | * defining the constraints an application can apply to downscale and decimate frame-rates 46 | * defining a privacy-sensitive permission model 47 | 48 | This leaves this spec to focus on the parts unique to acquiring display media, and its privacy challenges. 49 | 50 | ## Getting started 51 | 52 | This is how to request a video MediaStream sourced by screen-capture: 53 | 54 | ```js 55 | const stream = await navigator.mediaDevices.getDisplayMedia({video: true, audio: true}); 56 | ``` 57 | 58 | Compare to a request for camera and microphone: 59 | 60 | ```js 61 | const stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true}); 62 | ``` 63 | These streams can then be used interchangeably: 64 | 65 | ```js 66 | videoElement.srcObject = stream; // self-view 67 | 68 | new MediaRecorder(stream).start(); // record 69 | 70 | for (const track of stream.getTracks()) peerConnnection.addTrack(track, stream); // present 71 | 72 | await stream.getVideoTracks()[0].applyConstraints({height: 480}); // downscale 73 | 74 | for (const track of stream.getTracks()) track.stop(); // stop capture & relinquish access 75 | ``` 76 | 77 | Some important differences and unique properties of screen capture: 78 | 79 | * The request is gated by user activation. 80 | * The end-user is always prompted each time with a picker to select what to share. 81 | * It is not possible to persist permission grants (only blocks). 82 | * Application-supplied constraints are applied after selection, and do not narrow the end-user’s choices (unlike with camera). 83 | * All choices are videos. Any accompanying audio is optional and requires consent and support. 84 | * Screen capture sources are never exposed in enumerateDevices(). 85 | 86 | ## Security and privacy implications 87 | 88 | Allowing a web page to capture and effectively record your screen carries significant privacy and security risks. The three main ones are, in increasing order of severity: 89 | 90 | **Audio exposure and correlation.** When audio is captured alongside video (which requires specific end-user consent), it may expose additional information about system applications. It may contain system-wide audio in certain cases, which may include audible information from other domains. 91 | 92 | **End-user oversharing of video.** The immediate and obvious risk is that users inadvertently share content that they did not wish to share, or might not have realized would be shared. This can happen from trivial-seeming actions like scrolling, document flipping, even tab headers, anything that’s visible if just for a split second. 93 | 94 | **Capturing a web surface defeats same-origin protections.** Capturing a browser window or the desktop when a browser window is visible on it, poses a unique privacy and security risk that is unobvious and significant. If a captured browser window is displaying a page that is under the control of a malicious application, even indirectly, it can allow the malicious application to induce presentation of information that would otherwise be secret from it. For details, see [Share browser windows and entire screen only with sites you trust](https://blog.mozilla.org/webrtc/share-browser-windows-entire-screen-sites-trust/). 95 | 96 | ## Security and Privacy Questionnaire 97 | 98 | See [questionnaire.md](questionnaire.md). 99 | -------------------------------------------------------------------------------- /questionnaire.md: -------------------------------------------------------------------------------- 1 | # Security and Privacy Questionnaire for Screen Capture 2 | 3 | ## Questions to Consider 4 | 5 | ### 2.1. What information might this feature expose to Web sites or other parties, and for what purposes is that exposure necessary? 6 | 7 | With a user’s permission, it exposes to a website a live video stream of the user’s desktop, or a window of their choosing, optionally with accompanying audio, if available and consented to. 8 | The user may choose a **physical** or **virtual monitor**, a **window**, an **application**, or a **browser**. All information visible on the chosen surface is shared. Audible information may also be shared. In addition, depending on the surface, information that’s not currently visible may also be shared. For example: an entire window including parts presently offscreen or obscured by other windows. 9 | The purpose of the feature is to allow people to share their screen, if they so choose, with others, typically in an online video conference or one-on-one call. A presenter may wish to share the window of their presentation program. Friends and relatives may wish to spontaneously share what they’re looking at on their computer or device to aid or complement a conversation. 10 | See [explainer](explainer.md) for more. 11 | 12 | ### 2.2. Is this specification exposing the minimum amount of information necessary to power the feature? 13 | 14 | The decision of what to share (or whether to share anything at all) rests entirely with the end-user. Websites cannot influence this choice in any way, or demand audio be included. A user gesture is required to request, and users may reject or even block all requests. Defining the pool of available sources is left to user agents, as well as decisions about whether to share obscured parts. The spec requires user agents to implement prominent indicators warning users when sharing is live. 15 | 16 | ### 2.3. How does this specification deal with personal information or personally-identifiable information or information derived thereof? 17 | 18 | Nothing is shared without a user’s explicit choice. The spec uses the permissions [[PERMISSIONS]](https://www.w3.org/TR/security-privacy-questionnaire/#biblio-permissions) spec to persist denied permissions, and mandates an explicit per-use in-browser chooser prompt. By choosing a surface to share, the end user permits a website one-time access to continuous video (optionally with audio) of that surface, until the website stops the video and/or audio track, the page navigates away, or the user revokes the permission, whichever is sooner. A name (label) of the surface is also shared (e.g. the title of a window) with the track. 19 | 20 | This is a powerful feature, restricted to secure contexts. No attempt is made to mandate that personal information, sensitive information or cross-origin content be detected and blacked out. To some extent, this is a feature. 21 | 22 | ### 2.4. How does this specification deal with sensitive information? 23 | 24 | Per above, nothing prevents a user from sharing a surface that contains sensitive information. 25 | But additionally, the spec strongly advises user agents require [elevated permissions](https://w3c.github.io/mediacapture-screen-share/#elevated-permissions) to share **browser surfaces** or **monitors** with browsers visible. These sources carry **significant risk**, as sensitive information may be leaked through **active attacks on the same-origin policy**. For details, see [Share browser windows and entire screen only with sites you trust](https://blog.mozilla.org/webrtc/share-browser-windows-entire-screen-sites-trust/). 26 | 27 | ### 2.5. Does this specification introduce new state for an origin that persists across browsing sessions? 28 | 29 | Nothing is revealed without permission, and grants cannot be persisted. Permission blocking follows feature-policy. See next question. 30 | 31 | ### 2.6. What information from the underlying platform, e.g. configuration data, is exposed by this specification to an origin? 32 | 33 | Depending on what a user chooses to share, a website may learn physical properties of their system, such as the size and appearance of their desktop, and any information displayed, e.g. possibly their local time and location (weather) if the user has configured such display on their desktop. This can be correlated to other origins that are using the same API, if the user shares the same surface there. 34 | 35 | ### 2.7. Does this specification allow an origin access to sensors on a user’s device 36 | 37 | Results from sensors may be exposed. While screen-capture is live, the origin may record the result of the user's activity on the system, including, for instance, cursor movements in response to mouse movements. 38 | 39 | Also, no attempt is made to mandate that camera and microphone sourced playback be excluded from capture. Same with a location shown on a map (from GPS sensors). Users might perceive such mitigations as bugs. 40 | 41 | ### 2.8. What data does this specification expose to an origin? Please also document what data is identical to data exposed by other features, in the same or different contexts. 42 | 43 | (This question’s template mentions [same-origin policy](https://www.w3.org/TR/security-privacy-questionnaire/#same-origin-policy) so following that lead) As mentioned earlier, **browser** and **monitor** surfaces may be exploited to circumvent the [same-origin policy](https://www.w3.org/TR/security-privacy-questionnaire/#same-origin-policy), exposing details about another origin’s state in graphical or audible form, which if extracted may be used in POST or GET requests to another origin, potentially carrying severe consequences. 44 | 45 | A mitigation “strongly advised” by the spec for this is to require [elevated permissions](https://w3c.github.io/mediacapture-screen-share/#elevated-permissions) that “determine that the user exhibits an elevated level of trust in the application that is being granted access” to **browser** and **monitor** sources. At least [one browser attempts to implement](https://support.mozilla.org/en-US/kb/screenshare-safety) this mitigation. 46 | 47 | ### 2.9. Does this specification enable new script execution/loading mechanisms? 48 | 49 | No. 50 | 51 | ### 2.10. Does this specification allow an origin to access other devices? 52 | 53 | No direct access to other networked devices. All surfaces shared are local (even though this spec inherited the term “device” from the MediaCapture-main specification). 54 | 55 | No attempt is made to mandate that e.g. a user’s VNC or remote desktop client window be excluded from capture. Users might perceive such mitigations as bugs. 56 | 57 | ### 2.11. Does this specification allow an origin some measure of control over a user agent’s native UI? 58 | 59 | In combination with full screen mode, **monitor** surface capture increases a website’s ability to reconstruct a user’s native UI faithfully, in order to fool users or obscure security / privacy controls. However, since the nature of the threat remains unchanged, full screen mode’s existing mitigations should suffice. 60 | 61 | ### 2.12. What temporary identifiers might this specification create or expose to the web? 62 | 63 | No temporary identifiers (e.g. deviceIds) are exposed. 64 | 65 | ### 2.13. How does this specification distinguish between behavior in first-party and third-party contexts? 66 | 67 | It defines the feature policy “display-capture”. It is off by default in iframes. 68 | 69 | ### 2.14. How does this specification work in the context of a user agent’s Private Browsing or "incognito" mode? 70 | 71 | Assuming a user agent allows the same sources in both modes, the same risks of correlation mentioned earlier across origins apply here. Whether the permission is blocked or not also carries some information across, depending on the user agent. 72 | 73 | ### 2.15. Does this specification have a "Security Considerations" and "Privacy Considerations" section? 74 | 75 | Yes, see [§8 Security & Permissions](https://w3c.github.io/mediacapture-screen-share/#security-and-permissions) and [§7 Privacy Indicator Requirements](https://w3c.github.io/mediacapture-screen-share/#privacy-indicator-requirements). 76 | 77 | ### 2.16. Does this specification allow downgrading default security characteristics? 78 | 79 | Only permission delegation of this powerful feature to iframes through feature policy, to the extent a site is more secure without this feature. 80 | 81 | Sharing this feature with an embedded iframe exposes the top-level site to the risks of the same-origin vulnerabilities discussed earlier. 82 | 83 | ### 2.17. What should this questionnaire have asked? 84 | 85 | Seems thorough. It wasn’t always clear whether the word “device” referred to a user’s system, other networked systems, or peripherals like camera and microphone, or all of the above. This may stem from a terminology conflict with our WG. What we call “devices”, you seem to call “sensors”. 86 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 |This document defines how a user's display, or parts thereof, can be 17 | used as the source of a media stream using 18 | {{MediaDevices/getDisplayMedia}}, an extension to the Media Capture API 19 | [[GETUSERMEDIA]].
20 |This document is not complete. It is subject to major changes and, while 25 | early experimentations are encouraged, it is therefore not intended for 26 | implementation.
27 |This document describes an extension to the Media Capture API 35 | [[GETUSERMEDIA]] that enables the acquisition of a user's display, or part 36 | thereof, in the form of a video track. In some cases system, application or 37 | window audio is also captured which is presented in the form of an audio 38 | track. This enables a number of applications, including screen sharing 39 | using WebRTC [[WEBRTC]].
40 | 41 | 42 |This feature has signficant security implications. Applications that use 43 | this API to access information that is displayed to users could access 44 | confidential information from other origins if that information is under 45 | the control of the application. This includes content that would otherwise 46 | be inaccessible due to the protections offered by the user agent 47 | sandbox.
48 | 49 | 50 |This document concerns itself primarily with the capture of video and 51 | audio [[GETUSERMEDIA]], but the general mechanisms defined here could be 52 | extended to other types of media, of which depth [[MEDIACAPTURE-DEPTH]] is 53 | currently defined.
54 |This specification defines conformance criteria that apply to a single 59 | product: the user agent that implements 60 | the interfaces that it contains.
61 | 62 | 63 |Implementations that use ECMAScript [[ECMA-262]] to implement the APIs 64 | defined in this specification must implement them in a manner consistent 65 | with the ECMAScript Bindings defined in the Web IDL specification 66 | [[!WEBIDL]], as this specification uses that specification and 67 | terminology.
68 |The following example demonstrates a request for display capture using
76 | the navigator.mediaDevices.getDisplayMedia method defined in
77 | this document.
try {
80 | let mediaStream = await navigator.mediaDevices.getDisplayMedia({video:true});
81 | videoElement.srcObject = mediaStream;
82 | } catch (e) {
83 | console.log('Unable to acquire screen capture: ' + e);
84 | }
85 | This document uses the definition of {{MediaStream}}, 93 | {{MediaStreamTrack}} and {{ConstrainablePattern}} from 94 | [[!GETUSERMEDIA]].
95 | 96 | 97 |Screen capture encompasses the capture of several different types of 98 | screen-based surfaces. Collectively, these are referred to as display surfaces, of which this 100 | document defines the following types:
101 | 102 | 103 |This document draws a distinction between two variants of each type of 130 | display surface:
131 | 132 | 133 |Some operating systems permit windows from different applications to 146 | occlude other windows, in whole or part, so the visible display 147 | surface is a strict subset of the logical display surface.
148 | 149 | 150 |The source pixel ratio of a display 151 | surface is 1/96th of 1 inch divided by its vertical pixel size.
152 | 153 |The devicechange event is defined in 154 | [[GETUSERMEDIA]].
155 |Capture of displayed media is enabled through the addition of a new 172 | {{MediaDevices/getDisplayMedia}} method on the {{MediaDevices}} interface, 173 | that is similar to {{MediaDevices/getUserMedia()}} , except that it 174 | acquires media from one display device chosen by the end-user each 175 | time.
176 | 177 | 178 |partial interface MediaDevices {
182 | Promise<MediaStream> getDisplayMedia(optional DisplayMediaStreamOptions options = {});
183 | };
184 |
185 | Prompts the user for permission to live-capture their display.
193 | 194 | 195 |The user agent MUST let the end-user choose which [=display
196 | surface=] to share out of all available choices every time, and MUST
197 | NOT use any {{MediaTrackConstraints}} in
198 | options.video or
199 | options.audio to limit that choice.
The user agent MAY use the presence of the {{displaySurface}} 203 | constraint and its value to influence the presentation to the user of 204 | the sources to pick from. The user agent MUST still offer the user 205 | unlimited choice of any [=display surface=]. The user agent is 206 | strongly recommended to steer users away from sharing a monitor, as 207 | this poses risks to user 208 | privacy.
209 | 210 | 211 |Any {{MediaTrackConstraints}} in
212 | options.video or
213 | options.audio MUST be applied to the media
214 | chosen by the user only after the user has made their selection.
In the case of audio, the user agent MAY present the end-user with 218 | audio sources to share. Which choices are available to choose from is 219 | up to the user agent, and the audio source(s) are not necessarily the 220 | same as the video source(s). An audio source may be a particular [= 221 | display surface/window =], [= display surface/browser =], the entire 222 | system audio or any combination thereof. Unlike 223 | {{MediaDevices/getUserMedia()}} with regards to audio+video, the user 224 | agent is allowed not to return audio even if the audio constraint is 225 | present. If the user agent knows no audio will be shared for the 226 | lifetime of the stream it MUST NOT include an audio track in the 227 | resulting stream. The user agent MAY accept a request for audio and 228 | video by only returning a video track in the resulting stream, or it 229 | MAY accept the request by returning both an audio track and a video 230 | track in the resulting stream. The user agent MUST reject audio-only 231 | requests.
232 | 233 | 234 |In addition to drawing from a different set of sources and 235 | requiring user selection, {{MediaDevices/getDisplayMedia}} also 236 | differs from {{MediaDevices/getUserMedia()}} in that 237 | {{PermissionState/"granted"}} permissions cannot be persisted.
238 | 239 | 240 |When the {{MediaDevices/getDisplayMedia()}} method is called, the 241 | user agent MUST run the following steps:
242 | 243 | 244 |Let mediaDevices be [=this=].
247 |Let controller be
252 | options.controller if present, or
253 | null otherwise.
If controller is not null, run the
259 | following steps:
If controller.{{CaptureController/[[IsBound]]}}
265 | is true, return a promise [=reject|rejected=]
266 | with a {{DOMException}} object whose {{DOMException/name}}
267 | attribute has the value {{InvalidStateError}}.
Set
273 | controller.{{CaptureController/[[IsBound]]}} to
274 | true.
If the [=relevant global object=] of [=this=] does not have 282 | [=transient activation=], return a promise rejected with a 283 | {{DOMException}} object whose {{DOMException/name}} attribute has 284 | the value {{InvalidStateError}}.
285 |Let options be the method's first argument.
290 |Let constraints be
295 | [options.audio,
296 | options.video].
If constraints.video is false,
302 | return a promise [=reject|rejected=] with a newly
303 | [=exception/created=] {{TypeError}}.
For each [= map/exist | existing =] member in 309 | constraints whose value, CS, is a 310 | dictionary, run the following steps:
311 | 312 | 313 |If CS contains a member named
316 | advanced, return a promise [=reject|rejected=]
317 | with a newly [=exception/created=] {{TypeError}}.
If CS contains a member whose name specifies a
323 | constrainable property applicable to [=display surface=]s,
324 | and whose value in turn is a dictionary containing a member
325 | named either min or exact, return a
326 | promise [=reject|rejected=] with a newly
327 | [=exception/created=] {{TypeError}}.
If CS contains a member whose name specifies a
333 | constrainable property applicable to [=display surface=]s,
334 | and whose value in turn is a dictionary containing a member
335 | named max, and that member's value in turn is
336 | less than the constrainable property's [=floor value=], then
337 | let failedConstraint be the name of the member,
338 | let message be either undefined or an
339 | informative human-readable message, and return a promise
340 | [=reject|rejected=] with a new
341 | OverconstrainedError created by calling
342 | OverconstrainedError(failedConstraint,
343 | message).
Let requestedMediaTypes be the set of media types
351 | in constraints with either a dictionary value or a
352 | value of true.
If the current settings object's [=relevant global 358 | object=]'s [=associated `Document`=] is NOT [=Document/fully 359 | active=] or does NOT have 360 | focus, return a promise [=reject|rejected=] with a 361 | {{DOMException}} object whose {{DOMException/name}} attribute has 362 | the value {{InvalidStateError}}.
363 |Let p be a new promise.
368 |Run the following steps [=in parallel=]:
373 | 374 | 375 |For each media type T in 378 | requestedMediaTypes,
379 | 380 | 381 |If no sources of type T are available, 384 | [=queue a task=] on the [=user interaction task source=] 385 | to [=reject=] p with a new {{DOMException}} 386 | object whose {{DOMException/name}} attribute has the 387 | value {{NotFoundError}}, and abort these steps.
388 |Read the current [= permission state=] for obtaining 393 | sources of type T in the current browsing 394 | context. If the permission state is 395 | {{PermissionState/"denied"}}, jump to the step labeled 396 | PermissionFailure below.
397 |Optionally, e.g., based on a previously-established user 404 | preference, for security reasons, or due to platform 405 | limitations, jump to the step labeled Permission 406 | Failure below.
407 |[=Prompt the user to choose=] a display device, for a 412 | {{PermissionDescriptor}} with its 413 | {{PermissionDescriptor/name}} set to "display-capture", 414 | resulting in a set of provided media.
415 | 416 | 417 |The provided media MUST include precisely one video 418 | track.
419 | 420 | 421 |The provided media MUST include at most one audio track.
422 | This audio track MUST NOT be included if audio was not
423 | specified in requestedMediaTypes, or if it was
424 | specified as false.
The devices chosen MUST be the ones determined by the 428 | user. Once selected, the source of a {{MediaStreamTrack}} 429 | MUST NOT change, unless the user permits it through their 430 | interaction with the user agent.
431 | 432 | 433 |User agents are encouraged to warn users against sharing 434 | [= display surface/browser =] display devices as well as [= 435 | display surface/monitor =] display devices where browser 436 | windows are visible, or otherwise try to discourage their 437 | selection on the basis that these represent a significantly 438 | higher risk when shared.
439 | 440 | 441 |If the result of the request is
442 | {{PermissionState/"granted"}}, then for each device that is
443 | sourcing the provided media, using a stable and private id
444 | for the device, deviceId, set
445 | [[\devicesLiveMap]][deviceId] to
446 | true, if it isn’t already true, and
447 | set the [[\devicesAccessibleMap]][deviceId] to
448 | true, if it isn’t already true.
The user agent MUST NOT store a 452 | {{PermissionState/"granted"}} permission entry.
453 | 454 | 455 |If the result is {{PermissionState/"denied"}}, jump to the 456 | step labeled Permission Failure below. If the user 457 | never responds, this algorithm stalls on this step.
458 | 459 | 460 |If the user grants permission but a hardware error such as 461 | an OS/program/webpage lock prevents access, [=queue a task=] 462 | on the [=user interaction task source=] to [=reject=] 463 | p with a new {{DOMException}} object whose 464 | {{DOMException/name}} attribute has the value 465 | {{NotReadableError}}, and abort these steps.
466 | 467 | 468 |If the result is {{PermissionState/"granted"}} but device 469 | access fails for any reason other than those listed above, 470 | [=queue a task=] on the [=user interaction task source=] to 471 | [=reject=] p with a new {{DOMException}} object 472 | whose {{DOMException/name}} attribute has the value 473 | {{AbortError}}, and abort these steps.
474 |Let stream be a {{MediaStream}} object.
479 |For each source that the user granted permission 483 | to, run the following steps:
484 |Let track be the result of [=create a 487 | MediaStreamTrack|creating a MediaStreamTrack=] 488 | with source and mediaDevices.
489 |Add track to stream's track set.
492 |[=Tie track source to MediaDevices=] with source and mediaDevices.
495 |Run the [=ApplyConstraints algorithm=] on all tracks in
502 | stream with the appropriate constraints. Should
503 | this fail, let failedConstraint be the result of
504 | the algorithm that failed, and let message be
505 | either undefined or an informative
506 | human-readable message, and then [=queue a task=] on the
507 | [=user interaction task source=] to [=reject=] p
508 | with a new OverconstrainedError created by
509 | calling
510 | OverconstrainedError(failedConstraint,
511 | message), and abort these steps.
This invocation of {{MediaDevices/getDisplayMedia()}} is 517 | now considered to have produced a new 518 | capture-session.
519 |[=Queue a task=] on the [=user interaction task source=] to 522 | run the following steps:
523 |If controller is not `null`, run the 526 | following steps:
527 |Set 530 | controller.{{CaptureController/[[Source]]}} to 531 | stream's video track's [[\Source]].
533 |Set 536 | controller.{{CaptureController/[[DisplaySurfaceType]]}} 537 | to the to stream's video track's 538 | {{DisplayCaptureSurfaceType}}.
539 |[=Resolve=] p with stream.
548 |If controller is not `null`, [=queue a task=] 553 | on the [=user interaction task source=] to run the 554 | [=finalize focus decision algorithm=] on controller.
555 |Abort these steps.
558 |Permission Failure: [=Queue a task=] on the 561 | [=user interaction task source=] to 562 | [=reject=] p with 563 | a new {{DOMException}} object whose {{DOMException/name}} 564 | attribute has the value {{NotAllowedError}}.
565 |Return p.
572 |When the top-level document loses focus, run the following steps 577 | on all {{CaptureController}} objects in that document and in 578 | documents of its nested [=browsing contexts=]:
579 | 580 | 581 |If {{CaptureController/[[Source]]}} is undefined,
584 | abort these steps.
Set {{CaptureController/[[FocusChangeDisabled]]}} to
590 | true.
The user agent MUST NOT capture content that's behind a 596 | partially transparent captured display surface.
597 | 598 | 599 |For the newly created {{MediaStreamTrack}}, the user agent 600 | MUST NOT capture the prompt that was shown to the user.
601 | 602 | 603 |Information that is not currently rendered to the screen SHOULD be 604 | obscured in captures unless the application has been specifically 605 | authorized to access that content (e.g. through means such as 606 | elevated permissions).
607 | 608 | 609 |The user agent MUST NOT share audio without active user 610 | consent, for example if the capture of the video of a [= display 611 | surface/window =] is accompanied by capture of the audio of the 612 | entire system, including applications unrelated to that window.
613 |A display surface that is being shared may temporarily or 624 | permanently become inaccessible to the application because of actions 625 | taken by the operating system or user agent. What makes a display 626 | surface considered inaccesible is outside the scope of this 627 | specification, but examples MAY include a [= display surface/monitor =] 628 | disconnecting, [= display surface/window =] or [= display surface/browser 629 | =] closing or becoming minimized, or due to an incoming call on a 630 | phone.
631 | 632 | 633 |User agents ultimately control what inaccesible means in 634 | this context, but are encouraged to only fire mute and unmute events for 635 | interruptions that have external reasons.
636 | 637 | 638 |When display surface enters an inaccessible state that is not
639 | necessarily permanent, the user agent MUST [=queue a task=] on the
640 | [=user interaction task source=] that [= MediaStreamTrack/set a
641 | track's muted state|sets the muted state =] of the corresponding media
642 | track to true.
When display surface exits an inaccessible state and becomes
646 | accessible, the user agent MUST [=queue a task=] on the
647 | [=user interaction task source=] that [= MediaStreamTrack/set a track's muted
648 | state|sets the muted state =] of the corresponding media track to
649 | false.
When a display surface enters an inaccessible state that is 653 | permanent (such as the source [= display surface/window=] closing), the 654 | user agent MUST [=queue a task=] on the [=user interaction task source=] 655 | that [= MediaStreamTrack/ended | ends =] the corresponding media track.
656 | 657 | 658 |A stream that was just returned by {{MediaDevices/getDisplayMedia}} 659 | MAY contain tracks that are muted by default. Audio and video tracks 660 | belonging to the same stream MAY be muted/unmuted independently of one 661 | another.
662 |Not accepting constraints for source selection
670 | means that {{MediaDevices/getDisplayMedia}} only provides fingerprinting
671 | surface that exposes whether audio, video or audio and video display
672 | sources are present.
Note that accepting the {{displaySurface}} constraint does not limit 677 | user selection.
678 |Constraints serve a different purpose in 687 | {{MediaDevices/getDisplayMedia}} than they do in 688 | {{MediaDevices/getUserMedia()}}. They do not aid discovery, instead they 689 | are applied only after user-selection.
690 | 691 | 692 |This section define which constraints apply to 693 | {{MediaDevices/getDisplayMedia}} tracks; constraints defined for 694 | {{MediaDevices/getUserMedia()}} do not apply unless listed here.
695 | 696 | 697 |Some of these constraints enable user agent processing like 698 | downscaling and frame decimation, as well as display-specific features. 699 | Others enable observation of inherent properties of a user-selected 700 | display surface, as capabilities and settings.
701 | 702 | 703 |The following new and existing {{MediaStreamTrack}} Constrainable Properties are 705 | defined to apply to the user-selected video display surface, with 706 | the following behavior:
707 | 708 | 709 || Property Name | 713 | 714 |Type | 715 | 716 |Behavior | 717 |
|---|---|---|
| width 724 | | 725 | 726 |{{unsigned long}} | 727 | 728 |729 | The width, in pixels. As a capability, max MUST reflect the 730 | display surface's width, and min MUST reflect the width of 731 | the smallest aspect-preserving representation available through 732 | downscaling by the user agent. 733 | | 734 |
| height 739 | | 740 | 741 |{{unsigned long}} | 742 | 743 |744 | The height, in pixels. As a capability, max MUST reflect the 745 | display surface's height, and min MUST reflect the height 746 | of the smallest aspect-preserving representation available 747 | through downscaling by the user agent. 748 | | 749 |
| frameRate 754 | | 755 | 756 |{{double}} | 757 | 758 |759 | The frame rate (frames per second). As a capability, max MUST 760 | reflect the display surface's frame rate, and min MUST 761 | reflect the lowest frame rate available through frame decimation 762 | by the user agent. 763 | | 764 |
| aspectRatio 769 | | 770 | 771 |{{double}} | 772 | 773 |The exact aspect ratio (width in pixels divided by height in
774 | pixels, represented as a double rounded to the tenth decimal place)
775 | or aspect ratio range. As a setting, represents width /
776 | height. As a capability, min and max both MUST be the
777 | current setting value, rendering this property immutable from the
778 | application viewpoint. |
779 |
| resizeMode 784 | | 785 | 786 |{{DOMString}} | 787 | 788 |
789 | This string is one of the members of {{VideoResizeModeEnum}}. As
790 | a setting, {{VideoResizeModeEnum/"none"}} means the
791 | {{MediaStreamTrack}} contains all bits needed to render the
792 | display in full detail, which if the source pixel
793 | ratio > 1, means width and
794 | height will be larger than the display's appearance
795 | from an end-user viewpoint would suggest, whereas
796 | {{VideoResizeModeEnum/"crop-and-scale"}} means the
797 | {{MediaStreamTrack}} contains an aspect-preserved representation
798 | of the display surface that has been downscaled by the
799 | user agent, but not cropped. As a capability, the values
800 | {{VideoResizeModeEnum/"none"}} and
801 | {{VideoResizeModeEnum/"crop-and-scale"}} both MUST be present.
802 | |
803 |
| deviceId 808 | | 809 | 810 |{{DOMString}} | 811 | 812 |
813 | The identifier of the surface being captured.
814 |
815 | As a setting, identifies the [=display surface=] that 816 | is being captured. The identifier MUST be uniquely generated for 817 | each [=document=]. 818 | 819 |As a capability, the setting value MUST be the lone value 820 | present, rendering this property immutable from the application 821 | viewpoint. 822 | |
823 |
| displaySurface 828 | | 829 | 830 |{{DOMString}} | 831 | 832 |
833 | This string is one of the members of 834 | {{DisplayCaptureSurfaceType}}. 835 | 836 | 837 |As a setting, indicates the type of [=display surface=] that 838 | is being captured. 839 | 840 | 841 |As a capability, the setting value MUST be the lone value 842 | present, rendering this property immutable from the application 843 | viewpoint. 844 | 845 | 846 |As a constraint, the value signals the application's
847 | preference of a particular [=display surface=] type to the user
848 | agent; the user agent MAY reorder the options offered to the user
849 | according to that preference. This constraint is ignored for all
850 | other purposes, and can therefore not cause any side effects
851 | (such as being the cause of
852 | |
854 |
| logicalSurface 859 | | 860 | 861 |{{boolean}} | 862 | 863 |As a setting, a value of true indicates capture of
864 | a [=logical display surface=], whereas a value of
865 | false indicates a capture of a [=visible display
866 | surface=]. As a capability, this same value MUST be the lone value
867 | present, rendering this property immutable from the application
868 | viewpoint. |
869 |
| cursor 874 | | 875 | 876 |{{DOMString}} | 877 | 878 |This string is one of the members of 879 | {{CursorCaptureConstraint}}. As a setting, indicates if and when 880 | the cursor is included in the captured [=display surface=]. As a 881 | capability, the user agent MUST include only the set of values from 882 | {{CursorCaptureConstraint}} it is capable of supporting for this 883 | [=display surface=]. | 884 |
| screenPixelRatio 888 | | 889 | 890 |{{double}} | 891 | 892 |As a setting, it is the result of dividing the size of a 893 | CSS pixel 894 | at a page zoom 895 | of 1.0 and using a 896 | scale factor 897 | of 1.0 by the vertical size of a pixel from the [=display surface=]. 898 | It cannot be used as a constraint or capability. 899 | | 900 |
The following new and existing {{MediaStreamTrack}} Constrainable Properties are 907 | defined to apply to the user-selected audio sources, with the following 908 | behavior:
909 | 910 | 911 || Property Name | 915 | 916 |Type | 917 | 918 |Behavior | 919 |
|---|---|---|
| restrictOwnAudio 926 | | 927 | 928 |{{boolean}} | 929 | 930 |
931 | As a setting, this value indicates whether or not the user 932 | agent is applying own audio restriction to the source. 933 | 934 | 935 |As a constraint, this property can be constrained resulting in 936 | a source with own audio restriction enabled or 937 | disabled. 938 | 939 | 940 |When own audio restriction is applied, the user 941 | agent MUST attempt to remove any audio from the audio being 942 | captured that was produced by the document that performed 943 | {{MediaDevices/getDisplayMedia}}. If the user agent is not able 944 | to remove the audio through processing it SHOULD remove the audio 945 | by excluding the document's audio from being captured. If this 946 | results in no audio being captured, the user agent MUST keep the 947 | track muted until it is able to capture audio again. 948 | |
949 |
| suppressLocalAudioPlayback 954 | | 955 | 956 |{{boolean}} | 957 | 958 |
959 | As a setting, this value indicates whether or not the 960 | application instructed the user agent to apply local audio 961 | playback suppression to the source. 962 | 963 | 964 |As a constraint, this value is only meaningful if the user
965 | selects capturing a [= display surface/browser=] [=display
966 | surface=]. In that case, a value of When local audio playback suppression is applied, 973 | the user agent SHOULD stop relaying audio to the local speakers, 974 | but that audio MUST still be captured by any ongoing 975 | audio-capturing [=capture-sessions=]. This suppression MUST NOT 976 | be observable to the captured document. Furthermore, the 977 | capturing document may only observe whether it is applying 978 | suppressLocalAudioPlayback; not whether that suppression 979 | is having an effect (i.e. can't observe if the user is overriding 980 | this in the user agent). 981 | 982 | 983 |When a [= display surface/browser=] [=display surface=] is
984 | subject to multiple concurrent captures, local audio playback
985 | suppression SHOULD be applied as long as at least one active
986 | audio-capturing [=capture-session=] is constraining
987 | suppressLocalAudioPlayback to |
989 |
When inherent properties of the underlying source of a user-selected 995 | display surface change, for example in response to the end-user 996 | resizing a captured window, and these changes render the capabilities 997 | and/or settings of one or more constrainable properties outdated, the 998 | user agent MUST [=queue a task=] on the [=user interaction task source=] 999 | to run the following step:
1000 | 1001 | 1002 |Update all affected constrainable properties at the same time.
1005 | 1006 | 1007 |If this causes an "overconstrained" situation, then the user agent 1008 | MUST ignore the culprit constraints for as long as they 1009 | overconstrain. The user agent MUST NOT mute the track.
1010 |While min and exact constraints produce TypeError on 1016 | getDisplayMedia(), this specification does not alter the 1017 | track.applyConstraints() method. Therefore, they may instead produce 1018 | OverconstrainedError or succeed depending on values, and therefore 1019 | potentially be present to cause this "overconstrained" situation. The 1020 | max constraint may also cause this, e.g. with aspectRatio. This spec 1021 | considers these to be edge cases that aren't useful.
1022 |For the purposes of the [=SelectSettings=] algorithm, the user agent 1030 | SHOULD consider all possible combinations of downscaled dimensions that 1031 | preserve the aspect ratio of the original display surface (to 1032 | the nearest pixel), and frame rates available through frame decimation, 1033 | as available [= settings dictionaries =].
1034 | 1035 | 1036 |The downscaling and decimation effects of constraints is then 1037 | effectively governed by the [= fitness distance =] algorithm.
1038 | 1039 | 1040 |The intent is for the user agent to produce output that is close to
1041 | the ideal width, ideal height, and/or ideal
1042 | frameRate when these are specified, while at all times
1043 | preserving the aspect ratio of the original display surface.
The user agent SHOULD downscale by the source pixel ratio by 1047 | default, unless otherwise directed by applied constraints.
1048 | 1049 | 1050 |The user agent MUST NOT crop the captured output.
1051 | 1052 | 1053 |The user agent MUST NOT upscale the captured output, or create 1054 | additional frames, except as needed to preserve high resolutions and 1055 | frame rates in an aggregated display surface.
1056 | 1057 | 1058 |The max constraint type lets a web application provide a maximum 1060 | envelope for constrainable properties like width and height. This is 1061 | helpful to limit extreme aspect ratios, should the end-user resize a 1062 | [= display surface/window =] or [= display surface/browser =] surface 1063 | to such an extreme while it is being captured.
1064 |For each constrainable property of positive numeric type in this
1068 | specification, the user agent MUST establish a floor value,
1069 | representing the smallest allowable value supported by the user agent
1070 | regardless of source. This value MUST be constant and MUST be greater
1071 | than 0. The user agent is encouraged to support all values
1072 | above the floor value regardless of source.
The purpose of the floor value is to help user agents avoid
1077 | failing {{MediaDevices/getDisplayMedia()}} with
1078 | OverconstrainedError after the user has already been
1079 | prompted, and avoid leaking information about the user's system.
Describes whether an application invoking 1090 | {{CaptureController/setFocusBehavior()}} would like the user agent to 1091 | focus the [=display surface=] associated with that 1092 | {{CaptureController}}'s [=capture-session=].
1093 | 1094 |
1095 | enum CaptureStartFocusBehavior {
1096 | "focus-capturing-application",
1097 | "focus-captured-surface",
1098 | "no-focus-change"
1099 | };
1100 |
1101 |
1102 | | Enumeration description | 1106 ||
|---|---|
| focus-capturing-application 1112 | | 1113 | 1114 |The application prefers to be focused. | 1115 |
| focus-captured-surface 1121 | | 1122 | 1123 |The application prefers that the [=display surface=] 1124 | associated with this {{CaptureController}}'s [=capture-session=] 1125 | be focused. | 1126 |
| no-focus-change 1132 | | 1133 | 1134 |The application prefers that the user agent not change focus, 1135 | leaving focus with whichever surface last had focus following the 1136 | user's interaction with the user agent and/or operating 1137 | system. | 1138 |
A {{CaptureController}} object may be associated with a 1156 | [=capture-session=]. It would be used to expose functionality that's 1157 | associated with the [=capture-session=] itself, rather than with the 1158 | call to {{MediaDevices/getDisplayMedia()}} or its resulting stream or 1159 | tracks.
1160 | 1161 | 1162 |Any given [=capture-session=] is associated with at most one 1163 | {{CaptureController}}.
1164 | 1165 | 1166 |At most one {{CaptureController}} is associated with any given 1167 | [=capture-session=].
1168 | 1169 |
1170 | [Exposed=Window, SecureContext]
1171 | interface CaptureController : EventTarget {
1172 | constructor();
1173 | undefined setFocusBehavior(CaptureStartFocusBehavior focusBehavior);
1174 | };
1175 |
1176 |
1177 | {{CaptureController}} does not yet define event handlers, so it is 1179 | not required to inherit from {{EventTarget}}. This is for the benefit 1180 | of future specifications that extend {{CaptureController}} with event 1181 | handler attributes; if inheritance is not used, it can be 1182 | removed.
1183 || Internal Slot | 1200 | 1201 |Initial value | 1202 | 1203 |Description (non-normative) | 1204 |
|---|---|---|
| [[\IsBound]] 1211 | | 1212 | 1213 |false
1214 | |
1215 |
1216 | Whether an application has attempted to associate 1217 | [=this=] with a [=capture-session=]. | 1218 |
| [[\Source]] 1223 | | 1224 | 1225 |null
1226 | |
1227 |
1228 | The source of the associated [=capture-session=]. | 1229 |
| [[\DisplaySurfaceType]] 1234 | | 1235 | 1236 |null
1237 | |
1238 |
1239 | Once capture starts, this will be set to the type of the 1240 | captured [=display surface=]. | 1241 |
| [[\FocusChangeDisabled]] 1246 | | 1247 | 1248 |false
1249 | |
1250 |
1251 | Whether focus-change has been disabled by an external 1252 | event or a user agent consideration. | 1253 |
| [[\FocusDecisionFinalized]] 1258 | | 1259 | 1260 |false
1261 | |
1262 |
1263 | Set to true when the focus decision is finalized. | 1264 |
| [[\FocusBehavior]] 1269 | | 1270 | 1271 |null
1272 | |
1273 |
1274 | The focus behavior desired by the application. | 1275 |
The user agent MAY set
1281 | {{CaptureController/[[FocusChangeDisabled]]}} to true
1282 | at any moment based on its own logic.
Run the following steps:
1292 | 1293 | 1294 |Let focusBehavior be the method's first 1297 | argument.
1298 |If [=this=].{{CaptureController/[[Source]]}} is
1303 | null, set
1304 | [=this=].{{CaptureController/[[FocusBehavior]]}} to
1305 | focusBehavior and abort these steps.
If [=this=].{{CaptureController/[[Source]]}} has been 1311 | stopped, 1312 | [=exception/throw=] an "{{InvalidStateError}}" 1313 | {{DOMException}}.
1314 |If [=this=].{{CaptureController/[[DisplaySurfaceType]]}} is 1319 | neither {{DisplayCaptureSurfaceType/"browser"}} nor 1320 | {{DisplayCaptureSurfaceType/"window"}}, [=exception/throw=] an 1321 | "{{InvalidStateError}}" {{DOMException}}.
1322 |If [=this=].{{CaptureController/[[FocusDecisionFinalized]]}}
1327 | is true, [=exception/throw=] an
1328 | "{{InvalidStateError}}" {{DOMException}}.
Set [=this=].{{CaptureController/[[FocusBehavior]]}} to 1334 | focusBehavior.
1335 |Run the [=finalize focus decision algorithm=] on 1340 | [=this=].
1341 |The finalize focus decision algorithm, given a 1348 | controller, consists of running the following steps:
1349 | 1350 | 1351 |If too much time has elapsed since the [=capture-session=]
1354 | started, the user agent SHOULD set
1355 | {{CaptureController/[[FocusDecisionFinalized]]}} to
1356 | true. The timespan is left up to the user agent, but
1357 | it is recommended that a value of one second be used.
If
1363 | controller.{{CaptureController/[[FocusDecisionFinalized]]}}
1364 | is true, abort these steps.
Set
1370 | controller.{{CaptureController/[[FocusDecisionFinalized]]}}
1371 | to true.
If
1377 | controller.{{CaptureController/[[FocusChangeDisabled]]}}
1378 | is true, abort these steps.
If 1384 | controller.{{CaptureController/[[DisplaySurfaceType]]}} 1385 | is neither {{DisplayCaptureSurfaceType/"browser"}} nor 1386 | {{DisplayCaptureSurfaceType/"window"}}, abort these steps.
1387 |Let focusBehavior be 1392 | controller.{{CaptureController/[[FocusBehavior]]}}.
1393 |Run the following steps [=in parallel=]:
1398 | 1399 | 1400 |If focusBehavior is 1403 | {{CaptureStartFocusBehavior/"focus-capturing-application"}}, 1404 | focus the [=display surface=] representing the capturing 1405 | document.
1406 |If focusBehavior is 1411 | {{CaptureStartFocusBehavior/"focus-captured-surface"}}, focus 1412 | the [=display surface=] referred to by 1413 | controller.{{CaptureController/[[Source]]}}.
1414 |Describes the different hints an application can provide about 1427 | whether the [=display surface=] the application is in, should be among 1428 | the choices offered to the user.
1429 | 1430 |
1431 | enum SelfCapturePreferenceEnum {
1432 | "include",
1433 | "exclude"
1434 | };
1435 |
1436 |
1437 | | Enum value | 1441 | 1442 |Description | 1443 |
|---|---|
| include 1451 | | 1452 | 1453 |The application prefers the surface be included among the 1454 | choices offered. | 1455 |
| exclude 1461 | | 1462 | 1463 |The application prefers the surface be excluded from the 1464 | choices offered. | 1465 |
Describes whether an application invoking 1477 | {{MediaDevices/getDisplayMedia()}} would like the user agent to include 1478 | system audio among the audio sources offered to the user for 1479 | [=display surface/monitor=] [=display surfaces=]. Does not apply to any 1480 | other type of [=display surface=]. 1481 | 1482 |
1483 | enum SystemAudioPreferenceEnum {
1484 | "include",
1485 | "exclude"
1486 | };
1487 |
1488 |
1489 | | Enumeration description | 1493 ||
|---|---|
| include 1499 | | 1500 | 1501 |The application prefers that options to share system audio be 1502 | offered to the user for [=display surface/monitor=] [=display 1503 | surfaces=]. | 1504 |
| exclude 1510 | | 1511 | 1512 |The application prefers that options to share system audio 1513 | not be offered to the user for [=display surface/monitor=] 1514 | [=display surfaces=]. | 1515 |
Describes whether an application invoking 1527 | {{MediaDevices/getDisplayMedia()}} would like the user agent to include 1528 | window or system audio among the audio sources offered to the user for 1529 | [=display surface/window=] [=display surfaces=].
1530 | 1531 | 1532 |
1533 | enum WindowAudioPreferenceEnum {
1534 | "system",
1535 | "window",
1536 | "exclude"
1537 | };
1538 |
1539 |
1540 | | Enumeration description | 1544 ||
|---|---|
| system 1550 | | 1551 | 1552 |The application prefers that options to share system audio be 1553 | offered to the user for [=display surface/window=] [=display 1554 | surfaces=]. | 1555 |
| window 1561 | | 1562 | 1563 |The application prefers that options to share window audio be 1564 | offered to the user for [=display surface/window=] [=display 1565 | surfaces=]. | 1566 |
| exclude 1571 | | 1572 | 1573 |The application prefers that options to share audio not be 1574 | offered to the user for [=display surface/window=] [=display 1575 | surfaces=]. | 1576 |
Describes whether an application invoking 1588 | {{MediaDevices/getDisplayMedia()}} would like the user agent to offer 1589 | the user an option to dynamically switch the source [=display surface=] 1590 | during the capture.
1591 | 1592 |
1593 | enum SurfaceSwitchingPreferenceEnum {
1594 | "include",
1595 | "exclude"
1596 | };
1597 |
1598 |
1599 | | Enumeration description | 1603 ||
|---|---|
| include 1609 | | 1610 | 1611 |The application prefers that an option to dynamically switch 1612 | the source [=display surface=] during the capture be offered to 1613 | the user. | 1614 |
| exclude 1620 | | 1621 | 1622 |The application prefers that an option to dynamically switch 1623 | the source [=display surface=] during the capture NOT be offered 1624 | to the user. | 1625 |
Describes whether the application would like the user agent to offer 1637 | the user the option to choose [=display surfaces=] whose type is 1638 | [=display surface/monitor=].
1639 | 1640 |
1641 | enum MonitorTypeSurfacesEnum {
1642 | "include",
1643 | "exclude"
1644 | };
1645 |
1646 |
1647 | | Enumeration description | 1651 ||
|---|---|
| include 1657 | | 1658 | 1659 |The application prefers that the [=display surfaces=] 1660 | presented to the user include those of type [=display 1661 | surface/monitor=]. | 1662 |
| exclude 1668 | | 1669 | 1670 |The application prefers that the [=display surfaces=] 1671 | presented to the user exclude those of type [=display 1672 | surface/monitor=]. | 1673 |
The DisplayMediaStreamOptions dictionary is used to 1684 | instruct the user agent what sort of {{MediaStreamTrack}}s may be 1685 | included in the {{MediaStream}} returned by 1686 | {{MediaDevices/getDisplayMedia}}.
1687 | 1688 | 1689 |
1691 | dictionary DisplayMediaStreamOptions {
1692 | (boolean or MediaTrackConstraints) video = true;
1693 | (boolean or MediaTrackConstraints) audio = false;
1694 | CaptureController controller;
1695 | SelfCapturePreferenceEnum selfBrowserSurface;
1696 | SystemAudioPreferenceEnum systemAudio;
1697 | WindowAudioPreferenceEnum windowAudio;
1698 | SurfaceSwitchingPreferenceEnum surfaceSwitching;
1699 | MonitorTypeSurfacesEnum monitorTypeSurfaces;
1700 | };
1701 |
1702 | video of type (boolean or
1710 | {{MediaTrackConstraints}}), defaulting to
1711 | trueIf true, it requests that the returned
1716 | {{MediaStream}} contain a video track. If a
1717 | Constraints structure is provided, it further
1718 | specifies desired processing options to be applied to the video
1719 | track rendition of the display surface chosen by the user. If
1720 | false, the request will be [=rejected=] with a
1721 | {{TypeError}}, as per the getDisplayMedia
1723 | algorithm.
audio of type (boolean or
1728 | {{MediaTrackConstraints}}), defaulting to
1729 | falseIf true, it signals an interest that the
1734 | returned {{MediaStream}} contain an audio track, if supported
1735 | and audio is available for display surface chosen by the user.
1736 | If a Constraints structure is provided, it further
1737 | specifies desired processing options to be applied to the audio
1738 | track. If false, the {{MediaStream}} will not
1739 | contain an audio track.
controller of type
1744 | {{CaptureController}}If present, this {{CaptureController}} object will be 1749 | associated with the [=capture-session=]. Through the methods 1750 | exposed on this object, the [=capture-session=] can be 1751 | manipulated.
1752 |selfBrowserSurface of type
1756 | {{SelfCapturePreferenceEnum}}systemAudio of type
1768 | {{SystemAudioPreferenceEnum}}windowAudio of type
1778 | {{WindowAudioPreferenceEnum}}surfaceSwitching of type
1788 | {{SurfaceSwitchingPreferenceEnum}}monitorTypeSurfaces of type
1798 | {{MonitorTypeSurfacesEnum}}If present, signals whether the application would like the 1803 | user agent to include [=display surfaces=] whose type is 1804 | [=display surface/monitor=] among the choices offered to the 1805 | user. The user agent MAY ignore this hint.
1806 | 1807 | 1808 |The user agent may still offer to the user the option to 1810 | capture [=display surfaces=] of type [=display 1811 | surface/monitor=]. Applications are therefore encouraged to 1812 | still check the {{MediaTrackSettings/displaySurface}} setting 1813 | of the tracks they receive.
1814 |{{MediaTrackSupportedConstraints}} is extended here with the list of 1827 | constraints that a user agent recognizes.
1828 | 1829 |partial dictionary MediaTrackSupportedConstraints {
1830 | boolean displaySurface = true;
1831 | boolean logicalSurface = true;
1832 | boolean cursor = true;
1833 | boolean restrictOwnAudio = true;
1834 | boolean suppressLocalAudioPlayback = true;
1835 | };
1836 |
1837 | trueWhether {{displaySurface}} constraint is recognized.
1845 |logicalSurface of type {{boolean}},
1849 | defaulting to trueWhether {{logicalSurface}} constraint is recognized.
1854 |trueWhether {{cursor}} constraint is recognized.
1863 |trueWhether {{restrictOwnAudio}} constraint is recognized.
1872 |trueWhether {{suppressLocalAudioPlayback}} constraint is 1881 | recognized.
1882 |{{MediaTrackConstraintSet}} is used for reading the current status 1892 | of constraints.
1893 | 1894 |partial dictionary MediaTrackConstraintSet {
1895 | ConstrainDOMString displaySurface;
1896 | ConstrainBoolean logicalSurface;
1897 | ConstrainDOMString cursor;
1898 | ConstrainBoolean restrictOwnAudio;
1899 | ConstrainBoolean suppressLocalAudioPlayback;
1900 | };
1901 |
1902 | displaySurface of type
1904 | {{ConstrainDOMString}}The type of [=display surface=] that is being captured. This 1909 | assumes values from the {{DisplayCaptureSurfaceType}} 1910 | enumeration.
1911 |A value of true indicates capture of a [=logical
1919 | display surface=]; a value of false indicates a
1920 | capture of a [=visible display surface=].
Assumes values from the {{CursorCaptureConstraint}} enumeration 1929 | that determines if and when the cursor is included in the captured 1930 | display surface.
1931 |This constraint is only applicable to audio tracks. See 1939 | {{restrictOwnAudio}}.
1940 |This constraint is only applicable to audio tracks. See 1949 | {{suppressLocalAudioPlayback}}.
1950 |When the {{MediaStreamTrack/getSettings()}} method is invoked on a 1960 | video stream track, the user agent must return the extended 1961 | {{MediaTrackSettings}} dictionary, representing the current status of 1962 | the underlying user agent.
1963 | 1964 |partial dictionary MediaTrackSettings {
1965 | DOMString displaySurface;
1966 | boolean logicalSurface;
1967 | DOMString cursor;
1968 | boolean restrictOwnAudio;
1969 | boolean suppressLocalAudioPlayback;
1970 | double screenPixelRatio;
1971 | };
1972 |
1973 | The type of [=display surface=] that is being captured. This 1980 | assumes values from the {{DisplayCaptureSurfaceType}} 1981 | enumeration.
1982 |A value of true indicates capture of a logical
1990 | display surface; a value of false indicates a
1991 | capture capture of a visible display surface.
Assumes values from the {{CursorCaptureConstraint}} enumeration 2000 | that determines if and when the cursor is included in the captured 2001 | display surface.
2002 |Indicates whether the restrictOwnAudio constraint is applied
2011 | (true) or not (false).
Indicates whether or not the application instructed the user 2020 | agent to apply [=local audio playback suppression=] to the 2021 | source.
2022 |The screen pixel ratio of of the [=display surface=] being captured.
2030 |When the {{MediaStreamTrack/getCapabilities()}} method is invoked on 2040 | a video stream track, the user agent must return the extended 2041 | {{MediaTrackCapabilities}} dictionary, representing the capabilities of 2042 | the underlying user agent.
2043 | 2044 |partial dictionary MediaTrackCapabilities {
2045 | DOMString displaySurface;
2046 | boolean logicalSurface;
2047 | sequence<DOMString> cursor;
2048 | };
2049 |
2050 | MUST be the same value as is returned by 2057 | {{MediaStreamTrack/getSettings()}}, rendering this property 2058 | immutable from the application's viewpoint.
2059 |MUST be the same value as is returned by 2067 | {{MediaStreamTrack/getSettings()}}, rendering this property 2068 | immutable from the application's viewpoint.
2069 |MUST consist of exactly the set of values from 2077 | {{CursorCaptureConstraint}} that the user agent is capable of 2078 | supporting for this track.
2079 |The {{DisplayCaptureSurfaceType}} enumeration describes the 2090 | different types of display surface.
2091 | 2092 |enum DisplayCaptureSurfaceType {
2093 | "monitor",
2094 | "window",
2095 | "browser"
2096 | };
2097 |
2098 | | Enum value | 2102 | 2103 |Description | 2104 |
|---|---|
| monitor 2112 | | 2113 | 2114 |a [=display surface/monitor=] [=display surface=], physical 2115 | display, or collection of physical displays | 2116 |
| window 2122 | | 2123 | 2124 |a [= display surface/window =] [=display surface=], or single 2125 | application window | 2126 |
| browser 2132 | | 2133 | 2134 |a [=display surface/browser=] [=display surface=], or single 2135 | browser window | 2136 |
The {{CursorCaptureConstraint}} enumerates the conditions under 2148 | which the cursor is captured.
2149 | 2150 |enum CursorCaptureConstraint {
2151 | "never",
2152 | "always",
2153 | "motion"
2154 | };
2155 |
2156 | | Enum value | 2160 | 2161 |Description | 2162 |
|---|---|
| never 2169 | | 2170 | 2171 |a {{CursorCaptureConstraint/"never"}} cursor capture 2172 | constraint omits the cursor from the captured display 2173 | surface. | 2174 |
| always 2179 | | 2180 | 2181 |a {{CursorCaptureConstraint/"always"}} cursor capture 2182 | constraint includes the cursor in the captured display 2183 | surface. | 2184 |
| motion 2189 | | 2190 | 2191 |2192 | a {{CursorCaptureConstraint/"motion"}} cursor capture 2193 | constraint includes the cursor in the captured display surface 2194 | when the cursor/pointer is moved. The captured cursor is 2195 | removed when there is no further movement of the pointer/cursor 2196 | for certain period of time, as determined by the user 2197 | agent. 2198 | | 2199 |
Each potential source of capture is treated by this API as a discrete 2211 | media source. However, display capture sources MUST NOT be enumerated by 2212 | {{MediaDevices/enumerateDevices()}}, since this would reveal too much 2213 | information about the host system.
2214 | 2215 | 2216 |Display capture sources therefore cannot be selected with the 2217 | {{MediaTrackSupportedConstraints/deviceId}} constraint, since their 2218 | {{MediaDeviceInfo/deviceId}}s are not exposed.
2219 | 2220 | 2221 |This is not to be confused with the stable and private id of the 2223 | same name used in algorithms to implement privacy indicators.
2224 |Screen Capture is a [=powerful feature=] which is 2234 | identified by the [=powerful feature/name=] "display-capture", requiring 2235 | [=express permission=] to be used.
2236 | 2237 | 2238 |As required for integration with the [[[Permissions]]] specification, 2239 | this specification defines the following:
2240 | 2241 | 2242 |This specification defines a [=policy-controlled feature=] identified by
2261 | the string "display-capture". Its
2263 | [=policy-controlled feature/default allowlist=] is "self".
A [=document=]'s [=Document/permissions policy=] determines whether 2268 | any content in that document is allowed to use 2269 | {{MediaDevices/getDisplayMedia}}. If disabled in any document, no content 2270 | in the document will be [=allowed to use=] 2271 | {{MediaDevices/getDisplayMedia}}. This is enforced by the [=prompt the 2272 | user to choose=] algorithm.
2273 |This specification extends the Privacy Indicator 2283 | Requirements of {{MediaDevices/getUserMedia()}} to include 2284 | {{MediaDevices/getDisplayMedia}}.
2285 | 2286 | 2287 |References in this specification to [[\devicesLiveMap]], 2288 | [[\devicesAccessibleMap]], and [[\kindsAccessibleMap]] refer to the 2289 | definitions already created to support Privacy Indicator Requirements for 2290 | {{MediaDevices/getUserMedia()}}.
2291 | 2292 | 2293 |For each kind of device that {{MediaDevices/getDisplayMedia}}
2294 | exposes, using a stable and private id for the device, deviceId,
2295 | set kind to "Display" + kind, and do the
2296 | following:
false.false.Then, given the new definitions above, the requirements on the user 2322 | agent are those specified in Privacy Indicator 2324 | Requirements of {{MediaDevices/getUserMedia()}}.
2325 | 2326 | 2327 |Even though there's a single permission descriptor for 2329 | {{MediaDevices/getDisplayMedia}}, the above definitions distinguish by 2330 | kind to enable user agents to implement privacy indicators that show the 2331 | end-user the specific kinds of display sources that are being shared at 2332 | any point.
2333 |Since this specification forbids user agents from persisting 2338 | {{PermissionState/"granted"}} permissions, only the "Live" indicators are 2339 | significant.
2340 |The user agent MUST NOT fire the devicechange event
2344 | based on changes in the set of available sources from
2345 | {{MediaDevices/getDisplayMedia}}.
This section is informative; however, it notes some serious risks to 2354 | platform security if the advice it contains are not adhered to.
2355 | 2356 | 2357 |The risks to user privacy and security posed by capture of displayed 2358 | content are twofold. The immediate and obvious risk is that users 2359 | inadvertently share content that they did not wish to share, or might not 2360 | have realized would be shared.
2361 | 2362 | 2363 |Display capture presents a less obvious risk to the cross site request 2364 | forgery protections offered by the browser sandbox. Display and capture of 2365 | information that is also under the control of an application, even 2366 | indirectly, can allow that application to access information that would 2367 | otherwise be inaccessible to it directly. For example, the canvas API does 2368 | not permit sampling of a canvas, or conversion to an accessible form if it 2369 | is not origin-clean [[2DCONTEXT]].
2370 | 2371 | 2372 |This issue is discussed in further detail in [[!RTCWEB-SECURITY-ARCH]] 2373 | and [[!RTCWEB-SECURITY]].
2374 | 2375 | 2376 |Display capture that includes browser windows, particularly those that 2377 | are under any form of control by the application, risks violation of these 2378 | basic security protections. This risk is not entirely contained to browser 2379 | windows, since control channels between browser applications and other 2380 | applications, depending on the operating system. The key consideration is 2381 | whether the captured display surface could be somehow induced to 2382 | present information that would otherwise be secret from the application 2383 | that is receiving the resulting media.
2384 | 2385 | 2386 |Capture of logical display surfaces causes there to be a 2391 | potential for content to be shared that a user is not made aware of. A 2392 | logical display surface might render information that a user did 2393 | not intend to expose. This can be more easily recognized if this 2394 | information is visible. Such means are likely ineffectual against a 2395 | machine, but a human recipient is less able to process content that 2396 | appears only briefly.
2397 | 2398 | 2399 |It is encouraged that information that is not currently rendered to 2400 | the screen be obscured in captures unless the application has been 2401 | specifically authorized to access that content through elevated 2402 | permissions.
2403 | 2404 | 2405 |How obscured areas of the logical display surface are captured 2406 | to produce a visible display surface capture MAY vary. Some 2407 | applications, like presentation software, benefit from having obscured 2408 | portions of the screen render the image that appeared prior to being 2409 | obscured. Freezing images can cause visual artifacts for changing 2410 | content, or hide the fact that content is being obscured. Note that 2411 | frozen portions of a capture can be incorrectly perceived as a bug. 2412 | Alternatively, obscured areas might be replaced with content that marks 2413 | them as being obscured, such as a grey color or hatching.
2414 | 2415 | 2416 |Some systems may only capture the logical display surface. 2417 | Devices with small screens, for instance, do not typically have the 2418 | concept of a [= display surface/window =], and render applications in 2419 | full screen modes only. These systems might provide a capture of an 2420 | application that is not currently visible, which could be unusable 2421 | without capturing the logical display surface.
2422 | 2423 | 2424 |When capturing a [= display surface/window =] or other display 2425 | surface that is partially transparent, any content behind it will not 2426 | be captured.
2427 | 2428 | 2429 |There is a risk that the user prompt be exposed to the web page for a 2430 | short amount of time by the newly created {{MediaStreamTrack}}, for 2431 | instance if the user selects the screen on which the user prompt is 2432 | displayed. In the case of the user prompt displaying previews of the 2433 | various surfaces available for selection, those previews will not be 2434 | captured by the newly created {{MediaStreamTrack}}.
2435 | 2436 | 2437 |{{MediaDevices/getDisplayMedia}} allows capturing audio alongside 2441 | video, this poses privacy and security concern as this may expose 2442 | additional information about system applications, and the set of shared 2443 | audio sources are not necessarily the same as the set of shared video 2444 | sources. For example, the capture of the video of a [= display 2445 | surface/window =] that is accompanied by the audio of the entire system, 2446 | including applications unrelated to that window, will not be shared 2447 | without active user consent. It is important that the user is 2448 | aware of what content will be shared, including any possible audio. It is 2449 | strongly encouraged that the user is allowed to give consent to video but 2450 | not audio, resulting in a video-only stream. This ensures that the 2451 | request for audio is always optional and does not restrict the user's 2452 | choices compared to a video-only request.
2453 |This document encourages implementations to provide additional 2461 | limitations on the mechanisms used to affirm user consent. These 2462 | limitations are designed to mitigate the security and privacy risks that 2463 | the API poses.
2464 | 2465 | 2466 |Two forms of consent interaction are described: active user 2467 | consent and a range of elevated permissions. These are 2468 | non-normative recommandations only.
2469 | 2470 | 2471 |Active user consent is sufficient where there is little 2476 | or no risk of an application gaining information that the user did not 2477 | intend to share. These cases can be identified by those where the 2478 | application that requests capture has no control over what is rendered 2479 | to the captured display surface.
2480 | 2481 | 2482 |To prevent applications from limiting the available choices 2483 | presented to a user with the goal of promoting a particular choice, the 2484 | {{MediaDevices/getDisplayMedia}} API does not permit the use of 2485 | constraints to narrow the set of options presented.
2486 |It is strongly advised that elevated permissions be 2494 | required to access any display surface that might be used to 2495 | circumvent cross-origin protections for content. The key goal of this 2496 | consent process is not just to demonstrate that a user intends to share 2497 | content, but to also to determine that the user exhibits an elevated 2498 | level of trust in the application that is being granted access.
2499 | 2500 | 2501 |Several different controls might be provided to grant elevated 2502 | permissions. This section describes several different capabilities 2503 | that could be independently granted. A user agent might opt to 2504 | prohibit access to any capability that requires elevated 2505 | permissions.
2506 | 2507 | 2508 |If access to these surfaces is supported, it is strongly advised 2509 | that any mechanism to acquire elevated permissions not rely 2510 | solely on simple prompts for user consent. Any action needs to ensure 2511 | that a decision to authorize an application with elevated privileges is 2512 | deliberate. For instance, a user agent might require a process 2513 | equivalent to software installation to signify that user consent for 2514 | elevated permissions is granted.
2515 | 2516 | 2517 |An elevated permissions experience could allow the user 2518 | agent to communicate the risks associated with enabling this 2519 | feature, or at least to convey the need for augmented trust in the 2520 | application.
2521 | 2522 | 2523 |Note that elevated permissions are not a substitute for 2524 | active user consent. It is advised that user agents still 2525 | present users with the ability to select what is shared, even for 2526 | applications that have elevated permissions.
2527 |Elevated permissions are encouraged as a prerequisite for 2535 | access to capture of [= display surface/monitor =] or [= display 2536 | surface/browser =] display surfaces. Note that capture of a 2537 | complete [= display surface/monitor =] is included because this could 2538 | include a window from the user agent.
2539 | 2540 | 2541 |Similarly, elevated permissions are an encouraged 2542 | prerequisite for access to logical display surfaces, where that 2543 | would not ordinarily be provided.
2544 | 2545 | 2546 |It is encouraged that elevated permissions that are granted 2547 | to an origin be persisted. An elevated permissions process in 2548 | part relies on its novelty to ensure that it correctly captures user 2549 | intent.
2550 |Implementations are advised to provide user feedback and control 2559 | mechanisms similar to those offered users when sharing a camera or 2560 | microphone, as encouraged in [[GETUSERMEDIA]].
2561 | 2562 | 2563 |It is important that a user be aware that content is being shared when 2564 | content is actively being captured. User agents are advised to 2565 | display a prominent indicator while content is being captured. In 2566 | addition to an indicator, a user agent is advised to provide a 2567 | means to learn precisely what is being shared; while this capability is 2568 | trivially provided by an application by rendering the captured content, 2569 | this information allows a user to accurately assess what is being 2570 | shared.
2571 | 2572 | 2573 |In addition to feedback mechanisms, a means to for the user to stop 2574 | any active capture is advisable.
2575 |