Bug 802326 - make getUserMedia fail audio+video request unless user shares both. draft
authorJan-Ivar Bruaroey <jib@mozilla.com>
Thu, 05 May 2016 21:54:04 -0400
changeset 364628 b93caceabff632b108291f048f75642632f14d75
parent 364177 94ee40b75b0c69147f7ee54f2ee78e3075de6786
child 364629 8caf92d0d0eafb7d3646f300f36dc36ed0300b23
child 365498 8c0a5dbdbc32bfdbfe0fac9b3b3dfb266c0f7f3a
push id17507
push userjbruaroey@mozilla.com
push dateSat, 07 May 2016 01:37:14 +0000
bugs802326
milestone49.0a1
Bug 802326 - make getUserMedia fail audio+video request unless user shares both. MozReview-Commit-ID: GG9ZkEe5Eao
dom/media/MediaManager.cpp
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1263,16 +1263,22 @@ public:
 
   nsresult
   SetContraints(const MediaStreamConstraints& aConstraints)
   {
     mConstraints = aConstraints;
     return NS_OK;
   }
 
+  const MediaStreamConstraints&
+  GetConstraints()
+  {
+    return mConstraints;
+  }
+
   nsresult
   SetAudioDevice(AudioDevice* aAudioDevice)
   {
     mAudioDevice = aAudioDevice;
     mDeviceChosen = true;
     return NS_OK;
   }
 
@@ -2035,18 +2041,19 @@ MediaManager::GetUserMedia(nsPIDOMWindow
 
     uint32_t videoPerm = nsIPermissionManager::UNKNOWN_ACTION;
     if (IsOn(c.mVideo)) {
       rv = permManager->TestExactPermissionFromPrincipal(
         principal, "camera", &videoPerm);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
-    if ((!IsOn(c.mAudio) || audioPerm == nsIPermissionManager::DENY_ACTION) &&
-        (!IsOn(c.mVideo) || videoPerm == nsIPermissionManager::DENY_ACTION)) {
+    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"));
       onFailure->OnError(error);
       RemoveFromWindowList(windowID, listener);
       return NS_OK;
     }
   }
 
@@ -2720,21 +2727,16 @@ MediaManager::Observe(nsISupports* aSubj
 
     if (aSubject) {
       // A particular device or devices were chosen by the user.
       // NOTE: does not allow setting a device to null; assumes nullptr
       nsCOMPtr<nsISupportsArray> array(do_QueryInterface(aSubject));
       MOZ_ASSERT(array);
       uint32_t len = 0;
       array->Count(&len);
-      if (!len) {
-        // neither audio nor video were selected
-        task->Denied(NS_LITERAL_STRING("SecurityError"));
-        return NS_OK;
-      }
       bool videoFound = false, audioFound = false;
       for (uint32_t i = 0; i < len; i++) {
         nsCOMPtr<nsISupports> supports;
         array->GetElementAt(i,getter_AddRefs(supports));
         nsCOMPtr<nsIMediaDevice> device(do_QueryInterface(supports));
         MOZ_ASSERT(device); // shouldn't be returning anything else...
         if (device) {
           nsString type;
@@ -2749,16 +2751,24 @@ MediaManager::Observe(nsISupports* aSubj
               task->SetAudioDevice(static_cast<AudioDevice*>(device.get()));
               audioFound = true;
             }
           } else {
             NS_WARNING("Unknown device type in getUserMedia");
           }
         }
       }
+      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"));
+        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;