Bug 1355608 - Part 2: Eagerly transmit permissions to the content process for service worker registrations, r=catalinb
authorMichael Layzell <michael@thelayzells.com>
Tue, 11 Apr 2017 16:37:15 -0400
changeset 355158 0334bfc886c8b6bef2df8c9a130cde364bd5d816
parent 355157 eb249c8b3e6010cc3ae9a12432ee5498d598f8c5
child 355159 6518bd1e2c8cc39fc0bbe6b174e7758059c0bd38
push id89650
push usermichael@thelayzells.com
push dateThu, 27 Apr 2017 17:42:01 +0000
treeherdermozilla-inbound@0334bfc886c8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscatalinb
bugs1355608
milestone55.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 1355608 - Part 2: Eagerly transmit permissions to the content process for service worker registrations, r=catalinb This requires running code which checks whether or not the permissions have arrived, potentially delaying a fetch request for a very short period of time if the permissions are still in-flight. MozReview-Commit-ID: E6OTY6IDThb
dom/ipc/ContentParent.cpp
dom/workers/ServiceWorkerManager.cpp
dom/workers/ServiceWorkerManagerService.cpp
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -2400,16 +2400,26 @@ ContentParent::InitInternal(ProcessPrior
 #endif
 
   {
     RefPtr<ServiceWorkerRegistrar> swr = ServiceWorkerRegistrar::Get();
     MOZ_ASSERT(swr);
 
     nsTArray<ServiceWorkerRegistrationData> registrations;
     swr->GetRegistrations(registrations);
+
+    // Send down to the content process the permissions for each of the
+    // registered service worker scopes.
+    for (auto& registration : registrations) {
+      nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(registration.principal());
+      if (principal) {
+        TransmitPermissionsForPrincipal(principal);
+      }
+    }
+
     Unused << SendInitServiceWorkers(ServiceWorkerConfiguration(registrations));
   }
 
   {
     nsTArray<BlobURLRegistrationData> registrations;
     if (nsHostObjectProtocolHandler::GetAllBlobURLEntries(registrations,
                                                           this)) {
       Unused << SendInitBlobURLs(registrations);
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -21,16 +21,17 @@
 #include "nsISimpleEnumerator.h"
 #include "nsITimer.h"
 #include "nsIUploadChannel2.h"
 #include "nsPIDOMWindow.h"
 #include "nsScriptLoader.h"
 #include "nsServiceManagerUtils.h"
 #include "nsDebug.h"
 #include "nsISupportsPrimitives.h"
+#include "nsIPermissionManager.h"
 
 #include "jsapi.h"
 
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/ErrorNames.h"
 #include "mozilla/LoadContext.h"
 #include "mozilla/Telemetry.h"
@@ -2764,32 +2765,41 @@ ServiceWorkerManager::DispatchFetchEvent
 
   MOZ_DIAGNOSTIC_ASSERT(serviceWorker);
 
   nsCOMPtr<nsIRunnable> continueRunnable =
     new ContinueDispatchFetchEventRunnable(serviceWorker->WorkerPrivate(),
                                            aChannel, loadGroup,
                                            documentId, aIsReload);
 
+  // When this service worker was registered, we also sent down the permissions
+  // for the runnable. They should have arrived by now, but we still need to
+  // wait for them if they have not.
+  nsCOMPtr<nsIRunnable> permissionsRunnable = NS_NewRunnableFunction([=] () {
+      nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
+      MOZ_ALWAYS_SUCCEEDS(permMgr->WhenPermissionsAvailable(serviceWorker->Principal(),
+                                                            continueRunnable));
+    });
+
   nsCOMPtr<nsIChannel> innerChannel;
   aRv = aChannel->GetChannel(getter_AddRefs(innerChannel));
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(innerChannel);
 
   // If there is no upload stream, then continue immediately
   if (!uploadChannel) {
-    MOZ_ALWAYS_SUCCEEDS(continueRunnable->Run());
+    MOZ_ALWAYS_SUCCEEDS(permissionsRunnable->Run());
     return;
   }
   // Otherwise, ensure the upload stream can be cloned directly.  This may
   // require some async copying, so provide a callback.
-  aRv = uploadChannel->EnsureUploadStreamIsCloneable(continueRunnable);
+  aRv = uploadChannel->EnsureUploadStreamIsCloneable(permissionsRunnable);
 }
 
 bool
 ServiceWorkerManager::IsAvailable(nsIPrincipal* aPrincipal,
                                   nsIURI* aURI)
 {
   MOZ_ASSERT(aPrincipal);
   MOZ_ASSERT(aURI);
--- a/dom/workers/ServiceWorkerManagerService.cpp
+++ b/dom/workers/ServiceWorkerManagerService.cpp
@@ -101,16 +101,30 @@ ServiceWorkerManagerService::PropagateRe
       Unused << parent->SendNotifyRegister(aData);
 #ifdef DEBUG
     } else {
       parentFound = true;
 #endif
     }
   }
 
+  // Send permissions fot the newly registered service worker to all of the
+  // content processes.
+  PrincipalInfo pi = aData.principal();
+  NS_DispatchToMainThread(NS_NewRunnableFunction([pi] () {
+        nsTArray<ContentParent*> cps;
+        ContentParent::GetAll(cps);
+        for (auto* cp : cps) {
+          nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(pi);
+          if (principal) {
+            cp->TransmitPermissionsForPrincipal(principal);
+          }
+        }
+      }));
+
 #ifdef DEBUG
   MOZ_ASSERT(parentFound);
 #endif
 }
 
 void
 ServiceWorkerManagerService::PropagateSoftUpdate(
                                       uint64_t aParentID,