diff --git a/dom/interfaces/base/nsIServiceWorkerManager.idl b/dom/interfaces/base/nsIServiceWorkerManager.idl index cc1256303cca..ac391fba342f 100644 --- a/dom/interfaces/base/nsIServiceWorkerManager.idl +++ b/dom/interfaces/base/nsIServiceWorkerManager.idl @@ -162,6 +162,16 @@ interface nsIServiceWorkerManagerListener : nsISupports void onRegister(in nsIServiceWorkerRegistrationInfo aInfo); void onUnregister(in nsIServiceWorkerRegistrationInfo aInfo); + + /** + * Called by ServiceWorker bypass mitigations when checking whether an + * origin's quota usage is sufficiently full that we need to clear the origin + * (and possibly group's) data as part of our mitigation. + * This notification is provided primarily for testing code that needs to wait + * for this check to happen but has no other mechanism for knowing it's + * completed. Probably not relevant to devtools. + */ + void onQuotaUsageCheckFinish(in nsIServiceWorkerRegistrationInfo aInfo); }; [scriptable, builtinclass, uuid(7404c8e8-4d47-4449-8ed1-47d1261d4e33)] diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/ServiceWorkerManager.cpp index 01c6393285df..857b782c4f8f 100644 --- a/dom/serviceworkers/ServiceWorkerManager.cpp +++ b/dom/serviceworkers/ServiceWorkerManager.cpp @@ -1699,7 +1699,6 @@ void ServiceWorkerManager::AddScopeAndRegistration( MOZ_ASSERT(!scopeKey.IsEmpty()); auto* const data = swm->mRegistrationInfos.GetOrInsertNew(scopeKey); - data->mScopeContainer.InsertScope(aScope); data->mInfos.InsertOrUpdate(aScope, RefPtr{aInfo}); swm->NotifyListenersOnRegister(aInfo); @@ -1799,6 +1798,14 @@ void ServiceWorkerManager::MaybeRemoveRegistrationInfo( if (entry.Data()->mScopeContainer.IsEmpty() && entry.Data()->mJobQueues.Count() == 0) { entry.Remove(); + + // Need to reset the mQuotaUsageCheckCount, if + // RegistrationDataPerPrincipal:: mScopeContainer is empty. This + // RegistrationDataPerPrincipal might be reused, such that quota usage + // mitigation can be triggered for the new added registration. + } else if (entry.Data()->mScopeContainer.IsEmpty() && + entry.Data()->mQuotaUsageCheckCount) { + entry.Data()->mQuotaUsageCheckCount = 0; } } } @@ -2967,6 +2974,15 @@ void ServiceWorkerManager::NotifyListenersOnUnregister( } } +void ServiceWorkerManager::NotifyListenersOnQuotaUsageCheckFinish( + nsIServiceWorkerRegistrationInfo* aRegistration) { + nsTArray> listeners( + mListeners.Clone()); + for (size_t index = 0; index < listeners.Length(); ++index) { + listeners[index]->OnQuotaUsageCheckFinish(aRegistration); + } +} + class UpdateTimerCallback final : public nsITimerCallback, public nsINamed { nsCOMPtr mPrincipal; const nsCString mScope; diff --git a/dom/serviceworkers/ServiceWorkerManager.h b/dom/serviceworkers/ServiceWorkerManager.h index fe0cd14289f8..8f6eaa8655a4 100644 --- a/dom/serviceworkers/ServiceWorkerManager.h +++ b/dom/serviceworkers/ServiceWorkerManager.h @@ -353,6 +353,9 @@ class ServiceWorkerManager final : public nsIServiceWorkerManager, void NotifyListenersOnUnregister( nsIServiceWorkerRegistrationInfo* aRegistration); + void NotifyListenersOnQuotaUsageCheckFinish( + nsIServiceWorkerRegistrationInfo* aRegistration); + void ScheduleUpdateTimer(nsIPrincipal* aPrincipal, const nsACString& aScope); void UpdateTimerFired(nsIPrincipal* aPrincipal, const nsACString& aScope);