Bug 802326 - make getUserMedia fail audio+video request unless user shares both. r=jesup
authorJan-Ivar Bruaroey <jib@mozilla.com>
Thu, 05 May 2016 21:54:04 -0400
changeset 297396 2189a25ea1c654c72b61b6a5fd70af00a847a9ad
parent 297395 4ad6216b24475500b359a3f569542e52081bb855
child 297397 079cacde7af02a972136e9c4e38475c9e434441b
push id19218
push userkwierso@gmail.com
push dateFri, 13 May 2016 23:46:15 +0000
treeherderfx-team@93d60e9db618 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs802326
milestone49.0a1
Bug 802326 - make getUserMedia fail audio+video request unless user shares both. r=jesup MozReview-Commit-ID: GG9ZkEe5Eao
dom/media/MediaManager.cpp
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1262,16 +1262,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;
   }
 
@@ -2034,18 +2040,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;
     }
   }
 
@@ -2719,21 +2726,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;
@@ -2748,16 +2750,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;