Backed out changeset 15f8fa34d2f4 (bug 1580567) for perma fails on browser_temporary_permissions_expiry.js and browser_privatebrowsing_rememberprompt.js. CLOSED TREE
authorRazvan Maries <rmaries@mozilla.com>
Thu, 05 Dec 2019 01:05:34 +0200
changeset 505561 b4195b31ca936f7e2541c8f4d04aa9744d98443c
parent 505560 45d3a3e173d3b164c5cc6c3ff287d21bef6e4b11
child 505562 c7e0a39fdc1f09e75b755c8287ed0b4e12ff64d2
push id102344
push userrmaries@mozilla.com
push dateWed, 04 Dec 2019 23:06:16 +0000
treeherderautoland@b4195b31ca93 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1580567
milestone73.0a1
backs out15f8fa34d2f49562743d050164d939a66a0a34ab
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 15f8fa34d2f4 (bug 1580567) for perma fails on browser_temporary_permissions_expiry.js and browser_privatebrowsing_rememberprompt.js. CLOSED TREE
browser/app/profile/firefox.js
browser/base/content/browser-siteIdentity.js
browser/base/content/browser.xhtml
browser/base/content/test/permissions/browser_temporary_permissions_expiry.js
browser/base/content/test/permissions/permissions.html
browser/base/content/test/popupNotifications/browser_displayURI.js
browser/components/BrowserGlue.jsm
browser/components/preferences/in-content/privacy.inc.xhtml
browser/components/preferences/in-content/privacy.js
browser/components/preferences/sitePermissions.js
browser/components/privatebrowsing/test/browser/browser.ini
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_rememberprompt.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_xrprompt_page.html
browser/locales/en-US/browser/browser.ftl
browser/locales/en-US/browser/preferences/permissions.ftl
browser/locales/en-US/browser/preferences/preferences.ftl
browser/locales/en-US/chrome/browser/browser.properties
browser/locales/en-US/chrome/browser/sitePermissions.properties
browser/modules/PermissionUI.jsm
browser/modules/PermissionUITelemetry.jsm
browser/modules/SitePermissions.jsm
browser/modules/test/browser/browser_PermissionUI_prompts.js
browser/modules/test/browser/browser_SitePermissions.js
browser/modules/test/unit/test_SitePermissions.js
browser/themes/shared/incontentprefs/privacy.css
browser/themes/shared/jar.inc.mn
browser/themes/shared/notification-icons.inc.css
browser/themes/shared/notification-icons/xr-blocked.svg
browser/themes/shared/notification-icons/xr.svg
browser/tools/mozscreenshots/mozscreenshots/extension/lib/permissionPrompts.html
dom/base/Navigator.cpp
dom/base/Navigator.h
dom/base/nsGlobalWindowInner.cpp
dom/base/nsGlobalWindowInner.h
dom/tests/mochitest/general/test_interfaces.js
dom/vr/XRPermissionRequest.cpp
dom/vr/XRPermissionRequest.h
dom/vr/moz.build
dom/webidl/Navigator.webidl
dom/webidl/VRDisplay.webidl
testing/web-platform/meta/webvr/__dir__.ini
toolkit/components/telemetry/Events.yaml
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -403,17 +403,16 @@ pref("browser.sessionhistory.max_entries
 // Built-in default permissions.
 pref("permissions.manager.defaultsUrl", "resource://app/defaults/permissions");
 
 // Set default fallback values for site permissions we want
 // the user to be able to globally change.
 pref("permissions.default.camera", 0);
 pref("permissions.default.microphone", 0);
 pref("permissions.default.geo", 0);
-pref("permissions.default.xr", 0);
 pref("permissions.default.desktop-notification", 0);
 pref("permissions.default.shortcuts", 0);
 
 pref("permissions.desktop-notification.postPrompt.enabled", true);
 pref("permissions.desktop-notification.notNow.enabled", false);
 
 pref("permissions.fullscreen.allowed", false);
 
@@ -833,17 +832,16 @@ pref("gecko.handlerService.schemes.ircs.
 pref("gecko.handlerService.schemes.ircs.1.name", "chrome://browser-region/locale/region.properties");
 pref("gecko.handlerService.schemes.ircs.1.uriTemplate", "chrome://browser-region/locale/region.properties");
 pref("gecko.handlerService.schemes.ircs.2.name", "chrome://browser-region/locale/region.properties");
 pref("gecko.handlerService.schemes.ircs.2.uriTemplate", "chrome://browser-region/locale/region.properties");
 pref("gecko.handlerService.schemes.ircs.3.name", "chrome://browser-region/locale/region.properties");
 pref("gecko.handlerService.schemes.ircs.3.uriTemplate", "chrome://browser-region/locale/region.properties");
 
 pref("browser.geolocation.warning.infoURL", "https://www.mozilla.org/%LOCALE%/firefox/geolocation/");
-pref("browser.xr.warning.infoURL", "https://www.mozilla.org/%LOCALE%/firefox/xr/");
 
 pref("browser.sessionstore.resume_from_crash", true);
 pref("browser.sessionstore.resume_session_once", false);
 pref("browser.sessionstore.resuming_after_os_restart", false);
 
 // Minimal interval between two save operations in milliseconds (while the user is active).
 pref("browser.sessionstore.interval", 15000); // 15 seconds
 
--- a/browser/base/content/browser-siteIdentity.js
+++ b/browser/base/content/browser-siteIdentity.js
@@ -285,21 +285,16 @@ var gIdentityHandler = {
     ));
   },
 
   get _geoSharingIcon() {
     delete this._geoSharingIcon;
     return (this._geoSharingIcon = document.getElementById("geo-sharing-icon"));
   },
 
-  get _xrSharingIcon() {
-    delete this._xrSharingIcon;
-    return (this._xrSharingIcon = document.getElementById("xr-sharing-icon"));
-  },
-
   get _webRTCSharingIcon() {
     delete this._webRTCSharingIcon;
     return (this._webRTCSharingIcon = document.getElementById(
       "webrtc-sharing-icon"
     ));
   },
 
   get _insecureConnectionIconEnabled() {
@@ -572,17 +567,16 @@ var gIdentityHandler = {
 
   updateSharingIndicator() {
     let tab = gBrowser.selectedTab;
     this._sharingState = tab._sharingState;
 
     this._webRTCSharingIcon.removeAttribute("paused");
     this._webRTCSharingIcon.removeAttribute("sharing");
     this._geoSharingIcon.removeAttribute("sharing");
-    this._xrSharingIcon.removeAttribute("sharing");
 
     if (this._sharingState) {
       if (
         this._sharingState &&
         this._sharingState.webRTC &&
         this._sharingState.webRTC.sharing
       ) {
         this._webRTCSharingIcon.setAttribute(
@@ -592,19 +586,16 @@ var gIdentityHandler = {
 
         if (this._sharingState.webRTC.paused) {
           this._webRTCSharingIcon.setAttribute("paused", "true");
         }
       }
       if (this._sharingState.geo) {
         this._geoSharingIcon.setAttribute("sharing", this._sharingState.geo);
       }
-      if (this._sharingState.xr) {
-        this._xrSharingIcon.setAttribute("sharing", this._sharingState.xr);
-      }
     }
 
     if (this._identityPopup.state == "open") {
       this.updateSitePermissions();
       PanelView.forNode(
         this._identityPopupMainView
       ).descriptionHeightWorkaround();
     }
@@ -1349,30 +1340,16 @@ var gIdentityHandler = {
           id: "geo",
           state: SitePermissions.ALLOW,
           scope: SitePermissions.SCOPE_REQUEST,
           sharingState: true,
         });
       }
     }
 
-    if (this._sharingState && this._sharingState.xr) {
-      let xrPermission = permissions.find(perm => perm.id === "xr");
-      if (xrPermission) {
-        xrPermission.sharingState = true;
-      } else {
-        permissions.push({
-          id: "xr",
-          state: SitePermissions.ALLOW,
-          scope: SitePermissions.SCOPE_REQUEST,
-          sharingState: true,
-        });
-      }
-    }
-
     if (this._sharingState && this._sharingState.webRTC) {
       let webrtcState = this._sharingState.webRTC;
       // If WebRTC device or screen permissions are in use, we need to find
       // the associated permission item to set the sharingState field.
       for (let id of ["camera", "microphone", "screen"]) {
         if (webrtcState[id]) {
           let found = false;
           for (let permission of permissions) {
@@ -1590,22 +1567,19 @@ var gIdentityHandler = {
 
     /* We return the permission item here without a remove button if the permission is a
        SCOPE_POLICY or SCOPE_GLOBAL permission. Policy permissions cannot be
        removed/changed for the duration of the browser session. */
     if (isPolicyPermission) {
       return container;
     }
 
-    if (aPermission.id == "geo" || aPermission.id == "xr") {
+    if (aPermission.id == "geo") {
       let block = document.createXULElement("vbox");
-      block.setAttribute(
-        "id",
-        "identity-popup-" + aPermission.id + "-container"
-      );
+      block.setAttribute("id", "identity-popup-geo-container");
 
       let button = this._createPermissionClearButton(aPermission, block);
       container.appendChild(button);
 
       block.appendChild(container);
       return block;
     }
 
@@ -1629,18 +1603,18 @@ var gIdentityHandler = {
     let button = document.createXULElement("button");
     button.setAttribute("class", "identity-popup-permission-remove-button");
     let tooltiptext = gNavigatorBundle.getString("permissions.remove.tooltip");
     button.setAttribute("tooltiptext", tooltiptext);
     button.addEventListener("command", () => {
       let browser = gBrowser.selectedBrowser;
       this._permissionList.removeChild(container);
       if (aPermission.sharingState) {
-        if (aPermission.id === "geo" || aPermission.id === "xr") {
-          let origins = browser.getDevicePermissionOrigins(aPermission.id);
+        if (aPermission.id === "geo") {
+          let origins = browser.getDevicePermissionOrigins("geo");
           for (let origin of origins) {
             let principal = Services.scriptSecurityManager.createContentPrincipalFromOrigin(
               origin
             );
             this._removePermPersistentAllow(principal, aPermission.id);
           }
           origins.clear();
         } else if (
@@ -1685,18 +1659,16 @@ var gIdentityHandler = {
 
       this._permissionReloadHint.removeAttribute("hidden");
       PanelView.forNode(
         this._identityPopupMainView
       ).descriptionHeightWorkaround();
 
       if (aPermission.id === "geo") {
         gBrowser.updateBrowserSharing(browser, { geo: false });
-      } else if (aPermission.id === "xr") {
-        gBrowser.updateBrowserSharing(browser, { xr: false });
       }
     });
 
     return button;
   },
 
   _getGeoLocationLastAccess() {
     return new Promise(resolve => {
--- a/browser/base/content/browser.xhtml
+++ b/browser/base/content/browser.xhtml
@@ -885,23 +885,20 @@
                 <image id="identity-icon"
                        consumeanchor="identity-box"
                        onclick="PageProxyClickHandler(event);"/>
                 <image id="permissions-granted-icon"
                        tooltiptext="&urlbar.permissionsGranted.tooltip;"/>
                 <box style="pointer-events: none;">
                     <image class="sharing-icon" id="webrtc-sharing-icon"/>
                     <image class="sharing-icon geo-icon" id="geo-sharing-icon"/>
-                    <image class="sharing-icon xr-icon" id="xr-sharing-icon"/>
                 </box>
                 <box id="blocked-permissions-container" align="center">
                   <image data-permission-id="geo" class="blocked-permission-icon geo-icon" role="button"
                          data-l10n-id="urlbar-geolocation-blocked"/>
-                  <image data-permission-id="xr" class="blocked-permission-icon xr-icon" role="button"
-                         data-l10n-id="urlbar-xr-blocked"/>
                   <image data-permission-id="desktop-notification" class="blocked-permission-icon desktop-notification-icon" role="button"
                          data-l10n-id="urlbar-web-notifications-blocked"/>
                   <image data-permission-id="camera" class="blocked-permission-icon camera-icon" role="button"
                          data-l10n-id="urlbar-camera-blocked"/>
                   <image data-permission-id="microphone" class="blocked-permission-icon microphone-icon" role="button"
                          data-l10n-id="urlbar-microphone-blocked"/>
                   <image data-permission-id="screen" class="blocked-permission-icon screen-icon" role="button"
                          data-l10n-id="urlbar-screen-blocked"/>
@@ -922,18 +919,16 @@
                      hidden="true"
                      onmouseover="document.getElementById('identity-box').classList.add('no-hover');"
                      onmouseout="document.getElementById('identity-box').classList.remove('no-hover');"
                      align="center">
                   <image id="default-notification-icon" class="notification-anchor-icon" role="button"
                          data-l10n-id="urlbar-default-notification-anchor"/>
                   <image id="geo-notification-icon" class="notification-anchor-icon geo-icon" role="button"
                          data-l10n-id="urlbar-geolocation-notification-anchor"/>
-                  <image id="xr-notification-icon" class="notification-anchor-icon xr-icon" role="button"
-                         data-l10n-id="urlbar-xr-notification-anchor"/>
                   <image id="autoplay-media-notification-icon" class="notification-anchor-icon autoplay-media-icon" role="button"
                          data-l10n-id="urlbar-autoplay-notification-anchor"/>
                   <image id="addons-notification-icon" class="notification-anchor-icon install-icon" role="button"
                          data-l10n-id="urlbar-addons-notification-anchor"/>
                   <image id="canvas-notification-icon" class="notification-anchor-icon" role="button"
                          data-l10n-id="urlbar-canvas-notification-anchor"/>
                   <image id="indexedDB-notification-icon" class="notification-anchor-icon indexedDB-icon" role="button"
                          data-l10n-id="urlbar-indexed-db-notification-anchor"/>
--- a/browser/base/content/test/permissions/browser_temporary_permissions_expiry.js
+++ b/browser/base/content/test/permissions/browser_temporary_permissions_expiry.js
@@ -26,17 +26,17 @@ add_task(async function testTempPermissi
       ["privacy.temporary_permission_expire_time_ms", EXPIRE_TIME_MS],
       ["media.navigator.permission.fake", true],
     ],
   });
 
   let principal = Services.scriptSecurityManager.createContentPrincipalFromOrigin(
     ORIGIN
   );
-  let ids = ["geo", "camera", "xr"];
+  let ids = ["geo", "camera"];
 
   for (let id of ids) {
     await BrowserTestUtils.withNewTab(PERMISSIONS_PAGE, async function(
       browser
     ) {
       let blockedIcon = gIdentityHandler._identityBox.querySelector(
         `.blocked-permission-icon[data-permission-id='${id}']`
       );
--- a/browser/base/content/test/permissions/permissions.html
+++ b/browser/base/content/test/permissions/permissions.html
@@ -36,14 +36,13 @@ window.onmessage = function(event) {
   }
 };
 
 </script>
   <body onkeydown="gKeyDowns++;" onkeypress="gKeyPresses++">
 	<!-- This page could eventually request permissions from content
 	     and make sure that chrome responds appropriately -->
   <button id="geo" onclick="requestGeo()">Geolocation</button>
-  <button id="xr" onclick="navigator.getVRDisplays()">XR</button>
   <button id="desktop-notification" onclick="Notification.requestPermission()">Notifications</button>
   <button id="push" onclick="requestPush()">Push Notifications</button>
   <button id="camera" onclick="navigator.mediaDevices.getUserMedia({video: true, fake: true})">Camera</button>
   </body>
 </html>
--- a/browser/base/content/test/popupNotifications/browser_displayURI.js
+++ b/browser/base/content/test/popupNotifications/browser_displayURI.js
@@ -25,20 +25,17 @@ async function check(contentTask, option
   channel = channel.QueryInterface(Ci.nsIFileChannel);
 
   await BrowserTestUtils.withNewTab(channel.file.path, async function(browser) {
     let popupShownPromise = waitForNotificationPanel();
     await ContentTask.spawn(browser, null, contentTask);
     let panel = await popupShownPromise;
     let notification = panel.children[0];
     let body = notification.querySelector(".popup-notification-body");
-    if (
-      notification.id == "geolocation-notification" ||
-      notification.id == "xr-notification"
-    ) {
+    if (notification.id == "geolocation-notification") {
       ok(
         body.innerHTML.includes("local file"),
         `file:// URIs should be displayed as local file.`
       );
     } else {
       ok(
         body.innerHTML.includes("Unknown origin"),
         "file:// URIs should be displayed as unknown origin."
@@ -94,22 +91,16 @@ add_task(async function setup() {
 });
 
 add_task(async function test_displayURI_geo() {
   await check(async function() {
     content.navigator.geolocation.getCurrentPosition(() => {});
   });
 });
 
-add_task(async function test_displayURI_xr() {
-  await check(async function() {
-    content.navigator.getVRDisplays();
-  });
-});
-
 add_task(async function test_displayURI_camera() {
   await check(async function() {
     content.navigator.mediaDevices.getUserMedia({ video: true, fake: true });
   });
 });
 
 add_task(async function test_displayURI_geo_blob() {
   await check(
@@ -119,28 +110,16 @@ add_task(async function test_displayURI_
       let blob = new Blob([text], { type: "text/html" });
       let url = content.URL.createObjectURL(blob);
       content.location.href = url;
     },
     { skipOnExtension: true }
   );
 });
 
-add_task(async function test_displayURI_xr_blob() {
-  await check(
-    async function() {
-      let text = "<script>navigator.getVRDisplays()</script>";
-      let blob = new Blob([text], { type: "text/html" });
-      let url = content.URL.createObjectURL(blob);
-      content.location.href = url;
-    },
-    { skipOnExtension: true }
-  );
-});
-
 add_task(async function test_displayURI_camera_blob() {
   await check(
     async function() {
       let text =
         "<script>navigator.mediaDevices.getUserMedia({video: true, fake: true})</script>";
       let blob = new Blob([text], { type: "text/html" });
       let url = content.URL.createObjectURL(blob);
       content.location.href = url;
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -4026,19 +4026,16 @@ const ContentPermissionIntegration = {
    * @return {PermissionPrompt} (see PermissionUI.jsm),
    *         or undefined if the type cannot be handled.
    */
   createPermissionPrompt(type, request) {
     switch (type) {
       case "geolocation": {
         return new PermissionUI.GeolocationPermissionPrompt(request);
       }
-      case "xr": {
-        return new PermissionUI.XRPermissionPrompt(request);
-      }
       case "desktop-notification": {
         return new PermissionUI.DesktopNotificationPermissionPrompt(request);
       }
       case "persistent-storage": {
         return new PermissionUI.PersistentStoragePermissionPrompt(request);
       }
       case "midi": {
         return new PermissionUI.MIDIPermissionPrompt(request);
--- a/browser/components/preferences/in-content/privacy.inc.xhtml
+++ b/browser/components/preferences/in-content/privacy.inc.xhtml
@@ -771,40 +771,16 @@
                   permissions-remove-all.label,
                   permissions-button-cancel.label,
                   permissions-button-ok.label,
                   permissions-site-autoplay-window.title,
                   permissions-site-autoplay-desc,
                 " />
       </hbox>
     </hbox>
-
-    <hbox id="xrSettingsRow" align="center" role="group" aria-labelledby="xrPermissionsLabel">
-      <description flex="1">
-        <image class="xr-icon permission-icon" />
-        <separator orient="vertical" class="thin"/>
-        <label id="xrPermissionsLabel" data-l10n-id="permissions-xr"/>
-      </description>
-      <hbox pack="end">
-        <button id="xrSettingsButton"
-                is="highlightable-button"
-                class="accessory-button"
-                data-l10n-id="permissions-xr-settings"
-                search-l10n-ids="
-                  permissions-remove.label,
-                  permissions-remove-all.label,
-                  permissions-button-cancel.label,
-                  permissions-button-ok.label,
-                  permissions-site-xr-window.title,
-                  permissions-site-xr-desc,
-                  permissions-site-xr-disable-label,
-                  permissions-site-xr-disable-desc,
-                " />
-      </hbox>
-    </hbox>
   </vbox>
 
   <separator flex="1"/>
 
   <hbox data-subcategory="permissions-block-popups">
     <checkbox id="popupPolicy" preference="dom.disable_open_during_load"
               data-l10n-id="permissions-block-popups"
               flex="1" />
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -528,21 +528,16 @@ var gPrivacyPane = {
       gPrivacyPane.showNotificationExceptions
     );
     setEventListener(
       "locationSettingsButton",
       "command",
       gPrivacyPane.showLocationExceptions
     );
     setEventListener(
-      "xrSettingsButton",
-      "command",
-      gPrivacyPane.showXRExceptions
-    );
-    setEventListener(
       "cameraSettingsButton",
       "command",
       gPrivacyPane.showCameraExceptions
     );
     setEventListener(
       "microphoneSettingsButton",
       "command",
       gPrivacyPane.showMicrophoneExceptions
@@ -1679,32 +1674,16 @@ var gPrivacyPane = {
 
     gSubDialog.open(
       "chrome://browser/content/preferences/sitePermissions.xhtml",
       "resizable=yes",
       params
     );
   },
 
-  // XR
-
-  /**
-   * Displays the XR exceptions dialog where specific site XR
-   * preferences can be set.
-   */
-  showXRExceptions() {
-    let params = { permissionType: "xr" };
-
-    gSubDialog.open(
-      "chrome://browser/content/preferences/sitePermissions.xul",
-      "resizable=yes",
-      params
-    );
-  },
-
   // CAMERA
 
   /**
    * Displays the camera exceptions dialog where specific site camera
    * preferences can be set.
    */
   showCameraExceptions() {
     let params = { permissionType: "camera" };
--- a/browser/components/preferences/sitePermissions.js
+++ b/browser/components/preferences/sitePermissions.js
@@ -20,22 +20,16 @@ const sitePermissionsL10n = {
     disableDescription: "permissions-site-notification-disable-desc",
   },
   geo: {
     window: "permissions-site-location-window",
     description: "permissions-site-location-desc",
     disableLabel: "permissions-site-location-disable-label",
     disableDescription: "permissions-site-location-disable-desc",
   },
-  xr: {
-    window: "permissions-site-xr-window",
-    description: "permissions-site-xr-desc",
-    disableLabel: "permissions-site-xr-disable-label",
-    disableDescription: "permissions-site-xr-disable-desc",
-  },
   camera: {
     window: "permissions-site-camera-window",
     description: "permissions-site-camera-desc",
     disableLabel: "permissions-site-camera-disable-label",
     disableDescription: "permissions-site-camera-disable-desc",
   },
   microphone: {
     window: "permissions-site-microphone-window",
--- a/browser/components/privatebrowsing/test/browser/browser.ini
+++ b/browser/components/privatebrowsing/test/browser/browser.ini
@@ -1,14 +1,13 @@
 [DEFAULT]
 tags = openwindow
 support-files =
   browser_privatebrowsing_concurrent_page.html
   browser_privatebrowsing_geoprompt_page.html
-  browser_privatebrowsing_xrprompt_page.html
   browser_privatebrowsing_localStorage_before_after_page.html
   browser_privatebrowsing_localStorage_before_after_page2.html
   browser_privatebrowsing_localStorage_page1.html
   browser_privatebrowsing_localStorage_page2.html
   browser_privatebrowsing_placesTitleNoUpdate.html
   browser_privatebrowsing_protocolhandler_page.html
   browser_privatebrowsing_windowtitle_page.html
   head.js
@@ -31,28 +30,28 @@ tags = trackingprotection
 [browser_privatebrowsing_concurrent.js]
 [browser_privatebrowsing_context_and_chromeFlags.js]
 [browser_privatebrowsing_crh.js]
 [browser_privatebrowsing_downloadLastDir.js]
 skip-if = verify
 [browser_privatebrowsing_downloadLastDir_c.js]
 [browser_privatebrowsing_downloadLastDir_toggle.js]
 [browser_privatebrowsing_favicon.js]
+[browser_privatebrowsing_geoprompt.js]
+tags = geolocation
 [browser_privatebrowsing_lastpbcontextexited.js]
 [browser_privatebrowsing_localStorage.js]
 [browser_privatebrowsing_localStorage_before_after.js]
 [browser_privatebrowsing_noSessionRestoreMenuOption.js]
 [browser_privatebrowsing_nonbrowser.js]
 [browser_privatebrowsing_opendir.js]
 [browser_privatebrowsing_placesTitleNoUpdate.js]
 [browser_privatebrowsing_placestitle.js]
 [browser_privatebrowsing_popupblocker.js]
 [browser_privatebrowsing_protocolhandler.js]
-[browser_privatebrowsing_rememberprompt.js]
-tags = geolocation xr
 [browser_privatebrowsing_sidebar.js]
 [browser_privatebrowsing_theming.js]
 [browser_privatebrowsing_ui.js]
 [browser_privatebrowsing_urlbarfocus.js]
 [browser_privatebrowsing_windowtitle.js]
 [browser_privatebrowsing_zoom.js]
 [browser_privatebrowsing_zoomrestore.js]
 [browser_privatebrowsing_newtab_from_popup.js]
rename from browser/components/privatebrowsing/test/browser/browser_privatebrowsing_rememberprompt.js
rename to browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_rememberprompt.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
@@ -9,84 +9,72 @@
 // non-Fission e10s tests to try to avoid them.
 add_task(async function setup() {
   await SpecialPowers.pushPrefEnv({
     set: [["dom.ipc.keepProcessesAlive.webIsolated.perOrigin", 1]],
   });
 });
 
 add_task(async function test() {
-  function checkPrompt(aURL, aName, aPrivateMode, aWindow) {
+  const testPageURL =
+    "https://example.com/browser/" +
+    "browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt_page.html";
+
+  function checkGeolocation(aPrivateMode, aWindow) {
     return (async function() {
       aWindow.gBrowser.selectedTab = BrowserTestUtils.addTab(
         aWindow.gBrowser,
-        aURL
+        testPageURL
       );
       await BrowserTestUtils.browserLoaded(aWindow.gBrowser.selectedBrowser);
 
-      let notification = aWindow.PopupNotifications.getNotification(aName);
+      let notification = aWindow.PopupNotifications.getNotification(
+        "geolocation"
+      );
 
       // Wait until the notification is available.
       while (!notification) {
         await new Promise(resolve => {
           executeSoon(resolve);
         });
-        notification = aWindow.PopupNotifications.getNotification(aName);
+        notification = aWindow.PopupNotifications.getNotification(
+          "geolocation"
+        );
       }
 
       if (aPrivateMode) {
         // Make sure the notification is correctly displayed without a remember control
         ok(
           !notification.options.checkbox.show,
-          "Secondary actions should not exist (always/never remember)"
+          "Secondary actions should exist (always/never remember)"
         );
       } else {
         ok(
           notification.options.checkbox.show,
           "Secondary actions should exist (always/never remember)"
         );
       }
       notification.remove();
 
       aWindow.gBrowser.removeCurrentTab();
     })();
   }
 
-  function checkPrivateBrowsingRememberPrompt(aURL, aName) {
-    return (async function() {
-      let win = await BrowserTestUtils.openNewBrowserWindow();
-      let browser = win.gBrowser.selectedBrowser;
-      BrowserTestUtils.loadURI(browser, aURL);
-      await BrowserTestUtils.browserLoaded(browser);
-
-      await checkPrompt(aURL, aName, false, win);
+  let win = await BrowserTestUtils.openNewBrowserWindow();
+  let browser = win.gBrowser.selectedBrowser;
+  BrowserTestUtils.loadURI(browser, testPageURL);
+  await BrowserTestUtils.browserLoaded(browser);
 
-      let privateWin = await BrowserTestUtils.openNewBrowserWindow({
-        private: true,
-      });
-      let privateBrowser = privateWin.gBrowser.selectedBrowser;
-      BrowserTestUtils.loadURI(privateBrowser, aURL);
-      await BrowserTestUtils.browserLoaded(privateBrowser);
-
-      await checkPrompt(aURL, aName, true, privateWin);
+  await checkGeolocation(false, win);
 
-      // Cleanup
-      await BrowserTestUtils.closeWindow(win);
-      await BrowserTestUtils.closeWindow(privateWin);
-    })();
-  }
-
-  const geoTestPageURL =
-    "https://example.com/browser/" +
-    "browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt_page.html";
+  let privateWin = await BrowserTestUtils.openNewBrowserWindow({
+    private: true,
+  });
+  let privateBrowser = privateWin.gBrowser.selectedBrowser;
+  BrowserTestUtils.loadURI(privateBrowser, testPageURL);
+  await BrowserTestUtils.browserLoaded(privateBrowser);
 
-  await checkPrivateBrowsingRememberPrompt(geoTestPageURL, "geolocation");
-
-  const vrEnabled = Services.prefs.getBoolPref("dom.vr.enabled");
+  await checkGeolocation(true, privateWin);
 
-  if (vrEnabled) {
-    const xrTestPageURL =
-      "https://example.com/browser/" +
-      "browser/components/privatebrowsing/test/browser/browser_privatebrowsing_xrprompt_page.html";
-
-    await checkPrivateBrowsingRememberPrompt(xrTestPageURL, "xr");
-  }
+  // Cleanup
+  await BrowserTestUtils.closeWindow(win);
+  await BrowserTestUtils.closeWindow(privateWin);
 });
deleted file mode 100644
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_xrprompt_page.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<html>
-  <head>
-    <title>XR invoker</title>
-  </head>
-  <body>
-    <script type="text/javascript">
-      navigator.getVRDisplays();
-    </script>
-  </body>
-</html>
--- a/browser/locales/en-US/browser/browser.ftl
+++ b/browser/locales/en-US/browser/browser.ftl
@@ -52,18 +52,16 @@ urlbar-web-authn-anchor =
 urlbar-canvas-notification-anchor =
     .tooltiptext = Manage canvas extraction permission
 urlbar-web-rtc-share-microphone-notification-anchor =
     .tooltiptext = Manage sharing your microphone with the site
 urlbar-default-notification-anchor =
     .tooltiptext = Open message panel
 urlbar-geolocation-notification-anchor =
     .tooltiptext = Open location request panel
-urlbar-xr-notification-anchor =
-    .tooltiptext = Open virtual reality permission panel
 urlbar-storage-access-anchor =
     .tooltiptext = Open browsing activity permission panel
 urlbar-translate-notification-anchor =
     .tooltiptext = Translate this page
 urlbar-web-rtc-share-screen-notification-anchor =
     .tooltiptext = Manage sharing your windows or screen with the site
 urlbar-indexed-db-notification-anchor =
     .tooltiptext = Open offline storage message panel
@@ -81,18 +79,16 @@ urlbar-persistent-storage-notification-a
     .tooltiptext = Store data in Persistent Storage
 urlbar-addons-notification-anchor =
     .tooltiptext = Open add-on installation message panel
 urlbar-tip-help-icon =
     .title = Get help
 
 urlbar-geolocation-blocked =
     .tooltiptext = You have blocked location information for this website.
-urlbar-xr-blocked =
-    .tooltiptext = You have blocked virtual reality device access for this website.
 urlbar-web-notifications-blocked =
     .tooltiptext = You have blocked notifications for this website.
 urlbar-camera-blocked =
     .tooltiptext = You have blocked your camera for this website.
 urlbar-microphone-blocked =
     .tooltiptext = You have blocked your microphone for this website.
 urlbar-screen-blocked =
     .tooltiptext = You have blocked this website from sharing your screen.
--- a/browser/locales/en-US/browser/preferences/permissions.ftl
+++ b/browser/locales/en-US/browser/preferences/permissions.ftl
@@ -134,26 +134,16 @@ permissions-site-notification-disable-de
 permissions-site-location-window =
     .title = Settings - Location Permissions
     .style = { permissions-window.style }
 permissions-site-location-desc = The following websites have requested to access your location. You can specify which websites are allowed to access your location. You can also block new requests asking to access your location.
 permissions-site-location-disable-label =
     .label = Block new requests asking to access your location
 permissions-site-location-disable-desc = This will prevent any websites not listed above from requesting permission to access your location. Blocking access to your location may break some website features.
 
-## Site Permissions - Virtual Reality
-
-permissions-site-xr-window =
-    .title = Settings - Virtual Reality Permissions
-    .style = { permissions-window.style }
-permissions-site-xr-desc = The following websites have requested to access your virtual reality devices. You can specify which websites are allowed to access your virtual reality devices. You can also block new requests asking to access your virtual reality devices.
-permissions-site-xr-disable-label =
-    .label = Block new requests asking to access your virtual reality devices
-permissions-site-xr-disable-desc = This will prevent any websites not listed above from requesting permission to access your virtual reality devices. Blocking access to your virtual reality devices may break some website features.
-
 ## Site Permissions - Camera
 
 permissions-site-camera-window =
     .title = Settings - Camera Permissions
     .style = { permissions-window.style }
 permissions-site-camera-desc = The following websites have requested to access your camera. You can specify which websites are allowed to access your camera. You can also block new requests asking to access your camera.
 permissions-site-camera-disable-label =
     .label = Block new requests asking to access your camera
--- a/browser/locales/en-US/browser/preferences/preferences.ftl
+++ b/browser/locales/en-US/browser/preferences/preferences.ftl
@@ -1107,21 +1107,16 @@ tracking-manage-exceptions =
 
 permissions-header = Permissions
 
 permissions-location = Location
 permissions-location-settings =
     .label = Settings…
     .accesskey = t
 
-permissions-xr = Virtual Reality
-permissions-xr-settings =
-    .label = Settings…
-    .accesskey = t
-
 permissions-camera = Camera
 permissions-camera-settings =
     .label = Settings…
     .accesskey = t
 
 permissions-microphone = Microphone
 permissions-microphone-settings =
     .label = Settings…
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -623,25 +623,16 @@ geolocation.dontAllowLocation=Don’t Allow
 geolocation.dontAllowLocation.accesskey=n
 geolocation.shareWithSite3=Will you allow %S to access your location?
 geolocation.shareWithFile3=Will you allow this local file to access your location?
 # LOCALIZATION NOTE(geolocation.shareWithSiteUnsafeDelegation):
 # %1$S is the first party origin, %2$S is the third party origin.
 geolocation.shareWithSiteUnsafeDelegation=Will you allow %1$S to give %2$S permission to access your location?
 geolocation.remember=Remember this decision
 
-# Virtual Reality Device UI
-xr.allow=Allow Virtual Reality Access
-xr.allow.accesskey=A
-xr.dontAllow=Don’t Allow
-xr.dontAllow.accesskey=n
-xr.shareWithSite3=Will you allow %S to access virtual reality devices? This may expose sensitive information.
-xr.shareWithFile3=Will you allow this local file to access virtual reality devices? This may expose sensitive information.
-xr.remember=Remember this decision
-
 # Persistent storage UI
 persistentStorage.allow=Allow
 persistentStorage.allow.accesskey=A
 persistentStorage.neverAllow.label=Never Allow
 persistentStorage.neverAllow.accesskey=N
 persistentStorage.notNow.label=Not Now
 persistentStorage.notNow.accesskey=w
 persistentStorage.allowWithSite=Will you allow %S to store data in persistent storage?
--- a/browser/locales/en-US/chrome/browser/sitePermissions.properties
+++ b/browser/locales/en-US/chrome/browser/sitePermissions.properties
@@ -35,15 +35,14 @@ permission.autoplay.label = Autoplay
 permission.cookie.label = Set Cookies
 permission.desktop-notification3.label = Send Notifications
 permission.camera.label = Use the Camera
 permission.microphone.label = Use the Microphone
 permission.screen.label = Share the Screen
 permission.install.label = Install Add-ons
 permission.popup.label = Open Pop-up Windows
 permission.geo.label = Access Your Location
-permission.xr.label = Access Virtual Reality Devices
 permission.shortcuts.label = Override Keyboard Shortcuts
 permission.focus-tab-by-prompt.label = Switch to this Tab
 permission.persistent-storage.label = Store Data in Persistent Storage
 permission.canvas.label = Extract Canvas Data
 permission.midi.label = Access MIDI Devices
 permission.midi-sysex.label = Access MIDI Devices with SysEx Support
--- a/browser/modules/PermissionUI.jsm
+++ b/browser/modules/PermissionUI.jsm
@@ -883,121 +883,16 @@ GeolocationPermissionPrompt.prototype = 
     PermissionPromptForRequestPrototype.cancel.apply(this, args);
   },
 };
 
 PermissionUI.GeolocationPermissionPrompt = GeolocationPermissionPrompt;
 
 /**
  * Creates a PermissionPrompt for a nsIContentPermissionRequest for
- * the WebXR API.
- *
- * @param request (nsIContentPermissionRequest)
- *        The request for a permission from content.
- */
-function XRPermissionPrompt(request) {
-  this.request = request;
-}
-
-XRPermissionPrompt.prototype = {
-  __proto__: PermissionPromptForRequestPrototype,
-
-  get permissionKey() {
-    return "xr";
-  },
-
-  get permissionTelemetryKey() {
-    return "xr";
-  },
-
-  get popupOptions() {
-    let pref = "browser.xr.warning.infoURL";
-    let options = {
-      learnMoreURL: Services.urlFormatter.formatURLPref(pref),
-      displayURI: false,
-      name: this.principalName,
-    };
-
-    if (this.principal.URI.schemeIs("file")) {
-      options.checkbox = { show: false };
-    } else {
-      // Don't offer "always remember" action in PB mode
-      options.checkbox = {
-        show: !PrivateBrowsingUtils.isWindowPrivate(this.browser.ownerGlobal),
-      };
-    }
-
-    if (options.checkbox.show) {
-      options.checkbox.label = gBrowserBundle.GetStringFromName("xr.remember");
-    }
-
-    return options;
-  },
-
-  get notificationID() {
-    return "xr";
-  },
-
-  get anchorID() {
-    return "xr-notification-icon";
-  },
-
-  get message() {
-    if (this.principal.URI.schemeIs("file")) {
-      return gBrowserBundle.GetStringFromName("xr.shareWithFile3");
-    }
-
-    return gBrowserBundle.formatStringFromName("xr.shareWithSite3", ["<>"]);
-  },
-
-  get promptActions() {
-    return [
-      {
-        label: gBrowserBundle.GetStringFromName("xr.allow"),
-        accessKey: gBrowserBundle.GetStringFromName("xr.allow.accesskey"),
-        action: SitePermissions.ALLOW,
-      },
-      {
-        label: gBrowserBundle.GetStringFromName("xr.dontAllow"),
-        accessKey: gBrowserBundle.GetStringFromName("xr.dontAllow.accesskey"),
-        action: SitePermissions.BLOCK,
-      },
-    ];
-  },
-
-  _updateXRSharing(state) {
-    let gBrowser = this.browser.ownerGlobal.gBrowser;
-    if (gBrowser == null) {
-      return;
-    }
-    gBrowser.updateBrowserSharing(this.browser, { xr: state });
-
-    let devicePermOrigins = this.browser.getDevicePermissionOrigins("xr");
-    if (!state) {
-      devicePermOrigins.delete(this.principal.origin);
-      return;
-    }
-    devicePermOrigins.add(this.principal.origin);
-  },
-
-  allow(...args) {
-    this._updateXRSharing(true);
-    PermissionPromptForRequestPrototype.allow.apply(this, args);
-  },
-
-  cancel(...args) {
-    this._updateXRSharing(false);
-    PermissionPromptForRequestPrototype.cancel.apply(this, args);
-  },
-};
-
-PermissionUI.XRPermissionPrompt = XRPermissionPrompt;
-
-/**
- * Creates a PermissionPrompt for a nsIContentPermissionRequest for
  * the Desktop Notification API.
  *
  * @param request (nsIContentPermissionRequest)
  *        The request for a permission from content.
  * @return {PermissionPrompt} (see documentation in header)
  */
 function DesktopNotificationPermissionPrompt(request) {
   this.request = request;
--- a/browser/modules/PermissionUITelemetry.jsm
+++ b/browser/modules/PermissionUITelemetry.jsm
@@ -84,17 +84,16 @@ var PermissionUITelemetry = {
 
     let allPermsDenied = 0;
     let allPermsGranted = 0;
     let thisPermDenied = 0;
     let thisPermGranted = 0;
 
     let commonPermissions = [
       "geo",
-      "xr",
       "desktop-notification",
       "camera",
       "microphone",
       "screen",
     ];
     for (let perm of Services.perms.all) {
       if (!commonPermissions.includes(perm.type)) {
         continue;
--- a/browser/modules/SitePermissions.jsm
+++ b/browser/modules/SitePermissions.jsm
@@ -961,20 +961,16 @@ var gPermissionObject = {
         : SitePermissions.ALLOW;
     },
   },
 
   geo: {
     exactHostMatch: true,
   },
 
-  xr: {
-    exactHostMatch: true,
-  },
-
   "focus-tab-by-prompt": {
     exactHostMatch: true,
     states: [SitePermissions.UNKNOWN, SitePermissions.ALLOW],
   },
   "persistent-storage": {
     exactHostMatch: true,
   },
 
--- a/browser/modules/test/browser/browser_PermissionUI_prompts.js
+++ b/browser/modules/test/browser/browser_PermissionUI_prompts.js
@@ -13,21 +13,16 @@ const { PermissionTestUtils } = ChromeUt
   "resource://testing-common/PermissionTestUtils.jsm"
 );
 
 // Tests that GeolocationPermissionPrompt works as expected
 add_task(async function test_geo_permission_prompt() {
   await testPrompt(PermissionUI.GeolocationPermissionPrompt);
 });
 
-// Tests that XRPermissionPrompt works as expected
-add_task(async function test_xr_permission_prompt() {
-  await testPrompt(PermissionUI.XRPermissionPrompt);
-});
-
 // Tests that DesktopNotificationPermissionPrompt works as expected
 add_task(async function test_desktop_notification_permission_prompt() {
   Services.prefs.setBoolPref(
     "dom.webnotifications.requireuserinteraction",
     false
   );
   Services.prefs.setBoolPref(
     "permissions.desktop-notification.notNow.enabled",
--- a/browser/modules/test/browser/browser_SitePermissions.js
+++ b/browser/modules/test/browser/browser_SitePermissions.js
@@ -54,18 +54,16 @@ add_task(async function testGetAllPermis
     SitePermissions.SCOPE_SESSION
   );
   SitePermissions.setForPrincipal(
     principal,
     "shortcuts",
     SitePermissions.ALLOW
   );
 
-  SitePermissions.setForPrincipal(principal, "xr", SitePermissions.ALLOW);
-
   let permissions = SitePermissions.getAllPermissionDetailsForBrowser(
     tab.linkedBrowser
   );
 
   let camera = permissions.find(({ id }) => id === "camera");
   Assert.deepEqual(camera, {
     id: "camera",
     label: "Use the Camera",
@@ -109,27 +107,17 @@ add_task(async function testGetAllPermis
   let shortcuts = permissions.find(({ id }) => id === "shortcuts");
   Assert.deepEqual(shortcuts, {
     id: "shortcuts",
     label: "Override Keyboard Shortcuts",
     state: SitePermissions.ALLOW,
     scope: SitePermissions.SCOPE_PERSISTENT,
   });
 
-  let xr = permissions.find(({ id }) => id === "xr");
-  Assert.deepEqual(xr, {
-    id: "xr",
-    label: "Access Virtual Reality Devices",
-    state: SitePermissions.ALLOW,
-    scope: SitePermissions.SCOPE_PERSISTENT,
-  });
-
   SitePermissions.removeFromPrincipal(principal, "cookie");
   SitePermissions.removeFromPrincipal(principal, "popup");
   SitePermissions.removeFromPrincipal(principal, "geo");
   SitePermissions.removeFromPrincipal(principal, "shortcuts");
 
-  SitePermissions.removeFromPrincipal(principal, "xr");
-
   Services.prefs.clearUserPref("permissions.default.shortcuts");
 
   BrowserTestUtils.removeTab(gBrowser.selectedTab);
 });
--- a/browser/modules/test/unit/test_SitePermissions.js
+++ b/browser/modules/test/unit/test_SitePermissions.js
@@ -23,17 +23,16 @@ add_task(async function testPermissionsL
     "geo",
     "install",
     "microphone",
     "popup",
     "screen",
     "shortcuts",
     "persistent-storage",
     "storage-access",
-    "xr",
   ];
   if (RESIST_FINGERPRINTING_ENABLED) {
     // Canvas permission should be hidden unless privacy.resistFingerprinting
     // is true.
     expectedPermissions.push("canvas");
   }
   if (MIDI_ENABLED) {
     // Should remove this checking and add it as default after it is fully pref'd-on.
@@ -180,17 +179,16 @@ add_task(async function testExactHostMat
   let exactHostMatched = [
     "autoplay-media",
     "desktop-notification",
     "focus-tab-by-prompt",
     "camera",
     "microphone",
     "screen",
     "geo",
-    "xr",
     "persistent-storage",
   ];
   if (RESIST_FINGERPRINTING_ENABLED) {
     // Canvas permission should be hidden unless privacy.resistFingerprinting
     // is true.
     exactHostMatched.push("canvas");
   }
   if (MIDI_ENABLED) {
--- a/browser/themes/shared/incontentprefs/privacy.css
+++ b/browser/themes/shared/incontentprefs/privacy.css
@@ -64,20 +64,16 @@
 .content-blocking-icon[disabled] {
   fill: GrayText;
 }
 
 .geo-icon {
   list-style-image: url(chrome://browser/skin/notification-icons/geo.svg);
 }
 
-.xr-icon {
-  list-style-image: url(chrome://browser/skin/notification-icons/xr.svg);
-}
-
 .camera-icon {
   list-style-image: url(chrome://browser/skin/notification-icons/camera.svg);
 }
 
 .microphone-icon {
   list-style-image: url(chrome://browser/skin/notification-icons/microphone.svg);
 }
 
--- a/browser/themes/shared/jar.inc.mn
+++ b/browser/themes/shared/jar.inc.mn
@@ -86,18 +86,16 @@
   skin/classic/browser/notification-icons/microphone.svg                    (../shared/notification-icons/microphone.svg)
   skin/classic/browser/notification-icons/persistent-storage-blocked.svg    (../shared/notification-icons/persistent-storage-blocked.svg)
   skin/classic/browser/notification-icons/persistent-storage.svg            (../shared/notification-icons/persistent-storage.svg)
   skin/classic/browser/notification-icons/plugin-badge.svg                  (../shared/notification-icons/plugin-badge.svg)
   skin/classic/browser/notification-icons/popup.svg                         (../shared/notification-icons/popup.svg)
   skin/classic/browser/notification-icons/popup-subitem.svg                 (../shared/notification-icons/popup-subitem.svg)
   skin/classic/browser/notification-icons/screen-blocked.svg                (../shared/notification-icons/screen-blocked.svg)
   skin/classic/browser/notification-icons/screen.svg                        (../shared/notification-icons/screen.svg)
-  skin/classic/browser/notification-icons/xr-blocked.svg                    (../shared/notification-icons/xr-blocked.svg)
-  skin/classic/browser/notification-icons/xr.svg                            (../shared/notification-icons/xr.svg)
   skin/classic/browser/notification-icons/update.svg                        (../shared/notification-icons/update.svg)
   skin/classic/browser/notification-icons/midi.svg                          (../shared/notification-icons/midi.svg)
   skin/classic/browser/notification-icons/webauthn.svg                      (../shared/notification-icons/webauthn.svg)
   skin/classic/browser/notification-icons/block-cryptominer-dark.svg        (../shared/notification-icons/block-cryptominer-dark.svg)
   skin/classic/browser/notification-icons/block-cryptominer.svg             (../shared/notification-icons/block-cryptominer.svg)
   skin/classic/browser/notification-icons/block-fingerprinter-dark.svg      (../shared/notification-icons/block-fingerprinter-dark.svg)
   skin/classic/browser/notification-icons/block-fingerprinter.svg           (../shared/notification-icons/block-fingerprinter.svg)
   skin/classic/browser/notification-icons/block-social-dark.svg             (../shared/notification-icons/block-social-dark.svg)
--- a/browser/themes/shared/notification-icons.inc.css
+++ b/browser/themes/shared/notification-icons.inc.css
@@ -65,28 +65,16 @@
 .geo-icon.blocked-permission-icon {
   list-style-image: url(chrome://browser/skin/notification-icons/geo-blocked.svg);
 }
 
 .popup-notification-icon[popupid="geolocation"] {
   list-style-image: url(chrome://browser/skin/notification-icons/geo-detailed.svg);
 }
 
-.xr-icon {
-  list-style-image: url(chrome://browser/skin/notification-icons/xr.svg);
-}
-
-.xr-icon.blocked-permission-icon {
-  list-style-image: url(chrome://browser/skin/notification-icons/xr-blocked.svg);
-}
-
-.popup-notification-icon[popupid="xr"] {
-  list-style-image: url(chrome://browser/skin/notification-icons/xr.svg);
-}
-
 .autoplay-media-icon {
   list-style-image: url(chrome://browser/skin/notification-icons/autoplay-media.svg);
 }
 
 .popup-notification-icon[popupid="autoplay-media"] {
   list-style-image: url(chrome://browser/skin/notification-icons/autoplay-media-detailed.svg);
 }
 
deleted file mode 100644
--- a/browser/themes/shared/notification-icons/xr-blocked.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity">
-	<path d="M14.3,4.3l-2.6,2.6c0.6,0.3,0.9,1,0.6,1.6c-0.3,0.6-1,0.9-1.6,0.6c-0.2-0.1-0.4-0.3-0.6-0.6l-1.7,1.7L9,11.5
-		c0.1,0.1,0.2,0.2,0.3,0.2h4.8c0.6,0,1-0.5,1-1V5.3C15.1,4.8,14.8,4.4,14.3,4.3z"/>
-	<path d="M12.8,4.4c0.3-0.3,0.2-0.7,0-0.9c-0.3-0.2-0.7-0.2-0.9,0l-0.8,0.8H2c-0.6,0-1,0.5-1,1v5.4c0,0.6,0.5,1,1,1h1.7
-		c-0.2,0.3,0,0.7,0.3,0.9c0.3,0.1,0.6,0.1,0.8-0.1L12.8,4.4z M3.7,8.5c-0.3-0.6,0-1.3,0.6-1.6c0.6-0.3,1.3,0,1.6,0.6s0,1.3-0.6,1.6
-		C5.1,9.2,5,9.2,4.8,9.2C4.3,9.2,3.9,8.9,3.7,8.5z"/>
-</svg>
deleted file mode 100644
--- a/browser/themes/shared/notification-icons/xr.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity">
-	<path d="M14.1,4.3H2c-0.6,0-1,0.5-1,1v5.4c0,0.6,0.5,1,1,1h4.7c0.1,0,0.2-0.1,0.3-0.2l0.7-1.4C7.8,9.9,8,9.9,8.1,9.9
-		c0.1,0,0.1,0.1,0.2,0.2L9,11.5c0.1,0.1,0.2,0.2,0.3,0.2h4.8c0.6,0,1-0.5,1-1V5.3C15.1,4.7,14.6,4.3,14.1,4.3z M4.8,9.2
-		C4.1,9.2,3.6,8.7,3.6,8c0-0.7,0.5-1.2,1.2-1.2C5.5,6.8,6,7.3,6,8c0,0,0,0,0,0C6,8.7,5.5,9.2,4.8,9.2z M11.2,9.2
-		C10.5,9.2,10,8.7,10,8c0-0.7,0.5-1.2,1.2-1.2c0.7,0,1.2,0.5,1.2,1.2c0,0,0,0,0,0C12.4,8.7,11.9,9.2,11.2,9.2z"/>
-</svg>
--- a/browser/tools/mozscreenshots/mozscreenshots/extension/lib/permissionPrompts.html
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/lib/permissionPrompts.html
@@ -5,17 +5,16 @@
 <!DOCTYPE html>
 <html>
 <head>
   <meta charset="utf-8">
   <title>Permission Prompts</title>
 </head>
 <body>
   <button id="geo" onclick="navigator.geolocation.getCurrentPosition(() => {})">Geolocation</button>
-  <button id="xr" onclick="content.navigator.getVRDisplays();">WebXR</button>
   <button id="persistent-storage" onclick="navigator.storage.persist()">Persistent Storage</button>
   <button id="webRTC-shareDevices" onclick="shareDevice({video: true, fake: true});">Video</button>
   <button id="webRTC-shareMicrophone" onclick="shareDevice({audio: true, fake: true});">Audio</button>
   <button id="webRTC-shareDevices2" onclick="shareDevice({audio: true, video: true, fake: true});">Audio and Video</button>
   <button id="webRTC-shareScreen" onclick="shareDevice({video: {mediaSource: 'screen'}});">Screen</button>
   <button id="web-notifications" onclick="Notification.requestPermission()">web-notifications</button>
   <a id="addons" href="borderify.xpi">Install Add-On</a>
   <form>
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -1483,16 +1483,19 @@ already_AddRefed<Promise> Navigator::Get
   }
 
   if (!FeaturePolicyUtils::IsFeatureAllowed(mWindow->GetExtantDoc(),
                                             NS_LITERAL_STRING("vr"))) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return nullptr;
   }
 
+  nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(mWindow);
+  win->NotifyVREventListenerAdded();
+
   RefPtr<Promise> p = Promise::Create(mWindow->AsGlobal(), aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   RefPtr<BrowserChild> browser(BrowserChild::GetFrom(mWindow));
   if (!browser) {
     MOZ_ASSERT(XRE_IsParentProcess());
@@ -1510,63 +1513,49 @@ already_AddRefed<Promise> Navigator::Get
           MOZ_CRASH("Failed to make IPC call to IsWindowSupportingWebVR");
         });
   }
 
   return p.forget();
 }
 
 void Navigator::FinishGetVRDisplays(bool isWebVRSupportedInwindow, Promise* p) {
-  if (!isWebVRSupportedInwindow) {
+  if (isWebVRSupportedInwindow) {
+    nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(mWindow);
+
+    // Since FinishGetVRDisplays can be called asynchronously after an IPC
+    // response, it's possible that the Window can be torn down before this
+    // call. In that case, the Window's cyclic references to VR objects are
+    // also torn down and should not be recreated via
+    // NotifyVREventListenerAdded.
+    if (!win->IsDying()) {
+      win->NotifyVREventListenerAdded();
+      // We pass mWindow's id to RefreshVRDisplays, so
+      // NotifyVRDisplaysUpdated will be called asynchronously, resolving
+      // the promises in mVRGetDisplaysPromises.
+      if (!VRDisplay::RefreshVRDisplays(win->WindowID())) {
+        // Failed to refresh, reject the promise now
+        p->MaybeRejectWithTypeError(u"Failed to find attached VR displays.");
+      } else {
+        // Succeeded, so cache the promise to resolve later
+        mVRGetDisplaysPromises.AppendElement(p);
+      }
+    } else {
+      // The Window has been torn down, so there is no further work that can
+      // be done.
+      p->MaybeRejectWithTypeError(
+          u"Unable to return VRDisplays for a closed window.");
+    }
+  } else {
     // WebVR in this window is not supported, so resolve the promise
     // with no displays available
     nsTArray<RefPtr<VRDisplay>> vrDisplaysEmpty;
     p->MaybeResolve(vrDisplaysEmpty);
-    return;
   }
-
-  // Since FinishGetVRDisplays can be called asynchronously after an IPC
-  // response, it's possible that the Window can be torn down before this
-  // call. In that case, the Window's cyclic references to VR objects are
-  // also torn down and should not be recreated via
-  // NotifyVREventListenerAdded.
-  nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(mWindow);
-  if (win->IsDying()) {
-    // The Window has been torn down, so there is no further work that can
-    // be done.
-    p->MaybeRejectWithTypeError(
-        u"Unable to return VRDisplays for a closed window.");
-    return;
-  }
-
   mVRGetDisplaysPromises.AppendElement(p);
-  win->RequestXRPermission();
-}
-
-void Navigator::OnXRPermissionRequestAllow() {
-  nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(mWindow);
-
-  // We pass mWindow's id to RefreshVRDisplays, so NotifyVRDisplaysUpdated will
-  // be called asynchronously, resolving the promises in mVRGetDisplaysPromises.
-  if (!VRDisplay::RefreshVRDisplays(win->WindowID())) {
-    for (auto p : mVRGetDisplaysPromises) {
-      // Failed to refresh, reject the promise now
-      p->MaybeRejectWithTypeError(u"Failed to find attached VR displays.");
-    }
-  }
-}
-
-void Navigator::OnXRPermissionRequestCancel() {
-  nsTArray<RefPtr<VRDisplay>> vrDisplays;
-  for (auto p : mVRGetDisplaysPromises) {
-    // Resolve the promise with no vr displays when
-    // the user blocks access.
-    p->MaybeResolve(vrDisplays);
-  }
-  mVRGetDisplaysPromises.Clear();
 }
 
 void Navigator::GetActiveVRDisplays(
     nsTArray<RefPtr<VRDisplay>>& aDisplays) const {
   /**
    * Get only the active VR displays.
    * GetActiveVRDisplays should only enumerate displays that
    * are already active without causing any other hardware to be
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -176,18 +176,16 @@ class Navigator final : public nsISuppor
   network::Connection* GetConnection(ErrorResult& aRv);
   MediaDevices* GetMediaDevices(ErrorResult& aRv);
 
   void GetGamepads(nsTArray<RefPtr<Gamepad>>& aGamepads, ErrorResult& aRv);
   GamepadServiceTest* RequestGamepadServiceTest();
   already_AddRefed<Promise> GetVRDisplays(ErrorResult& aRv);
   void FinishGetVRDisplays(bool isWebVRSupportedInwindow, Promise* p);
   void GetActiveVRDisplays(nsTArray<RefPtr<VRDisplay>>& aDisplays) const;
-  void OnXRPermissionRequestAllow();
-  void OnXRPermissionRequestCancel();
   VRServiceTest* RequestVRServiceTest();
   bool IsWebVRContentDetected() const;
   bool IsWebVRContentPresenting() const;
   void RequestVRPresentation(VRDisplay& aDisplay);
   already_AddRefed<Promise> RequestMIDIAccess(const MIDIOptions& aOptions,
                                               ErrorResult& aRv);
 
   Presentation* GetPresentation(ErrorResult& aRv);
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -199,17 +199,16 @@
 #include "mozilla/dom/Gamepad.h"
 #include "mozilla/dom/GamepadManager.h"
 
 #include "gfxVR.h"
 #include "mozilla/dom/VRDisplay.h"
 #include "mozilla/dom/VRDisplayEvent.h"
 #include "mozilla/dom/VRDisplayEventBinding.h"
 #include "mozilla/dom/VREventObserver.h"
-#include "mozilla/dom/XRPermissionRequest.h"
 
 #include "nsRefreshDriver.h"
 #include "Layers.h"
 
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/Services.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/dom/Location.h"
@@ -852,18 +851,16 @@ nsGlobalWindowInner::nsGlobalWindowInner
       mNeedsFocus(true),
       mHasFocus(false),
       mShowFocusRingForContent(false),
       mFocusByKeyOccurred(false),
       mDidFireDocElemInserted(false),
       mHasGamepad(false),
       mHasVREvents(false),
       mHasVRDisplayActivateEvents(false),
-      mXRPermissionRequestInFlight(false),
-      mXRPermissionGranted(false),
       mHasSeenGamepadInput(false),
       mSuspendDepth(0),
       mFreezeDepth(0),
 #ifdef DEBUG
       mSerial(0),
 #endif
       mFocusMethod(0),
       mIdleRequestCallbackCounter(1),
@@ -1154,18 +1151,16 @@ void nsGlobalWindowInner::FreeInnerObjec
   mAudioContexts.Clear();
 
   DisableGamepadUpdates();
   mHasGamepad = false;
   mGamepads.Clear();
   DisableVRUpdates();
   mHasVREvents = false;
   mHasVRDisplayActivateEvents = false;
-  mXRPermissionRequestInFlight = false;
-  mXRPermissionGranted = false;
   mVRDisplays.Clear();
 
   // This breaks a cycle between the window and the ClientSource object.
   mClientSource.reset();
 
   if (mWindowGlobalChild) {
     // Remove any remaining listeners.
     int64_t nListeners = mWindowGlobalChild->BeforeUnloadListeners();
@@ -6035,58 +6030,23 @@ void nsGlobalWindowInner::DisableOrienta
 void nsGlobalWindowInner::SetHasGamepadEventListener(
     bool aHasGamepad /* = true*/) {
   mHasGamepad = aHasGamepad;
   if (aHasGamepad) {
     EnableGamepadUpdates();
   }
 }
 
-void nsGlobalWindowInner::RequestXRPermission() {
-  if (mXRPermissionGranted) {
-    // Don't prompt redundantly once permission to
-    // access XR devices has been granted.
-    OnXRPermissionRequestAllow();
-    return;
-  }
-  if (mXRPermissionRequestInFlight) {
-    // Don't allow multiple simultaneous permissions requests;
-    return;
-  }
-  mXRPermissionRequestInFlight = true;
-  RefPtr<XRPermissionRequest> request =
-      new XRPermissionRequest(this, WindowID());
-  Unused << NS_WARN_IF(NS_FAILED(request->Start()));
-}
-
-void nsGlobalWindowInner::OnXRPermissionRequestAllow() {
-  mXRPermissionRequestInFlight = false;
-  mXRPermissionGranted = true;
-
-  NotifyVREventListenerAdded();
-
-  dom::Navigator* nav = Navigator();
-  MOZ_ASSERT(nav != nullptr);
-  nav->OnXRPermissionRequestAllow();
-}
-
-void nsGlobalWindowInner::OnXRPermissionRequestCancel() {
-  mXRPermissionRequestInFlight = false;
-  dom::Navigator* nav = Navigator();
-  MOZ_ASSERT(nav != nullptr);
-  nav->OnXRPermissionRequestCancel();
-}
-
 void nsGlobalWindowInner::EventListenerAdded(nsAtom* aType) {
   if (aType == nsGkAtoms::onvrdisplayactivate ||
       aType == nsGkAtoms::onvrdisplayconnect ||
       aType == nsGkAtoms::onvrdisplaydeactivate ||
       aType == nsGkAtoms::onvrdisplaydisconnect ||
       aType == nsGkAtoms::onvrdisplaypresentchange) {
-    RequestXRPermission();
+    NotifyVREventListenerAdded();
   }
 
   if (aType == nsGkAtoms::onvrdisplayactivate) {
     mHasVRDisplayActivateEvents = true;
   }
 
   if (aType == nsGkAtoms::onbeforeunload && mWindowGlobalChild &&
       (!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS))) {
--- a/dom/base/nsGlobalWindowInner.h
+++ b/dom/base/nsGlobalWindowInner.h
@@ -367,19 +367,16 @@ class nsGlobalWindowInner final : public
   friend class FullscreenTransitionTask;
 
   // Inner windows only.
   virtual void SetHasGamepadEventListener(bool aHasGamepad = true) override;
   void NotifyVREventListenerAdded();
   bool HasUsedVR() const;
   bool IsVRContentDetected() const;
   bool IsVRContentPresenting() const;
-  void RequestXRPermission();
-  void OnXRPermissionRequestAllow();
-  void OnXRPermissionRequestCancel();
 
   using EventTarget::EventListenerAdded;
   virtual void EventListenerAdded(nsAtom* aType) override;
   using EventTarget::EventListenerRemoved;
   virtual void EventListenerRemoved(nsAtom* aType) override;
 
   // nsIInterfaceRequestor
   NS_DECL_NSIINTERFACEREQUESTOR
@@ -1284,25 +1281,16 @@ class nsGlobalWindowInner final : public
   // Indicates whether this window wants gamepad input events
   bool mHasGamepad : 1;
 
   // Indicates whether this window wants VR events
   bool mHasVREvents : 1;
 
   // Indicates whether this window wants VRDisplayActivate events
   bool mHasVRDisplayActivateEvents : 1;
-
-  // Indicates that an XR permission request has been requested
-  // but has not yet been resolved.
-  bool mXRPermissionRequestInFlight : 1;
-
-  // Indicates that an XR permission request has been granted.
-  // The page should not request permission multiple times.
-  bool mXRPermissionGranted : 1;
-
   nsCheapSet<nsUint32HashKey> mGamepadIndexSet;
   nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Gamepad> mGamepads;
   bool mHasSeenGamepadInput;
 
   RefPtr<nsScreen> mScreen;
 
   RefPtr<mozilla::dom::BarProp> mMenubar;
   RefPtr<mozilla::dom::BarProp> mToolbar;
--- a/dom/tests/mochitest/general/test_interfaces.js
+++ b/dom/tests/mochitest/general/test_interfaces.js
@@ -1291,47 +1291,53 @@ var interfaceNamesInGlobalScope = [
   { name: "UserProximityEvent", insecureContext: true, disabled: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "ValidityState", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "VideoPlaybackQuality", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "VisualViewport", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
-  { name: "VRDisplay", releaseNonWindowsAndMac: false },
+  { name: "VRDisplay", insecureContext: true, releaseNonWindowsAndMac: false },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   {
     name: "VRDisplayCapabilities",
+    insecureContext: true,
     releaseNonWindowsAndMac: false,
   },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   {
     name: "VRDisplayEvent",
+    insecureContext: true,
     releaseNonWindowsAndMac: false,
   },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   {
     name: "VREyeParameters",
+    insecureContext: true,
     releaseNonWindowsAndMac: false,
   },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   {
     name: "VRFieldOfView",
+    insecureContext: true,
     releaseNonWindowsAndMac: false,
   },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   {
     name: "VRFrameData",
+    insecureContext: true,
     releaseNonWindowsAndMac: false,
   },
   // IMPORTANT: Do not change this list without review from a DOM peer!
-  { name: "VRPose", releaseNonWindowsAndMac: false },
+  { name: "VRPose", insecureContext: true, releaseNonWindowsAndMac: false },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   {
     name: "VRStageParameters",
+    insecureContext: true,
     releaseNonWindowsAndMac: false,
   },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "VTTCue", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "VTTRegion", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "WaveShaperNode", insecureContext: true },
deleted file mode 100644
--- a/dom/vr/XRPermissionRequest.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "XRPermissionRequest.h"
-#include "nsIGlobalObject.h"
-#include "mozilla/Preferences.h"
-#include "nsContentUtils.h"
-
-namespace mozilla {
-namespace dom {
-
-//-------------------------------------------------
-// XR Permission Requests
-//-------------------------------------------------
-
-NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(XRPermissionRequest,
-                                               ContentPermissionRequestBase)
-
-NS_IMPL_CYCLE_COLLECTION_INHERITED(XRPermissionRequest,
-                                   ContentPermissionRequestBase)
-
-XRPermissionRequest::XRPermissionRequest(nsPIDOMWindowInner* aWindow,
-                                         uint64_t aWindowId)
-    : ContentPermissionRequestBase(aWindow->GetDoc()->NodePrincipal(), aWindow,
-                                   NS_LITERAL_CSTRING("dom.vr"),
-                                   NS_LITERAL_CSTRING("xr")),
-      mWindowId(aWindowId) {
-  MOZ_ASSERT(aWindow);
-  MOZ_ASSERT(aWindow->GetDoc());
-  mPrincipal = aWindow->GetDoc()->NodePrincipal();
-  MOZ_ASSERT(mPrincipal);
-}
-
-NS_IMETHODIMP
-XRPermissionRequest::Cancel() {
-  nsGlobalWindowInner* window =
-      nsGlobalWindowInner::GetInnerWindowWithId(mWindowId);
-  if (!window) {
-    return NS_OK;
-  }
-  window->OnXRPermissionRequestCancel();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-XRPermissionRequest::Allow(JS::HandleValue aChoices) {
-  MOZ_ASSERT(aChoices.isUndefined());
-  nsGlobalWindowInner* window =
-      nsGlobalWindowInner::GetInnerWindowWithId(mWindowId);
-  if (!window) {
-    return NS_OK;
-  }
-  window->OnXRPermissionRequestAllow();
-  return NS_OK;
-}
-
-nsresult XRPermissionRequest::Start() {
-  MOZ_ASSERT(NS_IsMainThread());
-  PromptResult pr = CheckPromptPrefs();
-  if (pr == PromptResult::Granted) {
-    return Allow(JS::UndefinedHandleValue);
-  }
-  if (pr == PromptResult::Denied) {
-    return Cancel();
-  }
-
-  return nsContentPermissionUtils::AskPermission(this, mWindow);
-}
-
-}  // namespace dom
-}  // namespace mozilla
deleted file mode 100644
--- a/dom/vr/XRPermissionRequest.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_XRPermissionRequest_h_
-#define mozilla_dom_XRPermissionRequest_h_
-
-#include "mozilla/dom/Promise.h"
-#include "nsContentPermissionHelper.h"
-#include "nsISupports.h"
-
-namespace mozilla {
-namespace dom {
-
-/**
- * Handles permission dialog management when requesting XR device access.
- */
-class XRPermissionRequest final : public ContentPermissionRequestBase {
- public:
-  XRPermissionRequest(nsPIDOMWindowInner* aWindow, uint64_t aWindowId);
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XRPermissionRequest,
-                                           ContentPermissionRequestBase)
-  // nsIContentPermissionRequest
-  NS_IMETHOD Cancel(void) override;
-  NS_IMETHOD Allow(JS::HandleValue choices) override;
-  nsresult Start();
-
- private:
-  ~XRPermissionRequest() = default;
-
-  uint64_t mWindowId;
-};
-
-}  // namespace dom
-}  // namespace mozilla
-
-#endif  // mozilla_dom_XR_h_
--- a/dom/vr/moz.build
+++ b/dom/vr/moz.build
@@ -6,26 +6,24 @@
 
 with Files("**"):
     BUG_COMPONENT = ("Core", "WebVR")
 
 EXPORTS.mozilla.dom += [
     'VRDisplay.h',
     'VRDisplayEvent.h',
     'VREventObserver.h',
-    'VRServiceTest.h',
-    'XRPermissionRequest.h',
+    'VRServiceTest.h'
     ]
 
 UNIFIED_SOURCES = [
     'VRDisplay.cpp',
     'VRDisplayEvent.cpp',
     'VREventObserver.cpp',
-    'VRServiceTest.cpp',
-    'XRPermissionRequest.cpp',
+    'VRServiceTest.cpp'
     ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '/dom/base'
 ]
--- a/dom/webidl/Navigator.webidl
+++ b/dom/webidl/Navigator.webidl
@@ -208,22 +208,21 @@ partial interface Navigator {
   [Throws, Pref="dom.gamepad.enabled"]
   sequence<Gamepad?> getGamepads();
 };
 partial interface Navigator {
   [Pref="dom.gamepad.test.enabled"]
   GamepadServiceTest requestGamepadServiceTest();
 };
 
-// https://immersive-web.github.io/webvr/spec/1.1/#interface-navigator
 partial interface Navigator {
-  [Throws, SecureContext, Pref="dom.vr.enabled"]
+  [Throws, Pref="dom.vr.enabled"]
   Promise<sequence<VRDisplay>> getVRDisplays();
   // TODO: Use FrozenArray once available. (Bug 1236777)
-  [SecureContext, Frozen, Cached, Pure, Pref="dom.vr.enabled"]
+  [Frozen, Cached, Pure, Pref="dom.vr.enabled"]
   readonly attribute sequence<VRDisplay> activeVRDisplays;
   [ChromeOnly, Pref="dom.vr.enabled"]
   readonly attribute boolean isWebVRContentDetected;
   [ChromeOnly, Pref="dom.vr.enabled"]
   readonly attribute boolean isWebVRContentPresenting;
   [ChromeOnly, Pref="dom.vr.enabled"]
   void requestVRPresentation(VRDisplay display);
 };
--- a/dom/webidl/VRDisplay.webidl
+++ b/dom/webidl/VRDisplay.webidl
@@ -1,25 +1,20 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://immersive-web.github.io/webvr/spec/1.1/
- */
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 enum VREye {
   "left",
   "right"
 };
 
 [Pref="dom.vr.enabled",
  HeaderFile="mozilla/dom/VRDisplay.h",
- SecureContext,
  Exposed=Window]
 interface VRFieldOfView {
   readonly attribute double upDegrees;
   readonly attribute double rightDegrees;
   readonly attribute double downDegrees;
   readonly attribute double leftDegrees;
 };
 
@@ -51,17 +46,16 @@ dictionary VRLayer {
 };
 
 /**
  * Values describing the capabilities of a VRDisplay.
  * These are expected to be static per-device/per-user.
  */
 [Pref="dom.vr.enabled",
  HeaderFile="mozilla/dom/VRDisplay.h",
- SecureContext,
  Exposed=Window]
 interface VRDisplayCapabilities {
   /**
    * hasPosition is true if the VRDisplay is capable of tracking its position.
    */
   readonly attribute boolean hasPosition;
 
   /**
@@ -94,17 +88,16 @@ interface VRDisplayCapabilities {
 };
 
 /**
  * Values describing the the stage / play area for devices
  * that support room-scale experiences.
  */
 [Pref="dom.vr.enabled",
  HeaderFile="mozilla/dom/VRDisplay.h",
- SecureContext,
  Exposed=Window]
 interface VRStageParameters {
   /**
    * A 16-element array containing the components of a column-major 4x4
    * affine transform matrix. This matrix transforms the sitting-space position
    * returned by get{Immediate}Pose() to a standing-space position.
    */
   [Throws] readonly attribute Float32Array sittingToStandingTransform;
@@ -121,17 +114,16 @@ interface VRStageParameters {
    * this rectangle.
    */
   readonly attribute float sizeX;
   readonly attribute float sizeZ;
 };
 
 [Pref="dom.vr.enabled",
  HeaderFile="mozilla/dom/VRDisplay.h",
- SecureContext,
  Exposed=Window]
 interface VRPose
 {
   /**
    * position, linearVelocity, and linearAcceleration are 3-component vectors.
    * position is relative to a sitting space. Transforming this point with
    * VRStageParameters.sittingToStandingTransform converts this to standing space.
    */
@@ -143,17 +135,16 @@ interface VRPose
   [Constant, Throws] readonly attribute Float32Array? orientation;
   /* angularVelocity and angularAcceleration are the components of 3-dimensional vectors. */
   [Constant, Throws] readonly attribute Float32Array? angularVelocity;
   [Constant, Throws] readonly attribute Float32Array? angularAcceleration;
 };
 
 [Pref="dom.vr.enabled",
  HeaderFile="mozilla/dom/VRDisplay.h",
- SecureContext,
  Exposed=Window]
 interface VRFrameData {
   constructor();
 
   readonly attribute DOMHighResTimeStamp timestamp;
 
   [Throws, Pure] readonly attribute Float32Array leftProjectionMatrix;
   [Throws, Pure] readonly attribute Float32Array leftViewMatrix;
@@ -161,17 +152,16 @@ interface VRFrameData {
   [Throws, Pure] readonly attribute Float32Array rightProjectionMatrix;
   [Throws, Pure] readonly attribute Float32Array rightViewMatrix;
 
   [Pure] readonly attribute VRPose pose;
 };
 
 [Pref="dom.vr.enabled",
  HeaderFile="mozilla/dom/VRDisplay.h",
- SecureContext,
  Exposed=Window]
 interface VREyeParameters {
   /**
    * offset is a 3-component vector representing an offset to
    * translate the eye. This value may vary from frame
    * to frame if the user adjusts their headset ipd.
    */
   [Constant, Throws] readonly attribute Float32Array offset;
@@ -186,17 +176,16 @@ interface VREyeParameters {
    * enough to fit both viewports.
    */
   [Constant] readonly attribute unsigned long renderWidth;
   [Constant] readonly attribute unsigned long renderHeight;
 };
 
 [Pref="dom.vr.enabled",
  HeaderFile="mozilla/dom/VRDisplay.h",
- SecureContext,
  Exposed=Window]
 interface VRDisplay : EventTarget {
   /**
    * presentingGroups is a bitmask indicating which VR session groups
    * have an active VR presentation.
    */
   [ChromeOnly] readonly attribute unsigned long presentingGroups;
   /**
--- a/testing/web-platform/meta/webvr/__dir__.ini
+++ b/testing/web-platform/meta/webvr/__dir__.ini
@@ -1,3 +1,1 @@
-prefs: [dom.vr.enabled:true,
-          dom.vr.prompt.testing:true, dom.vr.prompt.testing.allow:true, dom.security.featurePolicy.experimental.enabled:true,
-          dom.security.featurePolicy.enabled:true, dom.security.featurePolicy.header.enabled:true, dom.security.featurePolicy.webidl.enabled:true]
+prefs: [dom.vr.enabled:true, dom.security.featurePolicy.enabled:true, dom.security.featurePolicy.experimental.enabled:true, dom.security.featurePolicy.header.enabled:true, dom.security.featurePolicy.webidl.enabled:true]
--- a/toolkit/components/telemetry/Events.yaml
+++ b/toolkit/components/telemetry/Events.yaml
@@ -1780,17 +1780,16 @@ security:
 # This data collection is intended for study-only collection
 # and is not meant to be enabled permanently on opt-in or opt-out.
 # It is controlled by the permissions.eventTelemetry.enabled pref.
 security.ui.permissionprompt:
   show:
     objects: [
       "notifications",
       "geo",
-      "xr",
     ]
     bug_numbers:
       - 1536454
       - 1578266
     description: >
       When a permission prompt was shown.
     expiry_version: "74"
     notification_emails: