Bug 1216535 - WebrtcUI: Request runtime permissions if needed. r?nalexander draft
authorSebastian Kaspari <s.kaspari@gmail.com>
Mon, 11 Jan 2016 13:20:40 +0100
changeset 320487 c591777794215aef8d46bf390732d076bd0fb5cd
parent 320484 b7e9ae821a81f24178d79c63a0ee38ef1abf9283
child 512748 fab0ac180d5d8e9712cc38741efce24cc8d69f32
push id9209
push users.kaspari@gmail.com
push dateMon, 11 Jan 2016 14:42:22 +0000
reviewersnalexander
bugs1216535
milestone46.0a1
Bug 1216535 - WebrtcUI: Request runtime permissions if needed. r?nalexander
mobile/android/chrome/content/WebrtcUI.js
--- a/mobile/android/chrome/content/WebrtcUI.js
+++ b/mobile/android/chrome/content/WebrtcUI.js
@@ -2,16 +2,17 @@
  * 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/. */
 "use strict";
 
 this.EXPORTED_SYMBOLS = ["WebrtcUI"];
 
 XPCOMUtils.defineLazyModuleGetter(this, "Notifications", "resource://gre/modules/Notifications.jsm");
 XPCOMUtils.defineLazyServiceGetter(this, "ParentalControls", "@mozilla.org/parental-controls-service;1", "nsIParentalControlsService");
+XPCOMUtils.defineLazyModuleGetter(this, "RuntimePermissions", "resource://gre/modules/RuntimePermissions.jsm");
 
 var WebrtcUI = {
   _notificationId: null,
 
   // Add-ons can override stock permission behavior by doing:
   //
   //   var stockObserve = WebrtcUI.observe;
   //
@@ -23,17 +24,24 @@ var WebrtcUI = {
   //      ...
   //      default:
   //        return stockObserve.call(this, aSubject, aTopic, aData);
   //
   // See browser/modules/webrtcUI.jsm for details.
 
   observe: function(aSubject, aTopic, aData) {
     if (aTopic === "getUserMedia:request") {
-      this.handleGumRequest(aSubject, aTopic, aData);
+      RuntimePermissions
+        .waitForPermissions(this._determineNeededRuntimePermissions(aSubject))
+        .then((permissionGranted) => {
+          if (permissionGranted) {
+            WebrtcUI.handleGumRequest(aSubject, aTopic, aData);
+          } else {
+            Services.obs.notifyObservers(null, "getUserMedia:response:deny", aSubject.callID);
+          }});
     } else if (aTopic === "PeerConnection:request") {
       this.handlePCRequest(aSubject, aTopic, aData);
     } else if (aTopic === "recording-device-events") {
       switch (aData) {
         case "shutdown":
         case "starting":
           this.notify();
           break;
@@ -149,16 +157,30 @@ var WebrtcUI = {
           allowedDevices.AppendElement(videoDevices[videoId]);
 
         Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow", aCallID);
       },
       positive: true
     }];
   },
 
+  _determineNeededRuntimePermissions: function(aSubject) {
+    let permissions = [];
+
+    let constraints = aSubject.getConstraints();
+    if (constraints.video) {
+      permissions.push(RuntimePermissions.CAMERA);
+    }
+    if (constraints.audio) {
+      permissions.push(RuntimePermissions.RECORD_AUDIO);
+    }
+
+    return permissions;
+  },
+
   // Get a list of string names for devices. Ensures that none of the strings are blank
   _getList: function(aDevices, aType) {
     let defaultCount = 0;
     return aDevices.map(function(device) {
         // if this is a Camera input, convert the name to something readable
         let res = /Camera\ \d+,\ Facing (front|back)/.exec(device.name);
         if (res)
           return Strings.browser.GetStringFromName("getUserMedia." + aType + "." + res[1] + "Camera");