diff --git a/webrtc.html b/webrtc.html index 496f35c3f..54eae5fe1 100644 --- a/webrtc.html +++ b/webrtc.html @@ -128,6 +128,10 @@

Terminology

peeridentity, request an identity assertion and validate the identity are defined in [[!WEBRTC-IDENTITY]].

+

The terms permission, retrieve the permission + state, request permission to + use and create a permission storage + entry are defined in [[!PERMISSIONS]].

The general principles for Javascript APIs apply, including the principle of @@ -10959,6 +10963,161 @@

MediaTrackSupportedConstraints, MediaTrackCapabilities, +
+

Direct Connection Permission API

+

The Direct Connection Permission API allows a web application to request permission to use a less strict policy regarding sharing local addresses as defined in [[RTCWEB-IP-HANDLING]]. This API and the behavioral requirements of the user agent ensure that permission can be requested in a use case neutral way. Once permission has been granted, it provides explicit user consent as required by [[RTCWEB-IP-HANDLING]].

+

The best available IP handling mode the user agent can offer SHOULD be Mode 1 (enumerate all addresses) and the default IP handling mode the user agent uses by default SHOULD be Mode 2 (default route and associated local addresses). However, the user agent MAY choose different modes determined by the user agents preferences.

+
+

RTCPeerConnection Interface Extensions

+

The Direct Connection Permission API extends the RTCPeerConnection interface as described below.

+
+
partial interface RTCPeerConnection {
+    static void registerDirectConnectionInterest ();
+    attribute EventHandler onconnectionupgradable;
+};
+
+

Attributes

+
+
onconnectionupgradable of type + EventHandler
+
The event type of this event handler is + connectionupgradable.
+
+
+
+

Methods

+
+
registerDirectConnectionInterest
+
+

To register an interest to activate the best available IP handling mode, the user agent MUST run the following steps:

+
    +
  1. Return undefined and continue the following steps asynchronously.
  2. +
  3. +

    Request permission to use using a PermissionDescriptor with its name member set to "direct-connection"

    +

    The permission request MAY or MAY NOT prompt the user but the user MUST be able to grant the permission explicitly.

    +
  4. +
  5. +

    For each realm of the same origin, update the direct connection permission with the result of the permission request.

    +

    The user agent MAY choose to create a permission storage entry for later use by the same origin, so that the permission's state is persistent.

    +
  6. +
+
The idea of this mechanism is to allow user agents to choose whether they want to prompt the user or rely on a different mechanism of the UX.
+
+
+
+
+
+
+

Update Direct Connection Permission Algorithm

+

When the "direct-connection" permission has been updated for the current realm, the user agent MUST run the following steps:

+
    +
  1. Let result be the result of a permission request or an update to the "direct-connection" permission state.
  2. +
  3. Let mode refer to the default IP handling mode.
  4. +
  5. If result is "granted", then update mode to the best available IP handling mode.
  6. +
  7. For each RTCPeerConnection of the same realm:
  8. +
  9. +
      +
    1. Let connection be the RTCPeerConnection.
    2. +
    3. If connection's [[\IsClosed]] slot is true, then abort these steps.
    4. +
    5. Update the connection's [[RTCWEB-IP-HANDLING]] mode with mode.
    6. +
    7. Fire an event named connectionupgradable at connection and abort these steps.
    8. +
    +
  10. +
+
If the mode is being upgraded, the event will be fired. However, if the mode has been downgraded, the event will not fire and the downgrade will not be effective for the lifetime of the RTCPeerConnection.
+
+
+

Direct Connection Permission Usage Examples

+

A web application using the Direct Connection Permission API is recommended to only request this permission when really needed. If it does request the permission, it should provide context. Furthermore, it should not rely on a permission request being prompted. While the user agent may use a prompt, it may also use different techniques to enable explicit permission approval, for example in form of a toggle button next to the address bar of the browser.

+

The following examples will provide usage suggestions for a couple of use cases.

+
+

Upgrade connection

+

The following mechanism can be used for applications that want to establish a connection as soon as possible, albeit potentially not as direct as possible. In this example, the application tries to upgrade as soon as a connection has been established that is not considered ideal (or the connection could not be established).

+
+
+pc.onconnectionupgradable = async () => {
+  // Initiate an ICE restart
+  const offer = await pc.createOffer({iceRestart: true});
+
+  // Exchange offer/answer via the signalling channel...
+};
+
+pc.onconnectionstatechange = async () => {
+  const state = pc.connectionState;
+  if (state === 'failed' || state === 'connected') {
+    // For audio/video...
+    const iceTransport = rtpReceiver.transport.iceTransport
+
+    // For data channels...
+    const iceTransport = pc.sctp.transport.iceTransport;
+
+    // Check if requesting a direct connection would be useful
+    const pair = iceTransport.getSelectedCandidatePair();
+    if (pair.local.type !== 'host') {
+      // Once granted, this will fire the 'connectionupgradable' event
+      RTCPeerConnection.registerDirectConnectionInterest();
+    }
+  }
+};
+          
+
+

Ideally, the application supplies a mechanism to coordinate the permission request on both sides (if needed), to prevent two consecutive ICE restarts.

+
+
+

Joining a session

+

Voice and video chats usually have the concept of a room that is being joined. When a user joins such a room, the permission could be requested which would provide sufficient context to the user.

+
+
+pc.onconnectionupgradable = async () => {
+  // Initiate an ICE restart
+  const offer = await pc.createOffer({iceRestart: true});
+
+  // Exchange offer/answer via the signalling channel...
+};
+
+async function joinRoom() {
+  // Request camera/microphone access if desired
+  // Media devices may implicitly grant a direct connection permission
+  try {
+    await navigator.mediaDevices.getUserMedia(constraints);
+  } catch (err) {
+    console.error(err);
+  }
+
+  // Once granted, this will fire the 'connectionupgradable' event if needed
+  RTCPeerConnection.registerDirectConnectionInterest();
+
+  // Now, create the peer-to-peer connection
+}
+          
+
+
+
+

Sending a file

+

A file sharing application will eventually have to let the user choose a file to be transmitted. Once that selection has been made, requesting a direct connection should provide sufficient context to the user.

+
+
+pc.onconnectionupgradable = async () => {
+  // Initiate an ICE restart
+  const offer = await pc.createOffer({iceRestart: true});
+
+  // Exchange offer/answer via the signalling channel...
+};
+
+async function onFileSelected(file) {
+  // Once granted, this will fire the 'connectionupgradable' event if needed
+  RTCPeerConnection.registerDirectConnectionInterest();
+
+  // Now, create the peer-to-peer connection
+  // Then, send the file via a data channel
+}
+          
+
+
+
+

Examples and Call Flows

@@ -12013,6 +12172,12 @@

Event summary

A new RTCStatsEvent is dispatched to the script in response to one or more monitored objects being deleted at the same time. + + + connectionupgradable + Event + The [[RTCWEB-IP-HANDLING]] mode for the RTCPeerConnection has been upgraded. The application needs to do an ICE restart if it wants to upgrade its connection to be potentially more direct. +

The following events fire on RTCDTMFSender