Bug 1257950 - getUserMedia switched from SecurityError to NotAllowedError. draft
authorJan-Ivar Bruaroey <jib@mozilla.com>
Sun, 08 May 2016 22:29:46 -0400
changeset 365512 a4d4707128d36e402489b75dd315b3580ba8767d
parent 365500 0540b872ce87ee5655cca5008b00d06b0828f087
child 520583 9f7c814714a3b21a33af02ffae2622034c29fff6
push id17771
push userjbruaroey@mozilla.com
push dateTue, 10 May 2016 23:38:34 +0000
bugs1257950
milestone49.0a1
Bug 1257950 - getUserMedia switched from SecurityError to NotAllowedError. MozReview-Commit-ID: Di8fDDFkpwX
browser/base/content/test/general/browser_devices_get_user_media.js
browser/base/content/test/general/browser_devices_get_user_media_about_urls.js
dom/media/MediaManager.cpp
dom/media/MediaStreamError.cpp
dom/media/PeerConnection.js
dom/media/tests/mochitest/test_getUserMedia_basicScreenshare.html
dom/media/tests/mochitest/test_getUserMedia_constraints.html
--- a/browser/base/content/test/general/browser_devices_get_user_media.js
+++ b/browser/base/content/test/general/browser_devices_get_user_media.js
@@ -9,17 +9,18 @@ Cc["@mozilla.org/moz/jssubscript-loader;
   .getService(Ci.mozIJSSubScriptLoader)
   .loadSubScript(getRootDirectory(gTestPath) + "get_user_media_helpers.js",
                  this);
 
 registerCleanupFunction(function() {
   gBrowser.removeCurrentTab();
 });
 
-const permissionError = "error: SecurityError: The operation is insecure.";
+const permissionError = "error: NotAllowedError: The request is not allowed " +
+    "by the user agent or the platform in the current context.";
 
 var gTests = [
 
 {
   desc: "getUserMedia audio+video",
   run: function checkAudioVideo() {
     let promise = promisePopupNotificationShown("webRTC-shareDevices");
     yield promiseRequestDevice(true, true);
--- a/browser/base/content/test/general/browser_devices_get_user_media_about_urls.js
+++ b/browser/base/content/test/general/browser_devices_get_user_media_about_urls.js
@@ -57,17 +57,18 @@ function loadPage(aUrl) {
   content.location = aUrl;
   return deferred.promise;
 }
 
 registerCleanupFunction(function() {
   gBrowser.removeCurrentTab();
 });
 
-const permissionError = "error: SecurityError: The operation is insecure.";
+const permissionError = "error: NotAllowedError: The request is not allowed " +
+    "by the user agent or the platform in the current context.";
 
 var gTests = [
 
 {
   desc: "getUserMedia about:loopconversation shouldn't prompt",
   run: function checkAudioVideoLoop() {
     yield new Promise(resolve => SpecialPowers.pushPrefEnv({
       "set": [[PREF_LOOP_CSP, "default-src 'unsafe-inline'"]],
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1898,17 +1898,17 @@ MediaManager::GetUserMedia(nsPIDOMWindow
               !IsVistaOrLater()
 #endif
               ) ||
 #endif
             (!privileged && !HostIsHttps(*docURI)) ||
             !(loop || HostHasPermission(*docURI))) {
           RefPtr<MediaStreamError> error =
               new MediaStreamError(aWindow,
-                                   NS_LITERAL_STRING("SecurityError"));
+                                   NS_LITERAL_STRING("NotAllowedError"));
           onFailure->OnError(error);
           return NS_OK;
         }
         break;
 
       case MediaSourceEnum::Microphone:
       case MediaSourceEnum::Other:
       default: {
@@ -1979,17 +1979,17 @@ MediaManager::GetUserMedia(nsPIDOMWindow
         break;
 
       case MediaSourceEnum::AudioCapture:
         // Only enable AudioCapture if the pref is enabled. If it's not, we can
         // deny right away.
         if (!Preferences::GetBool("media.getusermedia.audiocapture.enabled")) {
           RefPtr<MediaStreamError> error =
             new MediaStreamError(aWindow,
-                                 NS_LITERAL_STRING("SecurityError"));
+                                 NS_LITERAL_STRING("NotAllowedError"));
           onFailure->OnError(error);
           return NS_OK;
         }
         break;
 
       case MediaSourceEnum::Other:
       default: {
         RefPtr<MediaStreamError> error =
@@ -2045,17 +2045,17 @@ MediaManager::GetUserMedia(nsPIDOMWindow
         principal, "camera", &videoPerm);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     if ((!IsOn(c.mAudio) && !IsOn(c.mVideo)) ||
         (IsOn(c.mAudio) && audioPerm == nsIPermissionManager::DENY_ACTION) ||
         (IsOn(c.mVideo) && videoPerm == nsIPermissionManager::DENY_ACTION)) {
       RefPtr<MediaStreamError> error =
-          new MediaStreamError(aWindow, NS_LITERAL_STRING("SecurityError"));
+          new MediaStreamError(aWindow, NS_LITERAL_STRING("NotAllowedError"));
       onFailure->OnError(error);
       RemoveFromWindowList(windowID, listener);
       return NS_OK;
     }
   }
 
 #if defined(MOZ_B2G_CAMERA) && defined(MOZ_WIDGET_GONK)
   if (mCameraManager == nullptr) {
@@ -2756,30 +2756,30 @@ MediaManager::Observe(nsISupports* aSubj
           }
         }
       }
       bool needVideo = IsOn(task->GetConstraints().mVideo);
       bool needAudio = IsOn(task->GetConstraints().mAudio);
       MOZ_ASSERT(needVideo || needAudio);
 
       if ((needVideo && !videoFound) || (needAudio && !audioFound)) {
-        task->Denied(NS_LITERAL_STRING("SecurityError"));
+        task->Denied(NS_LITERAL_STRING("NotAllowedError"));
         return NS_OK;
       }
     }
 
     if (sInShutdown) {
       return task->Denied(NS_LITERAL_STRING("In shutdown"));
     }
     // Reuse the same thread to save memory.
     MediaManager::PostTask(task.forget());
     return NS_OK;
 
   } else if (!strcmp(aTopic, "getUserMedia:response:deny")) {
-    nsString errorMessage(NS_LITERAL_STRING("SecurityError"));
+    nsString errorMessage(NS_LITERAL_STRING("NotAllowedError"));
 
     if (aSubject) {
       nsCOMPtr<nsISupportsString> msg(do_QueryInterface(aSubject));
       MOZ_ASSERT(msg);
       msg->GetData(errorMessage);
       if (errorMessage.IsEmpty())
         errorMessage.AssignLiteral(MOZ_UTF16("InternalError"));
     }
--- a/dom/media/MediaStreamError.cpp
+++ b/dom/media/MediaStreamError.cpp
@@ -15,16 +15,19 @@ BaseMediaMgrError::BaseMediaMgrError(con
                                      const nsAString& aConstraint)
   : mName(aName)
   , mMessage(aMessage)
   , mConstraint(aConstraint)
 {
   if (mMessage.IsEmpty()) {
     if (mName.EqualsLiteral("NotFoundError")) {
       mMessage.AssignLiteral("The object can not be found here.");
+    } else if (mName.EqualsLiteral("NotAllowedError")) {
+      mMessage.AssignLiteral("The request is not allowed by the user agent "
+                             "or the platform in the current context.");
     } else if (mName.EqualsLiteral("SecurityError")) {
       mMessage.AssignLiteral("The operation is insecure.");
     } else if (mName.EqualsLiteral("SourceUnavailableError")) {
       mMessage.AssignLiteral("The source of the MediaStream could not be "
           "accessed due to a hardware error (e.g. lock from another process).");
     } else if (mName.EqualsLiteral("InternalError")) {
       mMessage.AssignLiteral("Internal error.");
     } else if (mName.EqualsLiteral("NotSupportedError")) {
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -210,18 +210,19 @@ GlobalPCList.prototype = {
       }
     } else if (topic == "PeerConnection:response:allow" ||
                topic == "PeerConnection:response:deny") {
       var pc = this.findPC(data);
       if (pc) {
         if (topic == "PeerConnection:response:allow") {
           pc._settlePermission.allow();
         } else {
-          let err = new pc._win.DOMException("The operation is insecure.",
-                                             "SecurityError");
+          let err = new pc._win.DOMException("The request is not allowed by " +
+              "the user agent or the platform in the current context.",
+              "NotAllowedError");
           pc._settlePermission.deny(err);
         }
       }
     }
   },
 
   _registerPeerConnectionLifecycleCallback: function(winID, cb) {
     this._lifecycleobservers[winID] = cb;
--- a/dom/media/tests/mochitest/test_getUserMedia_basicScreenshare.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_basicScreenshare.html
@@ -61,17 +61,17 @@
           max: '10'
         }
       }
     ];
     return Promise.resolve()
       .then(() => pushPrefs(["media.getusermedia.screensharing.allowed_domains",
                              "mozilla.github.io,*.bugzilla.mozilla.org"]))
       .then(() => mustFailWith("Screensharing if absent in allowed_domains",
-                               "SecurityError",
+                               "NotAllowedError",
                                () => navigator.mediaDevices.getUserMedia({
                                  video: videoConstraints[0], fake: false
                                })))
       .then(() => pushPrefs(["media.getusermedia.screensharing.allowed_domains",
                              "mozilla.github.io,mochi.test,*.bugzilla.mozilla.org"]))
       .then(() => getUserMedia(constraints).then(stream => {
         var playback = new LocalMediaStreamPlayback(testVideo, stream);
         return playback.playMediaWithDeprecatedStreamStop(false);
--- a/dom/media/tests/mochitest/test_getUserMedia_constraints.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_constraints.html
@@ -21,26 +21,26 @@ var tests = [
   { message: "unknown required constraint on audio ignored",
     constraints: { audio: { somethingUnknown: { exact: 0 } } },
     error: null },
   { message: "audio overconstrained by facingMode ignored",
     constraints: { audio: { facingMode: { exact: 'left' } } },
     error: null },
   { message: "full screensharing requires permission",
     constraints: { video: { mediaSource: 'screen' } },
-    error: "SecurityError" },
+    error: "NotAllowedError" },
   { message: "application screensharing requires permission",
     constraints: { video: { mediaSource: 'application' } },
-    error: "SecurityError" },
+    error: "NotAllowedError" },
   { message: "window screensharing requires permission",
     constraints: { video: { mediaSource: 'window' } },
-    error: "SecurityError" },
+    error: "NotAllowedError" },
   { message: "browser screensharing requires permission",
     constraints: { video: { mediaSource: 'browser' } },
-    error: "SecurityError" },
+    error: "NotAllowedError" },
   { message: "unknown mediaSource in video fails",
     constraints: { video: { mediaSource: 'uncle' } },
     error: "OverconstrainedError",
     constraint: "mediaSource" },
   { message: "unknown mediaSource in audio fails",
     constraints: { audio: { mediaSource: 'uncle' } },
     error: "OverconstrainedError",
     constraint: "mediaSource" },