Bug 1393359 - Register active user media on top level window. r=smaug,jib
authorAndreas Farre <farre@mozilla.com>
Fri, 01 Sep 2017 10:32:33 +0200
changeset 428345 b9ea5a59464ceaf66879e021759e4a89686b0bee
parent 428344 4ce738a785677c1f8a4421903f713c218af3d460
child 428346 cbcfe5871b8377e9ba81921f48db51acf5b88300
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, jib
bugs1393359
milestone57.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 1393359 - Register active user media on top level window. r=smaug,jib
dom/base/TimeoutManager.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsPIDOMWindow.h
dom/media/MediaManager.cpp
--- a/dom/base/TimeoutManager.cpp
+++ b/dom/base/TimeoutManager.cpp
@@ -1253,18 +1253,17 @@ TimeoutManager::BudgetThrottlingEnabled(
   }
 
   // Check if there are any active IndexedDB databases
   if (mWindow.AsInner()->HasActiveIndexedDBDatabases()) {
     return false;
   }
 
   // Check if we have active GetUserMedia
-  if (MediaManager::Exists() &&
-      MediaManager::Get()->IsWindowStillActive(mWindow.WindowID())) {
+  if (mWindow.AsInner()->HasActiveUserMedia()) {
     return false;
   }
 
   // Check if we have active PeerConnection
   if (mWindow.AsInner()->HasActivePeerConnections()) {
     return false;
   }
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1034,17 +1034,18 @@ nsPIDOMWindow<T>::nsPIDOMWindow(nsPIDOMW
   mDesktopModeViewport(false), mIsRootOuterWindow(false), mInnerWindow(nullptr),
   mOuterWindow(aOuterWindow),
   // Make sure no actual window ends up with mWindowID == 0
   mWindowID(NextWindowID()), mHasNotifiedGlobalCreated(false),
   mMarkedCCGeneration(0), mServiceWorkersTestingEnabled(false),
   mLargeAllocStatus(LargeAllocStatus::NONE),
   mHasTriedToCacheTopInnerWindow(false),
   mNumOfIndexedDBDatabases(0),
-  mNumOfOpenWebSockets(0)
+  mNumOfOpenWebSockets(0),
+  mNumOfActiveUserMedia(0)
 {
   if (aOuterWindow) {
     mTimeoutManager =
       MakeUnique<mozilla::dom::TimeoutManager>(*nsGlobalWindow::Cast(AsInner()));
   }
 }
 
 template<class T>
@@ -4520,16 +4521,40 @@ nsPIDOMWindowInner::HasOpenWebSockets() 
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   return (mTopInnerWindow ? mTopInnerWindow->mNumOfOpenWebSockets
                           : mNumOfOpenWebSockets) > 0;
 }
 
 void
+nsPIDOMWindowInner::UpdateUserMediaCount(int32_t aDelta)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (aDelta == 0) {
+    return;
+  }
+
+  uint32_t& counter = mTopInnerWindow ? mTopInnerWindow->mNumOfActiveUserMedia
+                                      : mNumOfActiveUserMedia;
+
+  MOZ_DIAGNOSTIC_ASSERT(aDelta > 0 || ((aDelta + counter) < counter));
+
+  counter += aDelta;
+}
+
+bool
+nsPIDOMWindowInner::HasActiveUserMedia() const
+{
+  return (mTopInnerWindow ? mTopInnerWindow->mNumOfActiveUserMedia
+                          : mNumOfActiveUserMedia) > 0;
+}
+
+void
 nsPIDOMWindowOuter::MaybeActiveMediaComponents()
 {
   if (IsInnerWindow()) {
     return mOuterWindow->MaybeActiveMediaComponents();
   }
 
   if (mMediaSuspend != nsISuspendedTypes::SUSPENDED_BLOCK) {
     return;
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -746,16 +746,19 @@ protected:
   // could be null and we don't want it to be set multiple times.
   bool mHasTriedToCacheTopInnerWindow;
 
   // The number of active IndexedDB databases. Inner window only.
   uint32_t mNumOfIndexedDBDatabases;
 
   // The number of open WebSockets. Inner window only.
   uint32_t mNumOfOpenWebSockets;
+
+  // The number of active user media. Inner window only.
+  uint32_t mNumOfActiveUserMedia;
 };
 
 #define NS_PIDOMWINDOWINNER_IID \
 { 0x775dabc9, 0x8f43, 0x4277, \
   { 0x9a, 0xdb, 0xf1, 0x99, 0x0d, 0x77, 0xcf, 0xfb } }
 
 #define NS_PIDOMWINDOWOUTER_IID \
   { 0x769693d4, 0xb009, 0x4fe2, \
@@ -931,16 +934,22 @@ public:
 
   // Increase/Decrease the number of open WebSockets.
   void UpdateWebSocketCount(int32_t aDelta);
 
   // Return true if there are any open WebSockets that could block
   // timeout-throttling.
   bool HasOpenWebSockets() const;
 
+  // Increase/Decrease the number of active user media.
+  void UpdateUserMediaCount(int32_t aDelta);
+
+  // Return true if there are any currently ongoing user media.
+  bool HasActiveUserMedia() const;
+
 protected:
   void CreatePerformanceObjectIfNeeded();
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindowInner, NS_PIDOMWINDOWINNER_IID)
 
 // NB: It's very very important that these two classes have identical vtables
 // and memory layout!
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -2921,31 +2921,39 @@ MediaManager::AddWindowID(uint64_t aWind
   // Store the WindowID in a hash table and mark as active. The entry is removed
   // when this window is closed or navigated away from.
   // This is safe since we're on main-thread, and the windowlist can only
   // be invalidated from the main-thread (see OnNavigation)
   if (IsWindowStillActive(aWindowId)) {
     MOZ_ASSERT(false, "Window already added");
     return;
   }
+
+  auto* window = nsGlobalWindow::GetInnerWindowWithId(aWindowId);
+  if (window) {
+    window->AsInner()->UpdateUserMediaCount(1);
+  }
+
   GetActiveWindows()->Put(aWindowId, aListener);
 }
 
 void
 MediaManager::RemoveWindowID(uint64_t aWindowId)
 {
   mActiveWindows.Remove(aWindowId);
 
   // get outer windowID
   auto* window = nsGlobalWindow::GetInnerWindowWithId(aWindowId);
   if (!window) {
     LOG(("No inner window for %" PRIu64, aWindowId));
     return;
   }
 
+  window->AsInner()->UpdateUserMediaCount(-1);
+
   nsPIDOMWindowOuter* outer = window->AsInner()->GetOuterWindow();
   if (!outer) {
     LOG(("No outer window for inner %" PRIu64, aWindowId));
     return;
   }
 
   uint64_t outerID = outer->WindowID();