Bug 1425316 P3 Make nsGlobalWindowInner::ShouldReportForServiceWorkerScope() handle checks for controlled windows. r=asuth
authorBen Kelly <ben@wanderview.com>
Tue, 19 Dec 2017 10:04:48 -0500
changeset 448676 ca80e585ab6d3e85030c583d2139167e8c112ff6
parent 448675 81fe3f741dc336b2ce1df1c5d9718ee5b179a24a
child 448677 c08edd442321e8d3b1c04ca25489e6f1634abbeb
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1425316
milestone59.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 1425316 P3 Make nsGlobalWindowInner::ShouldReportForServiceWorkerScope() handle checks for controlled windows. r=asuth
dom/base/nsGlobalWindowInner.cpp
dom/base/nsGlobalWindowInner.h
dom/workers/ServiceWorkerManager.cpp
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -2329,28 +2329,63 @@ Maybe<ServiceWorkerDescriptor>
 nsPIDOMWindowInner::GetController() const
 {
   return Move(nsGlobalWindowInner::Cast(this)->GetController());
 }
 
 bool
 nsGlobalWindowInner::ShouldReportForServiceWorkerScope(const nsAString& aScope)
 {
+  bool result = false;
+
+  nsPIDOMWindowOuter* topOuter = GetScriptableTop();
+  NS_ENSURE_TRUE(topOuter, false);
+
+  nsGlobalWindowInner* topInner =
+    nsGlobalWindowInner::Cast(topOuter->GetCurrentInnerWindow());
+  NS_ENSURE_TRUE(topInner, false);
+
+  topInner->ShouldReportForServiceWorkerScopeInternal(NS_ConvertUTF16toUTF8(aScope),
+                                                      &result);
+  if (result) {
+    return true;
+  }
+
   RefPtr<workers::ServiceWorkerManager> swm =
     workers::ServiceWorkerManager::GetInstance();
   NS_ENSURE_TRUE(swm, false);
 
   bool aResult = false;
-  nsresult rv = swm->ShouldReportToWindow(GetOuterWindowInternal(),
+  nsresult rv = swm->ShouldReportToWindow(topOuter,
                                           NS_ConvertUTF16toUTF8(aScope), &aResult);
   NS_ENSURE_SUCCESS(rv, false);
 
   return aResult;
 }
 
+nsGlobalWindowInner::CallState
+nsGlobalWindowInner::ShouldReportForServiceWorkerScopeInternal(const nsACString& aScope,
+                                                               bool* aResultOut)
+{
+  MOZ_DIAGNOSTIC_ASSERT(aResultOut);
+
+  // First check to see if this window is controlled.  If so, then we have
+  // found a match and are done.
+  const Maybe<ServiceWorkerDescriptor> swd = GetController();
+  if (swd.isSome() && swd.ref().Scope() == aScope) {
+    *aResultOut = true;
+    return CallState::Stop;
+  }
+
+  // The current window doesn't care about this service worker, but maybe
+  // one of our child frames does.
+  return CallOnChildren(&nsGlobalWindowInner::ShouldReportForServiceWorkerScopeInternal,
+                        aScope, aResultOut);
+}
+
 void
 nsGlobalWindowInner::UpdateTopInnerWindow()
 {
   if (IsTopInnerWindow() || !mTopInnerWindow) {
     return;
   }
 
   mTopInnerWindow->UpdateWebSocketCount(-(int32_t)mNumOfOpenWebSockets);
--- a/dom/base/nsGlobalWindowInner.h
+++ b/dom/base/nsGlobalWindowInner.h
@@ -1132,16 +1132,20 @@ private:
   CallChild(nsGlobalWindowInner* aWindow, Method aMethod, Args& ...aArgs)
   {
     return (aWindow->*aMethod)(aArgs...);
   }
 
   void FreezeInternal();
   void ThawInternal();
 
+  CallState ShouldReportForServiceWorkerScopeInternal(const nsACString& aScope,
+                                                      bool* aResultOut);
+
+
 public:
   // Timeout Functions
   // |interval| is in milliseconds.
   int32_t SetTimeoutOrInterval(JSContext* aCx,
                                mozilla::dom::Function& aFunction,
                                int32_t aTimeout,
                                const mozilla::dom::Sequence<JS::Value>& aArguments,
                                bool aIsInterval, mozilla::ErrorResult& aError);
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -3714,43 +3714,16 @@ ServiceWorkerManager::ShouldReportToWind
       // Match.  We should report to this window.
       if (outer && winId == outer->WindowID()) {
         *aResult = true;
         return NS_OK;
       }
     }
   }
 
-  // Next examine controlled documents to see if the windows match.
-  for (auto iter = mControlledDocuments.Iter(); !iter.Done(); iter.Next()) {
-    ServiceWorkerRegistrationInfo* reg = iter.UserData();
-    MOZ_ASSERT(reg);
-    if (!reg->mScope.Equals(aScope)) {
-      continue;
-    }
-
-    nsCOMPtr<nsIDocument> doc = do_QueryInterface(iter.Key());
-    if (!doc || !doc->IsCurrentActiveDocument()) {
-      continue;
-    }
-
-    nsCOMPtr<nsPIDOMWindowOuter> win = doc->GetWindow();
-    if (!win) {
-      continue;
-    }
-
-    win = win->GetScriptableTop();
-
-    // Match.  We should report to this window.
-    if (win && winId == win->WindowID()) {
-      *aResult = true;
-      return NS_OK;
-    }
-  }
-
   // No match.  We should not report to this window.
   return NS_OK;
 }
 
 NS_IMETHODIMP
 ServiceWorkerManager::Observe(nsISupports* aSubject,
                               const char* aTopic,
                               const char16_t* aData)