Bug 1469941 Note DOMContentLoaded on the ClientSource and trigger service worker update in appropriate process. r=mrbkap
authorBen Kelly <ben@wanderview.com>
Sat, 23 Jun 2018 10:11:47 -0700
changeset 423447 3f78c17a1ceaaaa4b7e1fa04c3375f96e5acc9c8
parent 423446 c208fc0cd931b26fd918c5be4367402c17e93ff0
child 423448 c74adc90978c1a2182fc89909499e9d4c3075c1f
push id34181
push userbtara@mozilla.com
push dateSun, 24 Jun 2018 09:37:59 +0000
treeherdermozilla-central@d69b7fc884fb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs1469941
milestone62.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 1469941 Note DOMContentLoaded on the ClientSource and trigger service worker update in appropriate process. r=mrbkap
dom/base/nsDocument.cpp
dom/base/nsGlobalWindowInner.cpp
dom/base/nsGlobalWindowInner.h
dom/base/nsPIDOMWindow.h
dom/clients/manager/ClientSource.cpp
dom/clients/manager/ClientSource.h
dom/clients/manager/ClientSourceParent.cpp
dom/clients/manager/ClientSourceParent.h
dom/clients/manager/PClientSource.ipdl
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -5092,16 +5092,22 @@ nsIDocument::DispatchContentLoadedEvents
   // event.
   Element* root = GetRootElement();
   if (root && root->HasAttr(kNameSpaceID_None, nsGkAtoms::manifest)) {
     nsContentUtils::DispatchChromeEvent(this, this,
                                         NS_LITERAL_STRING("MozApplicationManifest"),
                                         true, true);
   }
 
+  nsPIDOMWindowInner* inner = GetInnerWindow();
+  if (inner) {
+    inner->NoteDOMContentLoaded();
+  }
+
+  // TODO
   if (mMaybeServiceWorkerControlled) {
     using mozilla::dom::ServiceWorkerManager;
     RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
     if (swm) {
       Maybe<ClientInfo> clientInfo = GetClientInfo();
       if (clientInfo.isSome()) {
         swm->MaybeCheckNavigationUpdate(clientInfo.ref());
       }
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -2350,16 +2350,22 @@ nsPIDOMWindowInner::GetOrCreateServiceWo
 }
 
 void
 nsPIDOMWindowInner::NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope)
 {
   nsGlobalWindowInner::Cast(this)->NoteCalledRegisterForServiceWorkerScope(aScope);
 }
 
+void
+nsPIDOMWindowInner::NoteDOMContentLoaded()
+{
+  nsGlobalWindowInner::Cast(this)->NoteDOMContentLoaded();
+}
+
 bool
 nsGlobalWindowInner::ShouldReportForServiceWorkerScope(const nsAString& aScope)
 {
   bool result = false;
 
   nsPIDOMWindowOuter* topOuter = GetScriptableTop();
   NS_ENSURE_TRUE(topOuter, false);
 
@@ -2467,16 +2473,26 @@ nsGlobalWindowInner::NoteCalledRegisterF
   if (!mClientSource) {
     return;
   }
 
   mClientSource->NoteCalledRegisterForServiceWorkerScope(aScope);
 }
 
 void
+nsGlobalWindowInner::NoteDOMContentLoaded()
+{
+  if (!mClientSource) {
+    return;
+  }
+
+  mClientSource->NoteDOMContentLoaded();
+}
+
+void
 nsGlobalWindowInner::MigrateStateForDocumentOpen(nsGlobalWindowInner* aOldInner)
 {
   MOZ_DIAGNOSTIC_ASSERT(aOldInner);
   MOZ_DIAGNOSTIC_ASSERT(aOldInner != this);
   MOZ_DIAGNOSTIC_ASSERT(mDoc);
 
   // Rebind DETH objects to the new global created by document.open().
   // XXX: Is this correct?  We should consider if the spec and our
--- a/dom/base/nsGlobalWindowInner.h
+++ b/dom/base/nsGlobalWindowInner.h
@@ -360,16 +360,18 @@ public:
   virtual RefPtr<mozilla::dom::ServiceWorker>
   GetOrCreateServiceWorker(const mozilla::dom::ServiceWorkerDescriptor& aDescriptor) override;
 
   RefPtr<mozilla::dom::ServiceWorkerRegistration>
   GetOrCreateServiceWorkerRegistration(const mozilla::dom::ServiceWorkerRegistrationDescriptor& aDescriptor) override;
 
   void NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope);
 
+  void NoteDOMContentLoaded();
+
   virtual nsresult FireDelayedDOMEvents() override;
 
   virtual nsresult SetNewDocument(nsIDocument *aDocument,
                                   nsISupports *aState,
                                   bool aForceReuseInnerWindow) override;
 
   virtual void SetOpenerWindow(nsPIDOMWindowOuter* aOpener,
                                bool aOriginalOpener) override;
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -327,16 +327,18 @@ public:
   mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const;
   mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController() const;
 
   RefPtr<mozilla::dom::ServiceWorker>
   GetOrCreateServiceWorker(const mozilla::dom::ServiceWorkerDescriptor& aDescriptor);
 
   void NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope);
 
+  void NoteDOMContentLoaded();
+
   mozilla::dom::TabGroup* TabGroup();
 
   virtual nsPIDOMWindowOuter* GetPrivateRoot() = 0;
 
   virtual mozilla::dom::CustomElementRegistry* CustomElements() = 0;
 
   // XXX: This is called on inner windows
   virtual nsPIDOMWindowOuter* GetScriptableTop() = 0;
--- a/dom/clients/manager/ClientSource.cpp
+++ b/dom/clients/manager/ClientSource.cpp
@@ -472,16 +472,32 @@ ClientSource::InheritController(const Se
 }
 
 const Maybe<ServiceWorkerDescriptor>&
 ClientSource::GetController() const
 {
   return mController;
 }
 
+void
+ClientSource::NoteDOMContentLoaded()
+{
+  if (mController.isSome() && !ServiceWorkerParentInterceptEnabled()) {
+    AssertIsOnMainThread();
+    RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
+    if (swm) {
+      swm->MaybeCheckNavigationUpdate(mClientInfo);
+    }
+  }
+
+  MaybeExecute([] (PClientSourceChild* aActor) {
+    aActor->SendNoteDOMContentLoaded();
+  });
+}
+
 RefPtr<ClientOpPromise>
 ClientSource::Focus(const ClientFocusArgs& aArgs)
 {
   NS_ASSERT_OWNINGTHREAD(ClientSource);
 
   RefPtr<ClientOpPromise> ref;
 
   if (mClientInfo.Type() != ClientType::Window) {
--- a/dom/clients/manager/ClientSource.h
+++ b/dom/clients/manager/ClientSource.h
@@ -145,16 +145,21 @@ public:
   void
   InheritController(const ServiceWorkerDescriptor& aServiceWorker);
 
   // Get the ClientSource's current controlling service worker, if one has
   // been set.
   const Maybe<ServiceWorkerDescriptor>&
   GetController() const;
 
+  // Note that the client has reached DOMContentLoaded.  Only applies to window
+  // clients.
+  void
+  NoteDOMContentLoaded();
+
   RefPtr<ClientOpPromise>
   Focus(const ClientFocusArgs& aArgs);
 
   RefPtr<ClientOpPromise>
   PostMessage(const ClientPostMessageArgs& aArgs);
 
   RefPtr<ClientOpPromise>
   Claim(const ClientClaimArgs& aArgs);
--- a/dom/clients/manager/ClientSourceParent.cpp
+++ b/dom/clients/manager/ClientSourceParent.cpp
@@ -165,16 +165,34 @@ ClientSourceParent::RecvInheritControlle
       });
 
     MOZ_ALWAYS_SUCCEEDS(SystemGroup::Dispatch(TaskCategory::Other, r.forget()));
   }
 
   return IPC_OK();
 }
 
+IPCResult
+ClientSourceParent::RecvNoteDOMContentLoaded()
+{
+  if (mController.isSome() && ServiceWorkerParentInterceptEnabled()) {
+    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
+      "ClientSourceParent::RecvNoteDOMContentLoaded",
+      [clientInfo = mClientInfo] () {
+        RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
+        NS_ENSURE_TRUE_VOID(swm);
+
+        swm->MaybeCheckNavigationUpdate(clientInfo);
+      });
+
+    MOZ_ALWAYS_SUCCEEDS(SystemGroup::Dispatch(TaskCategory::Other, r.forget()));
+  }
+  return IPC_OK();
+}
+
 void
 ClientSourceParent::ActorDestroy(ActorDestroyReason aReason)
 {
   DebugOnly<bool> removed = mService->RemoveSource(this);
   MOZ_ASSERT(removed);
 
   nsTArray<ClientHandleParent*> handleList(mHandleList);
   for (ClientHandleParent* handle : handleList) {
--- a/dom/clients/manager/ClientSourceParent.h
+++ b/dom/clients/manager/ClientSourceParent.h
@@ -43,16 +43,19 @@ class ClientSourceParent final : public 
   RecvFreeze() override;
 
   mozilla::ipc::IPCResult
   RecvThaw() override;
 
   mozilla::ipc::IPCResult
   RecvInheritController(const ClientControlledArgs& aArgs) override;
 
+  mozilla::ipc::IPCResult
+  RecvNoteDOMContentLoaded() override;
+
   void
   ActorDestroy(ActorDestroyReason aReason) override;
 
   PClientSourceOpParent*
   AllocPClientSourceOpParent(const ClientOpConstructorArgs& aArgs) override;
 
   bool
   DeallocPClientSourceOpParent(PClientSourceOpParent* aActor) override;
--- a/dom/clients/manager/PClientSource.ipdl
+++ b/dom/clients/manager/PClientSource.ipdl
@@ -21,16 +21,17 @@ sync protocol PClientSource
 
 parent:
   sync WorkerSyncPing();
   async Teardown();
   async ExecutionReady(ClientSourceExecutionReadyArgs aArgs);
   async Freeze();
   async Thaw();
   async InheritController(ClientControlledArgs aArgs);
+  async NoteDOMContentLoaded();
 
 child:
   async PClientSourceOp(ClientOpConstructorArgs aArgs);
 
   async __delete__();
 };
 
 } // namespace dom