Bug 1494675 - Remove windowID to MediaEngineSource mappings from MediaEngines. r=padenot
authorAndreas Pehrson <apehrson@mozilla.com>
Wed, 27 Mar 2019 14:10:10 +0000
changeset 525607 1248d2f659a9f341f0de5d6558eecf364fc6f0a2
parent 525606 20543d03a4cda05c785011a25079aa42aec8b2ba
child 525608 276622dfadd8c63574341b02fa5e594a36493c37
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1494675
milestone68.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 1494675 - Remove windowID to MediaEngineSource mappings from MediaEngines. r=padenot These once served a caching-and-reuse purpose it seems, but it makes less sense when sources are not shared. There seems to still be functioning code to re-use fake audio devices, but this seems like premature optimization. Especially since we don't care much about fake devices in release. This patch removes it all, together with some plumbing around the mechanism. Differential Revision: https://phabricator.services.mozilla.com/D24902
dom/media/MediaManager.cpp
dom/media/webrtc/MediaEngine.h
dom/media/webrtc/MediaEngineDefault.cpp
dom/media/webrtc/MediaEngineDefault.h
dom/media/webrtc/MediaEngineWebRTC.cpp
dom/media/webrtc/MediaEngineWebRTC.h
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -3430,23 +3430,16 @@ void MediaManager::OnNavigation(uint64_t
           MOZ_ASSERT(!self->GetWindowListener(windowID));
         });
   } else {
     RemoveWindowID(aWindowID);
   }
   MOZ_ASSERT(!GetWindowListener(aWindowID));
 
   RemoveMediaDevicesCallback(aWindowID);
-
-  MediaManager::PostTask(
-      NewTaskFrom([self = RefPtr<MediaManager>(this), aWindowID]() {
-        if (self->mBackend) {
-          self->mBackend->ReleaseResourcesForWindow(aWindowID);
-        }
-      }));
 }
 
 void MediaManager::RemoveMediaDevicesCallback(uint64_t aWindowID) {
   MutexAutoLock lock(mCallbackMutex);
   for (DeviceChangeCallback* observer : mDeviceChangeCallbackList) {
     dom::MediaDevices* mediadevices = static_cast<dom::MediaDevices*>(observer);
     MOZ_ASSERT(mediadevices);
     if (mediadevices) {
--- a/dom/media/webrtc/MediaEngine.h
+++ b/dom/media/webrtc/MediaEngine.h
@@ -40,17 +40,16 @@ class MediaEngine : public DeviceChangeC
   /**
    * Populate an array of sources of the requested type in the nsTArray.
    * Also include devices that are currently unavailable.
    */
   virtual void EnumerateDevices(uint64_t aWindowId, dom::MediaSourceEnum,
                                 MediaSinkEnum,
                                 nsTArray<RefPtr<MediaDevice>>*) = 0;
 
-  virtual void ReleaseResourcesForWindow(uint64_t aWindowId) = 0;
   virtual void Shutdown() = 0;
 
   virtual void SetFakeDeviceChangeEvents() {}
 
  protected:
   virtual ~MediaEngine() = default;
 };
 
--- a/dom/media/webrtc/MediaEngineDefault.cpp
+++ b/dom/media/webrtc/MediaEngineDefault.cpp
@@ -379,22 +379,16 @@ uint32_t MediaEngineDefaultAudioSource::
     distance =
         MediaConstraintsHelper::GetMinimumFitnessDistance(*cs, aDeviceId);
     break;  // distance is read from first entry only
   }
 #endif
   return distance;
 }
 
-bool MediaEngineDefaultAudioSource::IsAvailable() const {
-  AssertIsOnOwningThread();
-
-  return mState == kReleased;
-}
-
 nsresult MediaEngineDefaultAudioSource::Allocate(
     const dom::MediaTrackConstraints& aConstraints,
     const MediaEnginePrefs& aPrefs, const nsString& aDeviceId,
     const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
     const char** aOutBadConstraint) {
   AssertIsOnOwningThread();
 
   MOZ_ASSERT(mState == kReleased);
@@ -519,105 +513,34 @@ void AudioSourcePullListener::NotifyPull
 void MediaEngineDefault::EnumerateDevices(
     uint64_t aWindowId, dom::MediaSourceEnum aMediaSource,
     MediaSinkEnum aMediaSink, nsTArray<RefPtr<MediaDevice>>* aDevices) {
   AssertIsOnOwningThread();
 
   switch (aMediaSource) {
     case dom::MediaSourceEnum::Camera: {
       // Only supports camera video sources. See Bug 1038241.
-
-      // We once had code here to find a VideoSource with the same settings and
-      // re-use that. This is no longer possible since the resolution gets set
-      // 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()), newSource->GetGroupId(),
           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()), source->GetGroupId(),
-              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()),
-            newSource->GetGroupId(), NS_LITERAL_STRING("")));
-      }
+      auto newSource = MakeRefPtr<MediaEngineDefaultAudioSource>();
+      aDevices->AppendElement(MakeRefPtr<MediaDevice>(
+          newSource, newSource->GetName(),
+          NS_ConvertUTF8toUTF16(newSource->GetUUID()), newSource->GetGroupId(),
+          NS_LITERAL_STRING("")));
       return;
     }
     default:
       MOZ_ASSERT_UNREACHABLE("Unsupported source type");
       return;
   }
 
   if (aMediaSink == MediaSinkEnum::Speaker) {
     NS_WARNING("No default implementation for MediaSinkEnum::Speaker");
   }
 }
 
-void MediaEngineDefault::ReleaseResourcesForWindow(uint64_t aWindowId) {
-  nsTArray<RefPtr<MediaEngineDefaultAudioSource>>* audioDevicesForThisWindow =
-      mASources.Get(aWindowId);
-
-  if (audioDevicesForThisWindow) {
-    for (const RefPtr<MediaEngineDefaultAudioSource>& source :
-         *audioDevicesForThisWindow) {
-      source->Shutdown();
-    }
-  }
-
-  mASources.Remove(aWindowId);
-
-  nsTArray<RefPtr<MediaEngineSource>>* videoDevicesForThisWindow =
-      mVSources.Get(aWindowId);
-
-  if (videoDevicesForThisWindow) {
-    for (const RefPtr<MediaEngineSource>& source : *videoDevicesForThisWindow) {
-      source->Shutdown();
-    }
-  }
-
-  mVSources.Remove(aWindowId);
-}
-
-void MediaEngineDefault::Shutdown() {
-  AssertIsOnOwningThread();
-
-  for (auto iter = mVSources.Iter(); !iter.Done(); iter.Next()) {
-    for (const RefPtr<MediaEngineSource>& source : *iter.UserData()) {
-      if (source) {
-        source->Shutdown();
-      }
-    }
-  }
-  for (auto iter = mASources.Iter(); !iter.Done(); iter.Next()) {
-    for (const RefPtr<MediaEngineDefaultAudioSource>& source :
-         *iter.UserData()) {
-      if (source) {
-        source->Shutdown();
-      }
-    }
-  }
-  mVSources.Clear();
-  mASources.Clear();
-};
-
 }  // namespace mozilla
--- a/dom/media/webrtc/MediaEngineDefault.h
+++ b/dom/media/webrtc/MediaEngineDefault.h
@@ -122,18 +122,16 @@ class MediaEngineDefaultAudioSource : pu
   dom::MediaSourceEnum GetMediaSource() const override {
     return dom::MediaSourceEnum::Microphone;
   }
 
   uint32_t GetBestFitnessDistance(
       const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
       const nsString& aDeviceId) const override;
 
-  bool IsAvailable() const;
-
  protected:
   ~MediaEngineDefaultAudioSource();
 
   // Current state of this source.
   MediaEngineSourceState mState = kReleased;
   RefPtr<SourceMediaStream> mStream;
   TrackID mTrackID = TRACK_NONE;
   PrincipalHandle mPrincipalHandle = PRINCIPAL_HANDLE_NONE;
@@ -142,25 +140,17 @@ class MediaEngineDefaultAudioSource : pu
 };
 
 class MediaEngineDefault : public MediaEngine {
  public:
   MediaEngineDefault() = default;
 
   void EnumerateDevices(uint64_t aWindowId, dom::MediaSourceEnum, MediaSinkEnum,
                         nsTArray<RefPtr<MediaDevice>>*) override;
-  void Shutdown() override;
-  void ReleaseResourcesForWindow(uint64_t aWindowId) override;
+  void Shutdown() override {}
 
  private:
   ~MediaEngineDefault() = default;
-
-  // WindowID -> Array of devices.
-  nsClassHashtable<nsUint64HashKey, nsTArray<RefPtr<MediaEngineSource>>>
-      mVSources;
-  nsClassHashtable<nsUint64HashKey,
-                   nsTArray<RefPtr<MediaEngineDefaultAudioSource>>>
-      mASources;
 };
 
 }  // namespace mozilla
 
 #endif /* NSMEDIAENGINEDEFAULT_H_ */
--- a/dom/media/webrtc/MediaEngineWebRTC.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTC.cpp
@@ -53,18 +53,17 @@ void MediaEngineWebRTC::EnumerateVideoDe
   // flag sources with cross-origin exploit potential
   bool scaryKind = (aCapEngine == camera::ScreenEngine ||
                     aCapEngine == camera::BrowserEngine);
   /*
    * We still enumerate every time, in case a new device was plugged in since
    * the last call. TODO: Verify that WebRTC actually does deal with hotplugging
    * new devices (with or without new engine creation) and accordingly adjust.
    * Enumeration is not neccessary if GIPS reports the same set of devices
-   * for a given instance of the engine. Likewise, if a device was plugged out,
-   * mVideoSources must be updated.
+   * for a given instance of the engine.
    */
   int num;
 #if defined(_ARM64_) && defined(XP_WIN)
   // There are problems with using DirectShow on versions of Windows before
   // 19H1 on arm64. This disables the camera on older versions of Windows.
   if (aCapEngine == camera::CameraEngine) {
     typedef ULONG (*RtlGetVersionFn)(LPOSVERSIONINFOEXW);
     RtlGetVersionFn RtlGetVersion;
@@ -125,21 +124,18 @@ void MediaEngineWebRTC::EnumerateVideoDe
       // In case a device doesn't set uniqueId!
       strncpy(uniqueId, deviceName, sizeof(uniqueId));
       uniqueId[sizeof(uniqueId) - 1] = '\0';  // strncpy isn't safe
     }
 
     NS_ConvertUTF8toUTF16 uuid(uniqueId);
     RefPtr<MediaEngineSource> vSource;
 
-    nsRefPtrHashtable<nsStringHashKey, MediaEngineSource>*
-        devicesForThisWindow = mVideoSources.LookupOrAdd(aWindowId);
     vSource = new MediaEngineRemoteVideoSource(i, aCapEngine,
                                                scaryKind || scarySource);
-    devicesForThisWindow->Put(uuid, vSource);
     aDevices->AppendElement(MakeRefPtr<MediaDevice>(
         vSource, vSource->GetName(), NS_ConvertUTF8toUTF16(vSource->GetUUID()),
         vSource->GetGroupId(), NS_LITERAL_STRING("")));
   }
 
   if (mHasTabVideoSource || aCapEngine == camera::BrowserEngine) {
     RefPtr<MediaEngineSource> tabVideoSource = new MediaEngineTabVideoSource();
     aDevices->AppendElement(MakeRefPtr<MediaDevice>(
@@ -273,73 +269,23 @@ void MediaEngineWebRTC::EnumerateDevices
     EnumerateMicrophoneDevices(aWindowId, aDevices);
   }
 
   if (aMediaSink == MediaSinkEnum::Speaker) {
     EnumerateSpeakerDevices(aWindowId, aDevices);
   }
 }
 
-void MediaEngineWebRTC::ReleaseResourcesForWindow(uint64_t aWindowId) {
-  {
-    nsRefPtrHashtable<nsStringHashKey, MediaEngineSource>*
-        audioDevicesForThisWindow = mAudioSources.Get(aWindowId);
-
-    if (audioDevicesForThisWindow) {
-      for (auto iter = audioDevicesForThisWindow->Iter(); !iter.Done();
-           iter.Next()) {
-        iter.UserData()->Shutdown();
-      }
-
-      // This makes audioDevicesForThisWindow invalid.
-      mAudioSources.Remove(aWindowId);
-    }
-  }
-
-  {
-    nsRefPtrHashtable<nsStringHashKey, MediaEngineSource>*
-        videoDevicesForThisWindow = mVideoSources.Get(aWindowId);
-    if (videoDevicesForThisWindow) {
-      for (auto iter = videoDevicesForThisWindow->Iter(); !iter.Done();
-           iter.Next()) {
-        iter.UserData()->Shutdown();
-      }
-
-      // This makes videoDevicesForThisWindow invalid.
-      mVideoSources.Remove(aWindowId);
-    }
-  }
-}
-
-namespace {
-template <typename T>
-void ShutdownSources(T& aHashTable) {
-  for (auto iter = aHashTable.Iter(); !iter.Done(); iter.Next()) {
-    for (auto iterInner = iter.UserData()->Iter(); !iterInner.Done();
-         iterInner.Next()) {
-      MediaEngineSource* source = iterInner.UserData();
-      source->Shutdown();
-    }
-  }
-}
-}  // namespace
-
 void MediaEngineWebRTC::Shutdown() {
   // This is likely paranoia
   MutexAutoLock lock(mMutex);
 
   if (camera::GetCamerasChildIfExists()) {
     camera::GetChildAndCall(&camera::CamerasChild::RemoveDeviceChangeCallback,
                             this);
   }
 
   LOG(("%s", __FUNCTION__));
-  // Shutdown all the sources, since we may have dangling references to the
-  // sources in nsDOMUserMediaStreams waiting for GC/CC
-  ShutdownSources(mVideoSources);
-  ShutdownSources(mAudioSources);
-
   mEnumerator = nullptr;
-
   mozilla::camera::Shutdown();
 }
 
 }  // namespace mozilla
--- a/dom/media/webrtc/MediaEngineWebRTC.h
+++ b/dom/media/webrtc/MediaEngineWebRTC.h
@@ -59,17 +59,16 @@ class MediaEngineWebRTC : public MediaEn
   // before invoking Shutdown on this class.
   void Shutdown() override;
 
   // Returns whether the host supports duplex audio stream.
   bool SupportsDuplex();
 
   void EnumerateDevices(uint64_t aWindowId, dom::MediaSourceEnum, MediaSinkEnum,
                         nsTArray<RefPtr<MediaDevice>>*) override;
-  void ReleaseResourcesForWindow(uint64_t aWindowId) override;
 
  private:
   ~MediaEngineWebRTC() = default;
   void EnumerateVideoDevices(uint64_t aWindowId,
                              camera::CaptureEngine aCapEngine,
                              nsTArray<RefPtr<MediaDevice>>*);
   void EnumerateMicrophoneDevices(uint64_t aWindowId,
                                   nsTArray<RefPtr<MediaDevice>>*);
@@ -79,22 +78,13 @@ class MediaEngineWebRTC : public MediaEn
   // gUM runnables can e.g. Enumerate from multiple threads
   Mutex mMutex;
   RefPtr<mozilla::CubebDeviceEnumerator> mEnumerator;
   const bool mDelayAgnostic;
   const bool mExtendedFilter;
   // This also is set in the ctor and then never changed, but we can't make it
   // const because we pass it to a function that takes bool* in the ctor.
   bool mHasTabVideoSource;
-
-  // Maps WindowID to a map of device uuid to their MediaEngineSource,
-  // separately for audio and video.
-  nsClassHashtable<nsUint64HashKey,
-                   nsRefPtrHashtable<nsStringHashKey, MediaEngineSource>>
-      mVideoSources;
-  nsClassHashtable<nsUint64HashKey,
-                   nsRefPtrHashtable<nsStringHashKey, MediaEngineSource>>
-      mAudioSources;
 };
 
 }  // namespace mozilla
 
 #endif /* NSMEDIAENGINEWEBRTC_H_ */