Bug 1330467 - part 11. Use principal for permissions in webrtc UI; r=johannh
authorLiang-Heng Chen <xeonchen@gmail.com>
Wed, 08 May 2019 15:28:01 +0000
changeset 532218 2f2308fe574799b90705b7f55c402b9dd578369d
parent 532217 2cd09bae2bdf579412d83e7a5c11381de18f9e48
child 532219 0229d5353d503441ed11643c8e5e4e90011261b8
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjohannh
bugs1330467
milestone68.0a1
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
Bug 1330467 - part 11. Use principal for permissions in webrtc UI; r=johannh Differential Revision: https://phabricator.services.mozilla.com/D19932
browser/modules/webrtcUI.jsm
--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -403,30 +403,24 @@ function stopRecording(aBrowser, aReques
     set.delete(aRequest.windowID + aRequest.mediaSource + aRequest.rawID);
   }
 }
 
 function prompt(aBrowser, aRequest) {
   let { audioDevices, videoDevices, sharingScreen, sharingAudio,
         requestTypes } = aRequest;
 
-  let uri;
-  try {
-    // This fails for principals that serialize to "null", e.g. file URIs.
-    uri = Services.io.newURI(aRequest.origin);
-  } catch (e) {
-    uri = Services.io.newURI(aRequest.documentURI);
-  }
+  let principal = aBrowser.contentPrincipal;
 
   // If the user has already denied access once in this tab,
   // deny again without even showing the notification icon.
   if ((audioDevices.length && SitePermissions
-        .get(uri, "microphone", aBrowser).state == SitePermissions.BLOCK) ||
+        .getForPrincipal(principal, "microphone", aBrowser).state == SitePermissions.BLOCK) ||
       (videoDevices.length && SitePermissions
-        .get(uri, sharingScreen ? "screen" : "camera", aBrowser).state == SitePermissions.BLOCK)) {
+        .getForPrincipal(principal, sharingScreen ? "screen" : "camera", aBrowser).state == SitePermissions.BLOCK)) {
     denyRequest(aBrowser, aRequest);
     return;
   }
 
   // Tell the browser to refresh the identity block display in case there
   // are expired permission states.
   aBrowser.dispatchEvent(new aBrowser.ownerGlobal
                                      .CustomEvent("PermissionStateChange"));
@@ -469,29 +463,29 @@ function prompt(aBrowser, aRequest) {
       accessKey: stringBundle.getString("getUserMedia.dontAllow.accesskey"),
       callback(aState) {
         denyRequest(notification.browser, aRequest);
         let scope = SitePermissions.SCOPE_TEMPORARY;
         if (aState && aState.checkboxChecked) {
           scope = SitePermissions.SCOPE_PERSISTENT;
         }
         if (audioDevices.length)
-          SitePermissions.set(uri, "microphone",
-                              SitePermissions.BLOCK, scope, notification.browser);
+          SitePermissions.setForPrincipal(principal, "microphone",
+                                          SitePermissions.BLOCK, scope, notification.browser);
         if (videoDevices.length)
-          SitePermissions.set(uri, sharingScreen ? "screen" : "camera",
-                              SitePermissions.BLOCK, scope, notification.browser);
+          SitePermissions.setForPrincipal(principal, sharingScreen ? "screen" : "camera",
+                                          SitePermissions.BLOCK, scope, notification.browser);
       },
     },
   ];
 
   let productName = gBrandBundle.GetStringFromName("brandShortName");
 
   let options = {
-    name: getHostOrExtensionName(uri),
+    name: getHostOrExtensionName(principal.URI),
     persistent: true,
     hideClose: true,
     eventCallback(aTopic, aNewBrowser) {
       if (aTopic == "swapping")
         return true;
 
       let doc = this.browser.ownerDocument;
 
@@ -517,25 +511,25 @@ function prompt(aBrowser, aRequest) {
 
       // BLOCK is handled immediately by MediaManager if it has been set
       // persistently in the permission manager. If it has been set on the tab,
       // it is handled synchronously before we add the notification.
       // Handling of ALLOW is delayed until the popupshowing event,
       // to avoid granting permissions automatically to background tabs.
       if (aRequest.secure) {
         let micAllowed =
-          SitePermissions.get(uri, "microphone").state == SitePermissions.ALLOW;
+          SitePermissions.getForPrincipal(principal, "microphone").state == SitePermissions.ALLOW;
         let camAllowed =
-          SitePermissions.get(uri, "camera").state == SitePermissions.ALLOW;
+          SitePermissions.getForPrincipal(principal, "camera").state == SitePermissions.ALLOW;
 
         let perms = Services.perms;
         let mediaManagerPerm =
-          perms.testExactPermission(uri, "MediaManagerVideo");
+          perms.testExactPermissionFromPrincipal(principal, "MediaManagerVideo");
         if (mediaManagerPerm) {
-          perms.remove(uri, "MediaManagerVideo");
+          perms.removeFromPrincipal(principal, "MediaManagerVideo");
         }
 
         // Screen sharing shouldn't follow the camera permissions.
         if (videoDevices.length && sharingScreen)
           camAllowed = false;
 
         let activeCamera;
         let activeMic;
@@ -559,31 +553,31 @@ function prompt(aBrowser, aRequest) {
           }
         }
 
         if ((!audioDevices.length || micAllowed || activeMic) &&
             (!videoDevices.length || camAllowed || activeCamera)) {
           let allowedDevices = [];
           if (videoDevices.length) {
             allowedDevices.push((activeCamera || videoDevices[0]).deviceIndex);
-            Services.perms.add(uri, "MediaManagerVideo",
-                               Services.perms.ALLOW_ACTION,
-                               Services.perms.EXPIRE_SESSION);
+            Services.perms.addFromPrincipal(principal, "MediaManagerVideo",
+                                            Services.perms.ALLOW_ACTION,
+                                            Services.perms.EXPIRE_SESSION);
           }
           if (audioDevices.length) {
             allowedDevices.push((activeMic || audioDevices[0]).deviceIndex);
           }
 
           // Remember on which URIs we found persistent permissions so that we
           // can remove them if the user clicks 'Stop Sharing'. There's no
           // other way for the stop sharing code to know the hostnames of frames
           // using devices until bug 1066082 is fixed.
           let browser = this.browser;
-          browser._devicePermissionURIs = browser._devicePermissionURIs || [];
-          browser._devicePermissionURIs.push(uri);
+          browser._devicePermissionPrincipals = browser._devicePermissionPrincipals || [];
+          browser._devicePermissionPrincipals.push(principal);
 
           let camNeeded = videoDevices.length > 0;
           let micNeeded = audioDevices.length > 0;
           checkOSPermission(camNeeded, micNeeded).then((havePermission) => {
             if (havePermission) {
               let mm = browser.messageManager;
               mm.sendAsyncMessage("webrtc:Allow", {callID: aRequest.callID,
                                                    windowID: aRequest.windowID,
@@ -734,19 +728,19 @@ function prompt(aBrowser, aRequest) {
 
             let [pre, post] = string.split("<>");
             warning.textContent = pre;
             warning.appendChild(learnMore);
             warning.appendChild(chromeWin.document.createTextNode(post));
           }
 
           let perms = Services.perms;
-          let chromeUri = Services.io.newURI(doc.documentURI);
-          perms.add(chromeUri, "MediaManagerVideo", perms.ALLOW_ACTION,
-                    perms.EXPIRE_SESSION);
+          let chromePrincipal = Services.scriptSecurityManager.getSystemPrincipal();
+          perms.addFromPrincipal(chromePrincipal, "MediaManagerVideo", perms.ALLOW_ACTION,
+                                 perms.EXPIRE_SESSION);
 
           video.deviceId = deviceId;
           let constraints = { video: { mediaSource: type, deviceId: {exact: deviceId } } };
           chromeWin.navigator.mediaDevices.getUserMedia(constraints).then(stream => {
             if (video.deviceId != deviceId) {
               // The user has selected a different device or closed the panel
               // before getUserMedia finished.
               stream.getTracks().forEach(t => t.stop());
@@ -811,31 +805,31 @@ function prompt(aBrowser, aRequest) {
         if (videoDevices.length) {
           let listId = "webRTC-select" + (sharingScreen ? "Window" : "Camera") + "-menulist";
           let videoDeviceIndex = doc.getElementById(listId).value;
           let allowVideoDevice = videoDeviceIndex != "-1";
           if (allowVideoDevice) {
             allowedDevices.push(videoDeviceIndex);
             // Session permission will be removed after use
             // (it's really one-shot, not for the entire session)
-            perms.add(uri, "MediaManagerVideo", perms.ALLOW_ACTION,
-                      perms.EXPIRE_SESSION);
+            perms.addFromPrincipal(principal, "MediaManagerVideo", perms.ALLOW_ACTION,
+                                   perms.EXPIRE_SESSION);
             if (!webrtcUI.activePerms.has(aBrowser.outerWindowID)) {
               webrtcUI.activePerms.set(aBrowser.outerWindowID, new Set());
             }
 
             for (let device of videoDevices) {
               if (device.deviceIndex == videoDeviceIndex) {
                 webrtcUI.activePerms.get(aBrowser.outerWindowID)
                         .add(aRequest.windowID + device.mediaSource + device.id);
                 break;
               }
             }
             if (remember)
-              SitePermissions.set(uri, "camera", SitePermissions.ALLOW);
+              SitePermissions.setForPrincipal(principal, "camera", SitePermissions.ALLOW);
           }
         }
         if (audioDevices.length) {
           if (!sharingAudio) {
             let audioDeviceIndex = doc.getElementById("webRTC-selectMicrophone-menulist").value;
             let allowMic = audioDeviceIndex != "-1";
             if (allowMic) {
               allowedDevices.push(audioDeviceIndex);
@@ -846,34 +840,34 @@ function prompt(aBrowser, aRequest) {
               for (let device of audioDevices) {
                 if (device.deviceIndex == audioDeviceIndex) {
                   webrtcUI.activePerms.get(aBrowser.outerWindowID)
                           .add(aRequest.windowID + device.mediaSource + device.id);
                   break;
                 }
               }
               if (remember)
-                SitePermissions.set(uri, "microphone", SitePermissions.ALLOW);
+                SitePermissions.setForPrincipal(principal, "microphone", SitePermissions.ALLOW);
             }
           } else {
             // Only one device possible for audio capture.
             allowedDevices.push(0);
           }
         }
 
         if (!allowedDevices.length) {
           denyRequest(notification.browser, aRequest);
           return;
         }
 
         if (remember) {
           // Remember on which URIs we set persistent permissions so that we
           // can remove them if the user clicks 'Stop Sharing'.
-          aBrowser._devicePermissionURIs = aBrowser._devicePermissionURIs || [];
-          aBrowser._devicePermissionURIs.push(uri);
+          aBrowser._devicePermissionPrincipals = aBrowser._devicePermissionPrincipals || [];
+          aBrowser._devicePermissionPrincipals.push(principal);
         }
 
         let camNeeded = videoDevices.length > 0;
         let micNeeded = audioDevices.length > 0;
         let havePermission = await checkOSPermission(camNeeded, micNeeded);
         if (!havePermission) {
           denyRequestNoPermission(notification.browser, aRequest);
           return;