Bug 1156472 - Part 11 - Unbitrot MediaManager.cpp over jib's changes. r=jib
authorPaul Adenot <paul@paul.cx>
Fri, 24 Jul 2015 14:28:17 +0200
changeset 254778 a34909cbfb37fa90f9fec51650a5865ce920a291
parent 254777 092dcf4d57f208d1703f8afd91c7154acb43b6d7
child 254779 4c62be998cb40ab77296993113b181ace7374b9f
push id16720
push userryanvm@gmail.com
push dateMon, 27 Jul 2015 19:45:38 +0000
treeherderb2g-inbound@13354b414396 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjib
bugs1156472
milestone42.0a1
Bug 1156472 - Part 11 - Unbitrot MediaManager.cpp over jib's changes. r=jib
dom/media/MediaManager.cpp
dom/media/MediaManager.h
dom/media/webrtc/MediaEngineWebRTCAudio.cpp
modules/libpref/init/all.js
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1252,17 +1252,19 @@ static auto& MediaManager_ToJSArray = Me
 static auto& MediaManager_AnonymizeDevices = MediaManager::AnonymizeDevices;
 
 /**
  * EnumerateRawDevices - Enumerate a list of audio & video devices that
  * satisfy passed-in constraints. List contains raw id's.
  */
 
 already_AddRefed<MediaManager::PledgeSourceSet>
-MediaManager::EnumerateRawDevices(uint64_t aWindowId, MediaSourceEnum aVideoType,
+MediaManager::EnumerateRawDevices(uint64_t aWindowId,
+                                  MediaSourceEnum aVideoType,
+                                  MediaSourceEnum aAudioType,
                                   bool aFake, bool aFakeTracks)
 {
   MOZ_ASSERT(NS_IsMainThread());
   nsRefPtr<PledgeSourceSet> p = new PledgeSourceSet();
   uint32_t id = mOutstandingPledges.Append(*p);
 
   // Check if the preference for using audio/video loopback devices is
   // enabled. This is currently used for automated media tests only.
@@ -1282,17 +1284,18 @@ MediaManager::EnumerateRawDevices(uint64
       }
     } else {
       aFake = false;
     }
   }
 
   MediaManager::PostTask(FROM_HERE, NewTaskFrom([id, aWindowId, audioLoopDev,
                                                  videoLoopDev, aVideoType,
-                                                 aFake, aFakeTracks]() mutable {
+                                                 aAudioType, aFake,
+                                                 aFakeTracks]() mutable {
     nsRefPtr<MediaEngine> backend;
     if (aFake) {
       backend = new MediaEngineDefault(aFakeTracks);
     } else {
       nsRefPtr<MediaManager> manager = MediaManager_GetInstance();
       backend = manager->GetBackend(aWindowId);
     }
 
@@ -1301,17 +1304,17 @@ MediaManager::EnumerateRawDevices(uint64
     nsTArray<nsRefPtr<VideoDevice>> videos;
     GetSources(backend, aVideoType, &MediaEngine::EnumerateVideoDevices, videos,
                videoLoopDev);
     for (auto& source : videos) {
       result->AppendElement(source);
     }
 
     nsTArray<nsRefPtr<AudioDevice>> audios;
-    GetSources(backend, dom::MediaSourceEnum::Microphone,
+    GetSources(backend, aAudioType,
                &MediaEngine::EnumerateAudioDevices, audios, audioLoopDev);
     for (auto& source : audios) {
       result->AppendElement(source);
     }
 
     SourceSet* handoff = result.forget();
     NS_DispatchToMainThread(do_AddRef(NewRunnableFrom([id, handoff]() mutable {
       ScopedDeletePtr<SourceSet> result(handoff); // grab result
@@ -1623,16 +1626,17 @@ MediaManager::GetUserMedia(nsPIDOMWindow
     return rv;
   }
 
   if (!Preferences::GetBool("media.navigator.video.enabled", true)) {
     c.mVideo.SetAsBoolean() = false;
   }
 
   MediaSourceEnum videoType = dom::MediaSourceEnum::Camera;
+  MediaSourceEnum audioType = dom::MediaSourceEnum::Microphone;
 
   if (c.mVideo.IsMediaTrackConstraints()) {
     auto& vc = c.mVideo.GetAsMediaTrackConstraints();
     videoType = StringToEnum(dom::MediaSourceEnumValues::strings,
                              vc.mMediaSource,
                              videoType);
     switch (videoType) {
       case dom::MediaSourceEnum::Camera:
@@ -1711,16 +1715,33 @@ MediaManager::GetUserMedia(nsPIDOMWindow
     // Loop has implicit permissions within Firefox, as it is built-in,
     // and will manage the active tab and provide appropriate UI.
     if (loop && (videoType == dom::MediaSourceEnum::Window ||
                  videoType == dom::MediaSourceEnum::Application ||
                  videoType == dom::MediaSourceEnum::Screen)) {
        privileged = false;
     }
   }
+
+  if (c.mAudio.IsMediaTrackConstraints()) {
+    auto& ac = c.mAudio.GetAsMediaTrackConstraints();
+    audioType = StringToEnum(dom::MediaSourceEnumValues::strings,
+                             ac.mMediaSource,
+                             audioType);
+    // Only enable AudioCapture if the pref is enabled. If it's not, we can deny
+    // right away.
+    if (audioType == dom::MediaSourceEnum::AudioCapture &&
+        !Preferences::GetBool("media.getusermedia.audiocapture.enabled")) {
+      nsRefPtr<MediaStreamError> error =
+        new MediaStreamError(aWindow,
+            NS_LITERAL_STRING("PermissionDeniedError"));
+      onFailure->OnError(error);
+      return NS_OK;
+    }
+  }
   StreamListeners* listeners = AddWindowID(windowID);
 
   // Create a disabled listener to act as a placeholder
   nsRefPtr<GetUserMediaCallbackMediaStreamListener> listener =
     new GetUserMediaCallbackMediaStreamListener(mMediaThread, windowID);
 
   // No need for locking because we always do this in the main thread.
   listeners->AppendElement(listener);
@@ -1773,17 +1794,18 @@ MediaManager::GetUserMedia(nsPIDOMWindow
       Preferences::GetBool("media.navigator.streams.fake");
 
   bool fakeTracks = c.mFakeTracks.WasPassed()? c.mFakeTracks.Value() : false;
 
   bool askPermission = !privileged &&
       (!fake || Preferences::GetBool("media.navigator.permission.fake"));
 
   nsRefPtr<PledgeSourceSet> p = EnumerateDevicesImpl(windowID, videoType,
-                                                     fake, fakeTracks);
+                                                     audioType, fake,
+                                                     fakeTracks);
   p->Then([this, onSuccess, onFailure, windowID, c, listener, askPermission,
            prefs, isHTTPS, callID, origin](SourceSet*& aDevices) mutable {
     ScopedDeletePtr<SourceSet> devices(aDevices); // grab result
 
     // Ensure this pointer is still valid, and window is still alive.
     nsRefPtr<MediaManager> mgr = MediaManager::GetInstance();
     nsRefPtr<nsPIDOMWindow> window = static_cast<nsPIDOMWindow*>
         (nsGlobalWindow::GetInnerWindowWithId(windowID));
@@ -1929,17 +1951,19 @@ MediaManager::ToJSArray(SourceSet& aDevi
     }
   } else {
     var->SetAsEmptyArray(); // because SetAsArray() fails on zero length arrays.
   }
   return var.forget();
 }
 
 already_AddRefed<MediaManager::PledgeSourceSet>
-MediaManager::EnumerateDevicesImpl(uint64_t aWindowId, MediaSourceEnum aVideoType,
+MediaManager::EnumerateDevicesImpl(uint64_t aWindowId,
+                                   MediaSourceEnum aVideoType,
+                                   MediaSourceEnum aAudioType,
                                    bool aFake, bool aFakeTracks)
 {
   MOZ_ASSERT(NS_IsMainThread());
   nsPIDOMWindow *window = static_cast<nsPIDOMWindow*>
       (nsGlobalWindow::GetInnerWindowWithId(aWindowId));
 
   // This function returns a pledge, a promise-like object with the future result
   nsRefPtr<PledgeSourceSet> pledge = new PledgeSourceSet();
@@ -1958,22 +1982,23 @@ MediaManager::EnumerateDevicesImpl(uint6
 
   // GetOriginKey is an async API that returns a pledge (a promise-like
   // pattern). We use .Then() to pass in a lambda to run back on this same
   // thread later once GetOriginKey resolves. Needed variables are "captured"
   // (passed by value) safely into the lambda.
 
   nsRefPtr<Pledge<nsCString>> p = media::GetOriginKey(origin, privateBrowsing,
                                                       persist);
-  p->Then([id, aWindowId, aVideoType,
+  p->Then([id, aWindowId, aVideoType, aAudioType,
            aFake, aFakeTracks](const nsCString& aOriginKey) mutable {
     MOZ_ASSERT(NS_IsMainThread());
     nsRefPtr<MediaManager> mgr = MediaManager_GetInstance();
 
-    nsRefPtr<PledgeSourceSet> p = mgr->EnumerateRawDevices(aWindowId, aVideoType,
+    nsRefPtr<PledgeSourceSet> p = mgr->EnumerateRawDevices(aWindowId,
+                                                           aVideoType, aAudioType,
                                                            aFake, aFakeTracks);
     p->Then([id, aWindowId, aOriginKey](SourceSet*& aDevices) mutable {
       ScopedDeletePtr<SourceSet> devices(aDevices); // secondary result
 
       // Only run if window is still on our active list.
       nsRefPtr<MediaManager> mgr = MediaManager_GetInstance();
       if (!mgr) {
         return NS_OK;
@@ -2002,16 +2027,17 @@ MediaManager::EnumerateDevices(nsPIDOMWi
   uint64_t windowId = aWindow->WindowID();
 
   AddWindowID(windowId);
 
   bool fake = Preferences::GetBool("media.navigator.streams.fake");
 
   nsRefPtr<PledgeSourceSet> p = EnumerateDevicesImpl(windowId,
                                                      dom::MediaSourceEnum::Camera,
+                                                     dom::MediaSourceEnum::Microphone,
                                                      fake);
   p->Then([onSuccess](SourceSet*& aDevices) mutable {
     ScopedDeletePtr<SourceSet> devices(aDevices); // grab result
     nsCOMPtr<nsIWritableVariant> array = MediaManager_ToJSArray(*devices);
     onSuccess->OnSuccess(array);
   }, [onFailure](MediaStreamError& reason) mutable {
     onFailure->OnError(&reason);
   });
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -592,20 +592,24 @@ private:
   static bool IsLoop(nsIURI* aDocURI);
   static nsresult GenerateUUID(nsAString& aResult);
   static nsresult AnonymizeId(nsAString& aId, const nsACString& aOriginKey);
 public: // TODO: make private once we upgrade to GCC 4.8+ on linux.
   static void AnonymizeDevices(SourceSet& aDevices, const nsACString& aOriginKey);
   static already_AddRefed<nsIWritableVariant> ToJSArray(SourceSet& aDevices);
 private:
   already_AddRefed<PledgeSourceSet>
-  EnumerateRawDevices(uint64_t aWindowId, dom::MediaSourceEnum aSrcType,
+  EnumerateRawDevices(uint64_t aWindowId,
+                      dom::MediaSourceEnum aVideoType,
+                      dom::MediaSourceEnum aAudioType,
                       bool aFake, bool aFakeTracks);
   already_AddRefed<PledgeSourceSet>
-  EnumerateDevicesImpl(uint64_t aWindowId, dom::MediaSourceEnum aSrcType,
+  EnumerateDevicesImpl(uint64_t aWindowId,
+                       dom::MediaSourceEnum aVideoSrcType,
+                       dom::MediaSourceEnum aAudioSrcType,
                        bool aFake = false, bool aFakeTracks = false);
 
   StreamListeners* AddWindowID(uint64_t aWindowId);
   WindowTable *GetActiveWindows() {
     NS_ASSERTION(NS_IsMainThread(), "Only access windowlist on main thread");
     return &mActiveWindows;
   }
 
--- a/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
@@ -263,17 +263,17 @@ MediaEngineWebRTCMicrophoneSource::Confi
 // GetBestFitnessDistance returns the best distance the capture device can offer
 // as a whole, given an accumulated number of ConstraintSets.
 // Ideal values are considered in the first ConstraintSet only.
 // Plain values are treated as Ideal in the first ConstraintSet.
 // Plain values are treated as Exact in subsequent ConstraintSets.
 // Infinity = UINT32_MAX e.g. device cannot satisfy accumulated ConstraintSets.
 // A finite result may be used to calculate this device's ranking as a choice.
 
-uint32_t MediaEngineWebRTCAudioSource::GetBestFitnessDistance(
+uint32_t MediaEngineWebRTCMicrophoneSource::GetBestFitnessDistance(
     const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets,
     const nsString& aDeviceId)
 {
   uint32_t distance = 0;
 
   for (const MediaTrackConstraintSet* cs : aConstraintSets) {
     distance = GetMinimumFitnessDistance(*cs, false, aDeviceId);
     break; // distance is read from first entry only
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -440,16 +440,18 @@ pref("media.getusermedia.screensharing.e
 pref("media.getusermedia.screensharing.allowed_domains", "webex.com,*.webex.com,ciscospark.com,*.ciscospark.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,example.com,*.mypurecloud.com,*.mypurecloud.com.au,spreed.me,*.spreed.me,*.spreed.com");
 #else
  // temporary value, not intended for release - bug 1049087
 pref("media.getusermedia.screensharing.allowed_domains", "mozilla.github.io,webex.com,*.webex.com,ciscospark.com,*.ciscospark.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,example.com,*.mypurecloud.com,*.mypurecloud.com.au,spreed.me,*.spreed.me,*.spreed.com");
 #endif
 // OS/X 10.6 and XP have screen/window sharing off by default due to various issues - Caveat emptor
 pref("media.getusermedia.screensharing.allow_on_old_platforms", false);
 
+pref("media.getusermedia.audiocapture.enabled", false);
+
 // TextTrack support
 pref("media.webvtt.enabled", true);
 pref("media.webvtt.regions.enabled", false);
 
 // AudioTrack and VideoTrack support
 pref("media.track.enabled", false);
 
 // Whether to enable MediaSource support.