Bug 1228382 - Expose an API to relate nsIWorkerDebugger to its nsIServiceWorkerInfo instance. r=ejpbruel
authorAlexandre Poirot <poirot.alex@gmail.com>
Tue, 15 Dec 2015 03:10:53 -0800
changeset 313448 153bbd21f70e38ac3d5a795564ee303c76538afb
parent 313337 efbbf72b9d0a2c54f5fa08a01b6a5d4df8e0f738
child 313449 038664873a7bb62ef3fc904511dc063a28e601a4
push id1079
push userjlund@mozilla.com
push dateFri, 15 Apr 2016 21:02:33 +0000
treeherdermozilla-release@575fbf6786d5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersejpbruel
bugs1228382
milestone46.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 1228382 - Expose an API to relate nsIWorkerDebugger to its nsIServiceWorkerInfo instance. r=ejpbruel
dom/interfaces/base/nsIServiceWorkerManager.idl
dom/workers/ServiceWorkerManager.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/nsIWorkerDebugger.idl
dom/workers/test/serviceworkers/test_serviceworkerinfo.xul
--- a/dom/interfaces/base/nsIServiceWorkerManager.idl
+++ b/dom/interfaces/base/nsIServiceWorkerManager.idl
@@ -37,42 +37,48 @@ interface nsIServiceWorkerInfo : nsISupp
 };
 
 [scriptable, uuid(87e63548-d440-4b8a-b158-65ad1de0211E)]
 interface nsIServiceWorkerRegistrationInfoListener : nsISupports
 {
   void onChange();
 };
 
-[scriptable, builtinclass, uuid(72faba24-0a1b-4284-bad3-d44c044d6d95)]
+[scriptable, builtinclass, uuid(ddbc1fd4-2f2e-4fca-a395-6e010bbedfe3)]
 interface nsIServiceWorkerRegistrationInfo : nsISupports
 {
   readonly attribute nsIPrincipal principal;
 
   readonly attribute DOMString scope;
   readonly attribute DOMString scriptSpec;
 
   readonly attribute nsIServiceWorkerInfo installingWorker;
   readonly attribute nsIServiceWorkerInfo waitingWorker;
   readonly attribute nsIServiceWorkerInfo activeWorker;
 
+  // Allows to get the related nsIServiceWorkerInfo for a given
+  // nsIWorkerDebugger. Over time we shouldn't need this anymore,
+  // and instead always control then nsIWorkerDebugger from
+  // nsIServiceWorkerInfo and not the other way around.
+  nsIServiceWorkerInfo getWorkerByID(in unsigned long long aID);
+
   void addListener(in nsIServiceWorkerRegistrationInfoListener listener);
 
   void removeListener(in nsIServiceWorkerRegistrationInfoListener listener);
 };
 
 [scriptable, uuid(9e523e7c-ad6f-4df0-8077-c74aebbc679d)]
 interface nsIServiceWorkerManagerListener : nsISupports
 {
   void onRegister(in nsIServiceWorkerRegistrationInfo aInfo);
 
   void onUnregister(in nsIServiceWorkerRegistrationInfo aInfo);
 };
 
-[scriptable, builtinclass, uuid(a03f2b64-7aaf-423a-97b0-e1f733cce0f6)]
+[scriptable, builtinclass, uuid(12381ddf-9b51-4c0a-9123-9e7754393a5a)]
 interface nsIServiceWorkerManager : nsISupports
 {
   /**
    * Registers a ServiceWorker with script loaded from `aScriptURI` to act as
    * the ServiceWorker for aScope.  Requires a valid entry settings object on
    * the stack. This means you must call this from content code 'within'
    * a window.
    *
@@ -95,16 +101,19 @@ interface nsIServiceWorkerManager : nsIS
   nsISupports getRegistration(in nsIDOMWindow aWindow, in DOMString aScope);
 
   // Returns a Promise
   nsISupports getReadyPromise(in nsIDOMWindow aWindow);
 
   // Remove ready pending Promise
   void removeReadyPromise(in nsIDOMWindow aWindow);
 
+  nsIServiceWorkerRegistrationInfo getRegistrationByPrincipal(in nsIPrincipal aPrincipal,
+                                                              in DOMString aScope);
+
   /**
    * Call this to request that document `aDoc` be controlled by a ServiceWorker
    * if a registration exists for it's scope.
    *
    * This MUST only be called once per document!
    */
   [notxpcom,nostdcall] void MaybeStartControlling(in nsIDocument aDoc, in DOMString aDocumentId);
 
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -499,16 +499,30 @@ ServiceWorkerRegistrationInfo::GetActive
 {
   AssertIsOnMainThread();
   nsCOMPtr<nsIServiceWorkerInfo> info = do_QueryInterface(mActiveWorker);
   info.forget(aResult);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+ServiceWorkerRegistrationInfo::GetWorkerByID(uint64_t aID, nsIServiceWorkerInfo **aResult)
+{
+  AssertIsOnMainThread();
+  MOZ_ASSERT(aResult);
+
+  RefPtr<ServiceWorkerInfo> info = GetServiceWorkerInfoById(aID);
+  if (NS_WARN_IF(!info)) {
+    return NS_ERROR_FAILURE;
+  }
+  info.forget(aResult);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 ServiceWorkerRegistrationInfo::AddListener(
                             nsIServiceWorkerRegistrationInfoListener *aListener)
 {
   AssertIsOnMainThread();
 
   if (!aListener || mListeners.Contains(aListener)) {
     return NS_ERROR_INVALID_ARG;
   }
@@ -4066,16 +4080,40 @@ ServiceWorkerManager::GetRegistration(ns
   nsresult rv = PrincipalToScopeKey(aPrincipal, scopeKey);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
   }
 
   return GetRegistration(scopeKey, aScope);
 }
 
+NS_IMETHODIMP
+ServiceWorkerManager::GetRegistrationByPrincipal(nsIPrincipal* aPrincipal,
+                                                 const nsAString& aScope,
+                                                 nsIServiceWorkerRegistrationInfo** aInfo)
+{
+  MOZ_ASSERT(aPrincipal);
+  MOZ_ASSERT(aInfo);
+
+  nsCOMPtr<nsIURI> scopeURI;
+  nsresult rv = NS_NewURI(getter_AddRefs(scopeURI), aScope, nullptr, nullptr);
+  if (NS_FAILED(rv)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  RefPtr<ServiceWorkerRegistrationInfo> info =
+    GetServiceWorkerRegistrationInfo(aPrincipal, scopeURI);
+  if (!info) {
+    return NS_ERROR_FAILURE;
+  }
+  info.forget(aInfo);
+
+  return NS_OK;
+}
+
 already_AddRefed<ServiceWorkerRegistrationInfo>
 ServiceWorkerManager::GetRegistration(const nsACString& aScopeKey,
                                       const nsACString& aScope) const
 {
   RefPtr<ServiceWorkerRegistrationInfo> reg;
 
   RegistrationDataPerPrincipal* data;
   if (!mRegistrationInfos.Get(aScopeKey, &data)) {
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -3706,16 +3706,46 @@ WorkerDebugger::GetWindow(nsIDOMWindow**
   }
 
   nsCOMPtr<nsPIDOMWindow> window = mWorkerPrivate->GetWindow();
   window.forget(aResult);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+WorkerDebugger::GetPrincipal(nsIPrincipal** aResult)
+{
+  AssertIsOnMainThread();
+  MOZ_ASSERT(aResult);
+
+  if (!mWorkerPrivate) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  nsCOMPtr<nsIPrincipal> prin = mWorkerPrivate->GetPrincipal();
+  prin.forget(aResult);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+WorkerDebugger::GetServiceWorkerID(uint32_t* aResult)
+{
+  AssertIsOnMainThread();
+  MOZ_ASSERT(aResult);
+
+  if (!mWorkerPrivate || !mWorkerPrivate->IsServiceWorker()) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  *aResult = mWorkerPrivate->ServiceWorkerID();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 WorkerDebugger::Initialize(const nsAString& aURL, JSContext* aCx)
 {
   AssertIsOnMainThread();
 
   MutexAutoLock lock(mMutex);
 
   if (!mWorkerPrivate) {
     return NS_ERROR_UNEXPECTED;
--- a/dom/workers/nsIWorkerDebugger.idl
+++ b/dom/workers/nsIWorkerDebugger.idl
@@ -1,24 +1,25 @@
 #include "nsISupports.idl"
 
 interface nsIDOMWindow;
+interface nsIPrincipal;
 
 [scriptable, uuid(9cf3b48e-361d-486a-8917-55cf8d00bb41)]
 interface nsIWorkerDebuggerListener : nsISupports
 {
   void onClose();
 
   void onError(in DOMString filename, in unsigned long lineno,
                in DOMString message);
 
   void onMessage(in DOMString message);
 };
 
-[scriptable, builtinclass, uuid(2b8d801c-973d-425b-a6d5-1a2505dd8b78)]
+[scriptable, builtinclass, uuid(2fe71e0d-3a39-40a3-b809-8418b72328b4)]
 interface nsIWorkerDebugger : nsISupports
 {
   const unsigned long TYPE_DEDICATED = 0;
   const unsigned long TYPE_SHARED = 1;
   const unsigned long TYPE_SERVICE = 2;
 
   readonly attribute bool isClosed;
 
@@ -29,16 +30,20 @@ interface nsIWorkerDebugger : nsISupport
   readonly attribute nsIWorkerDebugger parent;
 
   readonly attribute unsigned long type;
 
   readonly attribute DOMString url;
 
   readonly attribute nsIDOMWindow window;
 
+  readonly attribute nsIPrincipal principal;
+
+  readonly attribute unsigned long serviceWorkerID;
+
   [implicit_jscontext]
   void initialize(in DOMString url);
 
   [implicit_jscontext, binaryname(PostMessageMoz)]
   void postMessage(in DOMString message);
 
   void addListener(in nsIWorkerDebuggerListener listener);
 
--- a/dom/workers/test/serviceworkers/test_serviceworkerinfo.xul
+++ b/dom/workers/test/serviceworkers/test_serviceworkerinfo.xul
@@ -65,17 +65,31 @@
 
           let activeWorker = registration.activeWorker;
           ok(activeWorker !== null, "Worker is not active!");
           ok(activeWorker.debugger === null);
 
           info("Attach a debugger to the service worker, and check that the " +
                "service worker is restarted.");
           activeWorker.attachDebugger();
-          ok(activeWorker.debugger !== null);
+          let workerDebugger = activeWorker.debugger;
+          ok(workerDebugger !== null);
+
+          // Verify debugger properties
+          ok(workerDebugger.principal instanceof Ci.nsIPrincipal);
+          is(workerDebugger.url, EXAMPLE_URL + "worker.js");
+
+          info("Verify that getRegistrationByPrincipal return the same " +
+               "nsIServiceWorkerRegistrationInfo");
+          let reg = swm.getRegistrationByPrincipal(workerDebugger.principal,
+                                                   workerDebugger.url);
+          is(reg, registration);
+
+          info("Check that getWorkerByID returns the same nsIWorkerDebugger");
+          is(activeWorker, reg.getWorkerByID(workerDebugger.serviceWorkerID));
 
           info("Detach the debugger from the service worker, and check that " +
                "the service worker eventually shuts down again.");
           promise = waitForServiceWorkerShutdown();
           activeWorker.detachDebugger();
           yield promise;
           ok(activeWorker.debugger === null);