/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "domstubs.idl" #include "nsIRequest.idl" interface mozIDOMWindow; interface nsPIDOMWindowInner; interface mozIDOMWindowProxy; interface nsIArray; interface nsIInterceptedChannel; interface nsIPrincipal; interface nsIPushSubscription; interface nsIRunnable; interface nsIURI; %{C++ namespace mozilla { namespace dom { class ClientInfo; class ServiceWorkerDescriptor; class IPCNotification; } // namespace dom } // namespace mozilla %} [ref] native const_ClientInfoRef(const mozilla::dom::ClientInfo); [ref] native const_ServiceWorkerDescriptorRef(const mozilla::dom::ServiceWorkerDescriptor); [ref] native const_IPCNotificationRef(const mozilla::dom::IPCNotification); [scriptable, uuid(52ee2c9d-ee87-4caf-9588-23ae77ff8798)] interface nsIServiceWorkerUnregisterCallback : nsISupports { // aState is true if the unregistration succeded. // It's false if this ServiceWorkerRegistration doesn't exist. void unregisterSucceeded(in boolean aState); void unregisterFailed(); }; interface nsIWorkerDebugger; [scriptable, builtinclass, uuid(76e357ed-208d-4e4c-9165-1c4059707879)] interface nsIServiceWorkerInfo : nsISupports { // State values below should match the ServiceWorkerState enumeration. const unsigned short STATE_PARSED = 0; const unsigned short STATE_INSTALLING = 1; const unsigned short STATE_INSTALLED = 2; const unsigned short STATE_ACTIVATING = 3; const unsigned short STATE_ACTIVATED = 4; const unsigned short STATE_REDUNDANT = 5; const unsigned short STATE_UNKNOWN = 6; readonly attribute AString id; readonly attribute AString scriptSpec; readonly attribute AString cacheName; // How many times has this ServiceWorker been launched since the registration // was loaded? This value is not persistent and starts at 0 every time the // browser restarts. The value also inherently starts at 0 for a freshly // installed or updated ServiceWorker. readonly attribute unsigned long launchCount; readonly attribute unsigned short state; readonly attribute nsIWorkerDebugger debugger; // Return whether the ServiceWorker has a "fetch" event listener. Throws if // this is unknown because the worker's main script hasn't finished executing // (when exposed as evaluatingWorker). readonly attribute boolean handlesFetchEvents; readonly attribute PRTime installedTime; readonly attribute PRTime activatedTime; readonly attribute PRTime redundantTime; // Returns the lifetime deadline of the ServiceWorker as the number of // milliseconds since the (parent) process was created or 0 if there is no // current deadline. This is primarily intended to allow tests to compare // consistent values, not be useful in general. But note that // `Components.utils.now()` operates in the same units (milliseconds since // current process startup), and so can be used to hackily translate to wall // clock time. readonly attribute double lifetimeDeadline; // Total number of navigation faults experienced by this ServiceWorker since // it was loaded from disk at startup or was installed. readonly attribute unsigned long navigationFaultCount; // Testing mechanism to induce synthetic failure of fetch events. If set to // something other than NS_OK, all fetch events dispatched will be propagated // to the content process, but when it comes time to dispatch the fetch event, // the cancellation control flow path will be triggered. attribute nsresult testingInjectCancellation; void attachDebugger(); void detachDebugger(); // Forcibly terminate the ServiceWorker if it is running, returning a promise // that will be resolved when the worker is fully terminated. If the // ServiceWorker was not running, the promise will be resolved immediately. // // For the purposes of the ServiceWorkerManager, it's as if the ServiceWorker // is already dead when the call completes and returns the Promise. Any new // functional events dispatched at the ServiceWorker will result in a new // instance/global being spun up. [implicit_jscontext] Promise terminateWorker(); }; [scriptable, uuid(87e63548-d440-4b8a-b158-65ad1de0211E)] interface nsIServiceWorkerRegistrationInfoListener : nsISupports { void onChange(); }; [scriptable, builtinclass, uuid(ddbc1fd4-2f2e-4fca-a395-6e010bbedfe3)] interface nsIServiceWorkerRegistrationInfo : nsISupports { // State values below should match the ServiceWorkerUpdateViaCache enumeration. const unsigned short UPDATE_VIA_CACHE_IMPORTS = 0; const unsigned short UPDATE_VIA_CACHE_ALL = 1; const unsigned short UPDATE_VIA_CACHE_NONE = 2; readonly attribute nsIPrincipal principal; readonly attribute boolean unregistered; readonly attribute AString scope; readonly attribute AString scriptSpec; readonly attribute unsigned short updateViaCache; readonly attribute PRTime lastUpdateTime; readonly attribute nsIServiceWorkerInfo evaluatingWorker; readonly attribute nsIServiceWorkerInfo installingWorker; readonly attribute nsIServiceWorkerInfo waitingWorker; readonly attribute nsIServiceWorkerInfo activeWorker; // Exposes the number of times we have ever checked the usage of this origin // for the purposes of mitigating ServiceWorker navigation faults that we // suspect to be due to quota limit problems. This should start out 0 and // max out at 1 for the time being. // // Note that the underlying value is tracked on our per-Principal data, but // we don't currently expose that data directly via XPCOM so we're exposing // this here as the next best thing and because most non-test consumers would // work in terms of the registration anyways. // // This will return -1 if there is no longer any per-origin data because the // last registration for the origin (principal) has been unregistered. // (Retaining a reference to this interface does not impact anything the // underlying scope-to-registration map that is implemented per spec.) readonly attribute long quotaUsageCheckCount; // 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. Returns // null if the service worker is no longer registered. nsIServiceWorkerInfo getWorkerByID(in unsigned long long aID); void addListener(in nsIServiceWorkerRegistrationInfoListener listener); void removeListener(in nsIServiceWorkerRegistrationInfoListener listener); // Terminate all the service worker relate to this registration. // This is used by the WebExtensions framework to shutdown the extension's // background service workers as part of shutdown, which happens when: // - the extension has been disabled. // - the extension is shutting down to be updated. // - the extension is shutting down as part of the uninstall flow. // // All the service workers instances related to this registration are expected // to be terminate immediately. // // TODO - Bug 1638099: This method should also allow the WebExtension framework // to mark the registration as disabled (e.g. through an additional parameter), // to avoid it to be started again until the WebExtensions framework does explicitly // mark it back to enabled. void forceShutdown(); }; [scriptable, uuid(9e523e7c-ad6f-4df0-8077-c74aebbc679d)] 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)] interface nsIServiceWorkerManager : nsISupports { /** * A testing helper that is meant to only be used in xpcshell-test to test behaviors * that would need a browser restart to re-initialize the ServiceWorkerManager from * the service worker registration dumped on disk (the one listed in the serviceworker.txt * file part of the Firefox profile directory). * * NOTE: this test helper does * - fail if "dom.serviceWorkers.testing.enabled" is not set to true * - fail if there are controlled clients (the test case is responsible of making sure that * there is none when this method is being called) * - shutdown and clear all service worker registrations (but without removing them from * the registration stored in serviceworker.txt) * - force reload the registration data stored in serviceworker.txt (but the test case using * this helper is responsible to be sure that the registrations have been already written * on disk) */ void reloadRegistrationsForTest(); /** * A testing helper that registers a service worker for testing purpose (e.g. used to test * a remote worker that has to spawn a new process to be launched). * This method can only be used when "dom.serviceWorkers.testing.enabled" is true and * it doesn't support all the registration options (e.g. updateViaCache is set automatically * to "imports"). */ [implicit_jscontext] Promise registerForTest(in nsIPrincipal aPrincipal, in AString aScope, in AString aScriptURL); /** * Register an extension background service worker for a given * extension principal and return a promise that resolves to the * nsIServiceWorkerRegistrationInfo (or rejects if there was one * already registered). */ [implicit_jscontext] Promise registerForAddonPrincipal(in nsIPrincipal aPrincipal); /** * Get an extension background service worker registration for a * given extension principal, return an nsIServiceWorkerRegistrationInfo * if one exists (or null if no registration has been found). */ void getRegistrationForAddonPrincipal(in nsIPrincipal aPrincipal, [optional, retval] out nsIServiceWorkerRegistrationInfo regInfo); /** * Wake up the extension background service worker given its extension base url, * for an API event identified by the namespace and event name strings. * * Returns a Promise which is resolved to true if a listener has been subscribed * during the synchronous worker script execution for the expected WebExtensions * API event. * * NOTE: ExtensionBrowser and ExtensionEventManager interfaces are keeping track * of these listeners. These are WebExtensions API event listeners and they do not * involve any functional events at all. */ [implicit_jscontext] Promise wakeForExtensionAPIEvent(in AString aExtensionBaseURL, in AString aAPINamespace, in AString aAPIEventName); /** * Unregister an existing ServiceWorker registration for `aScope`. * It keeps aCallback alive until the operation is concluded. */ void unregister(in nsIPrincipal aPrincipal, in nsIServiceWorkerUnregisterCallback aCallback, in AString aScope); nsIServiceWorkerRegistrationInfo getRegistrationByPrincipal(in nsIPrincipal aPrincipal, in AString aScope); [notxpcom, nostdcall] boolean StartControlling(in const_ClientInfoRef aClientInfo, in const_ServiceWorkerDescriptorRef aServiceWorker); // Testing AString getScopeForUrl(in nsIPrincipal aPrincipal, in AString aPath); // It returns an array of nsIServiceWorkerRegistrationInfos. nsIArray getAllRegistrations(); // For clear-origin-attributes-data void removeRegistrationsByOriginAttributes(in AString aOriginAttributes); // It calls unregister() in each child process. The callback is used to // inform when unregister() is completed on the current process. void propagateUnregister(in nsIPrincipal aPrincipal, in nsIServiceWorkerUnregisterCallback aCallback, in AString aScope); [noscript] void sendNotificationClickEvent(in ACString aOriginSuffix, in AString scope, in const_IPCNotificationRef aNotification, in AString aAction); [noscript] void sendNotificationCloseEvent(in ACString aOriginSuffix, in AString scope, in const_IPCNotificationRef aNotification); [optional_argc] void sendPushEvent(in ACString aOriginAttributes, in ACString aScope, [optional] in Array aDataBytes); void sendPushSubscriptionChangeEvent(in ACString aOriginAttributes, in ACString scope, [optional] in nsIPushSubscription aOldSubscription); void addListener(in nsIServiceWorkerManagerListener aListener); void removeListener(in nsIServiceWorkerManagerListener aListener); }; %{ C++ #define SERVICEWORKERMANAGER_CONTRACTID "@mozilla.org/serviceworkers/manager;1" %}