Bug 1213453 - Add group id in various MediaManager classes. r=pehrsons
☠☠ backed out by f63a07c8426b ☠ ☠
authorAlex Chronopoulos <achronop@gmail.com>
Fri, 08 Mar 2019 10:33:49 +0000
changeset 521012 6903f0739e83
parent 521011 56aaf8c9fb7c
child 521013 f78c357f2f5f
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspehrsons
bugs1213453
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1213453 - Add group id in various MediaManager classes. r=pehrsons Differential Revision: https://phabricator.services.mozilla.com/D20369
dom/media/AudioDeviceInfo.cpp
dom/media/AudioDeviceInfo.h
dom/media/MediaDeviceInfo.h
dom/media/MediaDevices.cpp
dom/media/MediaManager.cpp
dom/media/MediaManager.h
dom/media/nsIDOMNavigatorUserMedia.idl
dom/media/webrtc/MediaEngineDefault.cpp
dom/media/webrtc/MediaEngineWebRTC.cpp
dom/media/webrtc/MediaTrackConstraints.cpp
--- a/dom/media/AudioDeviceInfo.cpp
+++ b/dom/media/AudioDeviceInfo.cpp
@@ -57,16 +57,17 @@ AudioDeviceInfo::AudioDeviceInfo(
              "Wrong default format");
 }
 
 AudioDeviceID AudioDeviceInfo::DeviceID() const { return mDeviceId; }
 const nsString& AudioDeviceInfo::Name() const { return mName; }
 uint32_t AudioDeviceInfo::MaxChannels() const { return mMaxChannels; }
 uint32_t AudioDeviceInfo::Type() const { return mType; }
 uint32_t AudioDeviceInfo::State() const { return mState; }
+const nsString& AudioDeviceInfo::GroupID() const { return mGroupId; }
 
 bool AudioDeviceInfo::Preferred() const { return mPreferred; }
 
 /* readonly attribute DOMString name; */
 NS_IMETHODIMP
 AudioDeviceInfo::GetName(nsAString& aName) {
   aName = mName;
   return NS_OK;
--- a/dom/media/AudioDeviceInfo.h
+++ b/dom/media/AudioDeviceInfo.h
@@ -27,16 +27,17 @@ class AudioDeviceInfo final : public nsI
                   uint32_t aMinLatency);
   explicit AudioDeviceInfo(cubeb_device_info* aInfo);
 
   AudioDeviceID DeviceID() const;
   const nsString& Name() const;
   uint32_t MaxChannels() const;
   uint32_t Type() const;
   uint32_t State() const;
+  const nsString& GroupID() const;
   bool Preferred() const;
 
  private:
   virtual ~AudioDeviceInfo() = default;
 
   const AudioDeviceID mDeviceId;
   const nsString mName;
   const nsString mGroupId;
--- a/dom/media/MediaDeviceInfo.h
+++ b/dom/media/MediaDeviceInfo.h
@@ -19,18 +19,17 @@ namespace dom {
     0x25091870, 0x84d6, 0x4acf, {                      \
       0xaf, 0x97, 0x6e, 0xd5, 0x5b, 0xe0, 0x47, 0xb2   \
     }                                                  \
   }
 
 class MediaDeviceInfo final : public nsISupports, public nsWrapperCache {
  public:
   explicit MediaDeviceInfo(const nsAString& aDeviceId, MediaDeviceKind aKind,
-                           const nsAString& aLabel,
-                           const nsAString& aGroupId = nsString());
+                           const nsAString& aLabel, const nsAString& aGroupId);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaDeviceInfo)
   NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOM_MEDIADEVICEINFO_IMPLEMENTATION_IID)
 
   JSObject* WrapObject(JSContext* cx,
                        JS::Handle<JSObject*> aGivenProto) override;
 
--- a/dom/media/MediaDevices.cpp
+++ b/dom/media/MediaDevices.cpp
@@ -110,17 +110,17 @@ already_AddRefed<Promise> MediaDevices::
                  nsString label;
                  if (MediaManager::Get()->IsActivelyCapturingOrHasAPermission(
                          windowId) ||
                      Preferences::GetBool("media.navigator.permission.disabled",
                                           false)) {
                    label = device->mName;
                  }
                  infos.AppendElement(MakeRefPtr<MediaDeviceInfo>(
-                     device->mID, device->mKind, label));
+                     device->mID, device->mKind, label, device->mGroupID));
                }
                p->MaybeResolve(std::move(infos));
              },
              [this, self, p](const RefPtr<MediaMgrError>& error) {
                nsPIDOMWindowInner* window = GetWindowIfCurrent();
                if (!window) {
                  return;  // Leave Promise pending after navigation by design.
                }
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -808,61 +808,65 @@ class GetUserMediaWindowListener {
 
 /**
  * nsIMediaDevice implementation.
  */
 NS_IMPL_ISUPPORTS(MediaDevice, nsIMediaDevice)
 
 MediaDevice::MediaDevice(const RefPtr<MediaEngineSource>& aSource,
                          const nsString& aName, const nsString& aID,
-                         const nsString& aRawID)
+                         const nsString& aGroupID, const nsString& aRawID)
     : mSource(aSource),
       mSinkInfo(nullptr),
       mKind((mSource && MediaEngineSource::IsVideo(mSource->GetMediaSource()))
                 ? dom::MediaDeviceKind::Videoinput
                 : dom::MediaDeviceKind::Audioinput),
       mScary(mSource->GetScary()),
       mType(NS_ConvertUTF8toUTF16(
           dom::MediaDeviceKindValues::strings[uint32_t(mKind)].value)),
       mName(aName),
       mID(aID),
+      mGroupID(aGroupID),
       mRawID(aRawID) {
   MOZ_ASSERT(mSource);
 }
 
 MediaDevice::MediaDevice(const RefPtr<AudioDeviceInfo>& aAudioDeviceInfo,
-                         const nsString& aID, const nsString& aRawID)
+                         const nsString& aID, const nsString& aGroupID,
+                         const nsString& aRawID)
     : mSource(nullptr),
       mSinkInfo(aAudioDeviceInfo),
       mKind(mSinkInfo->Type() == AudioDeviceInfo::TYPE_INPUT
                 ? dom::MediaDeviceKind::Audioinput
                 : dom::MediaDeviceKind::Audiooutput),
       mScary(false),
       mType(NS_ConvertUTF8toUTF16(
           dom::MediaDeviceKindValues::strings[uint32_t(mKind)].value)),
       mName(mSinkInfo->Name()),
       mID(aID),
+      mGroupID(aGroupID),
       mRawID(aRawID) {
   // For now this ctor is used only for Audiooutput.
   // It could be used for Audioinput and Videoinput
   // when we do not instantiate a MediaEngineSource
   // during EnumerateDevices.
   MOZ_ASSERT(mKind == dom::MediaDeviceKind::Audiooutput);
   MOZ_ASSERT(mSinkInfo);
 }
 
 MediaDevice::MediaDevice(const RefPtr<MediaDevice>& aOther, const nsString& aID,
-                         const nsString& aRawID)
+                         const nsString& aGroupID, const nsString& aRawID)
     : mSource(aOther->mSource),
       mSinkInfo(aOther->mSinkInfo),
       mKind(aOther->mKind),
       mScary(aOther->mScary),
       mType(aOther->mType),
       mName(aOther->mName),
       mID(aID),
+      mGroupID(aGroupID),
       mRawID(aRawID) {
   MOZ_ASSERT(aOther);
 }
 
 /**
  * Helper functions that implement the constraints algorithm from
  * http://dev.w3.org/2011/webrtc/editor/getusermedia.html#methods-5
  */
@@ -947,16 +951,23 @@ MediaDevice::GetId(nsAString& aID) {
 NS_IMETHODIMP
 MediaDevice::GetRawId(nsAString& aID) {
   MOZ_ASSERT(NS_IsMainThread());
   aID.Assign(mRawID);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+MediaDevice::GetGroupId(nsAString& aGroupID) {
+  MOZ_ASSERT(NS_IsMainThread());
+  aGroupID.Assign(mGroupID);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 MediaDevice::GetScary(bool* aScary) {
   *aScary = mScary;
   return NS_OK;
 }
 
 void MediaDevice::GetSettings(dom::MediaTrackSettings& aOutSettings) const {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mSource);
@@ -3006,17 +3017,22 @@ RefPtr<MediaManager::StreamPromise> Medi
 void MediaManager::AnonymizeDevices(MediaDeviceSet& aDevices,
                                     const nsACString& aOriginKey) {
   if (!aOriginKey.IsEmpty()) {
     for (RefPtr<MediaDevice>& device : aDevices) {
       nsString id;
       device->GetId(id);
       nsString rawId(id);
       AnonymizeId(id, aOriginKey);
-      device = new MediaDevice(device, id, rawId);
+
+      nsString groupId;
+      device->GetGroupId(groupId);
+      AnonymizeId(groupId, aOriginKey);
+
+      device = new MediaDevice(device, id, groupId, rawId);
     }
   }
 }
 
 /* static */
 nsresult MediaManager::AnonymizeId(nsAString& aId,
                                    const nsACString& aOriginKey) {
   MOZ_ASSERT(NS_IsMainThread());
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -62,26 +62,26 @@ class GetUserMediaWindowListener;
 class MediaManager;
 class SourceListener;
 
 class MediaDevice : public nsIMediaDevice {
  public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIMEDIADEVICE
 
-  explicit MediaDevice(const RefPtr<MediaEngineSource>& aSource,
-                       const nsString& aName, const nsString& aID,
-                       const nsString& aRawID);
+  MediaDevice(const RefPtr<MediaEngineSource>& aSource, const nsString& aName,
+              const nsString& aID, const nsString& aGroupID,
+              const nsString& aRawID);
 
-  explicit MediaDevice(const RefPtr<AudioDeviceInfo>& aAudioDeviceInfo,
-                       const nsString& aID,
-                       const nsString& aRawID = NS_LITERAL_STRING(""));
+  MediaDevice(const RefPtr<AudioDeviceInfo>& aAudioDeviceInfo,
+              const nsString& aID, const nsString& aGroupID,
+              const nsString& aRawID = NS_LITERAL_STRING(""));
 
-  explicit MediaDevice(const RefPtr<MediaDevice>& aOther, const nsString& aID,
-                       const nsString& aRawID);
+  MediaDevice(const RefPtr<MediaDevice>& aOther, const nsString& aID,
+              const nsString& aGroupID, const nsString& aRawID);
 
   uint32_t GetBestFitnessDistance(
       const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
       bool aIsChrome);
 
   nsresult Allocate(const dom::MediaTrackConstraints& aConstraints,
                     const MediaEnginePrefs& aPrefs,
                     const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
@@ -125,16 +125,17 @@ class MediaDevice : public nsIMediaDevic
  public:
   const RefPtr<MediaEngineSource> mSource;
   const RefPtr<AudioDeviceInfo> mSinkInfo;
   const dom::MediaDeviceKind mKind;
   const bool mScary;
   const nsString mType;
   const nsString mName;
   const nsString mID;
+  const nsString mGroupID;
   const nsString mRawID;
 };
 
 typedef nsRefPtrHashtable<nsUint64HashKey, GetUserMediaWindowListener>
     WindowTable;
 typedef MozPromise<RefPtr<AudioDeviceInfo>, nsresult, true> SinkInfoPromise;
 
 class MediaManager final : public nsIMediaManagerService,
--- a/dom/media/nsIDOMNavigatorUserMedia.idl
+++ b/dom/media/nsIDOMNavigatorUserMedia.idl
@@ -8,16 +8,17 @@
 [scriptable, builtinclass, uuid(ba3b2e08-1c07-4cd3-8822-f4d7e35ff2ae)]
 interface nsIMediaDevice : nsISupports
 {
   readonly attribute AString type;
   readonly attribute AString name;
   readonly attribute AString id;
   readonly attribute AString mediaSource;
   readonly attribute AString rawId;
+  readonly attribute AString groupId;
   readonly attribute boolean scary;
 };
 
 [scriptable, function, uuid(24544878-d35e-4962-8c5f-fb84e97bdfee)]
 interface nsIGetUserMediaDevicesSuccessCallback : nsISupports
 {
   void onSuccess(in nsIVariant devices);
 };
--- a/dom/media/webrtc/MediaEngineDefault.cpp
+++ b/dom/media/webrtc/MediaEngineDefault.cpp
@@ -547,39 +547,41 @@ void MediaEngineDefault::EnumerateDevice
       // in Allocate().
 
       nsTArray<RefPtr<MediaEngineSource>>* devicesForThisWindow =
           mVSources.LookupOrAdd(aWindowId);
       auto newSource = MakeRefPtr<MediaEngineDefaultVideoSource>();
       devicesForThisWindow->AppendElement(newSource);
       aDevices->AppendElement(MakeRefPtr<MediaDevice>(
           newSource, newSource->GetName(),
-          NS_ConvertUTF8toUTF16(newSource->GetUUID()), NS_LITERAL_STRING("")));
+          NS_ConvertUTF8toUTF16(newSource->GetUUID()),
+          NS_LITERAL_STRING("GroupID"), NS_LITERAL_STRING("")));
       return;
     }
     case dom::MediaSourceEnum::Microphone: {
       nsTArray<RefPtr<MediaEngineDefaultAudioSource>>* devicesForThisWindow =
           mASources.LookupOrAdd(aWindowId);
       for (const RefPtr<MediaEngineDefaultAudioSource>& source :
            *devicesForThisWindow) {
         if (source->IsAvailable()) {
           aDevices->AppendElement(MakeRefPtr<MediaDevice>(
               source, source->GetName(),
-              NS_ConvertUTF8toUTF16(source->GetUUID()), NS_LITERAL_STRING("")));
+              NS_ConvertUTF8toUTF16(source->GetUUID()),
+              NS_LITERAL_STRING("GroupID"), NS_LITERAL_STRING("")));
         }
       }
 
       if (aDevices->IsEmpty()) {
         // All streams are currently busy, just make a new one.
         auto newSource = MakeRefPtr<MediaEngineDefaultAudioSource>();
         devicesForThisWindow->AppendElement(newSource);
-        aDevices->AppendElement(
-            MakeRefPtr<MediaDevice>(newSource, newSource->GetName(),
-                                    NS_ConvertUTF8toUTF16(newSource->GetUUID()),
-                                    NS_LITERAL_STRING("")));
+        aDevices->AppendElement(MakeRefPtr<MediaDevice>(
+            newSource, newSource->GetName(),
+            NS_ConvertUTF8toUTF16(newSource->GetUUID()),
+            NS_LITERAL_STRING("GroupID"), NS_LITERAL_STRING("")));
       }
       return;
     }
     default:
       MOZ_ASSERT_UNREACHABLE("Unsupported source type");
       return;
   }
 
--- a/dom/media/webrtc/MediaEngineWebRTC.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTC.cpp
@@ -139,25 +139,25 @@ void MediaEngineWebRTC::EnumerateVideoDe
       static_cast<MediaEngineRemoteVideoSource*>(vSource.get())->Refresh(i);
     } else {
       vSource = new MediaEngineRemoteVideoSource(i, aCapEngine,
                                                  scaryKind || scarySource);
       devicesForThisWindow->Put(uuid, vSource);
     }
     aDevices->AppendElement(MakeRefPtr<MediaDevice>(
         vSource, vSource->GetName(), NS_ConvertUTF8toUTF16(vSource->GetUUID()),
-        NS_LITERAL_STRING("")));
+        NS_LITERAL_STRING("GroupID"), NS_LITERAL_STRING("")));
   }
 
   if (mHasTabVideoSource || aCapEngine == camera::BrowserEngine) {
     RefPtr<MediaEngineSource> tabVideoSource = new MediaEngineTabVideoSource();
     aDevices->AppendElement(MakeRefPtr<MediaDevice>(
         tabVideoSource, tabVideoSource->GetName(),
         NS_ConvertUTF8toUTF16(tabVideoSource->GetUUID()),
-        NS_LITERAL_STRING("")));
+        NS_LITERAL_STRING("GroupID"), NS_LITERAL_STRING("")));
   }
 }
 
 void MediaEngineWebRTC::EnumerateMicrophoneDevices(
     uint64_t aWindowId, nsTArray<RefPtr<MediaDevice>>* aDevices) {
   mMutex.AssertCurrentThreadOwns();
 
   mEnumerator = CubebDeviceEnumerator::GetInstance();
@@ -180,17 +180,17 @@ void MediaEngineWebRTC::EnumerateMicroph
       MOZ_ASSERT(devices[i]->Type() == CUBEB_DEVICE_TYPE_INPUT);
       RefPtr<MediaEngineSource> source = new MediaEngineWebRTCMicrophoneSource(
           devices[i], devices[i]->Name(),
           // Lie and provide the name as UUID
           NS_ConvertUTF16toUTF8(devices[i]->Name()), devices[i]->MaxChannels(),
           mDelayAgnostic, mExtendedFilter);
       RefPtr<MediaDevice> device = MakeRefPtr<MediaDevice>(
           source, source->GetName(), NS_ConvertUTF8toUTF16(source->GetUUID()),
-          NS_LITERAL_STRING(""));
+          NS_LITERAL_STRING("GroupID"), NS_LITERAL_STRING(""));
       if (devices[i]->Preferred()) {
 #ifdef DEBUG
         if (!foundPreferredDevice) {
           foundPreferredDevice = true;
         } else {
           MOZ_ASSERT(!foundPreferredDevice,
                      "Found more than one preferred audio input device"
                      "while enumerating");
@@ -215,17 +215,18 @@ void MediaEngineWebRTC::EnumerateSpeaker
   for (auto& device : devices) {
     if (device->State() == CUBEB_DEVICE_STATE_ENABLED) {
       MOZ_ASSERT(device->Type() == CUBEB_DEVICE_TYPE_OUTPUT);
       nsString uuid(device->Name());
       // If, for example, input and output are in the same device, uuid
       // would be the same for both which ends up to create the same
       // deviceIDs (in JS).
       uuid.Append(NS_LITERAL_STRING("_Speaker"));
-      aDevices->AppendElement(MakeRefPtr<MediaDevice>(device, uuid));
+      nsString groupId(device->GroupID());
+      aDevices->AppendElement(MakeRefPtr<MediaDevice>(device, uuid, groupId));
     }
   }
 }
 
 void MediaEngineWebRTC::EnumerateDevices(
     uint64_t aWindowId, dom::MediaSourceEnum aMediaSource,
     MediaSinkEnum aMediaSink, nsTArray<RefPtr<MediaDevice>>* aDevices) {
   MOZ_ASSERT(aMediaSource != dom::MediaSourceEnum::Other ||
@@ -258,17 +259,17 @@ void MediaEngineWebRTC::EnumerateDevices
         break;
     }
   } else if (aMediaSource == dom::MediaSourceEnum::AudioCapture) {
     RefPtr<MediaEngineWebRTCAudioCaptureSource> audioCaptureSource =
         new MediaEngineWebRTCAudioCaptureSource(nullptr);
     aDevices->AppendElement(MakeRefPtr<MediaDevice>(
         audioCaptureSource, audioCaptureSource->GetName(),
         NS_ConvertUTF8toUTF16(audioCaptureSource->GetUUID()),
-        NS_LITERAL_STRING("")));
+        NS_LITERAL_STRING("GroupID"), NS_LITERAL_STRING("")));
   } else if (aMediaSource == dom::MediaSourceEnum::Microphone) {
     MOZ_ASSERT(aMediaSource == dom::MediaSourceEnum::Microphone);
     EnumerateMicrophoneDevices(aWindowId, aDevices);
   }
 
   if (aMediaSink == MediaSinkEnum::Speaker) {
     EnumerateSpeakerDevices(aWindowId, aDevices);
   }
--- a/dom/media/webrtc/MediaTrackConstraints.cpp
+++ b/dom/media/webrtc/MediaTrackConstraints.cpp
@@ -512,19 +512,19 @@ uint32_t MediaConstraintsHelper::Fitness
   return "";
 }
 
 /* static */ const char* MediaConstraintsHelper::FindBadConstraint(
     const NormalizedConstraints& aConstraints,
     const RefPtr<MediaEngineSource>& aMediaEngineSource,
     const nsString& aDeviceId) {
   AutoTArray<RefPtr<MediaDevice>, 1> devices;
-  devices.AppendElement(
-      MakeRefPtr<MediaDevice>(aMediaEngineSource, aMediaEngineSource->GetName(),
-                              aDeviceId, NS_LITERAL_STRING("")));
+  devices.AppendElement(MakeRefPtr<MediaDevice>(
+      aMediaEngineSource, aMediaEngineSource->GetName(), aDeviceId,
+      NS_LITERAL_STRING("GroupID"), NS_LITERAL_STRING("")));
   return FindBadConstraint(aConstraints, devices);
 }
 
 static void LogConstraintStringRange(
     const NormalizedConstraintSet::StringRange& aRange) {
   if (aRange.mExact.size() <= 1 && aRange.mIdeal.size() <= 1) {
     LOG("  %s: { exact: [%s], ideal: [%s] }", aRange.mName,
         (aRange.mExact.size()